diff --git a/CONTRIBUTE b/CONTRIBUTE index aaf26ece5a7..eda300f01bc 100644 --- a/CONTRIBUTE +++ b/CONTRIBUTE @@ -241,6 +241,8 @@ formatting them: there will be no individual ChangeLog entries beyond the one in the summary line. +- If the commit message is a single-line, it should end with a period. + - If the commit has more than one author, the commit message should contain separate lines to mention the other authors, like the following: diff --git a/admin/MAINTAINERS b/admin/MAINTAINERS index 207a6a920f9..d7416fa783f 100644 --- a/admin/MAINTAINERS +++ b/admin/MAINTAINERS @@ -245,9 +245,6 @@ Sean Whitton ============================================================================== 2. Areas that someone is willing to maintain, although he would not necessarily mind if someone else was the official maintainer. -This list also includes people who are in the process of handing over -maintainership to someone listed above, but who want to continue to be -CC'd as though they were still the primary maintainer, in the meantime. ============================================================================== Eli Zaretskii @@ -342,7 +339,6 @@ Tassilo Horn Dmitry Gutov lisp/whitespace.el - lisp/vc/* Vibhav Pant lisp/net/browse-url.el diff --git a/admin/gnulib-patches/lib/getloadavg.c.diff b/admin/gnulib-patches/lib/getloadavg.c.diff new file mode 100644 index 00000000000..afa633703b7 --- /dev/null +++ b/admin/gnulib-patches/lib/getloadavg.c.diff @@ -0,0 +1,14 @@ +diff --git a/lib/getloadavg.c b/lib/getloadavg.c +index 9da41c16c02..1cb1c01097d 100644 +--- a/lib/getloadavg.c ++++ b/lib/getloadavg.c +@@ -499,7 +499,8 @@ getloadavg (double loadavg[], int nelem) + } + # endif + +-# if !defined (LDAV_DONE) && (defined __linux__ || defined __ANDROID__) ++# if !defined (LDAV_DONE) && (defined __linux__ || defined __ANDROID__) \ ++ && (!defined __ANDROID__ || __ANDROID_API__ >= 13) + /* Linux without glibc, Android, Cygwin */ + # define LDAV_DONE + # undef LOAD_AVE_TYPE diff --git a/admin/merge-gnulib b/admin/merge-gnulib index ae433961df3..88f74d6eb7f 100755 --- a/admin/merge-gnulib +++ b/admin/merge-gnulib @@ -58,7 +58,7 @@ GNULIB_MODULES=' AVOIDED_MODULES=' access btowc chmod close crypto/af_alg dup fchdir fstat gnulib-i18n iswblank iswctype iswdigit iswxdigit langinfo-h libgmp-mpq - localename-unsafe-limited lock + locale-h localename-unsafe-limited lock mbrtowc mbsinit memchr mkdir msvc-inval msvc-nothrow nl_langinfo openat-die opendir pthread-h raise save-cwd select setenv sigprocmask stat stdarg-h @@ -80,6 +80,10 @@ case $src in *) src=$src/ ;; esac +GNULIB_TOOL_FLAGS="$GNULIB_TOOL_FLAGS + --local-dir="$src"admin/gnulib-patches +" + # Gnulib's source directory. gnulib_srcdir=${1-$src../gnulib} diff --git a/admin/notes/emba b/admin/notes/emba index 2d0aaa6e8f0..cf4184ccc92 100644 --- a/admin/notes/emba +++ b/admin/notes/emba @@ -91,7 +91,7 @@ emba.gnu.org:5050, is not accessible publicly. Instead, the container images must be build locally. Change the current directory to a recent Emacs branch (not a worktree), and apply the command - docker build --target emacs-inotify --tag emacs-inotify \ + docker buildx build --target emacs-inotify --tag emacs-inotify \ -f test/infra/Dockerfile.emba . This creates the Debian-based image emacs-inotify, based on the diff --git a/admin/notes/tree-sitter/build-module/build.sh b/admin/notes/tree-sitter/build-module/build.sh index 4f3c6da3c5f..0cece86e5f7 100755 --- a/admin/notes/tree-sitter/build-module/build.sh +++ b/admin/notes/tree-sitter/build-module/build.sh @@ -59,8 +59,11 @@ case "${lang}" in sourcedir="tree-sitter-typescript/tsx/src" grammardir="tree-sitter-typescript/tsx" ;; + "toml") + org="tree-sitter-grammars" + ;; "yaml") - org="ikatyang" + org="tree-sitter-grammars" ;; esac diff --git a/admin/nt/dist-build/emacs.nsi b/admin/nt/dist-build/emacs.nsi index 4a5de4f85f9..9239eb07ec7 100644 --- a/admin/nt/dist-build/emacs.nsi +++ b/admin/nt/dist-build/emacs.nsi @@ -72,6 +72,9 @@ Section # add registry key to enable uninstall from control panel WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "GNU Emacs ${VERSION_BRANCH}" + WriteRegStr HKLM "${UNINST_KEY}" "DisplayIcon" "$\"$UninstallerPath$\"" + WriteRegStr HKLM "${UNINST_KEY}" "DisplayVersion" "${VERSION_BRANCH}" + WriteRegStr HKLM "${UNINST_KEY}" "Publisher" "Free Software Foundation, Inc." WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" "$\"$UninstallerPath$\"" ;Create shortcuts diff --git a/admin/tree-sitter/treesit-admin.el b/admin/tree-sitter/treesit-admin.el index 86174ed2625..f41c4592039 100644 --- a/admin/tree-sitter/treesit-admin.el +++ b/admin/tree-sitter/treesit-admin.el @@ -72,31 +72,33 @@ ;;; Query validation (defvar treesit-admin--builtin-language-sources - '((c "https://github.com/tree-sitter/tree-sitter-c") - (cpp "https://github.com/tree-sitter/tree-sitter-cpp") - (cmake "https://github.com/uyha/tree-sitter-cmake") - (dockerfile "https://github.com/camdencheek/tree-sitter-dockerfile") - (go "https://github.com/tree-sitter/tree-sitter-go") - (ruby "https://github.com/tree-sitter/tree-sitter-ruby") - (javascript "https://github.com/tree-sitter/tree-sitter-javascript") + '((c "https://github.com/tree-sitter/tree-sitter-c" "v0.23.4") + (cpp "https://github.com/tree-sitter/tree-sitter-cpp" "v0.23.4") + (cmake "https://github.com/uyha/tree-sitter-cmake" "v0.5.0") + (dockerfile "https://github.com/camdencheek/tree-sitter-dockerfile" "v0.2.0") + (go "https://github.com/tree-sitter/tree-sitter-go" "v0.23.4") + (ruby "https://github.com/tree-sitter/tree-sitter-ruby" "v0.23.1") + (javascript "https://github.com/tree-sitter/tree-sitter-javascript" "v0.23.1") (typescript "https://github.com/tree-sitter/tree-sitter-typescript" - nil "typescript/src") + "v0.23.2" "typescript/src") (tsx "https://github.com/tree-sitter/tree-sitter-typescript" - nil "tsx/src") - (json "https://github.com/tree-sitter/tree-sitter-json") - (rust "https://github.com/tree-sitter/tree-sitter-rust") + "v0.23.2" "tsx/src") + (json "https://github.com/tree-sitter/tree-sitter-json" "v0.24.8") + (rust "https://github.com/tree-sitter/tree-sitter-rust" "v0.23.2") (php "https://github.com/tree-sitter/tree-sitter-php" - nil "php/src") - (css "https://github.com/tree-sitter/tree-sitter-css") + "v0.23.11" "php/src") + (css "https://github.com/tree-sitter/tree-sitter-css" "v0.23.1") (phpdoc "https://github.com/claytonrcarter/tree-sitter-phpdoc") - (doxygen "https://github.com/tree-sitter-grammars/tree-sitter-doxygen") - (lua "https://github.com/tree-sitter-grammars/tree-sitter-lua") - (python "https://github.com/tree-sitter/tree-sitter-python") - (html "https://github.com/tree-sitter/tree-sitter-html") - (elixir "https://github.com/elixir-lang/tree-sitter-elixir") - (heex "https://github.com/phoenixframework/tree-sitter-heex") - (java "https://github.com/tree-sitter/tree-sitter-java") - (jsdoc "https://github.com/tree-sitter/tree-sitter-jsdoc")) + (doxygen "https://github.com/tree-sitter-grammars/tree-sitter-doxygen" "v1.1.0") + (lua "https://github.com/tree-sitter-grammars/tree-sitter-lua" "v0.3.0") + (python "https://github.com/tree-sitter/tree-sitter-python" "v0.23.6") + (html "https://github.com/tree-sitter/tree-sitter-html" "v0.23.2") + (elixir "https://github.com/elixir-lang/tree-sitter-elixir" "v0.3.3") + (heex "https://github.com/phoenixframework/tree-sitter-heex" "v0.7.0") + (java "https://github.com/tree-sitter/tree-sitter-java" "v0.23.5") + (jsdoc "https://github.com/tree-sitter/tree-sitter-jsdoc" "v0.23.2") + (toml "https://github.com/tree-sitter-grammars/tree-sitter-toml" "v0.7.0") + (yaml "https://github.com/tree-sitter-grammars/tree-sitter-yaml" "v0.7.0")) "A list of sources for the builtin modes. The source information are in the format of `treesit-language-source-alist'. This is for development only.") @@ -154,9 +156,7 @@ queries that has problems with latest grammar." (unless (memq language (alist-get mode mode-language-alist)) (push language (alist-get mode mode-language-alist))) ;; Validate query. - (when (not (ignore-errors - (treesit-query-compile language query t) - t)) + (unless (treesit-query-valid-p language query) (push (list mode language feature) invalid-feature-list) (setq all-queries-valid nil)))) (when all-queries-valid @@ -259,9 +259,7 @@ Return non-nil if all queries are valid, nil otherwise." (language (treesit-query-language query))) ;; Validate query. (when (and (eq lang language) - (not (ignore-errors - (treesit-query-compile language query t) - t))) + (not (treesit-query-valid-p language query))) (setq all-queries-valid nil)))) all-queries-valid)) diff --git a/configure.ac b/configure.ac index fa582446bf7..85887580bb5 100644 --- a/configure.ac +++ b/configure.ac @@ -1866,6 +1866,7 @@ AS_IF([test $gl_gcc_warnings = no], gl_WARN_ADD([$w]) done gl_WARN_ADD([-Wredundant-decls]) # Prefer this, as we don't use Bison. + gl_WARN_ADD([-Wtrailing-whitespace]) # This project's coding style gl_WARN_ADD([-Wno-missing-field-initializers]) # We need this one gl_WARN_ADD([-Wno-override-init]) # More trouble than it is worth gl_WARN_ADD([-Wno-sign-compare]) # Too many warnings for now @@ -2239,7 +2240,7 @@ AC_CACHE_CHECK([for flags to work around GCC bug 58416], [AC_LANG_DEFINES_PROVIDED [/* Work around GCC bug with double in unions on x86, where the generated insns copy non-floating-point data - via fldl/fstpl instruction pairs. This can misbehave + via fldl/fstpl instruction pairs. This can misbehave if the data's bit pattern looks like a NaN. See, e.g.: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58416#c10 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71460 diff --git a/doc/emacs/building.texi b/doc/emacs/building.texi index 02ca71f069b..39c5e79a870 100644 --- a/doc/emacs/building.texi +++ b/doc/emacs/building.texi @@ -674,6 +674,9 @@ Run the SDB debugger. using the minibuffer. The minibuffer's initial contents contain the standard executable name and options for the debugger, and sometimes also a guess for the name of the executable file you want to debug. +For @code{pdb}, @code{perldb}, and @code{guiler}, if the current buffer +visits a file, pressing @kbd{M-n} (@code{next-history-element}) +in the prompt suggests a full command line including that file name. Shell wildcards and variables are not allowed in this command line. Emacs assumes that the first command argument which does not start with a @samp{-} is the executable file name. diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi index 770267bc78a..85b00567cf0 100644 --- a/doc/emacs/custom.texi +++ b/doc/emacs/custom.texi @@ -2165,6 +2165,10 @@ You can similarly enter the Shift, Control, and Meta modifiers by using @kbd{C-x @@ S}, @kbd{C-x @@ c}, and @kbd{C-x @@ m}, respectively, although this is rarely needed. + On graphical terminals, you can enable the Modifier Bar mode, which +allows simulating the missing modifier keys by clicking a tool-bar +button. @xref{Tool Bars}. + @node Function Keys @subsection Rebinding Function Keys @@ -2965,9 +2969,19 @@ Emacs will set @code{user-emacs-directory} to the directory it decides to use. This directory is subsequently used to look for your other user-specific Emacs files, such as @code{custom-file} (@pxref{Saving Customizations}), the saved desktop (@pxref{Saving Emacs Sessions}) and -others. The @code{--init-directory} command-line option (@pxref{Initial -Options}) overrides the value of @code{user-emacs-directory} determined -as side effect of the search for your user init file described above. +others. It is also used to compute the value of the +@code{native-comp-eln-load-path} (@pxref{Lisp Libraries}), which is +where Emacs looks for natively-compiled Lisp code and where it deposits +the newly-compiled Lisp code produced by asynchronous compilation of +packages your init files and the subsequent Emacs session load. The +@code{--init-directory} command-line option (@pxref{Initial Options}) +overrides the value of @code{user-emacs-directory} determined as side +effect of the search for your user init file described above. + +Since @code{user-emacs-directory}, once determined by Emacs, is used by +the rest of the startup code to locate other files and directories, we +do not recommend changing its value in your init files, as that could +disrupt or break the correct startup of your Emacs sessions. Although this is backward-compatible with older Emacs versions, modern POSIX platforms prefer putting your initialization files under diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi index 520d3289f2d..ad496b5b1cd 100644 --- a/doc/emacs/display.texi +++ b/doc/emacs/display.texi @@ -1811,6 +1811,21 @@ formats by setting each of the variables @code{eol-mnemonic-unix}, @code{eol-mnemonic-dos}, @code{eol-mnemonic-mac}, and @code{eol-mnemonic-undecided} to the strings you prefer. +@vindex mode-line-compact +@vindex mode-line-collapse-minor-modes + Some modes put a lot of data in the mode line, pushing elements at the +end of the mode line off to the right. Emacs can ``compress'' the mode +line if the @code{mode-line-compact} variable is non-@code{nil} by +turning stretches of spaces into a single space. If this variable is +@code{long}, this is only done when the mode line is wider than the +currently selected window. (This computation is approximate, based on +the number of characters, and not their displayed width.) This variable +can be buffer-local to only compress mode-lines in certain buffers. To +further ``compress'' the mode line, you may customize the +@code{mode-line-collapse-minor-modes} option to a non-@code{nil} value, +and Emacs will hide some minor mode indicators on the mode line by +collapsing them into a single clickable button. + @node Text Display @section How Text Is Displayed @cindex characters (in text) diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi index 6128be8f128..de6a83b5205 100644 --- a/doc/emacs/files.texi +++ b/doc/emacs/files.texi @@ -1093,7 +1093,7 @@ type @kbd{M-x normal-mode} to re-read them. Here is another example, with the time stamp inserted into the last paragraph of an HTML document. Since this template is at the end of the document, not in the first -eight lines, @code{time-stamp-format} starts with @code{-10/} to tell +eight lines, @code{time-stamp-pattern} starts with @code{-10/} to tell @code{time-stamp} to look at the last 10 lines. The @code{%%} asks for the default format (specified by @code{time-stamp-format}). @@ -2529,7 +2529,7 @@ select a group of images to copy somewhere else). The @kbd{m} (@code{image-mode-mark-file}) command will mark the current file in any Dired buffer(s) that display the current file's directory. If no such buffer is open, the directory is opened in a new buffer. To -unmark files, use the @kbd{u} (@code{image-mode-mark-file}) command. +unmark files, use the @kbd{u} (@code{image-mode-unmark-file}) command. Finally, if you just want to copy the current buffers file name to the kill ring, you can use the @kbd{w} (@code{image-mode-copy-file-name-as-kill}) command. diff --git a/doc/emacs/frames.texi b/doc/emacs/frames.texi index 1fa6e0b5b33..c2451e87715 100644 --- a/doc/emacs/frames.texi +++ b/doc/emacs/frames.texi @@ -1346,15 +1346,18 @@ displayed by moving the mouse pointer to the top of the screen. @cindex displaying modifier keys in the tool bar @cindex mode, Modifier Bar @cindex Modifier Bar - Keyboards often lack one or more of the modifier keys that Emacs -might want to use, making it difficult or impossible to input key -sequences that contain them. Emacs can optionally display a list of -buttons that act as substitutes for modifier keys within the tool bar; -these buttons are also referred to as the ``modifier bar''. Clicking -an icon within the modifier bar will cause a modifier key to be -applied to the next keyboard event that is read. The modifier bar is -displayed when the global minor mode @code{modifier-bar-mode} is -enabled; to do so, type @kbd{M-x modifier-bar-mode}. + Keyboards often lack one or more of the modifier keys (@pxref{Modifier +Keys}) that Emacs users might want to use, making it difficult or +impossible to input key sequences with these modifiers. For example, +many keyboards lack the Hyper and Super modifiers, and smartphones +usually also lack Ctrl and Alt modifiers. Emacs can optionally display +a tool bar of buttons that can substitute the modifier keys; this +additional tool bar is known as the @dfn{modifier bar}. Clicking a +button within the modifier bar will cause the modifier key shown on the +button to be applied to the next keyboard event that Emacs reads. The +modifier bar is displayed when the global minor mode +@code{modifier-bar-mode} is enabled; to do so, type @kbd{M-x +modifier-bar-mode}. @node Tab Bars @section Tab Bars diff --git a/doc/emacs/kmacro.texi b/doc/emacs/kmacro.texi index 62f275de259..09c6c5d4675 100644 --- a/doc/emacs/kmacro.texi +++ b/doc/emacs/kmacro.texi @@ -472,9 +472,9 @@ C-x C-k b 4 will bind the last keyboard macro to the key sequence @kbd{C-x C-k 4}. @findex insert-kbd-macro - Once a macro has a command name, you can save its definition in a file. -Then it can be used in another editing session. First, visit the file -you want to save the definition in. Then use this command: + You can save a macro's definition in a file. Then it can be used in +another editing session. First, visit the file you want to save the +definition in. Then use this command: @example M-x insert-kbd-macro @key{RET} @var{macroname} @key{RET} @@ -494,6 +494,9 @@ additional Lisp code to record the keys (if any) that you have bound to @var{macroname}, so that the macro will be reassigned the same keys when you load the file. + If you do not give @code{insert-kbd-macro} a macro name, it will +insert Lisp code to restore the @code{last-kdb-macro}. + @node Edit Keyboard Macro @section Editing a Keyboard Macro diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index 6e9653dcdc8..94f2c8331ca 100644 --- a/doc/emacs/maintaining.texi +++ b/doc/emacs/maintaining.texi @@ -190,8 +190,8 @@ which it refers to as @dfn{back ends}: @item Git is a decentralized version control system originally invented by Linus Torvalds to support development of Linux (his kernel). VC -supports many common Git operations, but others, such as repository -syncing, must be done from the command line. +supports all the common Git operations, but notably, Git rebases other +than simply to edit a commit message must be done from the command line. @cindex CVS @item @@ -235,8 +235,7 @@ everything you can do with RCS can be done through VC. @cindex Mercurial @item Mercurial (hg) is a decentralized version control system broadly -resembling Git. VC supports most Mercurial commands, with the -exception of repository sync operations. +resembling Git. VC supports most Mercurial commands. @cindex bzr @cindex Bazaar @@ -1783,20 +1782,18 @@ more programs. Files that belong to a project are typically stored in a hierarchy of directories; the top-level directory of the hierarchy is known as the @dfn{project root}. -@cindex project back-end +@cindex project backend Whether a given directory is a root of some project is determined by -the project-specific infrastructure, known as @dfn{project back-end}. -Emacs currently supports two such back-ends: VC-aware (@pxref{Version +the project-specific infrastructure, known as @dfn{project backend}. +Emacs currently supports two such backends: VC-aware (@pxref{Version Control}), whereby a VCS repository is considered a project; and EDE (@pxref{EDE}). This is expected to be extended in the future to support additional types of projects. Which files do or don't belong to a project is also determined by -the project back-end. For example, the VC-aware back-end doesn't +the project backend. For example, the VC-aware backend doesn't consider ``ignored'' files (@pxref{VC Ignore}) to be part of the -project. Also, the VC-aware Project back-end considers ``untracked'' -files by default. That behavior is controllable with the variable -@code{project-vc-include-untracked}. +project. See its entry below for description and related options. @cindex current project name on mode line @defopt project-mode-line @@ -1811,6 +1808,7 @@ The default value is @code{nil}. * Project Buffer Commands:: Commands for handling project buffers. * Switching Projects:: Switching between projects. * Managing Projects:: Managing the project list file. +* VC-Aware Project Backend:: Default project backend. @end menu @node Project File Commands @@ -2050,6 +2048,50 @@ matched against the project root, and the predicate should take the project object as the only argument and return non-@code{nil} if the project should @emph{not} be saved to @code{project-list-file}. +@cindex VC-aware project backend +@cindex project backend, VC-aware +@node VC-Aware Project Backend +This backend is part of Emacs and is enabled by default. (Other +backends may need installation of add-on packages and their proper +configuration.) + +It determines the contents of the project based on the VCS repository's +configuration (if any), excluding the ``ignored'' files from the output. + +It has some performance optimizations for listing the files with some of +the popular VCS systems (currently Git and Mercurial). + +@defopt project-vc-include-untracked +By default, files which are neither registered with nor ignored by the +VCS are considered part of the project. Customize this variable to nil +to change that. +@end defopt + +@defopt project-vc-ignores +Using this variable you can add more ignore patterns to the project, to +exclude more files from the project's file listing. The value is a list +of glob strings. They can match both regular files and directories. To +anchor an entry to the project root, start it with @code{./}. To match +directories only, end it with @code{/}. +@end defopt + +@defopt project-vc-name +This variable allows you to change the automatically detected name of +the project to a string of your choice. By default the name is the base +name of its root directory. +@end defopt + +@defopt project-vc-extra-root-markers +This variable allows you to set up detection of non-VC projects in this +backend, and also to have some subdirectories detected as separate +projects. The value is a list. + +Each element is either a base file name or a glob pattern for such. + +Example values: @file{.dir-locals.el}, @file{package.json}, +@file{requirements.txt}, @file{*.gemspec}. +@end defopt + @node Change Log @section Change Logs diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index 08a7f910c5c..d4f2de982d6 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -2924,11 +2924,15 @@ can use @kbd{M-x desktop-read} to restore a previously-saved desktop if the current Emacs session didn't load any desktop yet. @vindex desktop-restore-frames - By default, the desktop tries to save and restore the frame and -window configuration. To disable this, set -@code{desktop-restore-frames} to @code{nil}. (See that variable's -documentation for some related options that you can customize to -fine-tune this behavior.) + By default, the desktop tries to save and restore the frame and window +configuration.@footnote{ +Except on Android, where this option defaults to @code{nil} because the +window manager (@pxref{Android Windowing}) is too prohibitive, and +doesn't allow restoring frame configurations.} +To disable or enable this, set @code{desktop-restore-frames} to +@code{nil} or any non-@code{nil} value respectively. (See that +variable's documentation for some related options that you can customize +to fine-tune this behavior.) @vindex frameset-filter-alist When the desktop restores the frame and window configuration, it @@ -2968,8 +2972,8 @@ invoking @kbd{M-x desktop-read} next. The @code{desktop-clear} command kills all buffers except for internal ones, and clears the global variables listed in @code{desktop-globals-to-clear}. If you want it to preserve certain buffers, customize the variable -@code{desktop-clear-preserve-buffers-regexp}, whose value is a regular -expression matching the names of buffers not to kill. +@code{desktop-clear-preserve-buffers}, whose value is a list of regular +expressions matching the names of buffers not to kill. @vindex desktop-globals-to-save If you want to save minibuffer history from one session to diff --git a/doc/emacs/package.texi b/doc/emacs/package.texi index 857584b9933..182efff7afb 100644 --- a/doc/emacs/package.texi +++ b/doc/emacs/package.texi @@ -654,7 +654,13 @@ maintainer, you can use the command @code{package-report-bug} to report a bug via Email. This report will include all the user options that you have customized. If you have made a change you wish to share with the maintainers, first commit your changes then use the command -@code{package-vc-prepare-patch} to share it. @xref{Preparing Patches}. +@code{package-vc-prepare-patch} to share it. +@iftex +@xref{Preparing Patches,,,emacs-xtra, Specialized Emacs Features}. +@end iftex +@ifnottex +@xref{Preparing Patches}. +@end ifnottex @findex package-vc-install-from-checkout @findex package-vc-rebuild diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi index c34aeac0d24..f3cdc1b8e6c 100644 --- a/doc/emacs/programs.texi +++ b/doc/emacs/programs.texi @@ -958,11 +958,11 @@ argument specifies the number of levels to go down. @node Matching @subsection Matching Parentheses -@cindex matching parentheses +@cindex matching, parentheses and other paired delimiters @cindex parentheses, displaying matches - Emacs has a number of @dfn{parenthesis matching} features, which -make it easy to see how and whether parentheses (or other delimiters) + Emacs has a number of @dfn{parenthesis matching} features, which make +it easy to see how and whether parentheses (or other paired delimiters) match up. Whenever you type a self-inserting character that is a closing @@ -1063,16 +1063,17 @@ nonblank line. @findex electric-pair-mode Electric Pair mode, a global minor mode, provides a way to easily insert matching delimiters: parentheses, braces, brackets, etc. -Whenever you insert an opening delimiter, the matching closing -delimiter is automatically inserted as well, leaving point between the -two. Conversely, when you insert a closing delimiter over an existing -one, no insertion takes places, and that position is simply skipped -over. If the region is active (@pxref{Mark}), insertion of a -delimiter operates on the region: the characters in the region are -enclosed in a pair of matching delimiters, leaving point after the -delimiter you typed. If you provide a prefix argument when inserting -a delimiter, the numeric value of that prefix argument specifies the -number of pairs to insert. +Whenever you insert an opening delimiter, the matching closing delimiter +is automatically inserted as well, leaving point between the two. +However, if you insert a closing delimiter where one already exists +(probably a mistake, since typing the opening delimiter inserted the +closing one for you), Emacs simply moves point to after the closing +delimiter, skipping the insertion. If the region is active +(@pxref{Mark}), insertion of a delimiter operates on the region: the +characters in the region are enclosed in a pair of matching delimiters, +leaving point after the delimiter you typed. If you provide a prefix +argument when inserting a delimiter, the numeric value of that prefix +argument specifies the number of pairs to insert. These variables control additional features of Electric Pair mode: diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi index c9b1bdfc8bd..788d91f78ba 100644 --- a/doc/emacs/search.texi +++ b/doc/emacs/search.texi @@ -341,7 +341,7 @@ 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 +into the initial search string, type @kbd{M-s M-.}, which 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 diff --git a/doc/emacs/vc1-xtra.texi b/doc/emacs/vc1-xtra.texi index 45bc6d77728..5c448e741f2 100644 --- a/doc/emacs/vc1-xtra.texi +++ b/doc/emacs/vc1-xtra.texi @@ -312,7 +312,14 @@ If you expect to contribute patches on a regular basis, you can set the user option @code{vc-default-patch-addressee} to the address(es) you wish to use. This will be used as the default value when invoking @code{vc-prepare-patch}. Project maintainers may consider setting -this as a directory local variable (@pxref{Directory Variables}). +this as a directory local variable +@iftex +(@pxref{Directory Variables,,Per-Directory Local Variables, +emacs, the Emacs Manual}). +@end iftex +@ifnottex +(@pxref{Directory Variables}). +@end ifnottex @node Customizing VC @subsection Customizing VC diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi index a3d08b17834..e334faae13c 100644 --- a/doc/lispintro/emacs-lisp-intro.texi +++ b/doc/lispintro/emacs-lisp-intro.texi @@ -940,21 +940,21 @@ same time, and then press and release @kbd{t}.) Also, I often refer to one of Emacs's standard commands by listing the keys which you press to invoke the command and then giving the name of -the command in parentheses, like this: @kbd{M-C-\} +the command in parentheses, like this: @kbd{C-M-\} (@code{indent-region}). What this means is that the @code{indent-region} command is customarily invoked by typing -@kbd{M-C-\}. (You can, if you wish, change the keys that are typed to +@kbd{C-M-\}. (You can, if you wish, change the keys that are typed to invoke the command; this is called @dfn{rebinding}. @xref{Keymaps, , -Keymaps}.) The abbreviation @kbd{M-C-\} means that you type your -@key{META} key, @key{CTRL} key and @kbd{\} key all at the same time. +Keymaps}.) The abbreviation @kbd{C-M-\} means that you type your +@key{CTRL} key, @key{META} key, and @kbd{\} key all at the same time. (On many modern keyboards the @key{META} key is labeled @key{ALT}.) Sometimes a combination like this is called a keychord, since it is similar to the way you play a chord on a piano. If your keyboard does not have a @key{META} key, the @key{ESC} key prefix is used in place -of it. In this case, @kbd{M-C-\} means that you press and release your +of it. In this case, @kbd{C-M-\} means that you press and release your @key{ESC} key and then type the @key{CTRL} key and the @kbd{\} key at -the same time. But usually @kbd{M-C-\} means press the @key{CTRL} key +the same time. But usually @kbd{C-M-\} means press the @key{CTRL} key along with the key that is labeled @key{ALT} and, at the same time, press the @kbd{\} key. @@ -962,7 +962,7 @@ In addition to typing a lone keychord, you can prefix what you type with @kbd{C-u}, which is called the @dfn{universal argument}. The @kbd{C-u} keychord passes an argument to the subsequent command. Thus, to indent a region of plain text by 6 spaces, mark the region, -and then type @w{@kbd{C-u 6 M-C-\}}. (If you do not specify a number, +and then type @w{@kbd{C-u 6 C-M-\}}. (If you do not specify a number, Emacs either passes the number 4 to the command or otherwise runs the command differently than it would otherwise.) @xref{Arguments, , Numeric Arguments, emacs, The GNU Emacs Manual}. @@ -1258,7 +1258,7 @@ Interaction mode or Emacs Lisp mode, you have available to you several commands to format the Lisp expression so it is easy to read. For example, pressing the @key{TAB} key automatically indents the line the cursor is on by the right amount. A command to properly indent the -code in a region is customarily bound to @kbd{M-C-\}. Indentation is +code in a region is customarily bound to @kbd{C-M-\}. Indentation is designed so that you can see which elements of a list belong to which list---elements of a sub-list are indented more than the elements of the enclosing list. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index de0639187ab..3b48cb93405 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -404,8 +404,10 @@ elapsed since the time the first message was emitted. @defvar inhibit-message When this variable is non-@code{nil}, @code{message} and related functions -will not display any messages in the Echo Area. Echo-area messages -are still logged in the @file{*Messages*} buffer, though. +will not display any messages in the Echo Area, and will also not clear +previous echo-area messages when @code{message} is called with a +@code{nil} or an empty argument. Echo-area messages are still logged in +the @file{*Messages*} buffer, though. @end defvar @defmac with-temp-message message &rest body @@ -4122,6 +4124,14 @@ available, since it also checks whether the coding system for the text terminal can encode the character (@pxref{Terminal I/O Encoding}). @end defun +@defun char-displayable-on-frame-p char frame +This function behaves like @code{char-displayable-p} does (relative to +@var{frame}), but in the graphical case, it does not perform the final +check of whether the underlying text terminal can encode the character. +It thus provides a displayability check for @var{char} more specific to +@var{frame}. +@end defun + @node Low-Level Font @subsection Low-Level Font Representation @cindex font property @@ -5607,12 +5617,20 @@ instead of the text that has the display specification. @item (slice @var{x} @var{y} @var{width} @var{height}) This specification together with @code{image} specifies a @dfn{slice} -(a partial area) of the image to display. The elements @var{y} and -@var{x} specify the top left corner of the slice, within the image; -@var{width} and @var{height} specify the width and height of the -slice. Integers are numbers of pixels. A floating-point number -in the range 0.0--1.0 stands for that fraction of the width or height -of the entire image. +(a partial area) of the image to display. More precisely, the +specification should have the following form: + +@lisp + ((slice @var{x} @var{y} @var{width} @var{height}) @var{image-desc}) +@end lisp + +@noindent +where @var{image-desc} is an image descriptor described above. The +elements @var{x} and @var{y} specify the top left corner of the slice, +within the image; @var{width} and @var{height} specify the width and +height of the slice. Integers are numbers of pixels. A floating-point +number in the range 0.0--1.0 stands for that fraction of the width or +height of the entire image. @item ((margin nil) @var{string}) A display specification of this form means to display @var{string} diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index 197f4c17b46..73e6b6268d4 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi @@ -2839,8 +2839,11 @@ than deleted. @end deffn The following function checks whether a frame can be safely deleted. It -is useful to avoid that a subsequent call of @code{delete-frame} throws -an error. +is useful for avoiding the situation whereby a subsequent call of +@code{delete-frame} fails to delete its argument @var{frame} and/or +signals an error. To that end, your Lisp program should call +@code{delete-frame} only if the following function returns +non-@code{nil}. @defun frame-deletable-p &optional frame This function returns non-@code{nil} if the frame specified by diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 788d98fdf20..649b6206b7b 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -1510,9 +1510,6 @@ You can thus get the full benefit of adaptive filling (see the variable `adaptive-fill-mode'). \\@{text-mode-map@} Turning on Text mode runs the normal hook `text-mode-hook'." -@end group -@group - (setq-local text-mode-variant t) (setq-local require-final-newline mode-require-final-newline)) @end group @end smallexample @@ -2152,17 +2149,6 @@ windows, you can say something like: @end lisp @end defun -@vindex mode-line-compact - Some modes put a lot of data in the mode line, pushing elements at -the end of the mode line off to the right. Emacs can ``compress'' the -mode line if the @code{mode-line-compact} variable is non-@code{nil} -by turning stretches of spaces into a single space. If this variable -is @code{long}, this is only done when the mode line is wider than the -currently selected window. (This computation is approximate, based on -the number of characters, and not their displayed width.) This -variable can be buffer-local to only compress mode-lines in certain -buffers. - @node Mode Line Data @subsection The Data Structure of the Mode Line @cindex mode line construct diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi index 3da4d78f8b3..8eeddf20b12 100644 --- a/doc/lispref/os.texi +++ b/doc/lispref/os.texi @@ -1953,14 +1953,18 @@ This is a synonym for @samp{%H:%M:%S}. This stands for the numeric day of week (1--7). Monday is day 1. @item %U This stands for the week of the year (01--52), assuming that weeks -start on Sunday. +start on Sunday. If January 1 is not a Sunday, the first partial week +is week zero. @item %V -This stands for the week of the year according to ISO 8601. +This stands for the week of the year according to ISO 8601. Note that, +unlike @samp{%U} and @samp{%W}, the week according to ISO 8601 does +@emph{not} roll over to 1 on January 1, but keeps its last number. @item %w This stands for the numeric day of week (0--6). Sunday is day 0. @item %W -This stands for the week of the year (01--52), assuming that weeks -start on Monday. +This stands for the week of the year (01--52), assuming that weeks start +on Monday. If January 1 is not a Monday, the first partial week is week +zero. @item %x This has a locale-specific meaning. In the default locale (named @samp{C}), it is equivalent to @samp{%D}. diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi index 3e8e0851f2c..f7be47dc044 100644 --- a/doc/lispref/parsing.texi +++ b/doc/lispref/parsing.texi @@ -1814,12 +1814,12 @@ ranges for each parser are correct before using parsers in a buffer, and call @code{treesit-language-at} to figure out the language responsible for the text at some position. These two functions don't work by themselves; they need major modes to set @code{treesit-range-settings} -and @code{treesit-language-at-point-function}, which do the actual work. +and optionally @code{treesit-language-at-point-function}, which do the actual work. These functions and variables are explained in more detail towards the end of the section. In short, multi-language major modes should set -@code{treesit-primary-parser}, @code{treesit-range-settings}, and +@code{treesit-primary-parser}, @code{treesit-range-settings}, and optionally @code{treesit-language-at-point-function} before calling @code{treesit-major-mode-setup}. @@ -1921,9 +1921,9 @@ This function returns the language of the text at buffer position @var{pos}. Under the hood it calls @code{treesit-language-at-point-function} and returns its return value. If @code{treesit-language-at-point-function} is @code{nil}, -this function returns the language of the first parser in the returned -value of @code{treesit-parser-list}. If there is no parser in the -buffer, it returns @code{nil}. +this function returns the language of the deepest parser by embed level +among parsers returned by @code{treesit-parsers-at}. If there is no +parser at that buffer position, it returns @code{nil}. @end defun @heading Supporting multiple languages in major modes @@ -2011,7 +2011,7 @@ directly translate into operations shown above. @end group @group -;; Major modes with multiple languages should always set +;; Major modes with multiple languages can optionally set ;; `treesit-language-at-point-function' (which see). (setq treesit-language-at-point-function (lambda (pos) @@ -2094,17 +2094,45 @@ language of the buffer text at @var{pos}. This variable is used by @code{treesit-language-at}. @end defvar -@defun treesit-local-parsers-at &optional pos language +@defun treesit-parsers-at &optional pos language with-host only +This function returns all parsers at @var{pos} in the current buffer. +@var{pos} defaults to point. The returned parsers are sorted by the +decreasing embed level. + +If @var{language} is non-@code{nil}, return parsers only for that +language. + +If @var{with-host} is non-@code{nil}, return a list of +@w{@code{(@var{parser} . @var{host-parser})}} where @var{host-parser} +is the host parser which created the @var{parser}. + +If @var{only} is non-@code{nil}, return all parsers including the +primary parser. + +The argument @var{only} can be a list of symbols that specify what +parsers to include in the return value. + +If @var{only} contains the symbol @code{local}, include local parsers. +Local parsers are those which only parse a limited region marked by an +overlay with a non-@code{nil} @code{treesit-parser-local-p} property. + +If @var{only} contains the symbol @code{global}, include non-local parsers +excluding the primary parser. + +If @var{only} contains the symbol `primary', include the primary parser. +@end defun + +@defun treesit-local-parsers-at &optional pos language with-host This function returns all the local parsers at @var{pos} in the current buffer. @var{pos} defaults to point. Local parsers are those which only parse a limited region marked by an -overlay with a non-@code{nil} @code{treesit-parser} property. If -@var{language} is non-@code{nil}, only return parsers for that +overlay with a non-@code{nil} @code{treesit-parser-local-p} property. +If @var{language} is non-@code{nil}, only return parsers for that language. @end defun -@defun treesit-local-parsers-on &optional beg end language +@defun treesit-local-parsers-on &optional beg end language with-host This function is the same as @code{treesit-local-parsers-at}, but it returns the local parsers in the range between @var{beg} and @var{end} instead of at point. diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index 954979a00e6..75b2b1c3d60 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -1932,7 +1932,7 @@ they default to the whole buffer. This function adjusts the indentation at the beginning of the current line to the value specified by the variable @code{left-margin}. (That may involve either inserting or deleting whitespace.) This function -is value of @code{indent-line-function} in Paragraph-Indent Text mode. +is the value of @code{indent-line-function} in Paragraph-Indent Text mode. @end defun @defopt left-margin @@ -5366,11 +5366,17 @@ available in this Emacs session. When SQLite support is available, the following functions can be used. @cindex database object -@defun sqlite-open &optional file +@defun sqlite-open &optional file readonly disable-uri 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. +database is created instead. Second optional argument @var{readonly}, +if non-@code{nil}, means open the database only for reading; the +database must already exist in that case. By default, @var{file} can be +a @file{file://} URI as well as a file name; in the unusual case that +you have a local file whose name begins with @file{file:}, specify a +non-@code{nil} value for the third optional argument @var{disable-uri} +to disable the automatic recognition and processing of URIs. The return value is a @dfn{database object} that can be used as the argument to most of the subsequent functions described below. diff --git a/doc/lispref/tips.texi b/doc/lispref/tips.texi index 31716ffa9e1..6515e8d0b9b 100644 --- a/doc/lispref/tips.texi +++ b/doc/lispref/tips.texi @@ -73,18 +73,13 @@ not meant to be used by other packages. Occasionally, for a command name intended for users to use, it is more convenient if some words come before the package's name prefix. For example, it is our convention to have commands that list objects named -as @samp{list-@var{something}}, e.g., a package called @samp{frob} -could have a command @samp{list-frobs}, when its other global symbols -begin with @samp{frob-}. Also, constructs that define functions, -variables, etc., work better if they start with @samp{define-}, so put -the name prefix later on in the name. - -This recommendation applies even to names for traditional Lisp -primitives that are not primitives in Emacs Lisp---such as -@code{copy-list}. Believe it or not, there is more than one plausible -way to define @code{copy-list}. Play it safe; append your name prefix -to produce a name like @code{foo-copy-list} or @code{mylib-copy-list} -instead. +as @samp{list-@var{something}}, e.g., a package called @samp{frob} could +have a command @samp{list-frobs}, when its other global symbols begin +with @samp{frob-}. Also, constructs that define functions, variables, +etc., may work better if they start with @samp{define-}, so it's okay to +put the name prefix later on in the name. Outside of these +well-established cases, however, err on the side of prepending your name +prefix. If you write a function that you think ought to be added to Emacs under a certain name, such as @code{twiddle-files}, don't call it by that name diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi index 417c323be6b..3a8dffd1af1 100644 --- a/doc/lispref/windows.texi +++ b/doc/lispref/windows.texi @@ -2256,7 +2256,7 @@ unless stated otherwise. counterclockwise. @cindex rotate window layout -@deffn Command rotate-window-layout-clockwise &optional window +@deffn Command window-layout-rotate-clockwise &optional window This command rotates the window layout clockwise by 90 degrees. Imagine a layout with three live windows @var{A}, @var{B} and @var{C} as depicted on the left below. Then this command will produce the layout @@ -2276,8 +2276,8 @@ on the right. @end smallexample @end deffn -@deffn Command rotate-window-layout-counterclockwise &optional window -This is like @code{rotate-window-layout-clockwise} but rotates the +@deffn Command window-layout-rotate-anticlockwise &optional window +This is like @code{window-layout-rotate-clockwise} but rotates the layout in the opposite direction as demonstrated in the example below. @smallexample @@ -2298,7 +2298,7 @@ The next two commands @sc{flip} the window layout---rotate it around an imaginary horizontal or vertical axis. @cindex flip window layout -@deffn Command flip-window-layout-vertically &optional window +@deffn Command window-layout-flip-topdown &optional window This command flips windows such that windows on the bottom become windows on the top and vice-versa as in the example below. @@ -2316,7 +2316,7 @@ windows on the top and vice-versa as in the example below. @end smallexample @end deffn -@deffn Command flip-window-layout-horizontally &optional window +@deffn Command window-layout-flip-leftright &optional window This command rearranges window in a way that the windows on the right become the window on the left, and vice-versa. @@ -2338,7 +2338,7 @@ The next command can be used for @sc{transposing} windows---changing horizontal splits to vertical ones and vice-versa. @cindex transposing windows -@deffn Command transpose-window-layout &optional window +@deffn Command window-layout-transpose &optional window This command reorganizes windows such that every horizontal split becomes a vertical split and vice versa. diff --git a/doc/misc/efaq-w32.texi b/doc/misc/efaq-w32.texi index 4e409261cd9..e50716ff654 100644 --- a/doc/misc/efaq-w32.texi +++ b/doc/misc/efaq-w32.texi @@ -353,6 +353,7 @@ not bundled with Emacs. @xref{Other useful ports}. @section What is my init file? @cindex .emacs @cindex init file +@cindex early init file When Emacs starts up, it attempts to load and execute the contents of a file commonly called @file{.emacs} (though it may have other names, @@ -362,22 +363,31 @@ code to your .emacs, or you can use the Customization interface accessible from the @emph{Options} menu. If the file does not exist, Emacs will start with the default settings. +In addition, Emacs 27 and later attempts to load and execute the +contents of the @file{early-init.el} file. As its name suggests, this +file, if it exists, is loaded and executed early on during the Emacs +startup sequence, before @code{.emacs}, and is intended to contain the +few initializations which must be performed before @file{.emacs} is +looked up and loaded. + @node Location of init file @section Where do I put my init file? @cindex HOME directory @cindex .emacs.d @cindex _emacs @cindex init.el +@cindex early-init.el @cindex registry, setting the HOME directory in -On Windows, the @file{.emacs} file may be called @file{_emacs} for +On Windows, the @file{.emacs} init file may be called @file{_emacs} for backward compatibility with DOS and FAT filesystems where filenames could not start with a dot. Some users prefer to continue using such a name due to historical problems various Windows tools had in the past with file names that begin with a dot. The init file may also be -called @file{.emacs.d/init.el}. Many of the other files that are -created by Lisp packages are stored in the @file{.emacs.d} directory -too, which keeps all your Emacs related files in one place. +called @file{.emacs.d/init.el}. The @file{early-init.el} file and many +of the other files that are created by Lisp packages are stored in the +@file{.emacs.d} directory too, which keeps all your Emacs related files +in one place. All the files mentioned above should go in your @env{HOME} directory. The @env{HOME} directory is determined by following the steps below: @@ -2157,7 +2167,7 @@ MSYS2 is an independent rewrite of MSYS, based on modern Cygwin and MinGW-w64 with the aim of better interoperability with native Windows software. It plays the same role MSYS does in MinGW. Being a distribution, MSYS2 provides tools to build software as well as more -than 2.600 precompiled packages ready for use. +than 2600 precompiled packages ready for use. @node EZWinPorts @section EZWinPorts diff --git a/doc/misc/ert.texi b/doc/misc/ert.texi index 0e3aecdf313..38411ddee3d 100644 --- a/doc/misc/ert.texi +++ b/doc/misc/ert.texi @@ -134,11 +134,11 @@ package @file{pp.el}): ;; (pp-to-string '('a 'b)) ; same as above @end lisp -The code contained in these comments can be evaluated from time to -time to compare the output with the expected output. ERT formalizes -this and introduces a common convention, which simplifies Emacs -development, since programmers no longer have to manually find and -evaluate such comments. +The Lisp forms contained in these comments can be evaluated from time to +time, e.g. with @kbd{C-x C-e}, to compare the output with the expected +output. ERT formalizes this and introduces a common convention, which +simplifies Emacs development, since programmers no longer have to +manually find and evaluate such comments. An ERT test definition equivalent to the above comments is this: diff --git a/doc/misc/flymake.texi b/doc/misc/flymake.texi index 54835767928..d6c8778d785 100644 --- a/doc/misc/flymake.texi +++ b/doc/misc/flymake.texi @@ -62,7 +62,7 @@ To learn about using Flymake, @pxref{Using Flymake}. When the Emacs LSP support mode Eglot is enabled, Flymake will use that as an additional back-end. @xref{Eglot Features,,, eglot, Eglot: The Emacs LSP Client}. Flymake is also designed to be easily extended to -support new backends via an Elisp interface. @xref{Extending Flymake}. +support new backends via an Elisp interface. @xref{Flymake API}. @ifnottex @insertcopying @@ -70,7 +70,7 @@ support new backends via an Elisp interface. @xref{Extending Flymake}. @menu * Using Flymake:: -* Extending Flymake:: +* Flymake API:: * The legacy Proc backend:: * GNU Free Documentation License:: * Index:: @@ -178,6 +178,10 @@ 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. +When invoked on a diagnostic (either via the keyboard or a mouse click) +the command @code{flymake-show-buffer-diagnostics} attempts to reveal +said diagnostic in the listing. + @node Mode line status @section Mode line status @cindex flymake mode line @@ -210,7 +214,7 @@ investigate and remedy the situation (@pxref{Troubleshooting}). @item @code{?} @tab There are no applicable Flymake backends for this buffer, thus Flymake cannot annotate it. To fix this, a user may look to extending Flymake -and add a new backend (@pxref{Extending Flymake}). +and add a new backend (@pxref{Flymake API}). @end multitable @@ -313,6 +317,9 @@ The indicator type which Flymake should use to indicate lines with errors or warnings. Depending on your preference, this can either use @code{fringes} or @code{margins} for indicating errors. +If set to @code{fringes} (the default), it will automatically fall back +to using margins in windows or frames without fringes, such as text +terminals. @item flymake-error-bitmap A bitmap used in the fringe to mark lines for which an error has @@ -344,9 +351,14 @@ If non-@code{nil}, moving to errors with @code{flymake-goto-next-error} and @item flymake-show-diagnostics-at-end-of-line If non-@code{nil}, show summarized descriptions of diagnostics at the end of the line. Depending on your preference, this can either be -distracting and easily confused with actual code, or a significant -early aid that relieves you from moving around or reaching for the -mouse to consult an error message. +distracting and easily confused with actual code, or a significant early +aid that relieves you from moving around or reaching for the mouse to +consult an error message. This value may also be set to @code{fancy}, +which will attempt to layout diagnostics below the affected line using +unicode graphics to point to diagnostic locus. + +@item flymake-diagnostic-format-alist +Control which parts of a diagnostic to show in various situations. @item flymake-error-eol A custom face for summarizing diagnostic error messages. @@ -358,19 +370,23 @@ A custom face for summarizing diagnostic warning messages. A custom face for summarizing diagnostic notes. @end vtable -@node Extending Flymake -@chapter Extending Flymake +@node Flymake API, The legacy Proc backend, Using Flymake, Top +@chapter Flymake API @cindex extending flymake -Flymake can primarily be extended in one of two ways: +Flymake's API supports the following use cases: @enumerate @item -By changing the look and feel of the annotations produced by the +Changing the look and feel of the annotations produced by the different backends. @xref{Flymake error types}. @item -By adding a new buffer-checking backend. @xref{Backend functions}. +Adding a new buffer-checking backend. @xref{Backend functions}. + +@item +Writing extension to and process Flymake's output. @xref{Inspecting +diagnostics}. @end enumerate The following sections discuss each approach in detail. @@ -378,6 +394,7 @@ The following sections discuss each approach in detail. @menu * Flymake error types:: * Backend functions:: +* Inspecting diagnostics:: @end menu @node Flymake error types @@ -670,37 +687,19 @@ 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 locus beg end type text &optional data +@deffn Function flymake-make-diagnostic locus beg end type info &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 naming 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}, @code{flymake-diagnostic-type} and -@code{flymake-diagnostic-data}. - -Additionally, the function @code{flymake-diagnostics} will collect -such objects in the region you specify. - -@cindex collect diagnostic objects -@deffn Function flymake-diagnostics beg end -Get a list of Flymake diagnostics in the region determined by -@var{beg} and @var{end}. If neither @var{beg} or @var{end} is -supplied, use the whole buffer, otherwise if @var{beg} is -non-@code{nil} and @var{end} is @code{nil}, consider only diagnostics -at @var{beg}. +delimited by @var{beg} and @var{end}. @var{type} is a diagnostic symbol +(@pxref{Flymake error types}). @var{text} can be a string or a list +(@var{origin} @var{code} @var{message}) appropriately categorizing and +describing the diagnostic. Most commonly, @var{locus} is the buffer +object designating for the current buffer being syntax-checked. +However, it may be a string naming 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 buffer position from line and column number @@ -859,7 +858,7 @@ Binding,,, elisp, The Emacs Lisp Reference Manual}) to be active. ;; (cl-loop while (search-forward-regexp - "^\\(?:.*.rb\\|-\\):\\([0-9]+\\): \\(.*\\)$" + "^\\(?:.*\\.rb\\|-\\):\\([0-9]+\\): \\(.*\\)$" nil t) for msg = (match-string 2) for (beg . end) = (flymake-diag-region @@ -897,6 +896,32 @@ Binding,,, elisp, The Emacs Lisp Reference Manual}) to be active. @end group @end example +@node Inspecting diagnostics +@section Inspecting diagnostics + +When Flymake has called on the backend and collected its diagnostics, it +will annotate the buffer with it. After this happens, Elisp programs +may call @code{flymake-diagnostics} to collect such objects in a +specified region. + +@cindex collect diagnostic objects +@deffn Function flymake-diagnostics beg end +Get a list of Flymake diagnostics in the region determined by +@var{beg} and @var{end}. If neither @var{beg} or @var{end} is +supplied, use the whole buffer, otherwise if @var{beg} is +non-@code{nil} and @var{end} is @code{nil}, consider only diagnostics +at @var{beg}. +@end deffn + +@cindex access diagnostic object +A diagnostic object's properties can be accessed with the functions +@code{flymake-diagnostic-backend}, @code{flymake-diagnostic-buffer}, +@code{flymake-diagnostic-origin}, @code{flymake-diagnostic-code} +@code{flymake-diagnostic-message}, @code{flymake-diagnostic-beg}, +@code{flymake-diagnostic-end}, @code{flymake-diagnostic-type} and +@code{flymake-diagnostic-data}. @code{flymake-diagnostic-text} will +compose the diagnostic's origin, code and message in a single string. + @node The legacy Proc backend @chapter The legacy ``Proc'' backend @cindex legacy proc backend diff --git a/doc/misc/modus-themes.org b/doc/misc/modus-themes.org index 4c8a1c82749..8b5940f83a4 100644 --- a/doc/misc/modus-themes.org +++ b/doc/misc/modus-themes.org @@ -4,9 +4,9 @@ #+language: en #+options: ':t toc:nil author:t email:t num:t #+startup: content -#+macro: stable-version 4.6.0 -#+macro: release-date 2024-10-27 -#+macro: development-version 4.7.0-dev +#+macro: stable-version 4.7.0 +#+macro: release-date 2025-04-17 +#+macro: development-version 4.8.0-dev #+macro: file @@texinfo:@file{@@$1@@texinfo:}@@ #+macro: space @@texinfo:@: @@ #+macro: kbd @@texinfo:@kbd{@@$1@@texinfo:}@@ @@ -88,7 +88,7 @@ The Modus themes consist of eight themes, divided into four subgroups. are variants of the two main themes. They slightly tone down the intensity of the background and provide a bit more color variety. ~modus-operandi-tinted~ has a set of base tones that are shades of - light ocher (earthly colors), while ~modus-vivendi-tinted~ gives a + light ochre (earthly colors), while ~modus-vivendi-tinted~ gives a night sky impression. - Deuteranopia themes :: ~modus-operandi-deuteranopia~ and its @@ -1309,37 +1309,32 @@ Examples demonstrating how to use the aforementioned: #+findex: modus-themes-list-colors The command ~modus-themes-list-colors~ uses minibuffer completion to select an item from the Modus themes and then produces a buffer with -previews of its color palette entries. The buffer has a naming scheme -that reflects the given choice, like =modus-operandi-list-colors= for -the ~modus-operandi~ theme. +previews of all of its color palette entries. #+findex: modus-themes-list-colors-current The command ~modus-themes-list-colors-current~ skips the minibuffer -selection process and just produces a preview for the current Modus -theme. +selection process to produce a preview for the current Modus theme. When called with a prefix argument (=C-u= with the default key bindings), these commands will show a preview of the palette's -semantic color mappings instead of the named colors. In this context, -"named colors" are entries that associate a symbol to a string color -value, such as =(blue-warmer "#354fcf")=. Whereas "semantic color -mappings" associate a named color to a symbol, like =(string -blue-warmer)=, thus making the theme render all string constructs in -the =blue-warmer= color value ([[#h:34c7a691-19bb-4037-8d2f-67a07edab150][Option for palette overrides]]). +semantic color mappings instead of the full palette ([[#h:34c7a691-19bb-4037-8d2f-67a07edab150][Option for palette overrides]]). #+findex: modus-themes-preview-colors #+findex: modus-themes-preview-colors-current -Aliases for those commands are ~modus-themes-preview-colors~ and +Aliases for these commands are ~modus-themes-preview-colors~ and ~modus-themes-preview-colors-current~. -Each row shows a foreground and background coloration using the -underlying value it references. For example a line with =#a60000= (a -shade of red) will show red text followed by a stripe with that same -color as a backdrop. +Each row includes a foreground and background rendition of the given +color value. For example a line with =#a60000= (a shade of red) will +show a column with a red background combined with a suitable +foreground followed by another column with a red foreground against +the current theme's background. The intent is to illustrate which +values are suitable as a background or foreground. The name of the buffer describes the given Modus theme and what the -contents are, such as =*modus-operandi-list-colors*= for named colors -and ==*modus-operandi-list-mappings*= for the semantic color mappings. +contents are, such as =*modus-operandi-list-all*= for the entirety of +the palette (named colors as well as semantic color mappings) and +==*modus-operandi-list-mappings*= for the mappings only. * Use colors from the Modus themes palette :PROPERTIES: @@ -1361,7 +1356,7 @@ value in some other application. :END: #+findex: modus-themes-get-color-value -The function ~modus-themes-get-color-value~ can be called from Lisp to +The fuction ~modus-themes-get-color-value~ can be called from Lisp to return the value of a color from the active Modus theme palette. It takea a =COLOR= argument and an optional =OVERRIDES=. It also accepts a third =THEME= argument, to get the color from the given theme. @@ -2367,7 +2362,7 @@ until version 4.3.0. ;; was the default in versions of the Modus themes before 4.4.0 (setq modus-themes-common-palette-overrides '((bg-prose-block-contents unspecified) - (bg-prose-block-delimiter unspecified) + (bg-prose-block-delimiter unspeficied) (fg-prose-block-delimiter fg-dim))) #+end_src @@ -2941,7 +2936,7 @@ Reload the theme for changes to take effect. :CUSTOM_ID: h:a5140c9c-18b2-45db-8021-38d0b5074116 :END: -By default, the background of the ~region~ face extends from the +By the default, the background of the ~region~ face extends from the end of the line to the edge of the window. To limit it to the end of the line, we need to override the face's =:extend= attribute. Adding this to the Emacs configuration file will suffice: @@ -3365,7 +3360,7 @@ specification of that variable looks like this: With the exception of ~org-verbatim~ and ~org-code~ faces, everything else uses the corresponding type of emphasis: a bold typographic weight, or -italicized, underlined, and struck through text. +italicised, underlined, and struck through text. The best way for users to add some extra attributes, such as a foreground color, is to define their own faces and assign them to the @@ -3985,13 +3980,13 @@ styles to use. The following is but a basic attempt to get started. (modus-themes-with-colors (custom-set-faces ;; FIXME: What is a "region cursor" and should it differ from the position highlights below? - `(meow-region-cursor-1 ((,c :inherit (bold modus-themes-reset-soft) :background ,bg-char-0))) - `(meow-region-cursor-2 ((,c :inherit (bold modus-themes-reset-soft) :background ,bg-char-1))) - `(meow-region-cursor-3 ((,c :inherit (bold modus-themes-reset-soft) :background ,bg-char-2))) + `(meow-region-cursor-1 ((,c :inherit (bold modus-themes-search-current modus-themes-reset-soft)))) + `(meow-region-cursor-2 ((,c :inherit (bold modus-themes-search-current modus-themes-reset-soft)))) + `(meow-region-cursor-3 ((,c :inherit (bold modus-themes-search-current modus-themes-reset-soft)))) - `(meow-position-highlight-number-1 ((,c :inherit (bold modus-themes-reset-soft) :background ,bg-char-0))) - `(meow-position-highlight-number-2 ((,c :inherit (bold modus-themes-reset-soft) :background ,bg-char-1))) - `(meow-position-highlight-number-3 ((,c :inherit (bold modus-themes-reset-soft) :background ,bg-char-2)))))) + `(meow-position-highlight-number-1 ((,c :inherit (bold modus-themes-search-current modus-themes-reset-soft)))) + `(meow-position-highlight-number-2 ((,c :inherit (bold modus-themes-search-current modus-themes-reset-soft)))) + `(meow-position-highlight-number-3 ((,c :inherit (bold modus-themes-search-current modus-themes-reset-soft))))))) (add-hook 'enable-theme-functions #'my-modus-themes-custom-faces) #+end_src @@ -4049,45 +4044,6 @@ the theme level. Users can try this instead: [[#h:d87673fe-2ce1-4c80-a4b8-be36ca9f2d24][Using a hook at the post-load-theme phase]]. -** DIY Add support for howm -:PROPERTIES: -:CUSTOM_ID: h:7ea8fa66-1cd8-47b0-92b4-9998a3068f85 -:END: - -The ~howm~ package is a note-taking solution for Emacs. Users can add -support for its faces with something like the following. - -#+begin_src emacs-lisp -(defun my-modus-themes-custom-faces (&rest _) - (modus-themes-with-colors - (custom-set-faces - `(action-lock-face ((,c :inherit button))) - `(howm-mode-keyword-face (( ))) - `(howm-mode-ref-face ((,c :inherit link))) - `(howm-mode-title-face ((,c :inherit modus-themes-heading-0))) - `(howm-mode-wiki-face ((,c :inherit link))) - `(howm-reminder-deadline-face ((,c :foreground ,date-deadline))) - `(howm-reminder-late-deadline-face ((,c :inherit bold :foreground ,date-deadline))) - `(howm-reminder-defer-face ((,c :foreground ,date-scheduled))) - `(howm-reminder-scheduled-face ((,c :foreground ,date-scheduled))) - `(howm-reminder-done-face ((,c :foreground ,prose-done))) - `(howm-reminder-todo-face ((,c :foreground ,prose-todo))) - `(howm-reminder-normal-face ((,c :foreground ,date-common))) - `(howm-reminder-today-face ((,c :inherit bold :foreground ,date-common))) - `(howm-reminder-tomorrow-face ((,c :inherit bold :foreground ,date-scheduled))) - `(howm-simulate-todo-mode-line-face ((,c :inherit bold))) - `(howm-view-empty-face (( ))) - `(howm-view-hilit-face ((,c :inherit match))) - `(howm-view-name-face ((,c :inherit bold))) - `(iigrep-counts-face1 ((,c :foreground ,rainbow-1))) - `(iigrep-counts-face2 ((,c :foreground ,rainbow-2))) - `(iigrep-counts-face3 ((,c :foreground ,rainbow-3))) - `(iigrep-counts-face4 ((,c :foreground ,rainbow-4))) - `(iigrep-counts-face5 ((,c :foreground ,rainbow-5)))))) - -(add-hook 'enable-theme-functions #'my-modus-themes-custom-faces) -#+end_src - ** DIY Use a hook at the post-load-theme phase :PROPERTIES: :CUSTOM_ID: h:d87673fe-2ce1-4c80-a4b8-be36ca9f2d24 @@ -4207,6 +4163,7 @@ project. The idea is to offer an overview of the known status of all affected face groups. The items with an appended asterisk =*= tend to have lots of extensions, so the "full support" may not be 100% true… ++ abbrev + ace-window + agda2-mode + all-the-icons @@ -4314,6 +4271,7 @@ have lots of extensions, so the "full support" may not be 100% true… + hl-fill-column + hl-line-mode + hl-todo ++ howm + hydra + ibuffer + icomplete @@ -4420,6 +4378,7 @@ have lots of extensions, so the "full support" may not be 100% true… + sly + smart-mode-line + smerge ++ spacious-padding + speedbar + spell-fu + stripes @@ -4435,8 +4394,10 @@ have lots of extensions, so the "full support" may not be 100% true… + terraform-mode + term + textsec ++ tldr + transient (pop-up windows such as Magit's) + trashed ++ treemacs + tree-sitter + tty-menu + tuareg @@ -5407,7 +5368,7 @@ more effective than trying to do the same with either red or blue (the latter is the least effective in that regard). When we need to work with several colors, it is always better to have -sufficient maneuvering space, especially since we cannot pick arbitrary +sufficient manoeuvring space, especially since we cannot pick arbitrary colors but only those that satisfy the accessibility objectives of the themes. @@ -5513,7 +5474,7 @@ it is already understood that one must follow the indicator or headline to view its contents and (ii) underlining everything would make the interface virtually unusable. -Again, one must exercise judgment in order to avoid discrimination, +Again, one must exercise judgement in order to avoid discrimination, where "discrimination" refers to: + The treatment of substantially different magnitudes as if they were of @@ -5587,7 +5548,7 @@ the themes, which is partially fleshed out in this manual. With regard to the artistic aspect (where "art" qua skill may amount to an imprecise science), there is no hard-and-fast rule in effect as it -requires one to exercise discretion and make decisions based on +requires one to exercize discretion and make decisions based on context-dependent information or constraints. As is true with most things in life, when in doubt, do not cling on to the letter of the law but try to understand its spirit. @@ -5736,14 +5697,14 @@ The Modus themes are a collective effort. Every bit of work matters. Contovounesios, Björn Lindström, Carlo Zancanaro, Christian Tietze, Daniel Mendler, David Edmondson, Eli Zaretskii, Fritz Grabo, Gautier Ponsinet, Illia Ostapyshyn, Jared Finder, Kévin Le Gouguec, Koen van - Greevenbroek, Kostadin Ninev, Madhavan Krishnan, Manuel Giraud, - Markus Beppler, Matthew Stevenson, Mauro Aranda, Nacho Barrientos, - Niall Dooley, Nicolas De Jaeghere, Paul David, Pavel Novichkov, - Philip Kaludercic, Pierre Téchoueyres, Rudolf Adamkovič, Sergey - Nichiporchik, Shreyas Ragavan, Stefan Kangas, Stephen Berman, - Stephen Gildea, Steve Downey, Thanos Apollo, Tomasz Hołubowicz, - Utkarsh Singh, Vincent Murphy, Xinglu Chen, Yuanchen Xie, fluentpwn, - okamsn. + Greevenbroek, Kostadin Ninev, Leilei332, Madhavan Krishnan, Manuel + Giraud, Markus Beppler, Matthew Stevenson, Mauro Aranda, Nacho + Barrientos, Niall Dooley, Nicolas De Jaeghere, Paul David, Pavel + Novichkov, Philip Kaludercic, Pierre Téchoueyres, Rahul M. + {{{space()}}} Juliato, Rudolf Adamkovič, Sergey Nichiporchik, + Shreyas Ragavan, Stefan Kangas, Stephen Berman, Stephen Gildea, + Steve Downey, Thanos Apollo, Tomasz Hołubowicz, Utkarsh Singh, + Vincent Murphy, Xinglu Chen, Yuanchen Xie, fluentpwn, okamsn. + Ideas and user feedback :: Aaron Jensen, Adam Porter, Adam Spiers, Adrian Manea, Aleksei Pirogov, Alex Griffin, Alex Koen, Alex @@ -5779,7 +5740,8 @@ The Modus themes are a collective effort. Every bit of work matters. Eugene, Fourchaux, Fredrik, Moesasji, Nick, Summer Emacs, TheBlob42, TitusMu, Trey, ZharMeny, bepolymathe, bit9tream, bangedorrunt, derek-upham, doolio, fleimgruber, gitrj95, iSeeU, jixiuf, ltmsyvag, - okamsn, pRot0ta1p, shipmints, soaringbird, tumashu, wakamenod. + okamsn, pedro-nonfree, pRot0ta1p, shipmints, soaringbird, tumashu, + wakamenod. + Packaging :: Basil L.{{{space()}}} Contovounesios, Eli Zaretskii, Glenn Morris, Mauro Aranda, Richard Stallman, Stefan Kangas (core @@ -5812,7 +5774,7 @@ All errors are my own. Version 1.3, 3 November 2008 - Copyright (C) 2000-2002, 2007-2008, 2025 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex index faad184e345..3ebea93cb1d 100644 --- a/doc/misc/texinfo.tex +++ b/doc/misc/texinfo.tex @@ -3,7 +3,7 @@ % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % -\def\texinfoversion{2025-01-31.21} +\def\texinfoversion{2025-03-22.08} % % Copyright 1985, 1986, 1988, 1990-2025 Free Software Foundation, Inc. % @@ -287,7 +287,6 @@ % Avoid "undefined control sequence" errors. \def\currentchapterdefs{} \def\currentsectiondefs{} -\def\currentsection{} \def\prevchapterdefs{} \def\prevsectiondefs{} \def\currentcolordefs{} @@ -980,18 +979,51 @@ where each line of input produces a line of output.} \newif\ifpdf \newif\ifpdfmakepagedest +% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1 +% can be set). So we test for \relax and 0 as well as being undefined. +\ifx\pdfoutput\thisisundefined +\else + \ifx\pdfoutput\relax + \else + \ifcase\pdfoutput + \else + \pdftrue + \fi + \fi +\fi + +\newif\ifxetex +\ifx\XeTeXrevision\thisisundefined\else + \xetextrue +\fi + \newif\ifluatex \ifx\luatexversion\thisisundefined\else \luatextrue + \ifnum\luatexversion>84 + \pdftrue + \fi \fi +\newif\ifpdforxetex +\ifpdf + \pdforxetextrue +\fi +\ifxetex + \pdforxetextrue +\fi + + + +% Whether to use non-ASCII bytes in internal link targets. Presently this +% is almost always on. +\newif\iftxiuseunicodedestname +\txiuseunicodedestnametrue + % % For LuaTeX % -\newif\iftxiuseunicodedestname -\txiuseunicodedestnamefalse % For pdfTeX etc. - \ifluatex % Use Unicode destination names \txiuseunicodedestnametrue @@ -1045,7 +1077,7 @@ where each line of input produces a line of output.} % \endgroup \def\pdfescapestring#1{\directlua{PDFescstr('\luaescapestring{#1}')}} - \ifnum\luatexversion>84 + \ifpdf % For LuaTeX >= 0.85 \def\pdfdest{\pdfextension dest} \let\pdfoutput\outputmode @@ -1068,33 +1100,6 @@ where each line of input produces a line of output.} \fi \fi -% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1 -% can be set). So we test for \relax and 0 as well as being undefined. -\ifx\pdfoutput\thisisundefined -\else - \ifx\pdfoutput\relax - \else - \ifcase\pdfoutput - \else - \pdftrue - \fi - \fi -\fi - -\newif\ifxetex -\ifx\XeTeXrevision\thisisundefined\else - \xetextrue -\fi - -\newif\ifpdforxetex -\pdforxetexfalse -\ifpdf - \pdforxetextrue -\fi -\ifxetex - \pdforxetextrue -\fi - % Output page labels information. % See PDF reference v.1.7 p.594, section 8.3.1. @@ -1388,9 +1393,6 @@ output) for that.)} \safewhatsit{\pdfdest name{\pdfdestname} xyz}% } % - % used to mark target names; must be expandable. - \def\pdfmkpgn#1{#1} - % % Adding outlines to PDF; macros for calculating structure of outlines % come from Petr Olsak \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% @@ -1416,7 +1418,7 @@ output) for that.)} \def\pdfdestname{#4}% \fi % - \pdfoutline goto name{\pdfmkpgn{\pdfdestname}}#2{\pdfoutlinetext}% + \pdfoutline goto name{\pdfdestname}#2{\pdfoutlinetext}% } % \def\pdfmakeoutlines{% @@ -1427,15 +1429,18 @@ output) for that.)} \def\thischapnum{##2}% \def\thissecnum{0}% \def\thissubsecnum{0}% + \def\indexlastsec{chap\thischapnum}% }% \def\numsecentry##1##2##3##4{% \advancenumber{chap\thischapnum}% \def\thissecnum{##2}% \def\thissubsecnum{0}% + \def\indexlastsec{sec\thissecnum}% }% \def\numsubsecentry##1##2##3##4{% \advancenumber{sec\thissecnum}% \def\thissubsecnum{##2}% + \def\indexlastsec{subsec\thissecnum}% }% \def\numsubsubsecentry##1##2##3##4{% \advancenumber{subsec\thissubsecnum}% @@ -1443,7 +1448,13 @@ output) for that.)} \def\thischapnum{0}% \def\thissecnum{0}% \def\thissubsecnum{0}% + \let\indexlastsec\empty % + % Index initials are subsidiary to whatever sectioning command just + % occurred, usually @appendix or @chapter but occasionally a lower level. + \def\idxinitialentry##1##2##3##4{% + \expandafter\advancenumber\expandafter{\indexlastsec}% + }% % use \def rather than \let here because we redefine \chapentry et % al. a second time, below. \def\appentry{\numchapentry}% @@ -1455,9 +1466,6 @@ output) for that.)} \def\unnsubsecentry{\numsubsecentry}% \def\unnsubsubsecentry{\numsubsubsecentry}% % - % Treat index initials like @section. Note that this is the wrong - % level if the index is not at the level of @appendix or @chapter. - \def\idxinitialentry{\numsecentry}% \readdatafile{toc}% % % Read toc second time, this time actually producing the outlines. @@ -1482,18 +1490,6 @@ output) for that.)} \def\idxinitialentry##1##2##3##4{% \dopdfoutline{##1}{}{idx.##1.##2}{##4}}% % - % PDF outlines are displayed using system fonts, instead of - % document fonts. Therefore we cannot use special characters, - % since the encoding is unknown. For example, the eogonek from - % Latin 2 (0xea) gets translated to a | character. Info from - % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100. - % - % TODO this right, we have to translate 8-bit characters to - % their "best" equivalent, based on the @documentencoding. Too - % much work for too little return. Just use the ASCII equivalents - % we use for the index sort strings. - % - \indexnofonts \ifnodeseen\else \dopdfoutlinecontents \fi % for @contents at beginning \setupdatafile % We can have normal brace characters in the PDF outlines, unlike @@ -1501,9 +1497,9 @@ output) for that.)} \def\{{\lbracecharliteral}% \def\}{\rbracecharliteral}% \catcode`\\=\active \otherbackslash - \input \tocreadfilename + \input \tocreadfilename\relax + \ifnodeseen \dopdfoutlinecontents \fi % for @contents at end \endgroup - \ifnodeseen \dopdfoutlinecontents \fi % for @contents at end } \def\dopdfoutlinecontents{% \expandafter\dopdfoutline\expandafter{\putwordTOC}{}{txi.CONTENTS}{}% @@ -1541,7 +1537,7 @@ output) for that.)} % \def\pdflink#1{\pdflinkpage{#1}{#1}}% \def\pdflinkpage#1#2{% - \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}} + \startlink attr{/Border [0 0 0]} goto name{#1} \setcolor{\linkcolor}#2\endlink} \else % non-pdf mode @@ -1644,18 +1640,20 @@ output) for that.)} % horizontal space being required in the PDF viewer. \def\partentry##1##2##3##4{}% ignore parts in the outlines \def\numchapentry##1##2##3##4{% - \dopdfoutline{##2 ##1}{1}{##3}{##4}}% + \dopdfoutline{##2 ##1}{1}{##3}{##4}% + \def\indexseclevel{2}}% \def\numsecentry##1##2##3##4{% - \dopdfoutline{##1}{2}{##3}{##4}}% + \dopdfoutline{##1}{2}{##3}{##4}% + \def\indexseclevel{3}}% \def\numsubsecentry##1##2##3##4{% - \dopdfoutline{##1}{3}{##3}{##4}}% + \dopdfoutline{##1}{3}{##3}{##4}% + \def\indexseclevel{4}}% \def\numsubsubsecentry##1##2##3##4{% - \dopdfoutline{##1}{4}{##3}{##4}}% + \dopdfoutline{##1}{4}{##3}{##4}% + \def\indexseclevel{5}}% % - % Note this is at the wrong level unless the index is in an @appendix - % or @chapter. \def\idxinitialentry##1##2##3##4{% - \dopdfoutline{##1}{2}{idx.##1.##2}{##4}}% + \dopdfoutline{##1}{\indexseclevel}{idx.##1.##2}{##4}}% % \let\appentry\numchapentry% \let\appsecentry\numsecentry% @@ -1680,7 +1678,9 @@ output) for that.)} \def\{{\lbracecharliteral}% \def\}{\rbracecharliteral}% \catcode`\\=\active \otherbackslash + \xetexpreauxfile \input \tocreadfilename\relax + \xetexpostauxfile \ifnodeseen \dopdfoutlinecontents \fi % for @contents at end \endgroup } @@ -5177,8 +5177,8 @@ $$% % \uccode`\1=`\{ \uppercase{\def\{{1}}% \uccode`\1=`\} \uppercase{\def\}{1}}% - \let\lbracechar\{% - \let\rbracechar\}% + \def\lbracechar##1{\{}% + \def\rbracechar##1{\}}% % % % We need to get rid of all macros, leaving only the arguments (if present). @@ -5523,6 +5523,8 @@ $$% \tolerance = 9500 \plainfrenchspacing \everypar = {}% don't want the \kern\-parindent from indentation suppression. + \let\entry\indexentry + \ifxetex\xetexpreauxfile\fi % % See comment in \requireopenindexfile. \def\indexname{#1}\ifx\indexname\indexisfl\def\indexname{f1}\fi @@ -5548,6 +5550,7 @@ $$% \fi \fi \closein 1 + \ifxetex\xetexpostauxfile\fi \endgroup} % Checked in @bye @@ -5583,7 +5586,9 @@ might help (with 'rm \jobname.?? \jobname.??s')% }% \else \begindoublecolumns + \ifxetex\xetexpreauxfile\fi \input \jobname.\indexname s + \ifxetex\xetexpostauxfile\fi \enddoublecolumns \fi }{% @@ -5594,11 +5599,39 @@ might help (with 'rm \jobname.?? \jobname.??s')% % should work because we (hopefully) don't otherwise use @ in index files. %\catcode`\@=12\relax \catcode`\@=0\relax + \ifxetex\xetexpreauxfile\fi \input \jobname.\indexname s + \ifxetex\xetexpostauxfile\fi \enddoublecolumns }% } +\def\indexentry#1#2{% + \let\entrypagetarget\empty + \ifpdforxetex + % only link the index text to the page if no comma appears in the + % list of pages, i.e. there is only one page + \checkpagelistcomma{#2}\pagelistcomma + \expandafter\ifcase\pagelistcomma + \def\entrypagetarget{#2}% + \fi + \fi% + \entryinternal{#1}{#2}% +} + +\def\checkpagelistcomma#1#2{% + \checkpagelistcommaxx#2#1,\finish +} +\def\checkpagelistcommaxx#1#2,#3\finish{% + \def\tmp{#3}% + \ifx\tmp\empty + \def#1{0\relax} + \else + \def#1{1\relax} + \fi +} + + % These macros are used by the sorted index file itself. % Change them to control the appearance of the index. @@ -5673,18 +5706,14 @@ might help (with 'rm \jobname.?? \jobname.??s')% \def\doindexinitialentry#1{% \ifpdforxetex \global\advance\idxinitialno by 1 - \def\indexlbrace{\{} - \def\indexrbrace{\}} - \def\indexbackslash{\realbackslash} - \def\indexatchar{\@} + \def\indexlbrace{\{}% + \def\indexrbrace{\}}% + \def\indexbackslash{\realbackslash}% + \def\indexatchar{\@}% \writetocentry{idxinitial}{\asis #1}{IDX\the\idxinitialno}% % The @asis removes a pair of braces around e.g. {@indexatchar} that % are output by texindex. % - \vbox to 0pt{}% - % This vbox fixes the \pdfdest location for double column formatting. - % Without it, the \pdfdest is output above topskip glue at the top - % of a column as this glue is not added until the first box. \pdfmkdest{idx.\asis #1.IDX\the\idxinitialno}% \fi } @@ -5704,16 +5733,18 @@ might help (with 'rm \jobname.?? \jobname.??s')% \newdimen\entrycontskip \entrycontskip=1em -% for PDF output, whether to make the text of the entry a link to the page -% number. set for @contents and @shortcontents where there is only one -% page number. +% for PDF output, whether to make the text of the entry a link to the section. +% set for @contents and @shortcontents. \newif\iflinkentrytext -% \entry typesets a paragraph consisting of the text (#1), dot leaders, and -% then page number (#2) flushed to the right margin. It is used for index -% and table of contents entries. The paragraph is indented by \leftskip. -% If \tocnodetarget is set, link text to the referenced node. -\def\entry{% +% \entryinternal typesets a paragraph consisting of the text (#1), dot +% leaders, and then page number (#2) flushed to the right margin. It is +% used for index and table of contents entries. The paragraph is indented +% by \leftskip. +% For PDF output, if \linkentrytexttrue and \tocnodetarget is set, link text +% to the referenced node. Else if \entrypagetarget is set, link text to the +% page. +\def\entryinternal{% \begingroup % % Start a new paragraph if necessary, so our assignments below can't @@ -5761,7 +5792,11 @@ might help (with 'rm \jobname.?? \jobname.??s')% \endlink \fi \else - \unhbox\boxA + \ifx\entrypagetarget\empty + \unhbox\boxA + \else + \pdflinkpage{\entrypagetarget}{\unhbox\boxA}% + \fi \fi \else \unhbox\boxA @@ -6433,6 +6468,10 @@ might help (with 'rm \jobname.?? \jobname.??s')% \parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{} \suppressfirstparagraphindent} +% @xrefname - give text with printed name for linking to node and allow +% referencing node, but do not print any heading. +\parseargdef\xrefname{\donoderef{Yomitfromtoc}{#1}}% + % These macros generate a chapter, section, etc. heading only % (including whitespace, linebreaking, etc. around it), % given all the information in convenient, parsed form. @@ -6554,11 +6593,6 @@ might help (with 'rm \jobname.?? \jobname.??s')% \chapfonts \rm \let\footnote=\errfootnoteheading % give better error message % - % Have to define \currentsection before calling \donoderef, because the - % xref code eventually uses it. On the other hand, it has to be called - % after \pchapsepmacro, or the headline will change too soon. - \gdef\currentsection{#1}% - % % Only insert the separating space if we have a chapter/appendix % number, and don't print the unnumbered ``number''. \ifx\temptype\Ynothingkeyword @@ -6585,7 +6619,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% % been typeset. If the destination for the pdf outline is after the % text, then jumping from the outline may wind up with the text not % being visible, for instance under high magnification. - \donoderef{#2}% + \donoderef{#2}{#1}% % % Typeset the actual heading. \nobreak % Avoid page breaks at the interline glue. @@ -6701,21 +6735,17 @@ might help (with 'rm \jobname.?? \jobname.??s')% \ifx\temptype\Ynothingkeyword \setbox0 = \hbox{}% \def\toctype{unn}% - \gdef\currentsection{#1}% \else\ifx\temptype\Yomitfromtockeyword - % for @headings -- no section number, don't include in toc, - % and don't redefine \currentsection. + % for @headings -- no section number, don't include in toc. \setbox0 = \hbox{}% \def\toctype{omit}% \let\sectionlevel=\empty \else\ifx\temptype\Yappendixkeyword \setbox0 = \hbox{#4\enspace}% \def\toctype{app}% - \gdef\currentsection{#1}% \else \setbox0 = \hbox{#4\enspace}% \def\toctype{num}% - \gdef\currentsection{#1}% \fi\fi\fi % % Write the toc entry (before \donoderef). See comments in \chapmacro. @@ -6723,7 +6753,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% % % Write the node reference (= pdf destination for pdftex). % Again, see comments in \chapmacro. - \donoderef{#3}% + \donoderef{#3}{#1}% % % Interline glue will be inserted when the vbox is completed. % That glue will be a valid breakpoint for the page, since it'll be @@ -6955,6 +6985,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% % \def\contents{% \startcontents{\putwordTOC}{\contentsmkdest}% + \ifxetex\xetexpreauxfile\fi \openin 1 \tocreadfilename\space \ifeof 1 \else \findsecnowidths @@ -6966,6 +6997,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% \pdfmakeoutlines \fi \closein 1 + \ifxetex\xetexpostauxfile\fi \endgroup \contentsendroman } @@ -6999,11 +7031,13 @@ might help (with 'rm \jobname.?? \jobname.??s')% \let\numsubsubsecentry = \numsecentry \let\appsubsubsecentry = \numsecentry \let\unnsubsubsecentry = \numsecentry + \ifxetex\xetexpreauxfile\fi \openin 1 \tocreadfilename\space \ifeof 1 \else \readtocfile \fi \closein 1 + \ifxetex\xetexpostauxfile\fi \vfill \eject \contentsalignmacro % in case @setchapternewpage odd is in effect \endgroup @@ -7167,6 +7201,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% \extrasecnoskip=0pt \let\tocnodetarget\empty +\let\entrypagetarget\empty % \tocentry{TITLE}{SEC NO}{NODE}{PAGE} % @@ -7174,7 +7209,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% \def\tocnodetarget{#3}% \def\secno{#2}% \ifx\empty\secno - \entry{#1}{#4}% + \entryinternal{#1}{#4}% \else \ifdim 0pt=\secnowidth \setbox0=\hbox{#2\hskip\labelspace\hskip\extrasecnoskip}% @@ -7185,7 +7220,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% #2\hskip\labelspace\hskip\extrasecnoskip\hfill}% \fi \entrycontskip=\wd0 - \entry{\box0 #1}{#4}% + \entryinternal{\box0 #1}{#4}% \fi } \newdimen\labelspace @@ -8170,18 +8205,11 @@ might help (with 'rm \jobname.?? \jobname.??s')% } \fi -\let\E=\expandafter - % Used at the time of macro expansion. % Argument is macro body with arguments substituted \def\scanmacro#1{% \newlinechar`\^^M - % expand the expansion of \eatleadingcr twice to maybe remove a leading - % newline (and \else and \fi tokens), then call \eatspaces on the result. - \def\xeatspaces##1{% - \E\E\E\E\E\E\E\eatspaces\E\E\E\E\E\E\E{\eatleadingcr##1% - }}% - \def\xempty##1{}% + \def\xeatspaces##1{\eatleadingcrthen\eatspaces{##1}}% % % Process the macro body under the current catcode regime. \scantokens{#1@comment}% @@ -8234,10 +8262,12 @@ might help (with 'rm \jobname.?? \jobname.??s')% \unbrace{\gdef\trim@@@ #1 } #2@{#1} } -{\catcode`\^^M=\other% -\gdef\eatleadingcr#1{\if\noexpand#1\noexpand^^M\else\E#1\fi}}% -% Warning: this won't work for a delimited argument -% or for an empty argument +% Trim a single leading ^^M off a string, then call #1 +{\catcode`\^^M=\active \catcode`\Q=3% +\gdef\eatleadingcrthen #1#2{\eatlcra #1Q#2Q^^MQ}% +\gdef\eatlcra #1#2Q^^M{\eatlcrb #1#2Q}% +\gdef\eatlcrb #1Q#2Q#3Q{#1{#2}}% +} % Trim a single trailing ^^M off a string. {\catcode`\^^M=\other \catcode`\Q=3% @@ -8373,6 +8403,10 @@ might help (with 'rm \jobname.?? \jobname.??s')% % is #, then the preceding argument is delimited by % an opening brace, and that opening brace is not consumed. +% Make @ a letter, so that we can make private-to-Texinfo macro names. +\edef\texiatcatcode{\the\catcode`\@} +\catcode `@=11\relax + % Parse the optional {params} list to @macro or @rmacro. % Set \paramno to the number of arguments, % and \paramlist to a parameter text for the macro (e.g. #1,#2,#3 for a @@ -8385,14 +8419,13 @@ might help (with 'rm \jobname.?? \jobname.??s')% % That gets used by \mbodybackslash (above). % % If there are 10 or more arguments, a different technique is used: see -% \parsemmanyargdef. +% \parsemmanyargdef@@. % \def\parsemargdef#1;{% \paramno=0\def\paramlist{}% \let\hash\relax % \hash is redefined to `#' later to get it into definitions \let\xeatspaces\relax - \let\xempty\relax \parsemargdefxxx#1,;,% \ifnum\paramno<10\relax\else \paramno0\relax @@ -8404,11 +8437,9 @@ might help (with 'rm \jobname.?? \jobname.??s')% \else \let\next=\parsemargdefxxx \advance\paramno by 1 \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname - {\xeatspaces{\hash\the\paramno\noexpand\xempty{}}}% + {\xeatspaces{\hash\the\paramno}}% \edef\paramlist{\paramlist\hash\the\paramno,}% \fi\next} -% the \xempty{} is to give \eatleadingcr an argument in the case of an -% empty macro argument. % \parsemacbody, \parsermacbody % @@ -8419,14 +8450,12 @@ might help (with 'rm \jobname.?? \jobname.??s')% % body to be transformed. % Set \macrobody to the body of the macro, and call \macrodef. % +\catcode `\@\texiatcatcode {\catcode`\ =\other\long\gdef\parsemacbody#1@end macro{% \xdef\macrobody{\eatcr{#1}}\endgroup\macrodef}}% {\catcode`\ =\other\long\gdef\parsermacbody#1@end rmacro{% \xdef\macrobody{\eatcr{#1}}\endgroup\macrodef}}% - -% Make @ a letter, so that we can make private-to-Texinfo macro names. -\edef\texiatcatcode{\the\catcode`\@} -\catcode `@=11\relax +\catcode `\@=11\relax %%%%%%%%%%%%%% Code for > 10 arguments only %%%%%%%%%%%%%%%%%% @@ -8687,15 +8716,13 @@ might help (with 'rm \jobname.?? \jobname.??s')% \noexpand\expandafter \expandafter\noexpand\csname\the\macname @@\endcsname}% \expandafter\xdef\csname\the\macname @@\endcsname##1{% - \noexpand\passargtomacro - \expandafter\noexpand\csname\the\macname @@@\endcsname{##1,}}% + \noexpand\passargtomacro + \expandafter\noexpand\csname\the\macname @@@\endcsname{##1,}}% \expandafter\xdef\csname\the\macname @@@\endcsname##1{% - \expandafter\noexpand\csname\the\macname @@@@\endcsname ##1}% - \expandafter\expandafter - \expandafter\xdef - \expandafter\expandafter - \csname\the\macname @@@@\endcsname\paramlist{% - \endgroup\noexpand\scanmacro{\macrobody}}% + \expandafter\noexpand\csname\the\macname @@@@\endcsname ##1}% + \expandaftergroup{\expandafter\xdef\csname\the\macname @@@@\endcsname}% + \paramlist{% + \endgroup\noexpand\scanmacro{\macrobody}}% \else % 10 or more: \expandafter\xdef\csname\the\macname\endcsname{% \noexpand\getargvals@{\the\macname}{\argl}% @@ -8707,6 +8734,16 @@ might help (with 'rm \jobname.?? \jobname.??s')% \catcode `\@\texiatcatcode\relax % end private-to-Texinfo catcodes +% utility definition to avoid excessive use of \expandafter. call +% as \expandaftergroup{CONTENT}\WORD to expand \WORD exactly once and remove +% braces around CONTENT. +\def\expandaftergroup#1#2{% + \expandafter\expandaftergroupx\expandafter{#2}{#1}% +} +\def\expandaftergroupx#1#2{% + #2#1% +} + \def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} @@ -8876,9 +8913,8 @@ might help (with 'rm \jobname.?? \jobname.??s')% \expandafter\noexpand \csname\the\macname @@@\endcsname##1\noexpand\endlinemacro } - \expandafter\expandafter - \expandafter\xdef - \expandafter\expandafter\csname\the\macname @@@\endcsname\paramlist{% + \expandaftergroup{\expandafter\xdef\csname\the\macname @@@\endcsname}% + \paramlist{% \newlinechar=13 % split \macrobody into lines \noexpand\scantokens{\macrobody}% } @@ -8953,11 +8989,11 @@ might help (with 'rm \jobname.?? \jobname.??s')% \let\lastnode=\empty % Write a cross-reference definition for the current node. #1 is the -% type (Ynumbered, Yappendix, Ynothing). +% type (Ynumbered, Yappendix, Ynothing). #2 is the section title. % -\def\donoderef#1{% +\def\donoderef#1#2{% \ifx\lastnode\empty\else - \setref{\lastnode}{#1}% + \setref{\lastnode}{#1}{#2}% \global\let\lastnode=\empty \setnodeseenonce \fi @@ -8978,21 +9014,28 @@ might help (with 'rm \jobname.?? \jobname.??s')% % \def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} \def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} -\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} +\def\anchor#1{% + \savesf \setref{#1}{Yanchor}{#1}\restoresf \ignorespaces +} -% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an -% anchor), which consists of three parts: -% 1) NAME-title - the current sectioning name taken from \currentsection, -% or the anchor name. -% 2) NAME-snt - section number and type, passed as the SNT arg, or -% empty for anchors. +% @namedanchor{NAME, XREFNAME} -- define xref target at arbitrary point +% with label text for cross-references to it. +\def\namedanchor#1{\donamedanchor#1\finish}% +\def\donamedanchor#1,#2\finish{% + \savesf \setref{#1}{Yanchor}{\ignorespaces #2\unskip}\restoresf \ignorespaces +} + +% \setref{NAME}{SNT}{TITLE} defines a cross-reference point NAME (a node +% or an anchor), which consists of three parts: +% 1) NAME-title - the current sectioning name +% 2) NAME-snt - section number and type, passed as the SNT arg. % 3) NAME-pg - the page number. % % This is called from \donoderef, \anchor, and \dofloat. In the case of % floats, there is an additional part, which is not written here: % 4) NAME-lof - the text as it should appear in a @listoffloats. % -\def\setref#1#2{% +\def\setref#1#2#3{% \pdfmkdest{#1}% \iflinks {% @@ -9004,7 +9047,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef ##1}{##2}}% these are parameters of \writexrdef }% - \toks0 = \expandafter{\currentsection}% + \toks0 = {#3}% \immediate \writexrdef{title}{\the\toks0 }% \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc. \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout @@ -9058,15 +9101,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% \setbox\infofilenamebox = \hbox{\infofilename\unskip}% % \startxreflink{#1}{#4}% - {% - % Have to otherify everything special to allow the \csname to - % include an _ in the xref name, etc. - \indexnofonts - \turnoffactive - \def\value##1{##1}% - \expandafter\global\expandafter\let\expandafter\Xthisreftitle - \csname XR#1-title\endcsname - }% + \getrefx{#1-title}\Xthisreftitle % % Float references are printed completely differently: "Figure 1.2" % instead of "[somenode], p.3". \iffloat distinguishes them by @@ -9099,21 +9134,23 @@ might help (with 'rm \jobname.?? \jobname.??s')% % Cross-manual reference with a printed manual name. % \crossmanualxref{\cite{\printedmanual\unskip}}% - % \else\ifdim \wd\infofilenamebox > 0pt % Cross-manual reference with only an info filename (arg 4), no % printed manual name (arg 5). This is essentially the same as % the case above; we output the filename, since we have nothing else. % \crossmanualxref{\code{\infofilename\unskip}}% - % \else % Reference within this manual. % - % 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 + % Only output a following space if the -snt ref is nonempty, as is + % the case for @unnumbered and @anchor. + \getrefx{#1-snt}\tmp + \ifx\tmp\empty\else + \ifx\tmp\Yanchor\else + \tmp\space + \fi + \fi % % output the `[mynode]' via the macro below so it can be overridden. \xrefprintnodename\printedrefname @@ -9169,7 +9206,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% \else % Otherwise just copy the Info node name. \def\printedrefname{\ignorespaces #1}% - \fi% + \fi \fi \fi \fi @@ -9201,7 +9238,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% \ifnum\filenamelength>0 goto file{\the\filename.pdf} name{\pdfdestname}% \else - goto name{\pdfmkpgn{\pdfdestname}}% + goto name{\pdfdestname}% \fi \else % XeTeX \ifnum\filenamelength>0 @@ -9281,6 +9318,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% % \def\Ynothing{} \def\Yomitfromtoc{} +\def\Yanchor{\isanchor} \let\isanchor\relax \def\Ynumbered{% \ifnum\secno=0 \putwordChapter@tie \the\chapno @@ -9307,14 +9345,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% % \refx{NAME} - reference a cross-reference string named NAME. \def\refx#1{% - \requireauxfile - {% - \indexnofonts - \turnoffactive - \def\value##1{##1}% - \expandafter\global\expandafter\let\expandafter\thisrefX - \csname XR#1\endcsname - }% + \getrefx{#1}\thisrefX \ifx\thisrefX\relax % If not defined, say something at least. \angleleft un\-de\-fined\angleright @@ -9335,6 +9366,17 @@ might help (with 'rm \jobname.?? \jobname.??s')% \fi } +% Set #2 to xref string #1 +\def\getrefx#1#2{% + \requireauxfile + {% + \indexnofonts + \turnoffactive + \def\value##1{##1}% + \expandafter\global\expandafter\let\expandafter#2\csname XR#1\endcsname + }% +} + % This is the macro invoked by entries in the aux file. Define a control % sequence for a cross-reference target (we prepend XR to the control sequence % name to avoid collisions). The value is the page number. If this is a float @@ -9399,12 +9441,14 @@ might help (with 'rm \jobname.?? \jobname.??s')% % Read the last existing aux file, if any. No error if none exists. % \def\tryauxfile{% + \ifxetex\xetexpreauxfile\fi \openin 1 \jobname.aux \ifeof 1 \else \readdatafile{aux}% \global\havexrefstrue \fi \closein 1 + \ifxetex\xetexpostauxfile\fi } \def\setupdatafile{% @@ -9790,14 +9834,15 @@ might help (with 'rm \jobname.?? \jobname.??s')% \global\advance\floatno by 1 % {% - % This magic value for \currentsection is output by \setref as the - % XREFLABEL-title value. \xrefX uses it to distinguish float + % This magic value for the third argument of \setref is output as + % the XREFLABEL-title value. \xrefX uses it to distinguish float % labels (which have a completely different output format) from % node and anchor labels. And \xrdef uses it to construct the % lists of floats. % - \edef\currentsection{\floatmagic=\safefloattype}% - \setref{\floatlabel}{Yfloat}% + \edef\tmp{\noexpand\setref{\floatlabel}{Yfloat}% + {\floatmagic=\safefloattype}}% + \tmp }% \fi % @@ -9919,7 +9964,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% % #1 is the control sequence we are passed; we expand into a conditional % which is true if #1 represents a float ref. That is, the magic -% \currentsection value which we \setref above. +% value which we passed to \setref above. % \def\iffloat#1{\expandafter\doiffloat#1==\finish} % @@ -9976,6 +10021,7 @@ might help (with 'rm \jobname.?? \jobname.??s')% \toksA = \expandafter{\csname XR#1-lof\endcsname}% % % use the same \entry macro we use to generate the TOC and index. + \let\entry\entryinternal \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}% \writeentry }} @@ -10071,17 +10117,24 @@ directory should work if nowhere else does.} \fi \fi +\let\xetexpreauxfile\relax +\let\xetexpostauxfile\relax + % Set I/O by bytes instead of UTF-8 sequence for XeTeX and LuaTex % for non-UTF-8 (byte-wise) encodings. % \def\setbytewiseio{% \ifxetex - \XeTeXdefaultencoding "bytes" % For subsequent files to be read - \XeTeXinputencoding "bytes" % For document root file - % Unfortunately, there seems to be no corresponding XeTeX command for - % output encoding. This is a problem for auxiliary index and TOC files. - % The only solution would be perhaps to write out @U{...} sequences in - % place of non-ASCII characters. + % For document root file + \XeTeXinputencoding "bytes" + % + % Setting for subsequent files to be read with @include. + \XeTeXdefaultencoding "bytes" + % + % Use UTF-8 for reading auxiliary index and TOC files, which are + % always output in UTF-8 with XeTeX. + \def\xetexpreauxfile{\XeTeXdefaultencoding "UTF-8"}% + \def\xetexpostauxfile{\XeTeXdefaultencoding "bytes"}% \fi \ifluatex @@ -10713,12 +10766,12 @@ directory should work if nowhere else does.} % Suppress ligature creation from adjacent characters. \ifluatex - \def\nolig{{}} -\else % Braces do not suppress ligature creation in LuaTeX, e.g. in of{}fice % to suppress the "ff" ligature. Using a kern appears to be the only % workaround. \def\nolig{\kern0pt{}} +\else + \def\nolig{{}} \fi % https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_M diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index a22e514f055..c3af74ea1df 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -6769,6 +6769,15 @@ the following settings are required: @end group @end lisp +@vindex warning-suppress-types +@value{tramp} warnings are displayed in the @file{*Warnings*} buffer, +which pops up. If you don't want to see this buffer for every +@value{tramp} warning, set @code{warning-suppress-types}: + +@lisp +(setq warning-suppress-types '((tramp))) +@end lisp + If @code{tramp-verbose} is greater than or equal to 10, Lisp backtraces are also added to the @value{tramp} debug buffer in case of errors. diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index c8630cee1c9..2f980df9f45 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -1471,7 +1471,7 @@ faces. Example: (use-package example :custom-face (example-1-face ((t (:foreground "LightPink")))) - (example-2-face ((t (:foreground "LightGreen"))) face-defspec-spec)) + (example-2-face ((t (:foreground "LightGreen"))))) @end group @group @@ -1486,6 +1486,11 @@ faces. Example: @end group @end lisp +Similarly to @code{:custom} (@pxref{User options}), this allows +configuring customizable faces outside of Customize (@pxref{Saving +Customizations,,, emacs, GNU Emacs Manual}). Using both systems to +configure the same face can lead to confusing results. + @node Hiding minor modes @section Hiding minor modes with diminish and delight @cindex hiding minor modes diff --git a/etc/DEBUG b/etc/DEBUG index 546ff362b0a..ce9fe6f921c 100644 --- a/etc/DEBUG +++ b/etc/DEBUG @@ -19,11 +19,11 @@ such as --prefix): ./configure --enable-checking='yes,glyphs' --enable-check-lisp-object-type \ CFLAGS='-O0 -g3' -The -O0 flag is important, as debugging optimized code can be hard. -If the problem happens only with optimized code, you may need to -enable optimizations. If that happens, try using -Og first instead of --O2, as -Og disables some optimizations that make debugging some code -exceptionally hard. +The -O0 flag is important, as debugging optimized code can be hard, even +in the case that the -Og compiler option is used.[1] If the problem +happens only with optimized code, you may need to enable optimizations. +If that happens, try using -Og first instead of -O2, as -Og disables +some optimizations that make debugging some code exceptionally hard. Older versions of GCC may need more than just the -g3 flag. For more, search for "analyze failed assertions" below. @@ -38,6 +38,9 @@ this below under "Debugging Emacs redisplay problems". Emacs needs not be installed to be debugged, you can debug the binary created in the 'src' directory. +[1] gcc's -Og has some known problems and limitations, documented here: + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78685 + *** Configuring GDB To start GDB to debug Emacs, you can simply type "gdb ./emacs RET" at diff --git a/etc/EGLOT-NEWS b/etc/EGLOT-NEWS index 7b53d5943ba..6505a6d8567 100644 --- a/etc/EGLOT-NEWS +++ b/etc/EGLOT-NEWS @@ -47,6 +47,13 @@ The composition of Eglot's mode line can be fully customized by adding or removing symbols and strings from the customizable variable 'eglot-mode-line-format' +** Improved diagnostic-reporting performance and bugfixes (bug#77588) + +Eglot remembers the LSP document version to which diagonstics reported +by the LSP server pertain. This helps in skipping useless or harmful +updates, avoiding flakiness with code actions and flickering overlays +when the buffer is changed. + * Changes in Eglot 1.18 (20/1/2025) diff --git a/etc/NEWS b/etc/NEWS index dc77aff7ef2..e080d8ed3a2 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -30,9 +30,9 @@ The traditional unexec dumper, deprecated since Emacs 27, has been removed. --- -** Emacs's old ctags program is no longer built or installed. +** Emacs's old 'ctags' program is no longer built or installed. You are encouraged to use Universal Ctags instead. -For now, to get the old ctags behavior you can can run 'etags --ctags' +For now, to get the old 'ctags' behavior you can can run 'etags --ctags' or use a shell script named 'ctags' that runs 'etags --ctags "$@"'. --- @@ -64,6 +64,9 @@ init file. * Changes in Emacs 31.1 +** 'prettify-symbols-mode' attempts to ignore undisplayable characters. +Previously, such characters would be rendered as, e.g., white boxes. + +++ ** 'standard-display-table' now has more extra slots. 'standard-display-table' has been extended to allow specifying glyphs @@ -216,22 +219,25 @@ popup interface, such as the interfaces that the GNU ELPA packages Corfu and Company provide, you can set this option to the same sort function that your popup interface uses for a more integrated experience. -Note: 'completion-preview-sort-function' was present also in Emacs 30.1, -albeit as a variable, not a user option. +('completion-preview-sort-function' was already present in Emacs 30.1, +but as a plain Lisp variable, not a user option.) ** Windows +++ -*** New functions to modify window layout. -Several functions to modify the window layout have been added: -'rotate-window-layout-clockwise', 'rotate-window-layout-anticlockwise', -'flip-window-layout-vertically', 'flip-window-layout-horizontally', -'transpose-window-layout', 'rotate-windows', and 'rotate-windows-back'. +*** New commands to modify window layouts. + +- 'C-x w t' and 'C-x w r /' rotate the window layout. +- 'C-x w o /' rotate the windows within the current layout. +- 'C-x w f ///' flip window layouts. + +By default, these commands operate on the selected frame's root window. +With a prefix argument, they operate on the selected window's parent. +++ *** Windmove commands now move to skipped windows if invoked twice in a row. The new user option 'windmove-allow-repeated-command-override' controls -this behavior: if it's non-nil, invoking the same windmove command twice +this behavior: if it is non-nil, invoking the same windmove command twice overrides the 'no-other-window' property, allowing navigation to windows that would normally be skipped. The default is t; customize it to nil if you want the old behavior. @@ -304,14 +310,16 @@ window whose buffer shares text with the buffer to display. *** New variable 'window-state-normalize-buffer-name'. When bound to non-nil, 'window-state-get' will normalize 'uniquify' managed buffer names by removing 'uniquify' prefixes and suffixes. This -helps restore window buffers across Emacs sessions. +helps to restore window buffers across Emacs sessions. ** Frames +++ *** New function 'frame-deletable-p'. -Calling this function before 'delete-frame' is useful to avoid that the -latter throws an error when the argument FRAME cannot be deleted. +If this function returns nil, the following call to 'delete-frame' might +fail to delete its argument FRAME or might signal an error. It is +therefore advisable to use this function as part of a condition that +determines whether to call 'delete-frame'. +++ *** New value 'force' for user option 'frame-inhibit-implied-resize'. @@ -319,6 +327,20 @@ This will inhibit implied resizing while a new frame is made and can be useful on tiling window managers where the initial frame size should be specified by external means. +** Mode Line + ++++ +*** New user option 'mode-line-collapse-minor-modes'. +If non-nil, minor mode lighters on the mode line are collapsed into a +single button. The value could also be a list to specify minor mode +lighters to hide or show. The default value is nil, which retains the +previous behavior of showing all minor mode lighters. + +*** New user option 'mode-line-modes-delimiters'. +This option allows changing or removing the delimiters shown around +the major mode and list of minor modes in the mode line. The default +retains the existing behavior of inserting parentheses. + ** Tab Bars and Tab Lines --- @@ -360,12 +382,12 @@ docstring for arguments passed to a help-text function. --- *** New command 'project-root-find-file'. -It is equivalent to running ‘project-any-command’ with ‘find-file’. +It is equivalent to running 'project-any-command' with 'find-file'. --- *** New command 'project-customize-dirlocals'. -It is equivalent to running ‘project-any-command’ with -‘customize-dirlocals’. +It is equivalent to running 'project-any-command' with +'customize-dirlocals'. --- *** Improved prompt for 'project-switch-project'. @@ -435,8 +457,8 @@ doesn't already mention 'setopt', the 'describe-variable' command will now add a note about this automatically. +++ -** New user option 'eldoc-help-at-pt' to show help at point via Eldoc. -When enabled, display the 'help-at-pt-kbd-string' via Eldoc. This +** New user option 'eldoc-help-at-pt' to show help at point via ElDoc. +When enabled, display the 'help-at-pt-kbd-string' via ElDoc. This setting is an alternative to 'help-at-pt-display-when-idle'. @@ -474,10 +496,14 @@ Additionally, there is a general-purpose 'haudenosaunee-postfix' input method to facilitate writing in the orthographies of the five languages simultaneously. +--- +*** New input methods for languages based on Burmese. +These include: Burmese, Burmese (visual order), Shan, and Mon. + --- ** 'visual-wrap-prefix-mode' now supports variable-pitch fonts. When using 'visual-wrap-prefix-mode' in buffers with variable-pitch -fonts, the wrapped text will now be lined up correctly so that it's +fonts, the wrapped text will now be lined up correctly so that it is exactly below the text after the prefix on the first line. --- @@ -520,7 +546,7 @@ based on the state of the buffer, such as for the different states of modal editing packages. ** New user variable 'exchange-point-and-mark-highlight-region'. -When set to nil, this modifies `exchange-point-and-mark' so that it doesn't +When set to nil, this modifies 'exchange-point-and-mark' so that it doesn't activate the mark if it is not already active. The default value is t, which retains the old behavior. This variable has no effect when Transient Mark mode is off. @@ -528,9 +554,215 @@ This variable has no effect when Transient Mark mode is off. * Changes in Specialized Modes and Packages in Emacs 31.1 +** Tree-sitter + +*** New user option 'treesit-auto-install-grammar'. +It controls the automatic installation of tree-sitter grammar libraries +needed for tree-sitter based modes, if these grammar libraries are not +available when such modes are turned on. + +*** The file treesit-x.el defines a number of simple tree-sitter modes. +Using the new macro 'define-treesit-generic-mode', generic modes are +defined including, but not limited to, 'gitattributes-generic-ts-mode'. +Visiting a file in such mode asks for confirmation before installing +its tree-sitter grammar. Then it highlights the visited file +according to the syntax defined by the grammar. + +*** New command 'treesit-cycle-sexp-type'. +It cycles the type of navigation for commands that move across sexp's +and lists, such as 'treesit-forward-sexp', 'treesit-forward-list', +'treesit-down-list', and 'treesit-up-list'. The type can be either +'list', the default, or 'sexp'. +With the default 'list' type these commands move using syntax tables for +symbols and using the thing 'list' for lists. +With the 'sexp' type these commands move across nodes defined by +the tree-sitter thing 'sexp' in 'treesit-thing-settings'. + ++++ +*** Indirect buffers can have their own parser list. +Before, indirect buffers share their base buffer’s parser list and +parsers. Now they can have their own parser list. + ++++ +*** New variable 'treesit-language-remap-alist'. +This variable allows a user to remap one language into another, such +that creating a parser for language A actually creates a parser for +language B. By extension, any font-lock rules or indentation rules for +language A will be applied to language B instead. + +This is useful for reusing font-lock rules and indentation rules of +language A for language B, when language B is a strict superset of +language A. + ++++ +*** New accessor functions for each setting in 'treesit-font-lock-settings'. +Now users can access a setting's query, feature, enable flag, and +override flag by 'treesit-font-lock-setting-query', +'treesit-font-lock-setting-feature', 'treesit-font-lock-setting-enable', +and 'treesit-font-lock-setting-override'. + +*** New tree-sitter thing 'list'. +Unlike the existing thing 'sexp' that defines both lists and atoms, +'list' defines only lists to be navigated by 'forward-sexp'. +The new function 'treesit-forward-sexp-list' uses 'list' +to move across lists. But to move across atoms inside the list +it uses 'forward-sexp-default-function'. + +*** New tree-sitter based functions for moving by lists. +If a major mode defines 'list' in 'treesit-thing-settings', +tree-sitter setup for these modes sets 'forward-list-function' to +'treesit-forward-list', 'up-list-function' to 'treesit-up-list', and +'down-list-function' to 'treesit-down-list'. This enables the +'forward-list', 'up-list', and 'down-list' motion commands for those +modes. + +*** Tree-sitter enabled modes now properly support 'show-paren-mode'. +They do that by letting 'show-paren-mode' use the results of parsing by +the tree-sitter library. The new function 'treesit-show-paren-data' is +used to communicate the tree-sitter parsing results to 'show-paren-mode'. + +*** Tree-sitter enabled modes now properly support 'hs-minor-mode'. +All commands from hideshow.el can selectively display blocks +defined by the new tree-sitter thing 'list'. + +*** New tree-sitter thing 'comment'. +The new variable 'forward-comment-function' is set to the new function +'treesit-forward-comment' if a major mode defines the thing 'comment'. + ++++ +*** New function 'treesit-language-display-name'. +This new function returns the display name of a language given the +language symbol. For example, 'cpp' is translated to "C++". A new +variable 'treesit-language-display-name-alist' holds the translations of +language symbols where that translation is not trivial. + +*** New function 'treesit-merge-font-lock-feature-list'. +This function merges two tree-sitter font-lock feature lists. It +returns a new font-lock feature list with no duplicates in the same +level. It can be used to merge font-lock feature lists in a +multi-language major mode. + +*** New function 'treesit-replace-font-lock-feature-settings'. +Given two tree-sitter font-lock settings, it replaces the feature in the +second font-lock settings with the same feature in the first font-lock +settings. In a multi-language major mode it is sometimes necessary to +replace features from one of the major modes with others, that are +better suited to the new multilingual context. + +*** New function 'treesit-simple-indent-modify-rules'. +Given two tree-sitter indent rules, it replaces, adds, or prepends rules +in the old rules with new ones, then returns the modified rules. In a +multi-language major mode it is sometimes necessary to modify rules from +one of the major modes to better suit the new multilingual context. + ++++ +*** New variable 'treesit-aggregated-simple-imenu-settings'. +This variable allows major modes to setup Imenu for multiple languages. + ++++ +*** New variable 'treesit-aggregated-outline-predicate'. +This variable allows major modes to setup 'outline-minor-mode' +for multiple languages. + +*** New function 'treesit-simple-indent-add-rules'. +This new function makes it easier to customize indent rules for +tree-sitter modes. + +*** New variable 'treesit-simple-indent-override-rules'. +Users can customize this variable to add simple custom indentation rules +for tree-sitter major modes. + ++++ +*** 'treesit-language-at-point-function' is now optional. +Multi-language major modes can rely on the default return value from +'treesit-language-at' that uses the new function 'treesit-parsers-at'. + ++++ +*** New command 'treesit-explore'. +This command replaces 'treesit-explore-mode'. It turns on +'treesit-explore-mode' if it is not on, and pops up the explorer buffer +if it is already on. + ++++ +*** 'treesit-explore-mode' now supports local parsers. +Now 'treesit-explore-mode' (or 'treesit-explore') prompts for a parser +rather than a language, and it is now possible to select a local parser +at point to explore. + +** C-ts mode + ++++ +*** New user option 'c-ts-mode-enable-doxygen'. +By default, this is nil, and the Doxygen comment blocks in C/C++ sources +are highlighted like other comments. When non-nil, Doxygen comment +blocks are syntax-highlighted if the Doxygen grammar library is +available. + +** Go-ts mode + ++++ +*** New unit test commands. +Three new commands are now available to run unit tests. + +The 'go-ts-mode-test-function-at-point' command runs the unit test at +point. If a region is active, it runs all the unit tests under the +region. It is bound to 'C-c C-t t' in 'go-ts-mode'. + +The 'go-ts-mode-test-this-file' command runs all unit tests in the current +file. It is bound to 'C-c C-t f' in 'go-ts-mode'. + +The 'go-ts-mode-test-this-package' command runs all unit tests under the +package of the current buffer. It is bound to 'C-c C-t p' in 'go-ts-mode'. + +The 'go-ts-mode-build-tags' user option is available to set a list of +build tags for the test commands. + +The 'go-ts-mode-test-flags' user option is available to set a list of +additional flags to pass to the go test command line. + +** Java-ts mode + ++++ +*** New user option 'java-ts-mode-enable-doxygen'. +By default, this is nil, and the Doxygen comment blocks in Java sources +are highlighted like other comments. When non-nil, Doxygen comment +blocks are syntax-highlighted if the Doxygen grammar library is +available. + --- +*** New user option 'java-ts-mode-method-chaining-indent-offset'. +Now method chaining is indented by 8 spaces rather than 4, and this +option controls how much is indented for method chaining. + +** PHP-ts mode + +--- +*** 'php-ts-mode-run-php-webserver' can now accept a custom "php.ini" file. +You can use the new optional argument CONFIG when calling +'php-ts-mode-run-php-webserver' to pass an alternative "php.ini" file to +the built-in Web server. Interactively, when invoked with a prefix +argument, 'php-ts-mode-run-php-webserver' prompts for the config file as +well as for other connection parameters. + +** Rust-ts mode + +--- +*** New user option 'rust-ts-mode-fontify-number-suffix-as-type'. +Rust number literals may have an optional type suffix. When this option +is non-nil, this suffix is fontified using 'font-lock-type-face'. + +** EIEIO + +--- +*** New value 'warn' for 'eieio-backward-compatibility'. +This is the new default value and causes warnings to be emitted +at run-time for the use of the associated deprecated features. +'(setq eieio-backward-compatibility t)' can be used to recover +the previous silence. + ** Text mode +--- *** New commands to convert between ASCII and full-width characters. New commands 'fullwidth-region' and 'fullwidth-word' convert ASCII characters in region or in the word at point to the corresponding @@ -539,23 +771,25 @@ characters in CJK texts. For example, 'A' is converted to 'A', '1' is converted to '1', etc. Companion commands 'halfwidth-region' and 'halfwidth-word' perform the opposite conversion. ---- ** ASM mode -*** 'asm-mode-set-comment-hook' is obsolete. -You can now set `asm-comment-char' from 'asm-mode-hook' instead. - --- +*** 'asm-mode-set-comment-hook' is obsolete. +You can now set 'asm-comment-char' from 'asm-mode-hook' instead. + ** Ibuffer +--- *** New column 'recency' in Ibuffer display. The user option 'ibuffer-formats' configures the Ibuffer formats. Add 'recency' to the format to display the column. +--- *** New value 'title' for the user option 'ibuffer-use-header-line'. Display column titles in the header line if 'ibuffer-use-header-line' is set to 'title'. +--- *** New user option 'ibuffer-human-readable-size'. When non-nil, buffer sizes are shown in human readable format. @@ -565,9 +799,31 @@ The prompts 'opstring' and 'active-opstring' can now either be strings or functions. This is useful when your prompts can benefit from dynamic content. +** ElDoc + --- +*** New ElDoc function 'elisp-eldoc-funcall-with-docstring'. +This function includes the current function's docstring in the ElDoc +echo area and can be used as a more detailed alternative to +'elisp-eldoc-funcall'. + +--- +*** New user option 'elisp-eldoc-funcall-with-docstring-length'. +This user option specifies how long function docstrings must be +displayed in 'elisp-eldoc-funcall-with-docstring'. If set to 'short' +(the default), only display the first sentence of the docstring. +Otherwise, if set to 'full', display the full docstring. + +--- +*** New user option 'elisp-eldoc-docstring-length-limit'. +This user option controls the maximum length of docstrings in character +units that 'elisp-eldoc-funcall-with-docstring' and +'elisp-eldoc-var-docstring-with-value' will show. By default, it is set +to 1000 characters. + ** Buffer Menu +--- *** New user option 'Buffer-menu-human-readable-sizes'. When non-nil, buffer sizes are shown in human readable format. The default is nil, which retains the old format. @@ -664,6 +920,14 @@ It is an alias for the 'progn' special-form. +++ *** 'cl-gensym' is now obsolete; use 'gensym' instead. ++++ +*** New macro 'cl-with-accessors'. +This macro is similar to 'with-slots', but uses accessor functions +instead of slot names. It is useful when slots' accessor functions are +used repeatedly, such as reading from a slot and then writing to that +slot. Symbol macros are created for the accessor functions using +'cl-symbol-macrolet', so that they can be used with 'setq' and 'setf'. + ** Whitespace --- @@ -713,6 +977,12 @@ Emacs exit. ** Savehist +--- +*** The history file can be modified by external tools. +Emacs can now handle this case gracefully by merging the external +and internal history information. +This feature is activated only when 'savehist-additional-variables' is nil. + --- *** Savehist no longer saves additional variables more than once. If you configured 'savehist-additional-variables' with variables that @@ -881,30 +1151,31 @@ only search in input history. If you customize it to the symbol 'dwim', those commands search in input history only when the point is after the last prompt. -+++ ** Mail Utils ++++ *** New user option 'mail-re-regexps'. This contains the list of regular expressions used to match "Re:" and international variants of it when modifying the Subject field in replies. -+++ ** Rmail ++++ *** 'rmail-re-abbrevs' default value is now derived from 'mail-re-regexps'. 'mail-re-regexps' is a new user option that is easier to customize than 'rmail-re-abbrevs'. 'rmail-re-abbrevs' is still honored if it was already set. -+++ ** Message ++++ *** 'message-subject-re-regexp' default value is now derived from 'mail-re-regexps'. 'mail-re-regexps' is a new user option that is easier to customize than 'message-subject-re-regexp'. 'message-subject-re-regexp' is still honored if it was already set. ++++ *** 'message-strip-subject-re' now matches case-insensitively. ** SHR @@ -971,51 +1242,6 @@ To get the old behavior back, add an element '(enum-open 'c-offsets-alist' likewise in any of the other ways detailed in the "(ccmode) Config Basics" node of the CC mode manual. -** Go-ts mode - -+++ -*** New unit test commands. -Three new commands are now available to run unit tests. - -The 'go-ts-mode-test-function-at-point' command runs the unit test at -point. If a region is active, it runs all the unit tests under the -region. It is bound to 'C-c C-t t' in 'go-ts-mode'. - -The 'go-ts-mode-test-this-file' command runs all unit tests in the current -file. It is bound to 'C-c C-t f' in 'go-ts-mode'. - -The 'go-ts-mode-test-this-package' command runs all unit tests under the -package of the current buffer. It is bound to 'C-c C-t p' in 'go-ts-mode'. - -The 'go-ts-mode-build-tags' user option is available to set a list of -build tags for the test commands. - -The 'go-ts-mode-test-flags' user option is available to set a list of -additional flags to pass to the go test command line. - -** C-ts mode - -+++ -*** New user option 'c-ts-mode-enable-doxygen'. -By default, this is nil, and the Doxygen comment blocks in C/C++ source -are highlighted like other comments. When non-nil, Doxygen comment -blocks are syntax-highlighted if the Doxygen grammar library is -available. - -** Java-ts mode - -+++ -*** New user option 'java-ts-mode-enable-doxygen'. -By default, this is nil, and the Doxygen comment blocks in Java source -are highlighted like other comments. When non-nil, Doxygen comment -blocks are syntax-highlighted if the Doxygen grammar library is -available. - ---- -*** New user option 'java-ts-mode-method-chaining-indent-offset'. -Now method chaining is indented by 8 spaces rather than 4, and this -variable controls how much is indented for method chaining. - ** Emacs Lisp mode --- @@ -1193,23 +1419,6 @@ They suggest the previous revision as the default for REV1, not the last one as before. This makes them different from 'vc-diff' and 'vc-root-diff' when those are called without a prefix argument. -** PHP-ts mode - ---- -*** 'php-ts-mode-run-php-webserver' can now accept a custom "php.ini" file. -You can use the new optional argument CONFIG when calling -'php-ts-mode-run-php-webserver' to pass an alternative "php.ini" file to -the built-in Web server. Interactively, when invoked with a prefix -argument, 'php-ts-mode-run-php-webserver' prompts for the config file as -well as for other connection parameters. - -** Rust-ts mode - ---- -*** New user option 'rust-ts-mode-fontify-number-suffix-as-type'. -Rust number literals may have an optional type suffix. When this option -is non-nil, this suffix is fontified using 'font-lock-type-face'. - ** Ediff +++ @@ -1229,15 +1438,29 @@ changes when supplied with a universal prefix argument via 'C-u': - 'C-u c b' copies all changes from buffer C to buffer B. +++ -*** Ediff now supports more flexible custom window layouts +*** Ediff now supports more flexible custom window layouts. Custom implementations of 'ediff-window-setup-function' no -longer need to display *all* ediff windows. Any of the A, B, C, +longer need to display *all* Ediff windows. Any of the A, B, C, and control windows can be left undisplayed and the corresponding variable set to nil. This change enables custom layouts without a control panel window. ** Dired +--- +*** New user option 'dired-create-empty-file-in-current-directory'. +When non-nil, 'dired-create-empty-file' creates a new empty file and +adds an entry for it (or its topmost new parent directory if created) +under the current subdirectory in the Dired buffer by default +(otherwise, it adds the new file (and new subdirectories if provided) to +whichever directory the user enters at the prompt). When nil, +'dired-create-empty-file' acts on the default directory by default. + +Note that setting this user option to non-nil makes invoking +'dired-create-empty-file' outside of a Dired buffer raise an error (like +other Dired commands that always prompt with the current subdirectory, +such as 'dired-create-directory'). + +++ *** New user option 'dired-check-symlinks' allows disabling validity checks. Dired uses 'file-truename' to check symbolic link validity when @@ -1347,7 +1570,7 @@ mode. Now, one needs to say '(midnight-mode +1)' instead. ** Python mode -*** New repeat-map for Python indentation commands. +*** New 'repeat-map' for Python indentation commands. The commands 'python-indent-shift-left' and 'python-indent-shift-right' can now be repeated using 'repeat-mode'. With 'repeat-mode' enabled, after invoking one of these commands via 'C-c <' or 'C-c >', you can @@ -1457,10 +1680,10 @@ command line. --- *** New user options 'vc-resolve-conflicts' and 'vc-*-resolve-conflicts'. -Control whether to mark a conflicted file as resolved when saving. -You can now control it globally, with 'vc-resolve-conflicts' or for +They control whether to mark a conflicted file as resolved when saving. +You can now control it globally, with 'vc-resolve-conflicts', or for specific backends with 'vc-bzr-resolve-conflicts', -'vc-hg-resolve-conflicts' and 'vc-svn-resolve-conflicts'. +'vc-hg-resolve-conflicts', and 'vc-svn-resolve-conflicts'. --- *** New value for 'vc-git-resolve-conflicts'. @@ -1469,6 +1692,52 @@ its default value. Effectively, the default value hasn't changed, since 'vc-resolve-conflicts' defaults to t, the previous default value for 'vc-git-resolve-conflicts'. +--- +*** VC Directory can now automatically add and remove marks on other lines. +When you try to use a mark or unmark command where doing so would only +be permitted if other lines were marked or unmarked first, Emacs +will now ask you if you'd like to change the marks on those other lines. +For example, if you try to mark a file contained within a directory that +is already marked, Emacs will offer to unmark the directory, first. +Previously, Emacs would simply refuse to make any changes. +You can customize 'vc-dir-allow-mass-mark-changes' to restore the old +behavior or dispense with the prompting. + +--- +*** New VC Directory bindings 'z d' and 'D' to delete Git stashes. +These correspond to the existing 'z p' to pop a stash and 'P' to pop the +stash at point (deleting the stash at point is also bound to 'C-k'). + +--- +*** VC Directory now offers to register files when checking in mixed filesets. +Previously, if some files to be checked in were unregistered but others +were added, removed or edited, Emacs would refuse to proceed. +Now Emacs prompts to first register the unregistered files, so that all +files in the fileset are in a compatible state for a checkin. + +--- +*** New 'log-edit-hook' option to display diff of changes to commit. +You can customize 'log-edit-hook' to include its new +'log-edit-maybe-show-diff' option to enable displaying a diff of the +changes to be committed in a window. This is like the 'C-c C-d' command +in Log Edit mode buffers, except that it does not select the *vc-diff* +buffer's window, and so works well when added to 'log-edit-hook'. + +--- +*** New buffer-local variable 'vc-buffer-overriding-fileset'. +Primarily intended for buffers not visiting files, this specifies the +VC backend and VCS-managed file name or file names to which the buffer's +contents corresponds. It overrides the behavior of 'vc-deduce-fileset'. +This replaces and generalizes the old 'vc-annotate-parent-file'. + +--- +*** New buffer-local variable 'vc-buffer-revision'. +This specifies the revision to which the buffer's contents corresponds. +This replaces and generalizes the old 'vc-annotate-parent-rev'. + +--- +*** vc-dav.el is now obsolete. + ** Diff mode +++ @@ -1508,6 +1777,11 @@ interactively. *** 'package-upgrade' no longer accepts a string argument. When called from Lisp, it now only accepts a symbol. +--- +*** 'package-install-from-buffer' respects files marked by Dired. +When invoking the command in a Dired buffer with marked files, +the command will only copy those files. + +++ *** package-x.el is now obsolete. @@ -1577,27 +1851,22 @@ Meant to be given a global binding convenient to the user. Example: ** Speedbar +++ -*** The new command 'speedbar-window-mode' opens Speedbar in a window -instead of a frame. +*** New commands for Speedbar. + +- 'speedbar-window-mode' opens Speedbar in a window instead of a frame. +- 'speedbar-window' is an alias for 'speedbar-window-mode'. +++ -*** New command 'speedbar-window' is an alias for 'speedbar-window-mode'. +*** New user options for Speedbar. -+++ -*** The new user option 'speedbar-prefer-window', tells 'speedbar' to -open a side window instead of a frame. - -+++ -*** The new user option ‘speedbar-dedicated-window’ defines whether the -‘speedbar’ is displayed in a dedicated window. - -+++ -*** The new user option 'speedbar-window-default-width' defines the -initial width of the 'speedbar-window' - -+++ -*** The new user option 'speedbar-window-max-width' defines the maximum -width of the 'speedbar-window' when it is closed and then restored. +- 'speedbar-prefer-window' tells 'speedbar' to open a side window + instead of a frame. +- 'speedbar-dedicated-window' defines whether the 'speedbar' is + displayed in a dedicated window. +- 'speedbar-window-default-width' defines the initial width of the + 'speedbar-window'. +- 'speedbar-window-max-width' defines the maximum width of the + 'speedbar-window' when it is closed and then restored. --- *** 'speedbar-easymenu-definition-trailer' is now a function. @@ -1606,6 +1875,7 @@ width of the 'speedbar-window' when it is closed and then restored. *** New user options for 'icomplete-vertical-mode'. New user options have been added to enhance 'icomplete-vertical-mode': + - 'icomplete-vertical-in-buffer-adjust-list' aligns in-buffer completion to the original cursor column. - 'icomplete-vertical-render-prefix-indicator' adds a prefix indicator @@ -1617,20 +1887,18 @@ New user options have been added to enhance 'icomplete-vertical-mode': *** New faces for 'icomplete-vertical-mode'. New faces have been added to 'icomplete-vertical-mode': + - 'icomplete-vertical-selected-prefix-indicator-face' controls the appearance of the selected candidate prefix. - 'icomplete-vertical-unselected-prefix-indicator-face' controls the appearance of unselected candidate prefixes. -** CL-Lib +** Customize -+++ -*** New macro 'cl-with-accessors'. -This macro is similar to 'with-slots', but uses accessor functions -instead of slot names. It is useful when slots' accessor functions are -used repeatedly, such as reading from a slot and then writing to that -slot. Symbol macros are created for the accessor functions using -'cl-symbol-macrolet', so that they can be used with 'setq' and 'setf'. +--- +*** New major mode 'Customize-dirlocals-mode'. +This is intended for customizing directory-local variables in the +current directory's ".dir-locals.el" file. ** Miscellaneous @@ -1678,7 +1946,63 @@ modes. Customize it to a non-nil value to have the fill-column indicators change their face if the current line exceeds the 'fill-column'. The new face 'display-fill-column-indicator-warning-face' is used to -highlight the fill-column indicators. By default this is disabled. +highlight the fill-column indicators. By default, this is disabled. + +--- +** Flymake + +*** Windows without fringes now automatically use margin indicators. +When 'flymake-indicator-type' is set to 'fringes', as is now the default, +flymake will automatically fall back to using margin indicators in +windows without fringes, including any window on a text terminal. + +*** Enhanced 'flymake-show-diagnostics-at-end-of-line' +The new value 'fancy' allowed for this user option will attempt to +layout diagnostics below the affected line using unicode graphics to +point to diagnostic locus. + +*** Enhanced 'flymake-show-buffer-diagnostics'. +The command 'flymake-show-buffer-diagnostics' is now capable of +highlighting a nearby diagnostic in the resulting listing. Additionally, +it is bound to mouse clicks on fringe and margin indicators, operating +on the diagnostics of the corresponding line. The user may bind it in +other situations such as the diagnostic overlay map. + +*** More powerful 'flymake-make-diagnostic' API. +Flymake backends can now specify origin and code attributes, allowing +Flymake and other extensions to segregate diagnostics based on this +extended information. + +*** New user option 'flymake-diagnostic-format-alist'. +This provides fine-grained control over diagnostic formatting across +different contexts, allowing you to specify which components (origin, +code, message or one-liner message) appear in each output destination. + +*** Dynamic column sizing in diagnostic listings. +The tabulated listings produced by 'flymake-show-buffer-diagnostics' and +'flymake-show-project-diagnostics' now automatically adjust their column +widths based on content, optimizing display space and readability. + +** SQLite + ++++ +*** SQLite databases can now be opened in read-only mode. +The new optional argument READONLY to 'sqlite-open' function allows to +open an existing database only for reading. + +*** 'sqlite-open' now recognizes 'file://' URIs as well as file names. +The 'file://' URIs are supported by default. In the unusual case that a +normal file name starts with "file:", you can disable the URI +recognition by invoking 'sqlite-open' with the new optional argument +DISABLE-URI non-nil. + +** GUD + +--- +*** pdb, perldb, and guiler suggest debugging the current file via 'M-n'. +When starting these debuggers (e.g., 'M-x pdb') while visiting a file, +pressing 'M-n' in the command prompt suggests a command line including +the file name, using the minibuffer's "future history". * New Modes and Packages in Emacs 31.1 @@ -1702,21 +2026,6 @@ A major mode based on the tree-sitter library for editing "go.work" files. If tree-sitter is properly set-up by the user, it can be enabled for files named "go.work". -** The file treesit-x.el defines a number of simple treesit modes. -Using the new macro 'define-treesit-generic-mode' generic modes are -defined including, but not limited to, 'gitattributes-generic-ts-mode'. -Visiting a file in such mode ask for confirmation before installing -its tree-sitter grammar. Then it highlights the visited file -according to syntax defined by the grammar. - -** New minor mode 'electric-block-comment-mode'. -This mode automatically close block comment, typing -`block-comment-start' closes it inserting their corresponding -`block-comment-end'. Thus, allows closing block comments for major -modes that support it, such as: c-mode, c++-mode, java-mode, js-mode, -css-mode, and derived: html-mode, mhtml-mode, xml-mode and nxml-mode, -pascal-mode, lua-ts-mode, lisp-mode and common-lisp-mode - * Incompatible Lisp Changes in Emacs 31.1 @@ -1770,6 +2079,12 @@ restore the old behavior, you can set 'eshell-pwd-convert-function' to ** The rx 'eval' form now uses the current Elisp dialect for evaluation. Previously, its argument was always evaluated using dynamic binding. +--- +** Unused block comment variables have been removed. +The unused variables 'block-comment-start' and 'block-comment-end', +which never actually had any effect when set by major modes, have been +removed. + * Lisp Changes in Emacs 31.1 @@ -1779,20 +2094,32 @@ It has been promoted from 'subr-x' to the C code. You can now directly pass it a string or a buffer rather than a function. Actually passing it a function is now deprecated. ++++ +** New function 'char-displayable-on-frame-p'. +'char-displayable-on-frame-p' returns non-nil if Emacs ought to be able +to display its char argument on a given frame. This new function, +unlike 'char-displayable-p', does not check whether the character can be +encoded by the underlying terminal. + +++ ** New macros 'static-when' and 'static-unless'. Like 'static-if', these macros evaluate their condition at macro-expansion time and are useful for writing code that can work across different Emacs versions. +** Lexical binding + --- -** You can change the default value of 'lexical-binding'. +*** You can change the default value of 'lexical-binding'. While the default is still the use of dynamic binding dialect of Elisp in those places that don't explicitly set 'lexical-binding' you can change it globally with: (set-default-toplevel-value 'lexical-binding t) +--- +*** Loading a file displays a warning if there is no 'lexical-binding' cookie. + +++ ** New macros 'incf' and 'decf'. They increment or decrement the value stored in a variable (a symbol), @@ -1819,9 +2146,9 @@ This means that you can now call it with just one argument, like The following macros, previously only available in the experimental 'ert-x' module, are now considered stable and have been moved to 'ert': -- ert-with-test-buffer -- ert-with-buffer-selected -- ert-with-buffer-renamed +- 'ert-with-test-buffer' +- 'ert-with-buffer-selected' +- 'ert-with-buffer-renamed' See "(ert) Helper Functions" node in the ERT manual for more information. @@ -1867,114 +2194,6 @@ authorize the invoked D-Bus method (for example via polkit). ** The customization group 'wp' has been removed. It has been obsolete since Emacs 26.1. Use the group 'text' instead. -** Changes in tree-sitter modes - -+++ -*** Indirect buffers can have their own parser list. -Before, indirect buffers share their base buffer’s parser list and -parsers. Now they can have their own parser list. - -+++ -*** New variable 'treesit-language-remap-alist'. -This variable allows a user to remap one language into another, such -that creating a parser for language A actually creates a parser for -language B. By extension, any font-lock rules or indentation rules for -language A will be applied to language B instead. - -This is useful for reusing font-lock rules and indentation rules of -language A for language B, when language B is a strict superset of -language A. - -+++ -*** New accessor functions for each setting in 'treesit-font-lock-settings'. -Now users can access a setting's query, feature, enable flag, and -override flag by 'treesit-font-lock-setting-query', -'treesit-font-lock-setting-feature', 'treesit-font-lock-setting-enable', -and 'treesit-font-lock-setting-override'. - -*** New tree-sitter thing 'list'. -Unlike the existing thing 'sexp' that defines both lists and atoms, -'list' defines only lists to be navigated by 'forward-sexp'. -The new function 'treesit-forward-sexp-list' uses 'list' -to move across lists. But to move across atoms inside the list -it uses 'forward-sexp-default-function'. - -*** New tree-sitter based functions for moving by lists. -If a major mode defines 'list' in 'treesit-thing-settings', -tree-sitter setup for these modes sets 'forward-list-function' to -'treesit-forward-list', 'up-list-function' to 'treesit-up-list', and -'down-list-function' to 'treesit-down-list'. This enables the -'forward-list', 'up-list', and 'down-list' motion commands for those -modes. - -*** Tree-sitter enabled modes now properly support 'show-paren-mode'. -They do that by letting 'show-paren-mode' use the results of parsing by -the tree-sitter library. The new function 'treesit-show-paren-data' is -used to communicate the tree-sitter parsing results to -'show-paren-mode'. - -*** Tree-sitter enabled modes now properly support 'hs-minor-mode'. -All commands from hideshow.el can selectively display blocks -defined by the new tree-sitter thing 'list'. - -*** New tree-sitter thing 'comment'. -The new variable 'forward-comment-function' is set to the new function -'treesit-forward-comment' if a major mode defines the thing 'comment'. - -+++ -*** New function 'treesit-language-display-name'. -This new function returns the display name of a language given the -language symbol. For example, 'cpp' is translated to "C++". A new -variable 'treesit-language-display-name-alist' holds the translations of -language symbols where that translation is not trivial. - -*** New function 'treesit-merge-font-lock-feature-list'. -This function merges two tree-sitter font-lock feature lists. Returns a -new font-lock feature list with no duplicates in the same level. It can -be used to merge font-lock feature lists in a multi-language major mode. - -*** New function 'treesit-replace-font-lock-feature-settings'. -Given two tree-sitter font-lock settings, it replaces the feature in the -second font-lock settings with the same feature in the first font-lock -settings. In a multi-language major mode it is sometimes necessary to -replace features from one of the major modes, with others that are -better suited to the new multilingual context. - -*** New function 'treesit-simple-indent-modify-rules'. -Given two tree-sitter indent rules, it replaces, adds, or prepends rules -in the old rules with new ones, then returns the modified rules. In a -multi-language major mode it is sometimes necessary to modify rules from -one of the major modes to better suit the new multilingual context. - -+++ -*** New command 'treesit-explore'. -This command replaces 'treesit-explore-mode'. It turns on -'treesit-explore-mode' if it’s not on, and pops up the explorer buffer -if it’s already on. - -+++ -*** 'treesit-explore-mode' now supports local parsers. -Now 'treesit-explore-mode' (or 'treesit-explore') prompts for a parser -rather than a language, and it’s now possible to select a local parser -at point to explore. - -+++ -*** New variable 'treesit-aggregated-simple-imenu-settings'. -This variable allows major modes to setup Imenu for multiple languages. - -+++ -*** New variable 'treesit-aggregated-outline-predicate'. -This variable allows major modes to setup 'outline-minor-mode' -for multiple languages. - -*** New function 'treesit-simple-indent-add-rules'. -This new function makes it easier to customize indent rules for -tree-sitter modes. - -*** New variable 'treesit-simple-indent-override-rules'. -Users can customize this variable to add simple custom indentation rules -for tree-sitter major modes. - +++ ** New optional BUFFER argument for 'string-pixel-width'. If supplied, 'string-pixel-width' will use any face remappings from @@ -2055,6 +2274,12 @@ provide instructions for finding the definition. New convenience function 'find-function-update-type-alist' offers a concise way to update a symbol's 'find-function-type-alist' property. ++++ +** 'inhibit-message' can now inhibit clearing of the echo area. +Binding 'inhibit-message' to a non-nil value will now suppress both +the display of messages and the clearing of the echo area, such as +caused by calling 'message' with a nil argument. + ** Special Events +++ @@ -2085,6 +2310,19 @@ Put differently, this enables input events to be read and recursive editing sessions to be started from non-main threads. The only platform where this remains unsupported is Nextstep (GNUstep or Mac OS). +--- +** 'desktop-restore-frames' has been disabled by default on Android systems. +Restrictions imposed on clients by the window manager on these systems +are too prohibitive and don't allow restoring frame configurations. +(For the same reason many window management facilities are also not +implemented by Emacs.) + +--- +** Emacs responds to runtime display configuration changes on Android. +The upshot of this is that Emacs will adapt to display resolution / +layout changes applied while an Emacs session is active, which is +possible on some recently released devices. + --- ** 'NSSpeechRecognitionUsageDescription' now included in "Info.plist" (macOS). Should Emacs (or any built-in shell) invoke a process using macOS speech @@ -2092,7 +2330,7 @@ recognition APIs, the relevant permission dialog is now displayed, thus allowing Emacs users access to speech recognition utilities. Note: Accepting this permission allows the use of system APIs, which may -send user data to Apple’s speech recognition servers. +send user data to Apple's speech recognition servers. +++ ** On Mac OS X, stipples now render with color. diff --git a/etc/emacs.metainfo.xml b/etc/emacs.metainfo.xml index b063b918a2d..8414e9ac6ba 100644 --- a/etc/emacs.metainfo.xml +++ b/etc/emacs.metainfo.xml @@ -37,15 +37,50 @@ https://www.gnu.org/software/emacs/manual/html_node/emacs/Contributing.html emacs.desktop emacs.service + + keyboard + + + 480 + 312 + + + console + pointing + touch + + GNU GPL-3.0+ and GFDL-1.3+ Free Software Foundation - https://www.gnu.org/software/emacs/images/appdata-26.png - Editing a Lisp program whilst viewing the Emacs manual. + https://www.gnu.org/software/emacs/images/appdata-26.png + Editing a Lisp program, whilst viewing the manual + + + + + moderate + intense + mild + mild + moderate + intense + + + mild + mild + + + intense + + + intense + + emacs-devel_AT_gnu.org #7f5ab6 diff --git a/etc/themes/modus-operandi-deuteranopia-theme.el b/etc/themes/modus-operandi-deuteranopia-theme.el index 55015c7f30b..45167dbd7d4 100644 --- a/etc/themes/modus-operandi-deuteranopia-theme.el +++ b/etc/themes/modus-operandi-deuteranopia-theme.el @@ -1,6 +1,6 @@ ;;; modus-operandi-deuteranopia-theme.el --- Deuteranopia-optimized theme with a white background -*- lexical-binding:t -*- -;; Copyright (C) 2019-2025 Free Software Foundation, Inc. +;; Copyright (C) 2019-2025 Free Software Foundation, Inc. ;; Author: Protesilaos Stavrou ;; Maintainer: Protesilaos Stavrou @@ -167,15 +167,11 @@ standard)." (bg-completion "#c0deff") (bg-hover "#b2e4dc") - (bg-hover-secondary "#f5d0a0") + (bg-hover-secondary "#e5d7a0") (bg-hl-line "#dae5ec") (bg-region "#bdbdbd") (fg-region "#000000") - (bg-char-0 "#7feaff") - (bg-char-1 "#ffaaff") - (bg-char-2 "#dff000") - (bg-mode-line-active "#d0d6ff") (fg-mode-line-active "#0f0f0f") (border-mode-line-active "#4f4f74") @@ -216,13 +212,6 @@ standard)." (bg-diff-context "#f3f3f3") -;;; Paren match - - (bg-paren-match "#5fcfff") - (fg-paren-match fg-main) - (bg-paren-expression "#efd3f5") - (underline-paren-match unspecified) - ;;; Mappings ;;;; General mappings @@ -257,17 +246,17 @@ standard)." ;;;; Code mappings (bracket fg-main) - (builtin magenta-warmer) + (builtin yellow) (comment yellow-cooler) - (constant blue-cooler) + (constant blue-faint) (delimiter fg-main) (docmarkup magenta-faint) (docstring green-faint) - (fnname magenta) - (keyword magenta-cooler) + (fnname yellow-warmer) + (keyword blue-cooler) (number fg-main) (operator fg-main) - (preprocessor red-cooler) + (preprocessor magenta-cooler) (punctuation fg-main) (rx-backslash blue-cooler) (rx-construct yellow-cooler) @@ -275,12 +264,19 @@ standard)." (type cyan-cooler) (variable cyan) +;;;; Paren match + + (bg-paren-match bg-cyan-subtle) + (fg-paren-match fg-main) + (underline-paren-match unspecified) + (bg-paren-expression bg-yellow-nuanced) + ;;;; Accent mappings - (accent-0 blue) + (accent-0 blue-warmer) (accent-1 yellow-warmer) (accent-2 cyan) - (accent-3 magenta-cooler) + (accent-3 yellow-cooler) ;;;; Button mappings @@ -291,10 +287,10 @@ standard)." ;;;; Completion mappings - (fg-completion-match-0 blue) + (fg-completion-match-0 blue-warmer) (fg-completion-match-1 yellow-warmer) (fg-completion-match-2 cyan) - (fg-completion-match-3 magenta-cooler) + (fg-completion-match-3 yellow-cooler) (bg-completion-match-0 unspecified) (bg-completion-match-1 unspecified) (bg-completion-match-2 unspecified) @@ -313,7 +309,7 @@ standard)." (date-scheduled yellow-cooler) (date-scheduled-subtle yellow-faint) (date-weekday cyan) - (date-weekend magenta) + (date-weekend blue-cooler) ;;;; Line number mappings @@ -374,7 +370,7 @@ standard)." (fg-prose-macro magenta-cooler) (bg-prose-verbatim unspecified) - (fg-prose-verbatim magenta-warmer) + (fg-prose-verbatim yellow) (prose-done blue) (prose-todo yellow-warmer) @@ -385,7 +381,7 @@ standard)." (prose-table fg-alt) (prose-table-formula yellow-warmer) - (prose-tag magenta-faint) + (prose-tag fg-alt) ;;;; Rainbow mappings @@ -403,7 +399,7 @@ standard)." (bg-search-current bg-yellow-intense) (bg-search-lazy bg-blue-intense) - (bg-search-replace bg-magenta-intense) + (bg-search-replace bg-yellow-intense) (bg-search-rx-group-0 bg-cyan-intense) (bg-search-rx-group-1 bg-magenta-intense) @@ -463,11 +459,11 @@ standard)." (fg-heading-0 cyan-cooler) (fg-heading-1 fg-main) (fg-heading-2 yellow-faint) - (fg-heading-3 fg-alt) - (fg-heading-4 magenta) - (fg-heading-5 green-faint) - (fg-heading-6 red-faint) - (fg-heading-7 cyan-warmer) + (fg-heading-3 blue-faint) + (fg-heading-4 green-faint) + (fg-heading-5 magenta-cooler) + (fg-heading-6 yellow-cooler) + (fg-heading-7 cyan) (fg-heading-8 fg-dim) (bg-heading-0 unspecified) diff --git a/etc/themes/modus-operandi-theme.el b/etc/themes/modus-operandi-theme.el index 7c653b23fb3..6f92f864616 100644 --- a/etc/themes/modus-operandi-theme.el +++ b/etc/themes/modus-operandi-theme.el @@ -1,6 +1,6 @@ ;;; modus-operandi-theme.el --- Elegant, highly legible theme with a white background -*- lexical-binding:t -*- -;; Copyright (C) 2019-2025 Free Software Foundation, Inc. +;; Copyright (C) 2019-2025 Free Software Foundation, Inc. ;; Author: Protesilaos Stavrou ;; Maintainer: Protesilaos Stavrou @@ -170,10 +170,6 @@ which corresponds to a minimum contrast in relative luminance of (bg-region "#bdbdbd") (fg-region "#000000") - (bg-char-0 "#7feaff") - (bg-char-1 "#ffaaff") - (bg-char-2 "#dff000") - (bg-mode-line-active "#c8c8c8") (fg-mode-line-active "#000000") (border-mode-line-active "#5a5a5a") @@ -214,13 +210,6 @@ which corresponds to a minimum contrast in relative luminance of (bg-diff-context "#f3f3f3") -;;; Paren match - - (bg-paren-match "#5fcfff") - (fg-paren-match fg-main) - (bg-paren-expression "#efd3f5") - (underline-paren-match unspecified) - ;;; Mappings ;;;; General mappings @@ -273,6 +262,13 @@ which corresponds to a minimum contrast in relative luminance of (type cyan-cooler) (variable cyan) +;;;; Paren match + + (bg-paren-match bg-cyan-subtle) + (fg-paren-match fg-main) + (underline-paren-match unspecified) + (bg-paren-expression bg-yellow-nuanced) + ;;;; Accent mappings (accent-0 blue) diff --git a/etc/themes/modus-operandi-tinted-theme.el b/etc/themes/modus-operandi-tinted-theme.el index ca783c2f022..11b7f38ba0f 100644 --- a/etc/themes/modus-operandi-tinted-theme.el +++ b/etc/themes/modus-operandi-tinted-theme.el @@ -1,6 +1,6 @@ -;;; modus-operandi-tinted-theme.el --- Elegant, highly legible theme with a light ocher background -*- lexical-binding:t -*- +;;; modus-operandi-tinted-theme.el --- Elegant, highly legible theme with a light ochre background -*- lexical-binding:t -*- -;; Copyright (C) 2019-2025 Free Software Foundation, Inc. +;; Copyright (C) 2019-2025 Free Software Foundation, Inc. ;; Author: Protesilaos Stavrou ;; Maintainer: Protesilaos Stavrou @@ -44,7 +44,7 @@ ;;;###theme-autoload (deftheme modus-operandi-tinted - "Elegant, highly legible theme with a light ocher background. + "Elegant, highly legible theme with a light ochre background. Conforms with the highest legibility standard for color contrast between background and foreground in any given piece of text, which corresponds to a minimum contrast in relative luminance of @@ -73,18 +73,18 @@ which corresponds to a minimum contrast in relative luminance of (red-cooler "#a0132f") (red-faint "#7f0000") (red-intense "#d00000") - (green "#006800") - (green-warmer "#316500") - (green-cooler "#00663f") + (green "#006300") + (green-warmer "#306010") + (green-cooler "#00603f") (green-faint "#2a5045") (green-intense "#008900") - (yellow "#6f5500") - (yellow-warmer "#884900") - (yellow-cooler "#7a4f2f") - (yellow-faint "#624416") + (yellow "#6d5000") + (yellow-warmer "#894000") + (yellow-cooler "#602938") + (yellow-faint "#574316") (yellow-intense "#808000") (blue "#0031a9") - (blue-warmer "#3548cf") + (blue-warmer "#3546c2") (blue-cooler "#0000b0") (blue-faint "#003497") (blue-intense "#0000ff") @@ -93,10 +93,10 @@ which corresponds to a minimum contrast in relative luminance of (magenta-cooler "#531ab6") (magenta-faint "#7c318f") (magenta-intense "#dd22dd") - (cyan "#005e8b") - (cyan-warmer "#3f578f") + (cyan "#00598b") + (cyan-warmer "#32548f") (cyan-cooler "#005f5f") - (cyan-faint "#005077") + (cyan-faint "#304463") (cyan-intense "#008899") ;;; Uncommon accent foregrounds @@ -165,15 +165,11 @@ which corresponds to a minimum contrast in relative luminance of (bg-completion "#f0c1cf") (bg-hover "#b2e4dc") - (bg-hover-secondary "#f5d0a0") + (bg-hover-secondary "#dfe09f") (bg-hl-line "#f1d5d0") (bg-region "#c2bcb5") (fg-region "#000000") - (bg-char-0 "#7feaff") - (bg-char-1 "#ffaaff") - (bg-char-2 "#dff000") - (bg-mode-line-active "#cab9b2") (fg-mode-line-active "#000000") (border-mode-line-active "#545454") @@ -214,13 +210,6 @@ which corresponds to a minimum contrast in relative luminance of (bg-diff-context "#efe9df") -;;; Paren match - - (bg-paren-match "#7fdfcf") - (fg-paren-match fg-main) - (bg-paren-expression "#efd3f5") - (underline-paren-match unspecified) - ;;; Mappings ;;;; General mappings @@ -230,11 +219,11 @@ which corresponds to a minimum contrast in relative luminance of (keybind red) (name magenta) - (identifier yellow-cooler) + (identifier yellow-faint) (err red) - (warning yellow-warmer) - (info cyan-cooler) + (warning yellow) + (info green) (underline-err red-intense) (underline-warning yellow-intense) @@ -255,30 +244,37 @@ which corresponds to a minimum contrast in relative luminance of ;;;; Code mappings (bracket fg-main) - (builtin magenta-warmer) + (builtin magenta) (comment red-faint) - (constant blue-cooler) + (constant magenta-cooler) (delimiter fg-main) (docmarkup magenta-faint) - (docstring green-faint) - (fnname magenta) - (keyword magenta-cooler) + (docstring cyan-faint) + (fnname yellow-cooler) + (keyword blue) (number fg-main) (operator fg-main) - (preprocessor red-cooler) + (preprocessor yellow-warmer) (punctuation fg-main) - (rx-backslash magenta) - (rx-construct green-cooler) - (string blue-warmer) - (type cyan-cooler) - (variable cyan) + (rx-backslash magenta-warmer) + (rx-construct magenta-cooler) + (string cyan) + (type green-warmer) + (variable green-cooler) + +;;;; Paren match + + (bg-paren-match bg-cyan-subtle) + (fg-paren-match fg-main) + (underline-paren-match unspecified) + (bg-paren-expression bg-yellow-nuanced) ;;;; Accent mappings - (accent-0 blue) - (accent-1 magenta-warmer) - (accent-2 cyan) - (accent-3 red) + (accent-0 red-cooler) + (accent-1 cyan) + (accent-2 magenta-cooler) + (accent-3 yellow-warmer) ;;;; Button mappings @@ -336,14 +332,14 @@ which corresponds to a minimum contrast in relative luminance of ;;;; Mail mappings - (mail-cite-0 blue-faint) - (mail-cite-1 yellow-warmer) - (mail-cite-2 cyan-cooler) + (mail-cite-0 cyan-cooler) + (mail-cite-1 yellow) + (mail-cite-2 green-warmer) (mail-cite-3 red-cooler) - (mail-part cyan) - (mail-recipient magenta-cooler) + (mail-part magenta-cooler) + (mail-recipient blue-warmer) (mail-subject magenta-warmer) - (mail-other magenta-faint) + (mail-other magenta) ;;;; Mark mappings @@ -356,7 +352,7 @@ which corresponds to a minimum contrast in relative luminance of ;;;; Prompt mappings - (fg-prompt cyan-cooler) + (fg-prompt green-cooler) (bg-prompt unspecified) ;;;; Prose mappings @@ -366,13 +362,13 @@ which corresponds to a minimum contrast in relative luminance of (bg-prose-block-contents bg-dim) (bg-prose-code unspecified) - (fg-prose-code cyan-cooler) + (fg-prose-code green-cooler) (bg-prose-macro unspecified) - (fg-prose-macro magenta-cooler) + (fg-prose-macro blue-cooler) (bg-prose-verbatim unspecified) - (fg-prose-verbatim magenta-warmer) + (fg-prose-verbatim yellow-warmer) (prose-done green) (prose-todo red) @@ -458,7 +454,7 @@ which corresponds to a minimum contrast in relative luminance of ;;;; Heading mappings - (fg-heading-0 cyan-cooler) + (fg-heading-0 green-cooler) (fg-heading-1 fg-main) (fg-heading-2 yellow-faint) (fg-heading-3 fg-alt) diff --git a/etc/themes/modus-operandi-tritanopia-theme.el b/etc/themes/modus-operandi-tritanopia-theme.el index af6f9e3f1a4..8638d201d7f 100644 --- a/etc/themes/modus-operandi-tritanopia-theme.el +++ b/etc/themes/modus-operandi-tritanopia-theme.el @@ -1,6 +1,6 @@ ;;; modus-operandi-tritanopia-theme.el --- Tritanopia-optimized theme with a white background -*- lexical-binding:t -*- -;; Copyright (C) 2019-2025 Free Software Foundation, Inc. +;; Copyright (C) 2019-2025 Free Software Foundation, Inc. ;; Author: Protesilaos Stavrou ;; Maintainer: Protesilaos Stavrou @@ -63,7 +63,7 @@ standard)." (bg-dim "#f2f2f2") (fg-main "#000000") (fg-dim "#595959") - (fg-alt "#193668") + (fg-alt "#024960") (bg-active "#c4c4c4") (bg-inactive "#e0e0e0") (border "#9f9f9f") @@ -167,15 +167,11 @@ standard)." (bg-completion "#afdfef") (bg-hover "#ffafbc") - (bg-hover-secondary "#9fdfff") + (bg-hover-secondary "#abdfdd") (bg-hl-line "#dfeaec") (bg-region "#bdbdbd") (fg-region "#000000") - (bg-char-0 "#ff908f") - (bg-char-1 "#bfbfff") - (bg-char-2 "#5fcfdf") - (bg-mode-line-active "#afe0f2") (fg-mode-line-active "#0f0f0f") (border-mode-line-active "#2f4f44") @@ -216,13 +212,6 @@ standard)." (bg-diff-context "#f3f3f3") -;;; Paren match - - (bg-paren-match "#5fcfff") - (fg-paren-match fg-main) - (bg-paren-expression "#efd3f5") - (underline-paren-match unspecified) - ;;; Mappings ;;;; General mappings @@ -275,6 +264,13 @@ standard)." (type blue-warmer) (variable cyan-cooler) +;;;; Paren match + + (bg-paren-match bg-cyan-subtle) + (fg-paren-match fg-main) + (underline-paren-match unspecified) + (bg-paren-expression bg-red-nuanced) + ;;;; Accent mappings (accent-0 cyan) @@ -385,7 +381,7 @@ standard)." (prose-table fg-alt) (prose-table-formula red-cooler) - (prose-tag magenta-faint) + (prose-tag fg-alt) ;;;; Rainbow mappings diff --git a/etc/themes/modus-themes.el b/etc/themes/modus-themes.el index 655d7a830e6..945d7b5585f 100644 --- a/etc/themes/modus-themes.el +++ b/etc/themes/modus-themes.el @@ -1,12 +1,12 @@ ;;; modus-themes.el --- Elegant, highly legible and customizable themes -*- lexical-binding:t -*- -;; Copyright (C) 2019-2025 Free Software Foundation, Inc. +;; Copyright (C) 2019-2025 Free Software Foundation, Inc. ;; Author: Protesilaos Stavrou ;; Maintainer: Protesilaos Stavrou ;; URL: https://github.com/protesilaos/modus-themes -;; Version: 4.6.0 -;; Package-Requires: ((emacs "27.1")) +;; Version: 4.7.0 +;; Package-Requires: ((emacs "28.1")) ;; Keywords: faces, theme, accessibility ;; This file is part of GNU Emacs. @@ -309,11 +309,12 @@ If the value is nil or otherwise does not specify two valid Modus themes, the command `modus-themes-toggle' reverts to selecting a theme from the list of available Modus themes. In effect, it is the same as using the command `modus-themes-select'." - :type `(choice - (const :tag "No toggle" nil) - (list :tag "Pick two themes to toggle between" - (choice :tag "Theme one of two" ,@(mapcar (lambda (theme) (list 'const theme)) modus-themes-items)) - (choice :tag "Theme two of two" ,@(mapcar (lambda (theme) (list 'const theme)) modus-themes-items)))) + :type (let ((themes (mapcar (lambda (theme) (list 'const theme)) modus-themes-items))) + `(choice + (const :tag "No toggle" nil) + (list :tag "Pick two themes to toggle between" + (choice :tag "Theme one of two" ,@themes) + (choice :tag "Theme two of two" ,@themes)))) :package-version '(modus-themes . "4.0.0") :version "30.1" :group 'modus-themes) @@ -327,7 +328,8 @@ the same as using the command `modus-themes-select'." :version "31.1" :group 'modus-themes) -(defvaralias 'modus-themes-post-load-hook 'modus-themes-after-load-theme-hook) +(defvaralias 'modus-themes-post-load-hook 'modus-themes-after-load-theme-hook + "Alias for `modus-themes-after-load-theme-hook'.") (defcustom modus-themes-after-load-theme-hook nil "Hook that runs after loading a Modus theme. @@ -1153,7 +1155,7 @@ This function is used in the macros `modus-themes-theme', (eq value 'unspecified)) value) ((and (symbolp value) - (memq value (mapcar #'car palette))) + value) (modus-themes--retrieve-palette-value value palette)) (t 'unspecified)))) @@ -1209,15 +1211,15 @@ symbol, which is safe when used as a face attribute's value." "Render `modus-themes--list-known-themes' as completion with theme category." (modus-themes--completion-table 'theme (modus-themes--list-known-themes))) -(defun modus-themes--select-prompt () - "Minibuffer prompt to select a Modus theme." +(defun modus-themes--select-prompt (&optional prompt) + "Minibuffer prompt to select a Modus theme. +With optional PROMPT string, use it. Else use a generic prompt." (let ((completion-extra-properties `(:annotation-function ,#'modus-themes--annotate-theme))) (intern (completing-read - "Select Modus theme: " + (or prompt "Select Modus theme: ") (modus-themes--completion-table-candidates) - nil t nil - 'modus-themes--select-theme-history)))) + nil t nil 'modus-themes--select-theme-history)))) ;;;###autoload (defun modus-themes-select (theme) @@ -1231,13 +1233,13 @@ Disable other themes per `modus-themes-disable-other-themes'." (defun modus-themes--toggle-theme-p () "Return non-nil if `modus-themes-to-toggle' are valid." - (mapc - (lambda (theme) - (if (or (memq theme modus-themes-items) - (memq theme (modus-themes--list-known-themes))) - theme - (user-error "`%s' is not part of `modus-themes-items'" theme))) - modus-themes-to-toggle)) + (condition-case nil + (dolist (theme modus-themes-to-toggle) + (or (memq theme modus-themes-items) + (memq theme (modus-themes--list-known-themes)) + (error "`%s' is not part of `modus-themes-items'" theme))) + (error nil) + (:success modus-themes-to-toggle))) ;;;###autoload (defun modus-themes-toggle () @@ -1294,87 +1296,88 @@ the list becomes the last. Do not modify THEMES in the process." ;;;;; Preview a theme palette -(defun modus-themes--list-colors-render (buffer theme &optional mappings &rest _) - "Render colors in BUFFER from THEME for `modus-themes-list-colors'. -Optional MAPPINGS changes the output to only list the semantic -color mappings of the palette, instead of its named colors." +(defun modus-themes--list-colors-get-mappings (palette) + "Get the semantic palette entries in PALETTE. +PALETTE is the value of a variable like `modus-operandi-palette'." + (seq-remove + (lambda (cell) + (stringp (cadr cell))) + palette)) + +(defun modus-themes--list-colors-tabulated (theme &optional mappings) + "Return a data structure of THEME palette or MAPPINGS for tabulated list." (let* ((current-palette (modus-themes--palette-value theme mappings)) (palette (if mappings - (seq-remove (lambda (cell) - (stringp (cadr cell))) - current-palette) - current-palette)) - (current-buffer buffer) - (current-theme theme)) - (with-help-window buffer - (with-current-buffer standard-output - (erase-buffer) - (when (<= (display-color-cells) 256) - (insert (concat "Your display terminal may not render all color previews!\n" - "It seems to only support <= 256 colors.\n\n")) - (put-text-property (point-min) (point) 'face 'warning)) - ;; We need this to properly render the first line. - (insert " ") - (dolist (cell palette) - (let* ((name (car cell)) - (color (modus-themes-get-color-value name mappings theme)) - (pad (make-string 10 ?\s)) - (fg (if (eq color 'unspecified) - (progn - (readable-foreground-color (modus-themes-get-color-value 'bg-main nil theme)) - (setq pad (make-string 6 ?\s))) - (readable-foreground-color color)))) - (let ((old-point (point))) - (insert (format "%s %s" color pad)) - (put-text-property old-point (point) 'face `( :foreground ,color))) - (let ((old-point (point))) - (insert (format " %s %s %s\n" color pad name)) - (put-text-property old-point (point) - 'face `( :background ,color - :foreground ,fg - :extend t))) - ;; We need this to properly render the last line. - (insert " "))) - (setq-local revert-buffer-function - (lambda (_ignore-auto _noconfirm) - (modus-themes--list-colors-render current-buffer current-theme mappings))))))) + (modus-themes--list-colors-get-mappings current-palette) + current-palette))) + (mapcar (lambda (cell) + (pcase-let* ((`(,name ,value) cell) + (name-string (format "%s" name)) + (value-string (format "%s" value)) + (value-string-padded (string-pad value-string 30)) + (color (modus-themes-get-color-value name mappings theme))) ; resolve a semantic mapping + (list name + (vector + (if (and (symbolp value) + (not (eq value 'unspecified))) + "Yes" + "") + name-string + (propertize value-string 'face `( :foreground ,color)) + (propertize value-string-padded 'face (list :background color + :foreground (if (string= color "unspecified") + (readable-foreground-color (modus-themes-get-color-value 'bg-main nil theme)) + (readable-foreground-color color)))))))) + palette))) -(defvar modus-themes--list-colors-prompt-history '() - "Minibuffer history for `modus-themes--list-colors-prompt'.") +(defvar modus-themes-current-preview nil) +(defvar modus-themes-current-preview-show-mappings nil) -(defun modus-themes--list-colors-prompt () - "Prompt for Modus theme. -Helper function for `modus-themes-list-colors'." - (let ((def (format "%s" (modus-themes--current-theme))) - (completion-extra-properties `(:annotation-function ,#'modus-themes--annotate-theme))) - (completing-read - (format "Use palette from theme [%s]: " def) - (modus-themes--completion-table-candidates) - nil t nil - 'modus-themes--list-colors-prompt-history def))) +(defun modus-themes--set-tabulated-entries () + "Set the value of `tabulated-list-entries' with palette entries." + (setq-local tabulated-list-entries + (modus-themes--list-colors-tabulated modus-themes-current-preview modus-themes-current-preview-show-mappings))) (defun modus-themes-list-colors (theme &optional mappings) - "Preview named colors of the Modus THEME of choice. -With optional prefix argument for MAPPINGS preview the semantic -color mappings instead of the named colors." - (interactive (list (intern (modus-themes--list-colors-prompt)) current-prefix-arg)) - (modus-themes--list-colors-render - (format (if mappings "*%s-list-mappings*" "*%s-list-colors*") theme) - theme - mappings)) + "Preview the palette of the Modus THEME of choice. +With optional prefix argument for MAPPINGS preview only the semantic +color mappings instead of the complete palette." + (interactive + (let ((prompt (if current-prefix-arg + "Preview palette mappings of THEME: " + "Preview palette of THEME: "))) + (list + (modus-themes--select-prompt prompt) + current-prefix-arg))) + (let ((buffer (get-buffer-create (format (if mappings "*%s-list-mappings*" "*%s-list-all*") theme)))) + (with-current-buffer buffer + (let ((modus-themes-current-preview theme) + (modus-themes-current-preview-show-mappings mappings)) + (modus-themes-preview-mode))) + (pop-to-buffer buffer))) (defalias 'modus-themes-preview-colors 'modus-themes-list-colors - "Alias of `modus-themes-list-colors'.") + "Alias for `modus-themes-list-colors'.") (defun modus-themes-list-colors-current (&optional mappings) - "Call `modus-themes-list-colors' for the current Modus theme. -Optional prefix argument MAPPINGS has the same meaning as for -`modus-themes-list-colors'." + "Like `modus-themes-list-colors' with optional MAPPINGS for the current theme." (interactive "P") (modus-themes-list-colors (modus-themes--current-theme) mappings)) (defalias 'modus-themes-preview-colors-current 'modus-themes-list-colors-current - "Alias of `modus-themes-list-colors-current'.") + "Alias for `modus-themes-list-colors-current'.") + +(define-derived-mode modus-themes-preview-mode tabulated-list-mode "Modus palette" + "Major mode to display a Modus themes palette." + :interactive nil + (setq-local tabulated-list-format + [("Mapping?" 10 t) + ("Symbol name" 30 t) + ("As foreground" 30 t) + ("As background" 0 t)]) + (modus-themes--set-tabulated-entries) + (tabulated-list-init-header) + (tabulated-list-print)) @@ -1449,7 +1452,7 @@ color that is combined with FG-FOR-BG." :foreground fg :weight ;; If we have `bold' specifically, we inherit the face of - ;; the same name. This allows the user to customize that + ;; the same name. This allows the user to customise that ;; face, such as to change its font family. (if (and weight (not (eq weight 'bold))) weight @@ -1670,6 +1673,7 @@ FG and BG are the main colors." `(tool-bar ((,c :background ,bg-dim :foreground ,fg-main))) `(vertical-border ((,c :foreground ,border))) ;;;;; basic and/or ungrouped styles + `(abbrev-table-name ((,c :inherit bold))) `(appt-notification ((,c :inherit bold :foreground ,modeline-err))) `(blink-matching-paren-offscreen ((,c :background ,bg-paren-match))) `(bold ((,c :weight bold))) @@ -1720,6 +1724,25 @@ FG and BG are the main colors." `(link ((,c :inherit button))) `(link-visited ((,c :background ,bg-link-visited :foreground ,fg-link-visited :underline ,underline-link-visited))) `(tooltip ((,c :background ,bg-active :foreground ,fg-main))) +;;;;; adoc-mode + `(adoc-code-face ((,c :inherit font-lock-constant-face))) + `(adoc-command-face ((,c :inherit modus-themes-prose-macro))) + `(adoc-complex-replacement-face ((,c :background ,bg-magenta-subtle :foreground ,magenta))) + `(adoc-emphasis-face ((t (:inherit bold)))) + `(adoc-gen-face ((,c :foreground ,blue))) + `(adoc-meta-face ((,c :inherit modus-themes-fixed-pitch :foreground ,prose-metadata))) + `(adoc-meta-hide-face ((,c :inherit modus-themes-fixed-pitch :foreground ,prose-metadata))) + `(adoc-replacement-face ((,c :inherit font-lock-escape-face))) + `(adoc-secondary-text-face ((,c :inherit modus-themes-fixed-pitch :foreground ,prose-metadata-value))) + `(adoc-table-face ((,c :inherit modus-themes-fixed-pitch :foreground ,prose-table))) + `(adoc-title-0-face ((,c :inherit modus-themes-heading-0))) + `(adoc-title-1-face ((,c :inherit modus-themes-heading-1))) + `(adoc-title-2-face ((,c :inherit modus-themes-heading-2))) + `(adoc-title-3-face ((,c :inherit modus-themes-heading-3))) + `(adoc-title-4-face ((,c :inherit modus-themes-heading-4))) + `(adoc-title-5-face ((,c :inherit modus-themes-heading-5))) + `(adoc-typewriter-face ((,c :inherit modus-themes-prose-verbatim))) + `(adoc-verbatim-face ((,c :inherit modus-themes-prose-verbatim))) ;;;;; agda2-mode `(agda2-highlight-bound-variable-face ((,c :inherit font-lock-variable-name-face))) `(agda2-highlight-catchall-clause-face ((,c :background ,bg-inactive))) @@ -1849,13 +1872,14 @@ FG and BG are the main colors." `(TeX-error-description-warning ((,c :inherit warning))) ;;;;; auto-dim-other-buffers `(auto-dim-other-buffers-face ((,c :background ,bg-inactive))) + `(auto-dim-other-buffers-hide-face ((,c :foreground ,bg-inactive :background ,bg-inactive))) ;;;;; avy `(avy-background-face ((,c :background ,bg-dim :foreground ,fg-dim :extend t))) - `(avy-goto-char-timer-face ((,c :inherit bold :background ,bg-active))) - `(avy-lead-face ((,c :inherit (bold modus-themes-reset-soft) :background ,bg-char-0))) - `(avy-lead-face-0 ((,c :inherit (bold modus-themes-reset-soft) :background ,bg-char-1))) - `(avy-lead-face-1 ((,c :inherit modus-themes-reset-soft :background ,bg-inactive))) - `(avy-lead-face-2 ((,c :inherit (bold modus-themes-reset-soft) :background ,bg-char-2))) + `(avy-goto-char-timer-face ((,c :inherit (bold modus-themes-search-lazy modus-themes-reset-soft)))) + `(avy-lead-face ((,c :inherit (bold modus-themes-search-current modus-themes-reset-soft)))) + `(avy-lead-face-0 ((,c :inherit (bold modus-themes-search-current modus-themes-reset-soft)))) + `(avy-lead-face-1 ((,c :inherit (bold modus-themes-search-current modus-themes-reset-soft)))) + `(avy-lead-face-2 ((,c :inherit (bold modus-themes-search-current modus-themes-reset-soft)))) ;;;;; aw (ace-window) `(aw-background-face ((,c :foreground "gray50"))) `(aw-key-face ((,c :inherit modus-themes-key-binding))) @@ -2028,8 +2052,8 @@ FG and BG are the main colors." ;;;;; corfu-candidate-overlay `(corfu-candidate-overlay-face ((t :inherit shadow))) ;;;;; corfu-quick - `(corfu-quick1 ((,c :inherit bold :background ,bg-char-0))) - `(corfu-quick2 ((,c :inherit bold :background ,bg-char-1))) + `(corfu-quick1 ((,c :inherit (bold modus-themes-search-current)))) + `(corfu-quick2 ((,c :inherit (bold modus-themes-search-current)))) ;;;;; counsel `(counsel-active-mode ((,c :foreground ,keyword))) `(counsel-application-name ((,c :foreground ,name))) @@ -2518,10 +2542,10 @@ FG and BG are the main colors." `(geiser-font-lock-xref-link ((,c :inherit button))) ;;;;; git-commit `(git-commit-comment-action ((,c :inherit font-lock-comment-face))) - `(git-commit-comment-branch-local ((,c :inherit font-lock-comment-face :foreground ,accent-0))) - `(git-commit-comment-branch-remote ((,c :inherit font-lock-comment-face :foreground ,accent-1))) + `(git-commit-comment-branch-local ((,c :inherit (bold font-lock-comment-face) :foreground ,accent-0))) + `(git-commit-comment-branch-remote ((,c :inherit (bold font-lock-comment-face) :foreground ,accent-1))) `(git-commit-comment-heading ((,c :inherit (bold font-lock-comment-face)))) - `(git-commit-comment-file ((,c :inherit font-lock-comment-face :foreground ,name))) + `(git-commit-comment-file ((,c :inherit font-lock-comment-face :foreground ,accent-2))) ; like `magit-filename' `(git-commit-keyword ((,c :foreground ,keyword))) `(git-commit-nonempty-second-line ((,c :inherit error))) `(git-commit-overlong-summary ((,c :inherit warning))) @@ -2682,6 +2706,30 @@ FG and BG are the main colors." `(hl-fill-column-face ((,c :background ,bg-active))) ;;;;; hl-todo `(hl-todo ((,c :inherit (bold font-lock-comment-face) :foreground ,err))) +;;;;; howm + `(action-lock-face ((,c :inherit button))) + `(howm-mode-keyword-face (( ))) + `(howm-mode-ref-face ((,c :inherit link))) + `(howm-mode-title-face ((,c :inherit modus-themes-heading-0))) + `(howm-mode-wiki-face ((,c :inherit link))) + `(howm-reminder-deadline-face ((,c :foreground ,date-deadline))) + `(howm-reminder-late-deadline-face ((,c :inherit bold :foreground ,date-deadline))) + `(howm-reminder-defer-face ((,c :foreground ,date-scheduled))) + `(howm-reminder-scheduled-face ((,c :foreground ,date-scheduled))) + `(howm-reminder-done-face ((,c :foreground ,prose-done))) + `(howm-reminder-todo-face ((,c :foreground ,prose-todo))) + `(howm-reminder-normal-face ((,c :foreground ,date-common))) + `(howm-reminder-today-face ((,c :inherit bold :foreground ,date-common))) + `(howm-reminder-tomorrow-face ((,c :inherit bold :foreground ,date-scheduled))) + `(howm-simulate-todo-mode-line-face ((,c :inherit bold))) + `(howm-view-empty-face (( ))) + `(howm-view-hilit-face ((,c :inherit match))) + `(howm-view-name-face ((,c :inherit bold))) + `(iigrep-counts-face1 ((,c :foreground ,rainbow-1))) + `(iigrep-counts-face2 ((,c :foreground ,rainbow-2))) + `(iigrep-counts-face3 ((,c :foreground ,rainbow-3))) + `(iigrep-counts-face4 ((,c :foreground ,rainbow-4))) + `(iigrep-counts-face5 ((,c :foreground ,rainbow-5))) ;;;;; hydra `(hydra-face-amaranth ((,c :inherit bold :foreground ,yellow-warmer))) `(hydra-face-blue ((,c :inherit bold :foreground ,blue))) @@ -2695,14 +2743,16 @@ FG and BG are the main colors." `(ibut-face ((,c :inherit button :background ,bg-link-symbolic :foreground ,fg-link-symbolic :underline ,underline-link-symbolic))) ;;;;; icomplete `(icomplete-first-match ((,c :inherit modus-themes-completion-match-0))) + `(icomplete-vertical-selected-prefix-indicator-face ((,c :inherit bold :foreground ,keybind))) + `(icomplete-vertical-unselected-prefix-indicator-face ((,c :inherit shadow))) `(icomplete-selected-match ((,c :inherit modus-themes-completion-selected))) ;;;;; ido-mode `(ido-first-match ((,c :inherit modus-themes-completion-match-0))) `(ido-incomplete-regexp ((,c :inherit error))) `(ido-indicator ((,c :inherit bold))) `(ido-only-match ((,c :inherit ido-first-match))) - `(ido-subdir ((,c :foreground ,accent-0))) - `(ido-virtual ((,c :foreground ,accent-1))) + `(ido-subdir ((,c :foreground ,keyword))) + `(ido-virtual ((,c :foreground ,warning))) ;;;;; iedit `(iedit-occurrence ((,c :inherit modus-themes-search-lazy))) `(iedit-read-only-occurrence ((,c :inherit modus-themes-search-current))) @@ -2803,19 +2853,19 @@ FG and BG are the main colors." `(ivy-minibuffer-match-face-4 ((,c :inherit modus-themes-completion-match-2))) `(ivy-remote ((,c :inherit italic))) `(ivy-separator ((,c :inherit shadow))) - `(ivy-subdir ((,c :foreground ,accent-0))) - `(ivy-virtual ((,c :foreground ,accent-1))) + `(ivy-subdir ((,c :foreground ,keyword))) + `(ivy-virtual ((,c :foreground ,warning))) ;;;;; ivy-posframe `(ivy-posframe-border ((,c :background ,border))) `(ivy-posframe-cursor ((,c :background ,fg-main :foreground ,bg-main))) ;;;;; jabber `(jabber-activity-face ((,c :foreground ,modeline-info))) `(jabber-roster-user-away ((,c :foreground ,red-faint))) - `(jabber-roster-user-xa ((,c :foreground ,magenta :slant italic))) - `(jabber-roster-user-dnd ((,c :foreground ,red :weight bold))) + `(jabber-roster-user-xa ((,c :foreground ,magenta :italic t))) + `(jabber-roster-user-dnd ((,c :foreground ,red :bold t))) `(jabber-roster-user-chatty ((,c :foreground ,cyan-intense))) `(jabber-roster-user-error ((,c :inherit error))) - `(jabber-roster-user-offline ((,c :foreground ,fg-dim :slant italic))) + `(jabber-roster-user-offline ((,c :foreground ,fg-dim :italic t))) `(jabber-roster-user-online ((,c :foreground ,cyan :weight bold))) `(jabber-chat-prompt-foreign ((,c :foreground ,red :weight bold))) `(jabber-chat-prompt-system ((,c :foreground ,green))) @@ -3326,7 +3376,7 @@ FG and BG are the main colors." `(org-clock-overlay ((,c :inherit secondary-selection))) `(org-code ((,c :inherit modus-themes-prose-code))) `(org-column ((,c :inherit default :background ,bg-dim))) - `(org-column-title ((,c :inherit (bold default) :underline t :background ,bg-dim))) + `(org-column-title ((,c :inherit (modus-themes-fixed-pitch bold default) :underline t :background ,bg-dim))) `(org-date ((,c :inherit modus-themes-fixed-pitch :foreground ,date-common))) `(org-date-selected ((,c :foreground ,date-common :inverse-video t))) ;; NOTE 2024-03-17: Normally we do not want to add this padding @@ -3706,6 +3756,9 @@ FG and BG are the main colors." `(smerge-refined-changed (())) `(smerge-refined-removed ((,c :inherit diff-refine-removed))) `(smerge-upper ((,c :inherit diff-removed))) +;;;;; spacious-padding + `(spacious-padding-subtle-mode-line-active ((,c :foreground ,accent-0))) + `(spacious-padding-subtle-mode-line-inactive ((,c :foreground ,border))) ;;;;; speedbar `(speedbar-button-face ((,c :inherit button))) `(speedbar-directory-face ((,c :inherit bold :foreground ,accent-0))) @@ -3812,6 +3865,13 @@ FG and BG are the main colors." `(term-underline ((,c :underline t))) ;;;;; textsec `(textsec-suspicious (( ))) +;;;;; tldr + `(tldr-code-block (( ))) + `(tldr-command-argument ((,c :inherit font-lock-string-face))) + `(tldr-command-itself ((,c :inherit font-lock-builtin-face))) + `(tldr-description ((,c :inherit font-lock-doc-face))) + `(tldr-introduction ((,c :inherit font-lock-comment-face))) + `(tldr-title ((,c :inherit bold))) ;;;;; transient `(transient-active-infix ((,c :inherit highlight))) `(transient-amaranth ((,c :inherit bold :foreground ,yellow-warmer))) @@ -3834,7 +3894,9 @@ FG and BG are the main colors." `(transient-key ((,c :inherit modus-themes-key-binding))) `(transient-key-exit ((,c :inherit modus-themes-key-binding))) `(transient-key-noop ((,c :inherit (shadow modus-themes-key-binding)))) + `(transient-key-recurse ((,c :inherit modus-themes-key-binding))) `(transient-key-return ((,c :inherit modus-themes-key-binding))) + `(transient-key-stack ((,c :inherit modus-themes-key-binding))) `(transient-key-stay ((,c :inherit modus-themes-key-binding))) `(transient-mismatched-key ((,c :underline t))) `(transient-nonstandard-key ((,c :underline t))) @@ -3851,6 +3913,39 @@ FG and BG are the main colors." `(trashed-mark ((,c :inherit bold))) `(trashed-marked ((,c :inherit modus-themes-mark-alt))) `(trashed-restored ((,c :inherit modus-themes-mark-sel))) +;;;;; treemacs + `(treemacs-async-loading-face ((,c :foreground ,fg-main))) + `(treemacs-directory-face ((,c :foreground ,accent-0))) + `(treemacs-directory-collapsed-face ((,c :foreground ,accent-0))) + `(treemacs-file-face ((,c :foreground ,fg-main))) + `(treemacs-fringe-indicator-face ((,c :foreground ,fg-main))) + `(treemacs-git-added-face ((,c :inherit success))) + `(treemacs-git-commit-diff-face ((,c :foreground ,err))) + `(treemacs-git-conflict-face ((,c :inherit error))) + `(treemacs-git-ignored-face ((,c :inherit shadow))) + `(treemacs-git-modified-face ((,c :inherit warning))) + `(treemacs-git-renamed-face ((,c :inherit italic))) + `(treemacs-git-unmodified-face ((,c :foreground ,fg-main))) + `(treemacs-git-untracked-face ((,c :inherit success))) + `(treemacs-header-button-face ((,c :foreground ,fg-main))) + `(treemacs-help-column-face ((,c :inherit modus-themes-bold :foreground ,keyword))) + `(treemacs-help-title-face ((,c :foreground ,fg-main))) + `(treemacs-hl-line-face ((,c :background ,bg-hl-line :extend t))) + `(treemacs-marked-file-face ((,c :inherit modus-themes-mark-alt))) + `(treemacs-nerd-icons-face ((,c :foreground ,accent-0))) + `(treemacs-on-failure-pulse-face ((,c :foreground ,fg-main))) + `(treemacs-on-success-pulse-face ((,c :foreground ,fg-main))) + `(treemacs-peek-mode-indicator-face ((,c :foreground ,fg-main))) + `(treemacs-remote-face ((,c :foreground ,fg-main))) + `(treemacs-root-face ((,c :foreground ,accent-0))) + `(treemacs-root-remote-disconnected-face ((,c :inherit warning))) + `(treemacs-root-remote-unreadable-face ((,c :inherit warning))) + `(treemacs-root-unreadable-face ((,c :inherit error))) + `(treemacs-tags-face ((,c :foreground ,fg-main))) + `(treemacs-term-node-face ((,c :inherit modus-themes-bold :foreground ,keyword))) + `(treemacs-window-background-face ((,c :background ,bg-main))) + `(treemacs-nerd-icons-root-face ((,c :foreground ,accent-0))) + `(treemacs-nerd-icons-file-face ((,c :foreground ,accent-0))) ;;;;; tree-sitter `(tree-sitter-hl-face:attribute ((,c :inherit font-lock-variable-name-face))) `(tree-sitter-hl-face:constant.builtin ((,c :inherit tree-sitter-hl-face:constant))) @@ -3930,8 +4025,8 @@ FG and BG are the main colors." ;;;;; vertico `(vertico-current ((,c :inherit modus-themes-completion-selected))) ;;;;; vertico-quick - `(vertico-quick1 ((,c :inherit bold :background ,bg-char-0))) - `(vertico-quick2 ((,c :inherit bold :background ,bg-char-1))) + `(vertico-quick1 ((,c :inherit (bold modus-themes-search-current)))) + `(vertico-quick2 ((,c :inherit (bold modus-themes-search-current)))) ;;;;; vimish-fold `(vimish-fold-fringe ((,c :foreground ,cyan))) `(vimish-fold-mouse-face ((,c :inherit modus-themes-intense-blue))) @@ -3956,20 +4051,24 @@ FG and BG are the main colors." `(vr/match-1 ((,c :inherit modus-themes-search-lazy))) `(vr/match-separator-face ((,c :inherit bold :background ,bg-active))) ;;;;; vterm - ;; NOTE 2023-08-10: `vterm-color-black' and `vterm-color-white' - ;; use the "bright" semantic color mappings to make sure they are - ;; distinct from `vterm-color-default'. `(vterm-color-black ((,c :background ,bg-term-black :foreground ,fg-term-black))) - `(vterm-color-blue ((,c :background ,bg-term-blue :foreground ,fg-term-blue))) - `(vterm-color-cyan ((,c :background ,bg-term-cyan :foreground ,fg-term-cyan))) - `(vterm-color-default ((,c :background ,bg-main :foreground ,fg-main))) - `(vterm-color-green ((,c :background ,bg-term-green :foreground ,fg-term-green))) - `(vterm-color-inverse-video ((,c :background ,bg-main :inverse-video t))) - `(vterm-color-magenta ((,c :background ,bg-term-magenta :foreground ,fg-term-magenta))) + `(vterm-color-bright-black ((,c :background ,bg-term-black-bright :foreground ,fg-term-black-bright))) `(vterm-color-red ((,c :background ,bg-term-red :foreground ,fg-term-red))) - `(vterm-color-underline ((,c :underline t))) - `(vterm-color-white ((,c :background ,bg-term-white :foreground ,fg-term-white))) + `(vterm-color-bright-red ((,c :background ,bg-term-red-bright :foreground ,fg-term-red-bright))) + `(vterm-color-green ((,c :background ,bg-term-green :foreground ,fg-term-green))) + `(vterm-color-bright-green ((,c :background ,bg-term-green-bright :foreground ,fg-term-green-bright))) `(vterm-color-yellow ((,c :background ,bg-term-yellow :foreground ,fg-term-yellow))) + `(vterm-color-bright-yellow ((,c :background ,bg-term-yellow-bright :foreground ,fg-term-yellow-bright))) + `(vterm-color-blue ((,c :background ,bg-term-blue :foreground ,fg-term-blue))) + `(vterm-color-bright-blue ((,c :background ,bg-term-blue-bright :foreground ,fg-term-blue-bright))) + `(vterm-color-magenta ((,c :background ,bg-term-magenta :foreground ,fg-term-magenta))) + `(vterm-color-bright-magenta ((,c :background ,bg-term-magenta-bright :foreground ,fg-term-magenta-bright))) + `(vterm-color-cyan ((,c :background ,bg-term-cyan :foreground ,fg-term-cyan))) + `(vterm-color-bright-cyan ((,c :background ,bg-term-cyan-bright :foreground ,fg-term-cyan-bright))) + `(vterm-color-white ((,c :background ,bg-term-white :foreground ,fg-term-white))) + `(vterm-color-bright-white ((,c :background ,bg-term-white-bright :foreground ,fg-term-white-bright))) + `(vterm-color-inverse-video ((,c :background ,bg-main :inverse-video t))) + `(vterm-color-underline ((,c :underline t))) ;;;;; vundo `(vundo-default ((,c :inherit shadow))) `(vundo-highlight ((,c :inherit (bold vundo-node) :foreground ,red))) diff --git a/etc/themes/modus-vivendi-deuteranopia-theme.el b/etc/themes/modus-vivendi-deuteranopia-theme.el index ec4a97ff434..676432f8531 100644 --- a/etc/themes/modus-vivendi-deuteranopia-theme.el +++ b/etc/themes/modus-vivendi-deuteranopia-theme.el @@ -1,6 +1,6 @@ ;;; modus-vivendi-deuteranopia-theme.el --- Deuteranopia-optimized theme with a black background -*- lexical-binding:t -*- -;; Copyright (C) 2019-2025 Free Software Foundation, Inc. +;; Copyright (C) 2019-2025 Free Software Foundation, Inc. ;; Author: Protesilaos Stavrou ;; Maintainer: Protesilaos Stavrou @@ -167,15 +167,11 @@ standard)." (bg-completion "#2f447f") (bg-hover "#45605e") - (bg-hover-secondary "#654a39") + (bg-hover-secondary "#604c30") (bg-hl-line "#2f3849") (bg-region "#5a5a5a") (fg-region "#ffffff") - (bg-char-0 "#0050af") - (bg-char-1 "#7f1f7f") - (bg-char-2 "#625a00") - (bg-mode-line-active "#2a2a6a") (fg-mode-line-active "#f0f0f0") (border-mode-line-active "#8080a7") @@ -216,13 +212,6 @@ standard)." (bg-diff-context "#1a1a1a") -;;; Paren match - - (bg-paren-match "#2f7f9f") - (fg-paren-match fg-main) - (bg-paren-expression "#453040") - (underline-paren-match unspecified) - ;;; Mappings ;;;; General mappings @@ -257,17 +246,17 @@ standard)." ;;;; Code mappings (bracket fg-main) - (builtin magenta-warmer) + (builtin yellow) (comment yellow-cooler) - (constant blue-cooler) + (constant blue-faint) (delimiter fg-main) (docmarkup magenta-faint) (docstring cyan-faint) - (fnname magenta) - (keyword magenta-cooler) + (fnname yellow-warmer) + (keyword blue-cooler) (number fg-main) (operator fg-main) - (preprocessor red-cooler) + (preprocessor magenta-cooler) (punctuation fg-main) (rx-backslash blue-cooler) (rx-construct yellow-cooler) @@ -275,12 +264,19 @@ standard)." (type cyan-cooler) (variable cyan) +;;;; Paren match + + (bg-paren-match bg-cyan-subtle) + (fg-paren-match fg-main) + (underline-paren-match unspecified) + (bg-paren-expression bg-yellow-nuanced) + ;;;; Accent mappings - (accent-0 blue-cooler) + (accent-0 blue-warmer) (accent-1 yellow) (accent-2 cyan-cooler) - (accent-3 magenta-warmer) + (accent-3 yellow-cooler) ;;;; Button mappings @@ -294,7 +290,7 @@ standard)." (fg-completion-match-0 blue-cooler) (fg-completion-match-1 yellow) (fg-completion-match-2 cyan-cooler) - (fg-completion-match-3 magenta-warmer) + (fg-completion-match-3 yellow-cooler) (bg-completion-match-0 unspecified) (bg-completion-match-1 unspecified) (bg-completion-match-2 unspecified) @@ -313,7 +309,7 @@ standard)." (date-scheduled yellow-cooler) (date-scheduled-subtle yellow-faint) (date-weekday cyan) - (date-weekend magenta) + (date-weekend magenta-cooler) ;;;; Line number mappings @@ -374,7 +370,7 @@ standard)." (fg-prose-macro magenta-cooler) (bg-prose-verbatim unspecified) - (fg-prose-verbatim magenta-warmer) + (fg-prose-verbatim yellow) (prose-done blue) (prose-todo yellow-warmer) @@ -385,7 +381,7 @@ standard)." (prose-table fg-alt) (prose-table-formula yellow-warmer) - (prose-tag magenta-faint) + (prose-tag fg-alt) ;;;; Rainbow mappings @@ -403,7 +399,7 @@ standard)." (bg-search-current bg-yellow-intense) (bg-search-lazy bg-blue-intense) - (bg-search-replace bg-magenta-intense) + (bg-search-replace bg-yellow-intense) (bg-search-rx-group-0 bg-cyan-intense) (bg-search-rx-group-1 bg-magenta-intense) @@ -464,10 +460,10 @@ standard)." (fg-heading-1 fg-main) (fg-heading-2 yellow-faint) (fg-heading-3 blue-faint) - (fg-heading-4 magenta) - (fg-heading-5 green-faint) - (fg-heading-6 red-faint) - (fg-heading-7 cyan-faint) + (fg-heading-4 green-faint) + (fg-heading-5 magenta-cooler) + (fg-heading-6 yellow-cooler) + (fg-heading-7 cyan) (fg-heading-8 fg-dim) (bg-heading-0 unspecified) diff --git a/etc/themes/modus-vivendi-theme.el b/etc/themes/modus-vivendi-theme.el index 523e1586c3e..b613353ade7 100644 --- a/etc/themes/modus-vivendi-theme.el +++ b/etc/themes/modus-vivendi-theme.el @@ -1,6 +1,6 @@ ;;; modus-vivendi-theme.el --- Elegant, highly legible theme with a black background -*- lexical-binding:t -*- -;; Copyright (C) 2019-2025 Free Software Foundation, Inc. +;; Copyright (C) 2019-2025 Free Software Foundation, Inc. ;; Author: Protesilaos Stavrou ;; Maintainer: Protesilaos Stavrou @@ -170,10 +170,6 @@ which corresponds to a minimum contrast in relative luminance of (bg-region "#5a5a5a") (fg-region "#ffffff") - (bg-char-0 "#0050af") - (bg-char-1 "#7f1f7f") - (bg-char-2 "#625a00") - (bg-mode-line-active "#505050") (fg-mode-line-active "#ffffff") (border-mode-line-active "#959595") @@ -214,13 +210,6 @@ which corresponds to a minimum contrast in relative luminance of (bg-diff-context "#1a1a1a") -;;; Paren match - - (bg-paren-match "#2f7f9f") - (fg-paren-match fg-main) - (bg-paren-expression "#453040") - (underline-paren-match unspecified) - ;;; Mappings ;;;; General mappings @@ -273,6 +262,13 @@ which corresponds to a minimum contrast in relative luminance of (type cyan-cooler) (variable cyan) +;;;; Paren match + + (bg-paren-match bg-cyan-subtle) + (fg-paren-match fg-main) + (underline-paren-match unspecified) + (bg-paren-expression bg-yellow-nuanced) + ;;;; Accent mappings (accent-0 blue-cooler) diff --git a/etc/themes/modus-vivendi-tinted-theme.el b/etc/themes/modus-vivendi-tinted-theme.el index 03fb25edd02..ba186fc9f8f 100644 --- a/etc/themes/modus-vivendi-tinted-theme.el +++ b/etc/themes/modus-vivendi-tinted-theme.el @@ -1,6 +1,6 @@ ;;; modus-vivendi-tinted-theme.el --- Elegant, highly legible theme with a night sky background -*- lexical-binding:t -*- -;; Copyright (C) 2019-2025 Free Software Foundation, Inc. +;; Copyright (C) 2019-2025 Free Software Foundation, Inc. ;; Author: Protesilaos Stavrou ;; Maintainer: Protesilaos Stavrou @@ -71,11 +71,11 @@ which corresponds to a minimum contrast in relative luminance of (red "#ff5f59") (red-warmer "#ff6b55") (red-cooler "#ff7f86") - (red-faint "#ff9f80") + (red-faint "#ef8386") (red-intense "#ff5f5f") (green "#44bc44") - (green-warmer "#70b900") - (green-cooler "#00c06f") + (green-warmer "#75c13e") + (green-cooler "#11c777") (green-faint "#88ca9f") (green-intense "#44df44") (yellow "#d0bc00") @@ -165,15 +165,11 @@ which corresponds to a minimum contrast in relative luminance of (bg-completion "#483d8a") (bg-hover "#45605e") - (bg-hover-secondary "#654a39") + (bg-hover-secondary "#64404f") (bg-hl-line "#303a6f") (bg-region "#555a66") (fg-region "#ffffff") - (bg-char-0 "#0050af") - (bg-char-1 "#7f1f7f") - (bg-char-2 "#625a00") - (bg-mode-line-active "#484d67") (fg-mode-line-active "#ffffff") (border-mode-line-active "#979797") @@ -214,13 +210,6 @@ which corresponds to a minimum contrast in relative luminance of (bg-diff-context "#1a1f30") -;;; Paren match - - (bg-paren-match "#5f789f") - (fg-paren-match fg-main) - (bg-paren-expression "#453040") - (underline-paren-match unspecified) - ;;; Mappings ;;;; General mappings @@ -233,8 +222,8 @@ which corresponds to a minimum contrast in relative luminance of (identifier yellow-faint) (err red) - (warning yellow-warmer) - (info cyan-cooler) + (warning yellow) + (info green-cooler) (underline-err red-intense) (underline-warning yellow) @@ -255,30 +244,37 @@ which corresponds to a minimum contrast in relative luminance of ;;;; Code mappings (bracket fg-main) - (builtin magenta-warmer) + (builtin magenta) (comment red-faint) - (constant blue-cooler) + (constant magenta-cooler) (delimiter fg-main) (docmarkup magenta-faint) (docstring cyan-faint) - (fnname magenta) - (keyword magenta-cooler) + (fnname magenta-warmer) + (keyword blue-warmer) (number fg-main) (operator fg-main) (preprocessor red-cooler) (punctuation fg-main) - (rx-backslash magenta) - (rx-construct green-cooler) - (string blue-warmer) - (type cyan-cooler) - (variable cyan) + (rx-backslash magenta-warmer) + (rx-construct magenta-cooler) + (string blue) + (type green-cooler) + (variable cyan-warmer) + +;;;; Paren match + + (bg-paren-match bg-cyan-subtle) + (fg-paren-match fg-main) + (underline-paren-match unspecified) + (bg-paren-expression bg-yellow-nuanced) ;;;; Accent mappings - (accent-0 blue-cooler) - (accent-1 magenta-warmer) - (accent-2 cyan-cooler) - (accent-3 yellow) + (accent-0 magenta-cooler) + (accent-1 cyan) + (accent-2 magenta-warmer) + (accent-3 yellow-warmer) ;;;; Button mappings @@ -336,14 +332,14 @@ which corresponds to a minimum contrast in relative luminance of ;;;; Mail mappings - (mail-cite-0 blue-warmer) + (mail-cite-0 blue) (mail-cite-1 yellow-cooler) (mail-cite-2 cyan-cooler) (mail-cite-3 red-cooler) - (mail-part blue) - (mail-recipient magenta-cooler) + (mail-part magenta-cooler) + (mail-recipient blue-warmer) (mail-subject magenta-warmer) - (mail-other magenta-faint) + (mail-other magenta) ;;;; Mark mappings @@ -356,7 +352,7 @@ which corresponds to a minimum contrast in relative luminance of ;;;; Prompt mappings - (fg-prompt cyan-cooler) + (fg-prompt cyan-warmer) (bg-prompt unspecified) ;;;; Prose mappings diff --git a/etc/themes/modus-vivendi-tritanopia-theme.el b/etc/themes/modus-vivendi-tritanopia-theme.el index a06f8e04cb9..7929c69e31b 100644 --- a/etc/themes/modus-vivendi-tritanopia-theme.el +++ b/etc/themes/modus-vivendi-tritanopia-theme.el @@ -1,6 +1,6 @@ ;;; modus-vivendi-tritanopia-theme.el --- Tritanopia-optimized theme with a black background -*- lexical-binding:t -*- -;; Copyright (C) 2019-2025 Free Software Foundation, Inc. +;; Copyright (C) 2019-2025 Free Software Foundation, Inc. ;; Author: Protesilaos Stavrou ;; Maintainer: Protesilaos Stavrou @@ -63,7 +63,7 @@ standard)." (bg-dim "#1e1e1e") (fg-main "#ffffff") (fg-dim "#989898") - (fg-alt "#c6daff") + (fg-alt "#a0d7f2") (bg-active "#535353") (bg-inactive "#303030") (border "#646464") @@ -167,15 +167,11 @@ standard)." (bg-completion "#004253") (bg-hover "#8e3e3b") - (bg-hover-secondary "#00405f") + (bg-hover-secondary "#204853") (bg-hl-line "#2f3849") (bg-region "#5a5a5a") (fg-region "#ffffff") - (bg-char-0 "#922a00") - (bg-char-1 "#00709f") - (bg-char-2 "#5f3faf") - (bg-mode-line-active "#003c52") (fg-mode-line-active "#f0f0f0") (border-mode-line-active "#5f8fb4") @@ -216,13 +212,6 @@ standard)." (bg-diff-context "#1a1a1a") -;;; Paren match - - (bg-paren-match "#2f7f9f") - (fg-paren-match fg-main) - (bg-paren-expression "#453040") - (underline-paren-match unspecified) - ;;; Mappings ;;;; General mappings @@ -275,6 +264,13 @@ standard)." (type blue-warmer) (variable cyan-cooler) +;;;; Paren match + + (bg-paren-match bg-cyan-subtle) + (fg-paren-match fg-main) + (underline-paren-match unspecified) + (bg-paren-expression bg-red-nuanced) + ;;;; Accent mappings (accent-0 cyan) @@ -385,7 +381,7 @@ standard)." (prose-table fg-alt) (prose-table-formula red-cooler) - (prose-tag magenta-faint) + (prose-tag fg-alt) ;;;; Rainbow mappings diff --git a/exec/config-mips.m4.in b/exec/config-mips.m4.in index c42bbbad2ec..4ab395ff2cb 100644 --- a/exec/config-mips.m4.in +++ b/exec/config-mips.m4.in @@ -18,6 +18,7 @@ dnl You should have received a copy of the GNU General Public License dnl along with GNU Emacs. If not, see . define(`SYSCALL_open', `ifelse(`@MIPS_N32@',`yes',`6002',`4005')') +dnl define(`SYSCALL_openat', `ifelse(`@MIPS_N32@',`yes',`6251',`4288')') define(`SYSCALL_close', `ifelse(`@MIPS_N32@',`yes',`6003',`4006')') define(`SYSCALL_mmap', `ifelse(`@MIPS_N32@',`yes',`6009',`4090')') define(`SYSCALL_nanosleep', `ifelse(`@MIPS_N32@',`yes',`6034',`4166')') @@ -34,9 +35,14 @@ define(`SYSCALL', `ifelse(`@MIPS_N32@',`yes',` move $a4, $1 sw $4, 28($sp)')') define(`RESTORE', `ifelse(`@MIPS_N32@',`yes',` nop',` addi $sp, 32')') +define(`FP', `ifelse(`@MIPS_N32@',`yes',`$s8',`$fp')') dnl For mips64. Some assemblers don't want to assemble `daddi'. -define(`DADDI2', `ifelse(`@DADDI_BROKEN@',`yes',` li $at, $2 -dadd $1, $1, $at',` daddi $1, $2')') -define(`DADDI3', `ifelse(`@DADDI_BROKEN@',`yes',` li $at, $3 -dadd $1, $2, $at',` daddi $1, $2, $3')') +define(`DADDI2', `ifelse(`@DADDI_BROKEN@',`yes',`.set noat +li $at, $2 +dadd $1, $1, $at +.set at',` daddi $1, $2')') +define(`DADDI3', `ifelse(`@DADDI_BROKEN@',`yes',`.set noat +li $at, $3 +dadd $1, $2, $at +.set at',` daddi $1, $2, $3')') diff --git a/exec/configure.ac b/exec/configure.ac index d91049b8d7b..ef825e26788 100644 --- a/exec/configure.ac +++ b/exec/configure.ac @@ -213,11 +213,11 @@ AC_CACHE_CHECK([whether MIPS NABI calling convention is used], [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ -#ifndef __mips64__ +#if !defined __mips64__ && !defined __LP64__ #if _MIPS_SIM == _ABIO32 OABI in use. #endif /* _MIPS_SIM == _ABIO32 */ -#endif /* !__mips64__ */ +#endif /* !__mips64__ && !defined __LP64__ */ ]])], [exec_cv_mips_nabi=yes], [exec_cv_mips_nabi=no])]) @@ -455,12 +455,12 @@ AS_CASE([$host], [x86_64-*linux*], .section text .global __start __start: - li $t0, 0 - li $t1, 0 - daddi $t0, $t1, 1 - daddi $t0, $t1, -1 - daddi $t0, -1 - daddi $t0, 1 + li \$t0, 0 + li \$t1, 0 + daddi \$t0, \$t1, 1 + daddi \$t0, \$t1, -1 + daddi \$t0, -1 + daddi \$t0, 1 _ACEOF $AS $ASFLAGS conftest.s -o conftest.$OBJEXT \ @@ -470,7 +470,8 @@ _ACEOF AS_IF([test "x$exec_cv_as_daddi" != "xyes"], [DADDI_BROKEN=yes]) exec_CHECK_LINUX_CLONE3 - exec_CHECK_MIPS_NABI + AC_DEFINE([MIPS_NABI], [1], + [Define to 1 if MIPS NABI calling convention is being used.]) LOADERFLAGS="$LOADERFLAGS $LDPREFIX-Ttext=0x3e00000000" is_mips=yes exec_loader=loader-mips64el.s], [*], diff --git a/exec/exec.c b/exec/exec.c index b1c9825daff..b83e34bc1b2 100644 --- a/exec/exec.c +++ b/exec/exec.c @@ -231,10 +231,10 @@ struct exec_jump_command /* The value of AT_BASE inside the aux vector. */ USER_WORD at_base; -#if defined __mips__ && !defined MIPS_NABI - /* The FPU mode to apply. */ +#if defined __mips__ && !defined __LP64__ + /* The FPU mode to apply. Not used when !MIPS_NABI. */ USER_WORD fpu_mode; -#endif /* defined __mips__ && !defined MIPS_NABI */ +#endif /* defined __mips__ && !defined __LP64__ */ }; @@ -831,7 +831,7 @@ insert_args (struct exec_tracee *tracee, USER_REGS_STRUCT *regs, assert (new3 == new + effective_size); /* And that it is properly aligned. */ - assert (!(new3 & (sizeof new3 - 2))); + assert (!(new3 & (sizeof new3 - 1))); /* Now modify the system call argument to point to new + text_size. */ @@ -916,7 +916,9 @@ exec_0 (char *name, struct exec_tracee *tracee, program_header program; USER_WORD entry, program_entry, offset; USER_WORD header_offset; + USER_WORD name_len, aligned_len; struct exec_jump_command jump; + /* This also encompasses !__LP64__. */ #if defined __mips__ && !defined MIPS_NABI int fpu_mode; #endif /* defined __mips__ && !defined MIPS_NABI */ @@ -1129,7 +1131,9 @@ exec_0 (char *name, struct exec_tracee *tracee, fpu_mode = FP_FRE; jump.fpu_mode = fpu_mode; -#endif /* defined __mips__ && !defined MIPS_NABI */ +#elif defined __mips__ && !defined __LP64__ + jump.fpu_mode = 0; +#endif /* defined __mips__ && defined MIPS_NABI && !defined __LP64__ */ /* The offset used for at_phdr should be that of the first mapping. */ @@ -1146,6 +1150,23 @@ exec_0 (char *name, struct exec_tracee *tracee, sizeof jump); loader_area_used += sizeof jump; + /* Copy the length of NAME and NAME itself to the loader area. */ + name_len = strlen (name); + aligned_len = ((name_len + 1 + sizeof name_len - 1) + & -sizeof name_len); + if (sizeof loader_area - loader_area_used + < aligned_len + sizeof name_len) + goto fail1; + memcpy (loader_area + loader_area_used, &name_len, sizeof name_len); + loader_area_used += sizeof name_len; + memcpy (loader_area + loader_area_used, name, name_len + 1); + loader_area_used += name_len + 1; + + /* Properly align the loader area. */ + offset = aligned_len - (name_len + 1); + while (offset--) + loader_area[loader_area_used++] = '\0'; + /* Close the file descriptor and return the number of bytes used. */ diff --git a/exec/exec.h b/exec/exec.h index eee48dfe2ed..d420061ff87 100644 --- a/exec/exec.h +++ b/exec/exec.h @@ -152,6 +152,10 @@ struct exec_tracee completion. */ USER_WORD sp; + /* ID of the system call that is pending completion. This value is + not available as the call number is overwritten on success. */ + USER_WORD callno; + /* Name of the executable being run. */ char *exec_file; diff --git a/exec/loader-aarch64.s b/exec/loader-aarch64.s index 686a804aa0e..d3c565bf3f8 100644 --- a/exec/loader-aarch64.s +++ b/exec/loader-aarch64.s @@ -22,68 +22,68 @@ .section .text .global _start _start: - //mov x8, 101 // SYS_nanosleep - //adr x0, timespec // req - //mov x1, #0 // rem - //svc #0 // syscall + // mov x8, 101 // SYS_nanosleep + // adr x0, timespec // req + // mov x1, #0 // rem + // svc #0 // syscall mov x20, sp // x20 = sp ldr x10, [x20] // x10 = original SP add x20, x20, #16 // x20 = start of load area mov x28, #-1 // x28 = secondary fd -.next_action: +next_action: ldr x11, [x20] // action number and x12, x11, #-17 // actual action number - cbz x12, .open_file // open file? + cbz x12, open_file // open file? cmp x12, #3 // jump? - beq .rest_of_exec + beq rest_of_exec cmp x12, #4 // anonymous mmap? - beq .do_mmap_anon -.do_mmap: + beq do_mmap_anon +do_mmap: ldr x0, [x20, 8] // vm_address ldr x1, [x20, 32] // length ldr x2, [x20, 24] // protection ldr x3, [x20, 40] // flags tst x11, #16 // primary fd? mov x4, x29 // primary fd - beq .do_mmap_1 + beq do_mmap_1 mov x4, x28 // secondary fd -.do_mmap_1: +do_mmap_1: mov x8, #222 // SYS_mmap ldr x5, [x20, 16] // file_offset svc #0 // syscall ldr x9, [x20, 8] // length cmp x0, x9 // mmap result - bne .perror // print error + bne perror // print error ldr x3, [x20, 48] // clear add x1, x1, x0 // x1 = vm_address + end sub x3, x1, x3 // x3 = x1 - clear mov x0, #0 // x0 = 0 -.fill64: +fill64: sub x2, x1, x3 // x2 = x1 - x3 cmp x2, #63 // x2 >= 64? - ble .fillb // start filling bytes + ble fillb // start filling bytes stp x0, x0, [x3] // x3[0] = 0, x3[1] = 0 stp x0, x0, [x3, 16] // x3[2] = 0, x3[3] = 0 stp x0, x0, [x3, 32] // x3[4] = 0, x3[5] = 0 stp x0, x0, [x3, 48] // x3[6] = 0, x3[7] = 0 add x3, x3, #64 // x3 += 8 - b .fill64 -.fillb: + b fill64 +fillb: cmp x1, x3 // x1 == x3? - beq .continue // done + beq continue // done strb w0, [x3], #1 // ((char *) x3)++ = 0 - b .fillb -.continue: + b fillb +continue: add x20, x20, #56 // next action - b .next_action -.do_mmap_anon: + b next_action +do_mmap_anon: ldr x0, [x20, 8] // vm_address ldr x1, [x20, 32] // length ldr x2, [x20, 24] // protection ldr x3, [x20, 40] // flags mov x4, #-1 // fd - b .do_mmap_1 -.open_file: + b do_mmap_1 +open_file: mov x8, #56 // SYS_openat mov x0, #-100 // AT_FDCWD add x1, x20, #8 // file name @@ -91,19 +91,19 @@ _start: mov x3, #0 // mode svc #0 // syscall cmp x0, #-1 // rc < 0? - ble .perror + ble perror mov x19, x1 // x19 == x1 -.nextc: +nextc: ldrb w2, [x1], #1 // b = *x1++ cmp w2, #47 // dir separator? - bne .nextc1 // not dir separator + bne nextc1 // not dir separator mov x19, x1 // x19 = char past separator -.nextc1: - cbnz w2, .nextc // b? +nextc1: + cbnz w2, nextc // b? add x1, x1, #7 // round up x1 and x20, x1, #-8 // mask for round, set x20 tst x11, #16 // primary fd? - bne .secondary // secondary fd + bne secondary // secondary fd mov x29, x0 // primary fd mov x8, #167 // SYS_prctl mov x0, #15 // PR_SET_NAME @@ -113,75 +113,117 @@ _start: mov x4, #0 // arg4 mov x5, #0 // arg5 svc #0 // syscall - b .next_action // next action -.secondary: + b next_action // next action +secondary: mov x28, x0 // secondary fd - b .next_action // next action. -.perror: + b next_action // next action. +perror: mov x8, #93 // SYS_exit mvn x0, x0 // x1 = ~x0 add x0, x0, 1 // x1 += 1 svc #0 // exit -.rest_of_exec: +rest_of_exec: mov x7, x20 // x7 = x20 - mov x20, x10 // x20 = x10 - ldr x9, [x20] // argc - add x9, x9, #2 // x9 += 2 + mov x8, x10 // x8 = x10 + ldr x9, [x8], #16 // (void *) x8 += 2 lsl x9, x9, #3 // argc * 8 - add x20, x20, x9 // now past argv -.skipenv: - ldr x9, [x20], #8 // x9 = *envp++ - cbnz x9, .skipenv // x9? -.one_auxv: - ldr x9, [x20], #16 // x9 = *sp, sp += 2 - cbz x9, .cleanup // !x9? - cmp x9, #3 // is AT_PHDR? - beq .replace_phdr // replace - cmp x9, #4 // is AT_PHENT? - beq .replace_phent // replace - cmp x9, #5 // is AT_PHNUM? - beq .replace_phnum // replace - cmp x9, #9 // is AT_ENTRY? - beq .replace_entry // replace - cmp x9, #7 // is AT_BASE? - beq .replace_base // replace - b .one_auxv // next auxv -.replace_phdr: - ldr x9, [x7, 40] // at_phdr - str x9, [x20, -8] // store value - b .one_auxv -.replace_phent: - ldr x9, [x7, 24] // at_phent - str x9, [x20, -8] // store value - b .one_auxv -.replace_phnum: - ldr x9, [x7, 32] // at_phnum - str x9, [x20, -8] // store value - b .one_auxv -.replace_entry: - ldr x9, [x7, 16] // at_entry - str x9, [x20, -8] // store value - b .one_auxv -.replace_base: - ldr x9, [x7, 48] // at_base - str x9, [x20, -8] // store value - b .one_auxv -.cleanup: - cmp x28, #-1 // is secondary fd set? - bne .cleanup1 // not set + add x8, x8, x9 // now past argv +skip_environ: + ldr x9, [x8], #8 // x9 = *envp++ + cbnz x9, skip_environ // x9? + // Skip the auxiliary vector. +1: ldp x11, x12, [x8], #16 // a_type, a_un.a_val + cbnz x11, 1b // a_type != NULL + // Prepare sufficient space at x20 for the file name string. + // Load the aforesaid string, and its length. + ldr x6, [x7, 56] // string length + add x6, x6, 1 + add x5, x7, 64 // string pointer + sub x4, x10, x8 // number of elements to copy + sub x7, x8, x6 // AT_EXECFN location + and x7, x7, -8 // align value + add x4, x7, x4 // destination argc + and x4, x4, -16 // align destination argc + // Load values that must be preserved into registers x14-x19. + // x14 = cmd->entry + // x15 = cmd->at_entry + // x16 = cmd->at_phent + // x17 = cmd->at_phnum + // x18 = cmd->at_phdr + // x19 = cmd->at_base + ldp x14, x15, [x20, 8] + ldp x16, x17, [x20, 24] + ldp x18, x19, [x20, 40] + // Move the string to a safe location, if necessary. + sub x3, x4, x5 // distance from dest to string + cmp x3, x6 // distance > length + bge copy_env_and_args // not necessary + mov x2, x5 // src + sub x5, x4, x6 // backup string + mov x1, x5 // dst + add x9, x2, x6 // src end + cmp x2, x9 + bcs copy_env_and_args +1: ldrb w3, [x2], #1 + strb w3, [x1], #1 + cmp x2, x9 + blo 1b +copy_env_and_args: + // Copy argc and the environment array. + mov x8, x10 + mov x10, x4 +1: ldr x9, [x8], #8 // envp + str x9, [x4], #8 + cbnz x9, 1b +1: ldr x9, [x8], #8 // environ + str x9, [x4], #8 + cbnz x9, 1b +copy_auxv: + ldp x11, x12, [x8], #16 // a_type, a_un.a_val + stp x11, x12, [x4], #16 // write value + cbz x11, cleanup // AT_NULL + cmp x11, #3 // AT_PHDR + csel x12, x18, x12, eq + cmp x11, #4 // AT_PHENT + csel x12, x16, x12, eq + cmp x11, #5 // AT_PHNUM + csel x12, x17, x12, eq + cmp x11, #9 // AT_ENTRY + csel x12, x15, x12, eq + cmp x11, #7 // AT_BASE + csel x12, x19, x12, eq + cmp x11, #31 // AT_EXECFN + csel x12, x7, x12, eq + str x12, [x4, -8] // replace value + b copy_auxv +cleanup: + // Copy the filename. + add x9, x5, x6 // end + cmp x5, x9 + bcs 2f +1: ldrb w3, [x5], #1 + strb w3, [x7], #1 + cmp x5, x9 + blo 1b + // Close file descriptors. +2: cmp x28, #-1 // is secondary fd set? + beq cleanup1 // not set mov x8, #57 // SYS_close mov x0, x28 // secondary fd svc #0 // syscall -.cleanup1: +cleanup1: mov x8, #57 // SYS_close mov x0, x29 // primary fd svc #0 // syscall -.enter: +enter: mov sp, x10 // restore original SP mov x0, #0 // clear rtld_fini - ldr x1, [x7, 8] // branch to code - br x1 + br x14 -timespec: - .quad 10 - .quad 10 +// timespec: +// .quad 10 +// .quad 10 + +// Local Variables: +// asm-comment-char: ?/ +// End: diff --git a/exec/loader-armeabi.s b/exec/loader-armeabi.s index 2aa52f3e006..572020bb573 100644 --- a/exec/loader-armeabi.s +++ b/exec/loader-armeabi.s @@ -18,23 +18,23 @@ .section .text .global _start _start: - @mov r7, #162 @ SYS_nanosleep - @adr r0, timespec @ req - @mov r1, #0 @ rem - @swi #0 @ syscall + @@ mov r7, #162 @ SYS_nanosleep + @@ adr r0, timespec @ req + @@ mov r1, #0 @ rem + @@ swi #0 @ syscall mov r8, sp @ r8 = sp ldr r9, [r8], #8 @ r9 = original sp, r8 += 8 mov r14, #-1 @ r14 = secondary fd -.next_action: +next_action: ldr r11, [r8] @ r11 = action number and r12, r11, #-17 @ actual action number cmp r12, #0 @ open file? - beq .open_file @ open file. + beq open_file @ open file. cmp r12, #3 @ jump? - beq .rest_of_exec @ jump to code. + beq rest_of_exec @ jump to code. cmp r12, #4 @ anonymous mmap? - beq .do_mmap_anon @ anonymous mmap. -.do_mmap: + beq do_mmap_anon @ anonymous mmap. +do_mmap: add r6, r8, #4 @ r6 = r8 + 4 ldm r6!, {r0, r5} @ vm_address, file_offset ldm r6!, {r1, r2} @ protection, length @@ -45,28 +45,28 @@ _start: ldm r6!, {r3, r12} @ flags, clear tst r11, #16 @ primary fd? mov r4, r10 @ primary fd - beq .do_mmap_1 + beq do_mmap_1 mov r4, r14 @ secondary fd -.do_mmap_1: +do_mmap_1: mov r7, #192 @ SYS_mmap2 swi #0 @ syscall ldr r2, [r8, #4] @ vm_address cmp r2, r0 @ rc == vm_address? - bne .perror + bne perror add r0, r1, r2 @ r0 = length + vm_address sub r3, r0, r12 @ r3 = r0 - clear mov r1, #0 @ r1 = 0 -.align: +align: cmp r0, r3 @ r0 == r3? - beq .continue @ continue + beq continue @ continue tst r3, #3 @ r3 & 3? - bne .fill32 @ fill aligned + bne fill32 @ fill aligned strb r1, [r3], #1 @ fill byte - b .align @ align again -.fill32: + b align @ align again +fill32: sub r2, r0, r3 @ r2 = r0 - r3 cmp r2, #31 @ r2 >= 32? - ble .fillb @ start filling bytes + ble fillb @ start filling bytes str r1, [r3], #4 @ *r3++ = 0 str r1, [r3], #4 @ *r3++ = 0 str r1, [r3], #4 @ *r3++ = 0 @@ -75,16 +75,16 @@ _start: str r1, [r3], #4 @ *r3++ = 0 str r1, [r3], #4 @ *r3++ = 0 str r1, [r3], #4 @ *r3++ = 0 - b .fill32 -.fillb: + b fill32 +fillb: cmp r0, r3 @ r0 == r3 - beq .continue @ done + beq continue @ done strb r1, [r3], #1 @ ((char *) r3)++ = 0 - b .fillb -.continue: + b fillb +continue: add r8, r8, #28 @ next action - b .next_action -.do_mmap_anon: + b next_action +do_mmap_anon: add r6, r8, #4 @ r6 = r8 + 4 ldm r6!, {r0, r5} @ vm_address, file_offset ldm r6!, {r1, r2} @ protection, length @@ -94,29 +94,29 @@ _start: mov r2, r3 @ swap ldm r6!, {r3, r12} @ flags, clear mov r4, #-1 @ fd - b .do_mmap_1 -.open_file: + b do_mmap_1 +open_file: mov r7, #5 @ SYS_open add r0, r8, #4 @ file name mov r1, #0 @ O_RDONLY mov r2, #0 @ mode swi #0 @ syscall cmp r0, #-1 @ r0 <= -1? - ble .perror + ble perror add r8, r8, #4 @ r8 = start of string mov r1, r8 @ r1 = r8 -.nextc: +nextc: ldrb r2, [r8], #1 @ b = *r0++ cmp r2, #47 @ dir separator? - bne .nextc1 @ not dir separator + bne nextc1 @ not dir separator mov r1, r8 @ r1 = char past separator -.nextc1: +nextc1: cmp r2, #0 @ b? - bne .nextc @ next character + bne nextc @ next character add r8, r8, #3 @ round up r8 and r8, r8, #-4 @ mask for round, set r8 tst r11, #16 @ primary fd? - bne .secondary @ secondary fd + bne secondary @ secondary fd mov r10, r0 @ primary fd mov r7, #172 @ SYS_prctl mov r0, #15 @ PR_SET_NAME, r1 = name @@ -125,79 +125,139 @@ _start: mov r4, #0 @ arg4 mov r5, #0 @ arg5 swi #0 @ syscall - b .next_action @ next action -.secondary: + b next_action @ next action +secondary: mov r14, r0 @ secondary fd - b .next_action @ next action -.perror: + b next_action @ next action +perror: mov r7, #1 @ SYS_exit mvn r0, r0 @ r0 = ~r0 add r0, r0, #1 @ r0 += 1 swi #0 -.rest_of_exec: +rest_of_exec: @ r8 points to seven ints + string mov r7, r9 @ r7 = original SP - ldr r6, [r7] @ argc - add r6, r6, #2 @ argc + 2 + ldr r6, [r7], #8 @ argc & terminator lsl r6, r6, #2 @ argc *= 4 add r7, r7, r6 @ now past argv -.skipenv: - ldr r6, [r7], #4 @ r6 = *r7++ - cmp r6, #0 @ r6? - bne .skipenv @ r6? -.one_auxv: - ldr r6, [r7], #8 @ r6 = *r7, r7 += 2 - cmp r6, #0 @ !r6? - beq .cleanup @ r6? - cmp r6, #3 @ is AT_PHDR? - beq .replace_phdr @ replace - cmp r6, #4 @ is AT_PHENT? - beq .replace_phent @ replace - cmp r6, #5 @ is AT_PHNUM? - beq .replace_phnum @ replace - cmp r6, #9 @ is AT_ENTRY? - beq .replace_entry @ replace - cmp r6, #7 @ is AT_BASE? - beq .replace_base @ replace - b .one_auxv @ next auxv -.replace_phdr: - ldr r6, [r8, #20] @ at_phdr - str r6, [r7, #-4] @ store value - b .one_auxv -.replace_phent: - ldr r6, [r8, #12] @ at_phent - str r6, [r7, #-4] @ store value - b .one_auxv -.replace_phnum: - ldr r6, [r8, #16] @ at_phnum - str r6, [r7, #-4] @ store value - b .one_auxv -.replace_entry: - ldr r6, [r8, #8] @ at_entry - str r6, [r7, #-4] @ store value - b .one_auxv -.replace_base: - ldr r6, [r8, #24] @ at_base - str r6, [r7, #-4] @ store value - b .one_auxv -.cleanup: + ldr r6, [r8, #28] @ length of string + add r6, r6, #1 +skip_environ: +1: ldr r1, [r7], #4 @ r1 = *r7++ + tst r1, r1 @ r1 + bne 1b @ r1 +1: ldm r7!, {r0, r1} @ a_type, a_un.a_val + tst r0, r0 + bne 1b @ a_type -> 1b + @@ Establish the number of bytes in the argument, environment, + @@ and auxiliary vectors to be moved. + sub r5, r7, r9 @ r5 = bytes in vectors + @@ Expand r7 with sufficient space for the filename and align + @@ it. + sub r4, r7, r5 + and r4, r4, #-8 @ r4 = address of AT_EXECFN + sub r3, r4, r5 @ r4 - number of bytes in vectors + and r3, r3, #-16 @ r3 = position of new argc + @@ Reserve an area that is guaranteed not to be clobbered into + @@ which to copy the command and file name. + mov r2, r3 + cmp r2, r8 + blo 1f + mov r2, r8 +1: sub r2, r2, #24 @ space for data + @@ [r2, #0] = entry + @@ [r2, #4] = at_entry + @@ [r2, #8] = at_phent + @@ [r2, #12] = at_phnum + @@ [r2, #16] = at_phdr + @@ [r2, #20] = at_base + add r7, r8, #4 @ &cmd->entry + ldm r7!, {r0, r1} + stm r2!, {r0, r1} + ldm r7!, {r0, r1} + stm r2!, {r0, r1} + ldm r7!, {r0, r1} + stm r2!, {r0, r1} + sub r2, r2, #24 + sub r0, r2, r6 @ r0 = copy of AT_EXECFN + add r1, r8, #32 @ src + add r5, r1, r6 @ src end + cmp r1, r5 + bcs copy_env_and_args +1: ldrb r7, [r1], #1 + strb r7, [r0], #1 + cmp r1, r5 + blo 1b +copy_env_and_args: + mov r5, r3 +1: ldr r0, [r9], #4 @ argc and arguments + str r0, [r5], #4 @ *dst = ... + tst r0, r0 + bne 1b +1: ldr r0, [r9], #4 @ environment string + str r0, [r5], #4 @ *dst = ... + tst r0, r0 + bne 1b +copy_auxv: + ldm r9!, {r0, r1} @ a_type, a_un.a_val + tst r0, r0 @ AT_NULL + beq 8f + cmp r0, #3 @ AT_PHDR + beq 2f + cmp r0, #4 @ AT_PHENT + beq 3f + cmp r0, #5 @ AT_PHNUM + beq 4f + cmp r0, #9 @ AT_ENTRY + beq 5f + cmp r0, #7 @ AT_BASE + beq 6f + cmp r0, #31 @ AT_EXECFN + beq 7f +1: stm r5!, {r0, r1} + b copy_auxv +2: ldr r1, [r2, #16] + b 1b +3: ldr r1, [r2, #8] + b 1b +4: ldr r1, [r2, #12] + b 1b +5: ldr r1, [r2, #4] + b 1b +6: ldr r1, [r2, #20] + b 1b +7: mov r1, r4 + b 1b +8: + stm r5!, {r0, r1} +cleanup: + @@ Copy the filename. + sub r0, r2, r6 @ src + add r1, r0, r6 @ src end + cmp r0, r1 + bcs 2f +1: ldrb r5, [r0], #1 + strb r5, [r4], #1 @ *dst++ + cmp r0, r1 + blo 1b +2: mov r9, r3 @ replace original SP cmp r14, #-1 @ secondary fd set? - bne .cleanup1 @ not set + beq cleanup1 @ not set mov r7, #6 @ SYS_close mov r0, r14 @ secondary fd swi #0 @ syscall -.cleanup1: +cleanup1: mov r7, #6 @ SYS_close mov r0, r10 @ primary fd swi #0 @ syscall -.enter: +enter: mov sp, r9 @ restore original SP mov r0, #0 @ clear rtld_fini - ldr r1, [r8, #4] @ branch to code + ldr r1, [r2] @ branch to code bx r1 -timespec: - .long 10 - .long 10 +@@ timespec: +@@ .long 10 +@@ .long 10 @ Local Variables: @ asm-comment-char: ?@ diff --git a/exec/loader-mips64el.s b/exec/loader-mips64el.s index 491b7ccfb60..2f20c2cf5d3 100644 --- a/exec/loader-mips64el.s +++ b/exec/loader-mips64el.s @@ -17,32 +17,38 @@ include(`config-mips.m4') +/* These "registers" alias a4-a7 and caution must be exercised not + to overwrite them when issuing system calls. */ +define(`T4', `$a4') +define(`T5', `$a5') +define(`T6', `$a6') +define(`T7', `$a7') + .set noreorder # delay slots managed by hand - .set noat # no assembler macros .section .text .global __start __start: -dnl li $v0, 5034 # SYS_nanosleep -dnl dla $a0, .timespec # rqtp -dnl li $a1, 0 # rmtp -dnl syscall # syscall - ld $s2, ($sp) # original stack pointer + ## li $v0, 5034 # SYS_nanosleep + ## dla $a0, timespec # rqtp + ## li $a1, 0 # rmtp + ## syscall # syscall + ld $s6, ($sp) # original stack pointer DADDI3( $s0, $sp, 16) # start of load area DADDI2( $sp, -16) # primary fd, secondary fd li $t0, -1 # secondary fd sd $t0, 8($sp) # initialize secondary fd -.next_action: +next_action: ld $s1, ($s0) # action number andi $t0, $s1, 15 # t0 = action number & 15 - beqz $t0, .open_file # open file? + beqz $t0, open_file # open file? nop # delay slot DADDI2( $t0, -3) # t0 -= 3 - beqz $t0, .rest_of_exec # jump to code + beqz $t0, rest_of_exec # jump to code nop # delay slot li $t1, 1 - beq $t0, $t1, .do_mmap_anon # anonymous mmap? + beq $t0, $t1, do_mmap_anon # anonymous mmap? nop # delay slot -.do_mmap: +do_mmap: ld $t0, 8($s0) # vm address ld $t1, 16($s0) # file_offset ld $t2, 24($s0) # protection @@ -50,10 +56,10 @@ dnl syscall # syscall ld $v0, 40($s0) # flags ld $v1, ($sp) # primary fd andi $s3, $s1, 16 # s1 & 16? - beqz $s3, .do_mmap_1 # secondary fd? + beqz $s3, do_mmap_1 # secondary fd? nop # delay slot ld $v1, 8($sp) # secondary fd -.do_mmap_1: +do_mmap_1: move $a0, $t0 # syscall arg move $a1, $t3 # syscall arg move $a2, $t2 # syscall arg @@ -62,21 +68,21 @@ dnl syscall # syscall move $a5, $t1 # syscall arg li $v0, 5009 # SYS_mmap syscall # syscall - bne $a3, $zero, .perror # perror? + bne $a3, $zero, perror # perror? nop # delay slot ld $t1, 48($s0) # clear dadd $t0, $a0, $a1 # t0 = end of mapping dsub $t1, $t0, $t1 # t1 = t0 - clear -.align: - beq $t0, $t1, .continue # already finished +align: + beq $t0, $t1, continue # already finished nop # delay slot andi $t2, $t1, 7 # t1 & 7? - bnez $t2, .filld # start filling longs + bnez $t2, filld # start filling longs nop # delay slot -.filld: +filld: dsub $t2, $t0, $t1 # t2 = t0 - t1 sltiu $t2, $t2, 64 # t2 < 64? - bne $t2, $zero, .fillb # fill bytes + bne $t2, $zero, fillb # fill bytes nop # delay slot sd $zero, ($t1) # zero doubleword DADDI2( $t1, 8) # next doubleword @@ -94,140 +100,258 @@ dnl syscall # syscall DADDI2( $t1, 8) # next doubleword sd $zero, ($t1) # zero doubleword DADDI2( $t1, 8) # next doubleword - j .filld # fill either doubleword or byte + j filld # fill either doubleword or byte nop # delay slot -.fillb: - beq $t0, $t1, .continue # already finished? +fillb: + beq $t0, $t1, continue # already finished? nop # delay slot sb $zero, ($t1) # clear byte DADDI2( $t1, 1) # t1++ -.continue: +continue: DADDI2( $s0, 56) # s0 = next action - j .next_action # next action + j next_action # next action nop # delay slot -.do_mmap_anon: +do_mmap_anon: ld $t0, 8($s0) # vm address ld $t1, 16($s0) # file_offset ld $t2, 24($s0) # protection ld $t3, 32($s0) # length ld $v0, 40($s0) # flags - li $v1, -1 # fd - j .do_mmap_1 # do mmap + dli $v1, -1 # fd + j do_mmap_1 # do mmap nop # branch delay slot -.open_file: - li $v0, 5002 # SYS_open +open_file: + dli $v0, 5002 # SYS_open DADDI3( $a0, $s0, 8) # start of name move $a1, $zero # flags = O_RDONLY move $a2, $zero # mode = 0 syscall # syscall - bne $a3, $zero, .perror # perror + bne $a3, $zero, perror # perror nop # delay slot DADDI2( $s0, 8) # start of string move $t3, $s0 # t3 = s0 -.nextc: +nextc: lb $t0, ($s0) # load byte DADDI2( $s0, 1) # s0++ - li $t1, 47 # directory separator `/' - bne $t0, $t1, .nextc1 # is separator char? + dli $t1, 47 # directory separator `/' + bne $t0, $t1, nextc1 # is separator char? nop # delay slot move $t3, $s0 # t3 = char past separator -.nextc1: - bnez $t0, .nextc # next character? +nextc1: + bnez $t0, nextc # next character? nop # delay slot DADDI2( $s0, 7) # adjust for round - li $t2, -8 # t2 = -8 + dli $t2, -8 # t2 = -8 and $s0, $s0, $t2 # mask for round andi $t0, $s1, 16 # t1 = s1 & 16 move $t1, $sp # address of primary fd - beqz $t0, .primary # primary fd? + beqz $t0, primary # primary fd? nop # delay slot DADDI2( $t1, 8) # address of secondary fd sd $v0, ($t1) # store fd - j .next_action # next action + j next_action # next action nop # delay slot -.primary: +primary: sd $v0, ($t1) # store fd - li $v0, 5153 # SYS_prctl - li $a0, 15 # PR_SET_NAME + dli $v0, 5153 # SYS_prctl + dli $a0, 15 # PR_SET_NAME move $a1, $t3 # char past separator move $a2, $zero # a2 move $a3, $zero # a3 move $a4, $zero # a4 move $a5, $zero # a5 syscall # syscall - j .next_action # next action + j next_action # next action nop # delay slot -.perror: +perror: move $a0, $v0 # errno - li $v0, 5058 # SYS_exit + dli $v0, 5058 # SYS_exit syscall # syscall -.rest_of_exec: - move $s1, $s2 # original SP +rest_of_exec: + move $s1, $s6 # original SP ld $t0, ($s1) # argc dsll $t0, $t0, 3 # argc *= 8 DADDI2( $t0, 16) # argc += 16 dadd $s1, $s1, $t0 # s1 = start of envp -.skipenv: - ld $t0, ($s1) # t0 = *s1 - DADDI2( $s1, 8) # s1++ - bne $t0, $zero, .skipenv # skip again - nop # delay slot - dla $t3, .auxvtab # address of auxv table -.one_auxv: - ld $t0, ($s1) # t0 = auxv type - li $t1, 10 # t1 = 10 - beqz $t0, .finish # is AT_IGNORE? - nop # delay slot - sltu $t1, $t0, $t1 # t1 = t0 < num offsets - beqz $t1, .next # next auxv - nop # delay slot - dsll $t1, $t0, 2 # t1 = t0 * 4 - dadd $t1, $t3, $t1 # t1 = .auxvtab + t1 - lw $t2, ($t1) # t2 = *t1 - beqz $t2, .next # skip auxv - nop # delay slot - dadd $t2, $s0, $t2 # t2 = s0 + t2 - ld $t2, ($t2) # t2 = *t2 - sd $t2, 8($s1) # set auxv value -.next: - DADDI2( $s1, 16) # next auxv - j .one_auxv # next auxv - nop # delay slot -.finish: - ld $t0, 8($sp) # secondary fd +skip_environ: + /* Locate the auxiliary vector. */ + li $t8, 8 # DADDI2 isn't appropriate in delay slots. +1: ld $t0, ($s1) # t0 = *s1 + bnez $t0, 1b # skip environment entry + dadd $s1, $s1, $t8 # s1++ + move $s2, $s1 # s2 = end of environment + li $t8, 16 +1: ld $t0, ($s1) # t0 = s1->a_type + bnez $t0, 1b # skip auxiliary vector entry + dadd $s1, $s1, $t8 # (Elf64_auxv_t *) s1++ + /* Decide how many bytes must be copied and where to + save the file name. Move the stack pointer to a safe + position below any data that must be preserved. */ + ld $t1, 56($s0) # length of string + DADDI2( $t1, 1) + DADDI3( $t2, $s0, 64) # pointer to string + dsub $t3, $s1, $s6 # number of bytes in vectors + dsub $t0, $s1, $t1 # position of string + and $t0, $t0, -16 # align value + dsub $t3, $t0, $t3 # position of argc + and $t3, $t3, -16 # align value + /* Move the stack pointer and save required information. + 8($fp) = secondary/interpreter fd. + 0($fp) = primary/executable fd. + -8($fp) = cmd->entry + -16($fp) = cmd->at_entry + -24($fp) = cmd->at_phent + -32($fp) = cmd->at_phnum + -40($fp) = cmd->at_phdr + -48($fp) = cmd->at_base + $sp = copy of string. */ + move T4, $sp # current sp + dsub T5, $t3, $sp # new argc - current sp + li $t8, -16 + blt T5, 16, 1f # more than two slots apart + dadd $sp, $t3, $t8 # $sp = two slots below new argc + j 2f # skip copying fds + move $sp, T4 # retain current sp +1: ld T5, (T4) # old primary fd + ld T5, ($sp) # save the same + ld T5, 8(T4) # old interpreter fd + sd T5, 8($sp) # save the same +2: move $fp, $sp # set base pointer + DADDI2( $sp, -48) # command data + ld T5, 8($s0) # entry + ld T6, 16($s0) # at_entry + ld T7, 24($s0) # at_phent + ld $t8, 32($s0) # at_phnum + sd T5, -8($fp) # save entry + ld T5, 40($s0) # at_phdr + sd T6, -16($fp) # save at_entry + ld T6, 48($s0) # at_base + sd T7, -24($fp) # save at_phent + sd $t8, -32($fp) # save at_phnum + sd T5, -40($fp) # save at_phdr + sd T6, -48($fp) # save at_base + dsub $sp, $sp, $t1 # space for string + /* Save the input string. */ + dadd T5, $t2, $t1 # end of source ($t2) + move T6, $sp # dst + move $s0, $t1 # $s0 = length of string + /* src = $t2, dst = T6 */ + bgeu $t2, T5, 2f # there already? + nop +1: lb $t1, ($t2) # $t1 = *$t2 + DADDI2( $t2, 1) # $t2++ + DADDI2( T6, 1) # $t6++ + bltu $t2, T5, 1b + sb $t1, -1(T6) # *(T6 - 1) = $t1 +2: move $s3, $sp # copy of string + and $sp, $sp, -16 # align stack +copy_env_and_args: + /* Copy argc, argv, and the environment array. + T4 = destination, T5 = src, $s2 = src_end */ + move T4, $t3 # destination of argc + move T5, $s6 # original SP + bgeu T5, $s2, 2f # there already? + nop +1: ld $t1, (T5) # $t1 = *src + DADDI2( T5, 8) # src++ + DADDI2( T4, 8) # dst++ + bltu T5, $s2, 1b # src < src_end + sd $t1, -8(T4) # *(dst - 8) = $t1 +copy_auxv: + /* T4 = destination, T5 = first auxval. */ +2: ld $t1, (T5) # a_type + ld $t2, 8(T5) # a_un.a_val + DADDI2( T4, 16) # (Elf64_auxv_t *) dst++ + DADDI2( T5, 16) # (Elf64_auxv_t *) src + beqz $t1, 8f # AT_NULL + li T6, 3 + beq $t1, T6, 1f # AT_PHDR + li T6, 4 + beq $t1, T6, 2f # AT_PHENT + li T6, 5 + beq $t1, T6, 3f # AT_PHNUM + li T6, 9 + beq $t1, T6, 4f # AT_ENTRY + li T6, 7 + beq $t1, T6, 5f # AT_BASE + li T6, 31 + beq $t1, T6, 6f # AT_EXECFN + nop + b 7f + nop +1: b 7f + ld $t2, -40($fp) +2: b 7f + ld $t2, -24($fp) +3: b 7f + ld $t2, -32($fp) +4: b 7f + ld $t2, -16($fp) +5: b 7f + ld $t2, -48($fp) +6: b 7f + move $t2, $t0 +7: sd $t1, -16(T4) # dst->a_type + j copy_auxv + sd $t2, -8(T4) # dst->a_un.a_val + /* Copy the final element. */ +8: sd $t1, -16(T4) # dst->a_type + sd $t2, -8(T4) # dst->a_un.a_val +finish: + /* Copy the string to its position in auxv + (src = $s3, dst = $t0). */ + dadd $t1, $s3, $s0 # src end + bgeu $s3, $t1, 2f # there already? + nop +1: lb $t2, ($s3) # c = *src + DADDI2( $s3, 1) # src++ + DADDI2( $t0, 1) # dst++ + bltu $s3, $t1, 1b + sb $t2, -1($t0) # *(dst - 1) = c + /* Save variables. */ +2: move $s6, $t3 # new stack pointer + ld $t0, 8($fp) # secondary fd li $t1, -1 # t1 = -1 - ld $s1, ($sp) # s1 = primary fd + ld $s1, ($fp) # s1 = primary fd + beq $t0, $t2, finish1 # secondary fd set? li $v0, 5003 # SYS_close - beq $t0, $t2, .finish1 # secondary fd set? - nop # delay slot move $a0, $t0 # secondary fd syscall # syscall li $v0, 5003 # SYS_close -.finish1: +finish1: move $a0, $s1 # primary fd syscall # syscall -.jump: +jump: move $v0, $zero # rtld_fini - ld $t0, 8($s0) # entry - move $sp, $s2 # restore stack pointer, delay slot - jr $t0 # enter + ld $t9, -8($fp) # entry + move $sp, $s6 # restore stack pointer, delay slot + /* Clear at least one page's worth of stack. glibc on mipsel + copies certain fields from the stack to the `link_map' + structure representing ld.so, which are not subsequently + replaced if otherwise than zero. + + XXX: report this glibc bug? */ + DADDI3( $v0, $sp, -4096) + and $v0, $v0, -4095 +1: sd $zero, ($v0) # copy 32 byte blocks + sd $zero, 8($v0) + sd $zero, 16($v0) + sd $zero, 24($v0) + DADDI2( $v0, 32) + dsub $t0, $sp, $v0 # remainder + bge $t0, 32, 1b # test remainder + nop # copy 4 byte blocks + beqz $t0, 2f + nop +1: DADDI2( $v0, 4) + bltu $v0, $sp, 1b + sw $zero, -4($v0) +2: jr $t9 # enter nop # delay slot -.auxvtab: - .long 0 # 0 - .long 0 # 1 - .long 0 # 2 - .long 40 # 3 AT_PHDR - .long 24 # 4 AT_PHENT - .long 32 # 5 AT_PHNUM - .long 0 # 6 - .long 48 # 7 AT_BASE - .long 0 # 8 - .long 16 # 9 AT_ENTRY - -.timespec: - .quad 10 - .quad 10 +## timespec: +## .quad 10 +## .quad 10 # Local Variables: # asm-comment-char: ?# diff --git a/exec/loader-mipsel.s b/exec/loader-mipsel.s index 9ffe7e928e7..92239614de3 100644 --- a/exec/loader-mipsel.s +++ b/exec/loader-mipsel.s @@ -17,32 +17,32 @@ include(`config-mips.m4') -# Make sure not to use t4 through t7, in order to maintain portability -# with N32 ABI systems. +## Beware: $t0-$t4 alias the syscall (and function, but they are not +## material in this context) argument registers on N32 systems, and +## mustn't be relied upon to hold arguments to `SYSCALL'. .set noreorder # delay slots managed by hand .section .text .global __start __start: -dnl li $v0, SYSCALL_nanosleep # SYS_nanosleep -dnl la $a0, .timespec # rqtp -dnl li $a1, 0 # rmtp -dnl syscall # syscall + ## li $v0, SYSCALL_nanosleep # SYS_nanosleep + ## la $a0, timespec # rqtp + ## li $a1, 0 # rmtp + ## syscall # syscall lw $s6, ($sp) # original stack pointer addi $s0, $sp, 8 # start of load area addi $sp, -8 # primary fd, secondary fd li $t0, -1 # secondary fd sw $t0, 4($sp) # initialize secondary fd -.next_action: +next_action: lw $s2, ($s0) # action number - nop # delay slot andi $t0, $s2, 15 # t0 = s2 & 15 - beqz $t0, .open_file # open file? + beqz $t0, open_file # open file? li $t1, 3 # t1 = 3, delay slot - beq $t0, $t1, .rest_of_exec # jump to code + beq $t0, $t1, rest_of_exec # jump to code li $t1, 4 # t1 = 4, delay slot - beq $t0, $t1, .do_mmap_anon # anonymous mmap -.do_mmap: + beq $t0, $t1, do_mmap_anon # anonymous mmap +do_mmap: lw $a0, 4($s0) # vm_address, delay slot lw $v1, 8($s0) # file_offset lw $a2, 12($s0) # protection @@ -50,33 +50,33 @@ dnl syscall # syscall lw $a3, 20($s0) # flags lw $v0, ($sp) # primary fd andi $t1, $s2, 16 # t1 = s2 & 16 - beqz $t1, .do_mmap_1 # secondary fd? + beqz $t1, do_mmap_1 # secondary fd? nop # delay slot lw $v0, 4($sp) # secondary fd nop # delay slot -.do_mmap_1: +do_mmap_1: SYSCALL(`$v0',`$v1',`$zero',`$zero') # syscall args li $v0, SYSCALL_mmap # SYS_mmap syscall # syscall - bne $a3, $zero, .perror # perror + bnez $a3, perror # perror RESTORE() # delay slot, restore sp lw $s5, 24($s0) # clear add $t0, $a0, $a1 # t0 = length + vm_address, delay slot sub $t1, $t0, $s5 # t1 = t0 - clear -.align: - beq $t0, $t1, .continue # already finished? +align: + beq $t0, $t1, continue # already finished? nop # delay slot andi $t2, $t1, 3 # t1 & 3? - bnez $t2, .fillw # start filling longs + bnez $t2, fillw # start filling longs nop # delay slot sb $zero, ($t1) # clear byte addi $t1, $t1, 1 # t1++ - j .align # continue + j align # continue nop # delay slot -.fillw: +fillw: sub $t2, $t0, $t1 # t2 = t0 - t1 sltiu $t2, $t2, 32 # r2 < 32? - bne $t2, $zero, .fillb # fill bytes + bne $t2, $zero, fillb # fill bytes nop # delay slot sw $zero, ($t1) # zero word addi $t1, $t1, 4 # next word @@ -94,53 +94,52 @@ RESTORE() # delay slot, restore sp addi $t1, $t1, 4 # next word sw $zero, ($t1) # zero word addi $t1, $t1, 4 # next word - j .fillw # fill either word or byte + j fillw # fill either word or byte nop # delay slot -.fillb: - beq $t0, $t1, .continue # already finished? +fillb: + beq $t0, $t1, continue # already finished? nop # delay slot sb $zero, ($t1) # clear byte addi $t1, $t1, 1 # t1++ -.continue: +continue: addi $s0, $s0, 28 # s0 = next action - j .next_action # next action + j next_action # next action nop # delay slot -.do_mmap_anon: +do_mmap_anon: lw $v1, 8($s0) # file_offset lw $a2, 12($s0) # protection lw $a1, 16($s0) # length lw $a3, 20($s0) # flags - li $t4, -1 # fd - j .do_mmap_1 # do mmap - nop # delay slot -.open_file: + j do_mmap_1 # do mmap + li $v0, -1 # fd, delay slot +open_file: li $v0, SYSCALL_open # SYS_open addi $a0, $s0, 4 # start of name move $a1, $zero # flags = O_RDONLY move $a2, $zero # mode = 0 syscall # syscall - bne $a3, $zero, .perror # perror + bne $a3, $zero, perror # perror addi $s0, $s0, 4 # start of string, delay slot move $t3, $s0 # t3 = char past separator -.nextc: +nextc: lb $t0, ($s0) # load byte addi $s0, $s0, 1 # s0++ li $t1, 47 # directory separator `/' - bne $t0, $t1, .nextc1 # is separator char? + bne $t0, $t1, nextc1 # is separator char? nop # delay slot move $t3, $s0 # t3 = char past separator -.nextc1: - bnez $t0, .nextc # next character? +nextc1: + bnez $t0, nextc # next character? nop # delay slot addi $s0, $s0, 3 # adjust for round li $t2, -4 # t2 = -4 and $s0, $s0, $t2 # mask for round andi $t0, $s2, 16 # t1 = s2 & 16 - beqz $t0, .primary # primary fd? + beqz $t0, primary # primary fd? move $t0, $sp # address of primary fd, delay slot addi $t0, $t0, 4 # address of secondary fd - j .next_action # next action -.primary: + j next_action # next action +primary: sw $v0, ($t0) # store fd, delay slot li $v0, SYSCALL_prctl # SYS_prctl li $a0, 15 # PR_SET_NAME @@ -150,86 +149,208 @@ RESTORE() # delay slot, restore sp SYSCALL(`$a2',`$a2',`$a2',`$a2') # syscall args syscall # syscall RESTORE() # restore sp - j .next_action # next action + j next_action # next action nop # delay slot -.perror: +perror: move $a0, $v0 # errno li $v0, SYSCALL_exit # SYS_exit syscall # syscall -.rest_of_exec: +rest_of_exec: move $s1, $s6 # s1 = original SP lw $t0, ($s1) # argc - nop # delay slot sll $t0, $t0, 2 # argc *= 4 addi $t0, $t0, 8 # argc += 8 add $s1, $s1, $t0 # s1 = start of envp -.skipenv: - lw $t0, ($s1) # t0 = *s1 +skip_environ: + /* Locate the auxiliary vector. */ +1: lw $t0, ($s1) # t0 = *s1 + bnez $t0, 1b # skip environment entry addi $s1, $s1, 4 # s1++ - bne $t0, $zero, .skipenv # skip again - nop # delay slot - la $s2, .auxvtab # address of auxv table -.one_auxv: - lw $t0, ($s1) # t0 = auxv type - li $t1, 10 # t1 = 10, delay slot - beqz $t0, .finish # is AT_IGNORE? - sltu $t1, $t0, $t1 # t1 = t0 < num offsets, delay slot - beq $t1, $zero, .next # next auxv - sll $t1, $t0, 2 # t1 = t0 * 4, delay slot - add $t1, $s2, $t1 # t1 = .auxvtab + t1 - lw $t2, ($t1) # t2 = *t1 - nop # delay slot - beqz $t2, .next # skip auxv - add $t2, $s0, $t2 # t2 = s0 + t2 - lw $t2, ($t2) # t2 = *t2 - nop # delay slot - sw $t2, 4($s1) # set auxv value -.next: - addi $s1, $s1, 8 # next auxv - j .one_auxv # next auxv - nop # delay slot -.finish: - lw $t0, 4($sp) # secondary fd - lw $s1, ($sp) # primary fd, delay slot, preserved + move $s2, $s1 # $s2 = end of environment +1: lw $t0, ($s1) # t0 = *s1 + bnez $t0, 1b # skip auxiliary vector entry + addi $s1, $s1, 8 # (Elf32_auxv_t *) s1++ + /* Decide how many bytes must be copied and where to + save the file name. Move the stack pointer to a safe + position below any data that must be preserved. */ + lw $t1, 32($s0) # length of string + addi $t1, $t1, 1 + addi $t2, $s0, 36 # pointer to string + sub $t3, $s1, $s6 # number of bytes in vectors + sub $t0, $s1, $t1 # position of string + and $t0, $t0, -16 # align value + sub $t3, $t0, $t3 # position of argc + and $t3, $t3, -16 # align value + /* Move the stack pointer and save required information. + 4(FP) = secondary/interpreter fd. + 0(FP) = primary/executable fd. + -4(FP) = cmd->entry + -8(FP) = cmd->at_entry + -12(FP) = cmd->at_phent + -16(FP) = cmd->at_phnum + -20(FP) = cmd->at_phdr + -24(FP) = cmd->at_base + -28(FP) = cmd->fpu_mode (only significant when N32) + $sp = copy of string. */ + move $t4, $sp # current sp + sub $t5, $t3, $sp # new argc - current sp + blt $t5, 8, 1f # more than two slots apart + addi $sp, $t3, -8 # $sp = two slots below new argc + j 2f # skip copying fds + move $sp, $t4 # retain current sp +1: lw $t5, ($t4) # old primary fd + sw $t5, ($sp) # save the same + lw $t5, 4($t4) # old interpreter fd + sw $t5, 4($sp) # save the same +2: move FP, $sp # set base pointer + addi $sp, $sp, -28 # command data + lw $t5, 4($s0) # entry + lw $t6, 8($s0) # at_entry + sw $t5, -4(FP) # save entry + sw $t6, -8(FP) # save at_entry + lw $t5, 12($s0) # at_phent + lw $t6, 16($s0) # at_phnum + sw $t5, -12(FP) # save at_phent + sw $t6, -16(FP) # save at_phnum + lw $t5, 20($s0) # at_phdr + lw $t6, 24($s0) # at_base + sw $t5, -20(FP) # save at_phdr + sw $t6, -24(FP) # save at_base + lw $t5, 28($s0) # fpu_mode + sw $t5, -28(FP) # save fpu_mode + sub $sp, $sp, $t1 # space for string + /* Save the input string. */ + add $t5, $t2, $t1 # end of source ($t2) + move $t6, $sp # dst + move $s0, $t1 # $s0 = length of string + /* src = $t2, dst = $t6 */ + bgeu $t2, $t5, 2f # there already? + nop +1: lb $t1, ($t2) # $t1 = *$t2 + addi $t2, $t2, 1 # $t2++ + addi $t6, $t6, 1 # $t6++ + bltu $t2, $t5, 1b + sb $t1, -1($t6) # *($t6 - 1) = $t1 +2: move $s3, $sp # copy of string + and $sp, $sp, -16 # align stack +copy_env_and_args: + /* Copy argc, argv, and the environment array. + $t4 = destination, $t5 = src, $s2 = src_end */ + move $t4, $t3 # destination of argc + move $t5, $s6 # original SP + bgeu $t5, $s2, 2f # there already? + nop +1: lw $t1, ($t5) # $t1 = *src + addi $t5, $t5, 4 # src++ + addi $t4, $t4, 4 # dst++ + bltu $t5, $s2, 1b # src < src_end + sw $t1, -4($t4) # *(dst - 4) = $t1 +copy_auxv: + /* $t4 = destination, $t5 = first auxval. */ +2: lw $t1, ($t5) # a_type + lw $t2, 4($t5) # a_un.a_val + addi $t4, $t4, 8 # (Elf32_auxv_t *) dst++ + addi $t5, $t5, 8 # (Elf32_auxv_t *) src++ + beqz $t1, 8f # AT_NULL + li $t6, 3 + beq $t1, $t6, 1f # AT_PHDR + li $t6, 4 + beq $t1, $t6, 2f # AT_PHENT + li $t6, 5 + beq $t1, $t6, 3f # AT_PHNUM + li $t6, 9 + beq $t1, $t6, 4f # AT_ENTRY + li $t6, 7 + beq $t1, $t6, 5f # AT_BASE + li $t6, 31 + beq $t1, $t6, 6f # AT_EXECFN + nop + b 7f + nop +1: b 7f + lw $t2, -20(FP) +2: b 7f + lw $t2, -12(FP) +3: b 7f + lw $t2, -16(FP) +4: b 7f + lw $t2, -8(FP) +5: b 7f + lw $t2, -24(FP) +6: b 7f + move $t2, $t0 +7: sw $t1, -8($t4) # dst->a_type + j copy_auxv + sw $t2, -4($t4) # dst->a_un.a_val + /* Copy the final element. */ +8: sw $t1, -8($t4) # dst->a_type + sw $t2, -4($t4) # dst->a_un.a_val +finish: + /* Copy the string to its position in auxv + (src = $s3, dst = $t0). */ + add $t1, $s3, $s0 # src end + bgeu $s3, $t1, 2f # there already? + nop +1: lb $t2, ($s3) # c = *src + addi $s3, $s3, 1 # *src++ + addi $t0, $t0, 1 # dst++ + bltu $s3, $t1, 1b + sb $t2, -1($t0) # *(dst - 1) = c + /* Save variables. */ +2: move $s6, $t3 # new stack pointer + lw $t4, 4(FP) # secondary fd + lw $s1, (FP) # primary fd, delay slot, preserved li $t2, -1 # immediate -1 - beq $t0, $t2, .finish1 # secondary fd set? + beq $t4, $t2, finish1 # secondary fd set? li $v0, SYSCALL_close # SYS_close, delay slot - move $a0, $t0 # fd + move $a0, $t4 # fd syscall # syscall li $v0, SYSCALL_close # SYS_close -.finish1: +finish1: move $a0, $s1 # primary fd syscall # syscall li $v0, SYSCALL_prctl # SYS_prctl li $a0, 45 # PR_SET_FP_MODE - lw $a1, 28($s0) # fpu_mode + lw $a1, -28(FP) # fpu_mode move $a2, $zero # arg3 move $a3, $zero # arg4 SYSCALL(`$a2',`$a2',`$a2',`$a2') # syscall args syscall # syscall RESTORE() # restore sp -.jump: +jump: move $v0, $zero # rtld_fini - lw $t0, 4($s0) # entry + lw $t9, -4(FP) # entry move $sp, $s6 # restore stack pointer, delay slot - jr $t0 # enter + /* Clear at least one page's worth of stack. glibc on mipsel + copies certain fields from the stack to the `link_map' + structure representing ld.so, which are not subsequently + replaced if otherwise than zero. + + XXX: report this glibc bug? */ + addi $v0, $sp, -4096 + and $v0, $v0, -4095 +1: sw $zero, ($v0) # copy 32 byte blocks + sw $zero, 4($v0) + sw $zero, 8($v0) + sw $zero, 12($v0) + sw $zero, 16($v0) + sw $zero, 20($v0) + sw $zero, 24($v0) + sw $zero, 28($v0) + addi $v0, $v0, 32 + sub $t0, $sp, $v0 # remainder + bge $t0, 32, 1b # test remainder + nop # copy 4 byte blocks + beqz $t0, 2f +1: addi $v0, $v0, 4 + bltu $v0, $sp, 1b + sw $zero, -4($v0) +2: jr $t9 # enter nop # delay slot -.auxvtab: - .long 0 # 0 - .long 0 # 1 - .long 0 # 2 - .long 20 # 3 AT_PHDR - .long 12 # 4 AT_PHENT - .long 16 # 5 AT_PHNUM - .long 0 # 6 - .long 24 # 7 AT_BASE - .long 0 # 8 - .long 8 # 9 AT_ENTRY - -.timespec: - .long 10 - .long 10 +## timespec: +## .long 10 +## .long 10 # Local Variables: # asm-comment-char: ?# diff --git a/exec/loader-x86.s b/exec/loader-x86.s index 5e5bb7253ab..d9cfa28f6a3 100644 --- a/exec/loader-x86.s +++ b/exec/loader-x86.s @@ -15,26 +15,29 @@ # You should have received a copy of the GNU General Public License # along with GNU Emacs. If not, see . +/* Sorry! This program is a hopeless shambles in consequence of + being hastily written in under twenty minutes with minimal testing. */ + .section .text .global _start _start: -# movl $162, %eax # SYS_nanosleep -# leal timespec, %ebx -# xorl %ecx, %ecx -# int $0x80 + ## movl $162, %eax # SYS_nanosleep + ## leal timespec, %ebx + ## xorl %ecx, %ecx + ## int $0x80 leal 8(%esp), %ebp # ebp = start of load area subl $8, %esp # (%esp) = primary fd, 4(%esp) = secondary fd movl $-1, 4(%esp) -.next_action: +next_action: movl (%ebp), %edx # edx = action number andl $-17, %edx cmpl $0, %edx # open file? - je .open_file + je open_file cmpl $3, %edx # jump? - je .rest_of_exec + je rest_of_exec cmpl $4, %edx # anonymous mmap? - je .do_mmap_anon -.do_mmap: + je do_mmap_anon +do_mmap: subl $24, %esp movl $90, %eax # SYS_old_mmap movl %esp, %ebx @@ -52,27 +55,27 @@ _start: movl %ecx, 16(%esp) # fd movl 8(%ebp), %ecx # offset movl %ecx, 20(%esp) -.do_mmap_1: +do_mmap_1: int $0x80 addl $24, %esp # restore esp cmpl $-1, %eax # mmap failed? - je .perror + je perror movl 24(%ebp), %ecx # clear testl %ecx, %ecx - jz .continue + jz continue movl 4(%ebp), %esi # start of mapping addl 16(%ebp), %esi # end of mapping subl %ecx, %esi # start of clear area -.again: +again: testl %ecx, %ecx - jz .continue + jz continue subl $1, %ecx movb $0, (%esi, %ecx, 1) - jmp .again -.continue: + jmp again +continue: leal 28(%ebp), %ebp - jmp .next_action -.do_mmap_anon: + jmp next_action +do_mmap_anon: subl $24, %esp movl $90, %eax # SYS_old_mmap movl %esp, %ebx @@ -87,8 +90,8 @@ _start: movl $-1, 16(%esp) # fd movl 8(%ebp), %ecx # offset movl %ecx, 20(%esp) - jmp .do_mmap_1 -.open_file: + jmp do_mmap_1 +open_file: movl $5, %eax # SYS_open leal 4(%ebp), %ebx # ebx = %esp + 8 pushl %ebx @@ -96,27 +99,27 @@ _start: xorl %edx, %edx # mode = 0 int $0x80 cmpl $-1, %eax # open failed? - jle .perror + jle perror movl %ebp, %esi # (esi) = original action number popl %ebp # ebp = start of string movl %ebp, %ecx # char past separator decl %ebp -.nextc: +nextc: incl %ebp movb (%ebp), %dl # dl = *ebp cmpb $47, %dl # dl == '\?'? - jne .nextc1 + jne nextc1 leal 1(%ebp), %ecx # ecx = char past separator -.nextc1: +nextc1: cmpb $0, %dl # dl == 0? - jne .nextc + jne nextc addl $4, %ebp # adjust past ebp prior to rounding andl $-4, %ebp # round ebp up to the next long testl $16, (%esi) # original action number & 16? - jz .primary + jz primary movl %eax, 4(%esp) # secondary fd = eax - jmp .next_action -.primary: + jmp next_action +primary: pushl %ebp xorl %esi, %esi # arg3 movl %eax, 4(%esp) # primary fd = eax @@ -127,74 +130,168 @@ _start: xorl %ebp, %ebp # arg5 int $0x80 # syscall popl %ebp - jmp .next_action -.perror: + jmp next_action +perror: movl %eax, %ebx negl %ebx movl $1, %eax int $0x80 -.rest_of_exec: +rest_of_exec: movl 8(%esp), %ecx # ecx = original stack pointer movl (%ecx), %esi # esi = argc leal 8(%ecx, %esi, 4), %ecx # ecx = start of environ -.skip_environ: + movl (%esp), %eax # %eax = primary fd + movl 4(%esp), %edi # %edi = secondary fd +skip_environ: movl (%ecx), %esi # envp[N] addl $4, %ecx testl %esi, %esi # envp[n] ? - jnz .skip_environ # otherwise, esi is now at the start of auxv -.one_auxv: - movl (%ecx), %esi # auxv type + jnz skip_environ # otherwise, ecx is now at the end of auxv +1: testl $-1, (%ecx) # auxv type leal 8(%ecx), %ecx # skip to next auxv - testl %esi, %esi # is 0? - jz .cleanup - cmpl $3, %esi # is AT_PHDR - je .replace_phdr - cmpl $4, %esi # is AT_PHENT? - je .replace_phent - cmpl $5, %esi # is AT_PHNUM? - je .replace_phnum - cmpl $9, %esi # is AT_ENTRY? - je .replace_entry - cmpl $7, %esi # is AT_BASE - je .replace_base - jmp .one_auxv -.replace_phdr: - movl 20(%ebp), %esi + jnz 1b # otherwise copy auxv + movl %ecx, %edx # end of auxv + /* Prepare sufficient space for the new executable name at the + start of the auxiliary vector. */ +1: leal 32(%ebp), %esi # file name + /* 28(%ebp) = file name length. */ + subl 28(%ebp), %ecx # destination of file name + decl %ecx + /* This is still 16 bytes on i386--see arch_align_stack: + https://android.googlesource.com/kernel/goldfish/+/refs/heads + /android-goldfish-3.10/arch/x86/kernel/process.c#446. */ + andl $-16, %ecx # align stack + /* Prepare to store the auxiliary, environment, and argument + vectors. */ + subl 8(%esp), %edx # end of auxv to start of stack + negl %edx + andl $-16, %edx # align value + movl %ecx, (%ebp) # temporarily save ecx + addl %edx, %ecx # %ecx = new position of argc + /* Allocate a temporary stack away from any crucial data in which + to store parameters and temporaries. */ + cmpl %ecx, %ebp # select position of temporary stack + movl %ecx, %ebx # ebx = temporary stack + jge 1f # %ebx = MIN (%ecx, %edx) + movl %ebp, %ebx # ebx = temporary stack +1: movl (%ebp), %edx # edx = destination of file name + movl %edx, -4(%ebx) # -4(%ebx) = destination of file name + movl 28(%ebp), %edx # file name length + movl %edx, -8(%ebx) # -8(%ebx) = file name length + movl %ecx, -12(%ebx) # -12(%ebx) = new position of argc + movl %esi, -16(%ebx) # -16(%ebx) = file name + movl 8(%esp), %edx # %edx = initial stack pointer + leal -16(%ebx), %esp # switch to temporary stack + /* Push parameters of `struct exec_jump_command'. */ + push %edx # initial stack pointer -20(%ebx) + push 4(%ebp) # entry -24(%ebx) + push 8(%ebp) # at_entry -28(%ebx) + push 12(%ebp) # at_phent -32(%ebx) + push 16(%ebp) # at_phnum -36(%ebx) + push 20(%ebp) # at_phdr -40(%ebx) + push 24(%ebp) # at_base -44(%ebx) + /* Push primary and secondary fds. */ + push %eax # primary fd -48(%ebx) + push %edi # secondary fd -52(%ebx) + /* Swap %ebp with %ebx. */ + push %ebp + push %ebx + pop %ebp + pop %ebx # ebx is the exec_jump_command + /* Save the string lest it should be overwritten while + the environment is moved. */ + movl -8(%ebp), %ecx + subl $4, %esp # -56(%ebp) + subl %ecx, %esp + leal -1(%esp), %edi + movl %edi, -56(%ebp) # copy of string + incl %ecx + movl %edi, %esp + cld + rep movsb # complete copy + andl $-4, %esp # align stack + movl -12(%ebp), %ecx + /* Begin moving the argument vectors and environment from + the original SP to the adjusted one. */ +1: movl (%edx), %eax # argc and values + movl %eax, (%ecx) + leal 4(%ecx), %ecx + leal 4(%edx), %edx + testl %eax, %eax + jnz 1b +1: movl (%edx), %eax # envp + movl %eax, (%ecx) + leal 4(%ecx), %ecx + leal 4(%edx), %edx + testl %eax, %eax + jnz 1b +copy_auxv: + movl (%edx), %eax # a_type + movl 4(%edx), %esi # a_un.a_val + testl %eax, %eax + leal 8(%edx), %edx + movl %eax, (%ecx) # copy auxv type + leal 8(%ecx), %ecx + jz cleanup # AT_NULL + cmpl $3, %eax # AT_PHDR + jz 1f + cmpl $4, %eax # AT_PHENT + jz 2f + cmpl $5, %eax # AT_PHNUM + jz 3f + cmpl $9, %eax # AT_ENTRY + jz 4f + cmpl $7, %eax # AT_BASE + jz 5f + cmpl $31, %eax # AT_EXECFN + jz 6f movl %esi, -4(%ecx) - jmp .one_auxv -.replace_phent: - movl 12(%ebp), %esi + jmp copy_auxv +1: movl -40(%ebp), %esi movl %esi, -4(%ecx) - jmp .one_auxv -.replace_phnum: - movl 16(%ebp), %esi + jmp copy_auxv +2: movl -32(%ebp), %esi movl %esi, -4(%ecx) - jmp .one_auxv -.replace_entry: - movl 8(%ebp), %esi + jmp copy_auxv +3: movl -36(%ebp), %esi movl %esi, -4(%ecx) - jmp .one_auxv -.replace_base: - movl 24(%ebp), %esi + jmp copy_auxv +4: movl -28(%ebp), %esi movl %esi, -4(%ecx) - jmp .one_auxv -.cleanup: + jmp copy_auxv +5: movl -44(%ebp), %esi + movl %esi, -4(%ecx) + jmp copy_auxv +6: movl -4(%ebp), %esi # Note: the filename is yet to be copied. + movl %esi, -4(%ecx) + jmp copy_auxv +cleanup: + movl $0, -4(%ecx) # AT_NULL value + /* Copy data for AT_EXECFN to the destination address. */ + movl -4(%ebp), %edi + movl -56(%ebp), %esi + movl -8(%ebp), %ecx + incl %ecx + rep movsb movl $6, %eax # SYS_close - cmpl $-1, 4(%esp) # see if interpreter fd is set - je .cleanup_1 - movl 4(%esp), %ebx + cmpl $-1, -52(%ebp) # see if interpreter fd is set + je cleanup_1 + movl -52(%ebp), %ebx int $0x80 movl $6, %eax # SYS_close -.cleanup_1: - movl (%esp), %ebx +cleanup_1: + movl -48(%ebp), %ebx int $0x80 -.enter: +enter: pushl $0 popfl # restore floating point state - movl 8(%esp), %esp # restore initial stack pointer + movl -12(%ebp), %esp # restore initial stack pointer xorl %edx, %edx # clear rtld_fini - jmpl *4(%ebp) # entry + jmpl *-24(%ebp) # entry +## timespec: +## .long 10 +## .long 10 -timespec: - .long 10 - .long 10 +# Local Variables: +# asm-comment-char: ?# +# End: diff --git a/exec/loader-x86_64.s b/exec/loader-x86_64.s index 0854df98db9..9340ac8fc65 100644 --- a/exec/loader-x86_64.s +++ b/exec/loader-x86_64.s @@ -25,17 +25,17 @@ _start: popq %r13 # original SP popq %r15 # size of load area. movq $-1, %r12 # r12 is the interpreter fd -.next_action: +next_action: movq (%rsp), %r14 # action number movq %r14, %r15 # original action number andq $-17, %r14 cmpq $0, %r14 # open file? - je .open_file + je open_file cmpq $3, %r14 # jump? - je .rest_of_exec + je rest_of_exec cmpq $4, %r14 # anonymous mmap? - je .do_mmap_anon -.do_mmap: + je do_mmap_anon +do_mmap: movq $9, %rax # SYS_mmap movq 8(%rsp), %rdi # address movq 16(%rsp), %r9 # offset @@ -46,26 +46,26 @@ _start: testq $16, %r15 movq %r12, %r8 cmovzq %rbx, %r8 -.do_mmap_1: +do_mmap_1: syscall cmpq $-1, %rax # mmap failed - je .perror + je perror movq 48(%rsp), %r9 # clear testq %r9, %r9 - jz .continue + jz continue movq 8(%rsp), %r10 # start of mapping addq 32(%rsp), %r10 # end of mapping subq %r9, %r10 # start of clear area -.again: +again: testq %r9, %r9 - jz .continue + jz continue subq $1, %r9 movb $0, (%r10, %r9, 1) - jmp .again -.continue: + jmp again +continue: leaq 56(%rsp), %rsp - jmp .next_action -.do_mmap_anon: + jmp next_action +do_mmap_anon: movq $9, %rax # SYS_mmap movq 8(%rsp), %rdi # address movq 16(%rsp), %r9 # offset @@ -73,35 +73,35 @@ _start: movq 32(%rsp), %rsi # length movq 40(%rsp), %r10 # flags movq $-1, %r8 # -1 - jmp .do_mmap_1 -.open_file: + jmp do_mmap_1 +open_file: movq $2, %rax # SYS_open leaq 8(%rsp), %rdi # rdi = %rsp + 8 xorq %rsi, %rsi # flags = O_RDONLY xorq %rdx, %rdx # mode = 0 syscall cmpq $-1, %rax # open failed - jle .perror + jle perror movq %rdi, %rsp # rsp = start of string subq $1, %rsp movq %rsp, %r14 # r14 = start of string -.nextc: +nextc: addq $1, %rsp movb (%rsp), %dil # rdi = *rsp cmpb $47, %dil # *rsp == '/'? - jne .nextc1 + jne nextc1 movq %rsp, %r14 # r14 = rsp addq $1, %r14 # r14 = char past separator -.nextc1: +nextc1: cmpb $0, %dil # *rsp == 0? - jne .nextc + jne nextc addq $8, %rsp # adjust past rsp prior to rounding andq $-8, %rsp # round rsp up to the next quad testq $16, %r15 # r15 & 16? - jz .primary + jz primary movq %rax, %r12 # otherwise, move fd to r12 - jmp .next_action -.primary: + jmp next_action +primary: movq %rax, %rbx # if not, move fd to rbx movq $157, %rax # SYS_prctl movq $15, %rdi # PR_SET_NAME @@ -111,82 +111,159 @@ _start: xorq %r8, %r8 # arg4 xorq %r9, %r9 # arg5 syscall - jmp .next_action -.perror: + jmp next_action +perror: movq %rax, %r12 # error code negq %r12 movq $1, %rax # SYS_write movq $1, %rdi # stdout leaq error(%rip), %rsi # buffer - movq $23, %rdx # count + movq $24, %rdx # count syscall movq $60, %rax # SYS_exit movq %r12, %rdi # code syscall -.rest_of_exec: # rsp now points to six quads: +rest_of_exec: # rsp now points to seven quads + string: movq %rsp, %r8 # now, they are r8 movq %r13, %rsp # restore SP popq %r10 # argc leaq 8(%rsp,%r10,8), %rsp # now at start of environ -.skip_environ: - popq %r10 # envp[N] - testq %r10, %r10 # envp[n]? - jnz .skip_environ # otherwise, rsp is now at the start of auxv -.one_auxv: - popq %rcx # auxv type - addq $8, %rsp # skip value - testq %rcx, %rcx # is 0? - jz .cleanup - cmpq $3, %rcx # is AT_PHDR? - je .replace_phdr - cmpq $4, %rcx # is AT_PHENT? - je .replace_phent - cmpq $5, %rcx # is AT_PHNUM? - je .replace_phnum - cmpq $9, %rcx # is AT_ENTRY? - je .replace_entry - cmpq $7, %rcx # is AT_BASE? - je .replace_base - jmp .one_auxv -.replace_phdr: - movq 40(%r8), %r9 - movq %r9, -8(%rsp) # set at_phdr - jmp .one_auxv -.replace_phent: - movq 24(%r8), %r9 - movq %r9, -8(%rsp) # set at_phent - jmp .one_auxv -.replace_phnum: - movq 32(%r8), %r9 - movq %r9, -8(%rsp) # set at_phnum - jmp .one_auxv -.replace_entry: - movq 16(%r8), %r9 - movq %r9, -8(%rsp) # set at_entry - jmp .one_auxv -.replace_base: - movq 48(%r8), %r9 - movq %r9, -8(%rsp) # set at_base - jmp .one_auxv -.cleanup: +skip_environ: + popq %rcx # envp[N] + testq %rcx, %rcx # envp[n]? + jnz skip_environ # otherwise, rsp is now at the end of auxv + movq %rsp, %r11 # start of auxv +1: testq $-1, (%r11) # NULL? + leaq 16(%r11), %r11 # next entry + jnz 1b # otherwise copy auxv + /* Prepare sufficient space for the new executable name at the + start of the auxiliary vector. */ +1: leaq 64(%r8), %rsi # file name + movq 56(%r8), %r9 # name length + leaq -1(%r11), %r14 + subq %r9, %r14 # destination of file name + andq $-16, %r14 # align destination + /* Prepare to copy argv, environ and auxv. */ +1: subq %r13, %r11 # size required + addq $15, %r11 # align size + andq $-16, %r11 + negq %r11 # subtract + leaq -56(%r14,%r11,1), %r11 # %r11 = destination - struct exec_jump_command + /* Move the file name out of the way. */ + leaq 9(%rsi,%r9,1), %r10 # end of name + 8 + cmpq %r10, %r11 # end of name >= struct exec_jump_command - 8 + jae 1f # save exec command + xorq %r10, %r10 + subq %r9, %r10 + leaq -9(%r11,%r10,1), %rdi # position of new name + movq %rdi, %r10 + cld + leaq 1(%r9), %rcx # length (including termination) + rep movsb # copy file name + movq %r10, %rsi # file name + /* Preserve jump command. */ +1: cmpq %r8, %r11 # decide copy direction + jb 1f # copy forward + movq 48(%r8), %rax + movq %rax, 48(%r11) # %r11->at_base + movq 40(%r8), %rax + movq %rax, 40(%r11) # %r11->at_phdr + movq 32(%r8), %rax + movq %rax, 32(%r11) # %r11->at_phnum + movq 24(%r8), %rax + movq %rax, 24(%r11) # %r11->at_phent + movq 16(%r8), %rax + movq %rax, 16(%r11) # %r11->at_entry + movq 8(%r8), %rax + movq %rax, 8(%r11) # %r11->entry + movq (%r8), %rax + movq %rax, (%r11) # %r11->command + movq %r14, -8(%r11) # destination of file name + jmp copy_env_and_args +1: movq %r14, -8(%r11) # destination of file name + movq (%r8), %rax + movq %rax, (%r11) # %r11->command + movq 8(%r8), %rax + movq %rax, 8(%r11) # %r11->entry + movq 16(%r8), %rax + movq %rax, 16(%r11) # %r11->at_entry + movq 24(%r8), %rax + movq %rax, 24(%r11) # %r11->at_phent + movq 32(%r8), %rax + movq %rax, 32(%r11) # %r11->at_phnum + movq 40(%r8), %rax + movq %rax, 40(%r11) # %r11->at_phdr + movq 48(%r8), %rax + movq %rax, 48(%r11) # %r11->at_base +copy_env_and_args: + /* Copy argv and environ to their new positions. */ + leaq 8(%r13), %r10 # src + leaq 64(%r11), %rdi # dest + movq (%r13), %rcx # argc + movq %rcx, -8(%rdi) # copy argc +1: movq (%r10), %rcx + movq %rcx, (%rdi) + testq %rcx, %rcx + leaq 8(%r10), %r10 # src++ + leaq 8(%rdi), %rdi # dst++ + jnz 1b +1: movq (%r10), %rcx + movq %rcx, (%rdi) + testq %rcx, %rcx + leaq 8(%r10), %r10 # src++ + leaq 8(%rdi), %rdi # dst++ + jnz 1b +copy_auxv: + movq (%r10), %rcx # a_type + movq 8(%r10), %rdx # a_un.a_val + addq $16, %r10 # next entry + movq %rcx, (%rdi) + jrcxz cleanup # AT_NULL + cmpq $3, %rcx # AT_PHDR + cmoveq 40(%r11), %rdx # %r11->at_phdr + cmpq $4, %rcx # AT_PHENT + cmoveq 24(%r11), %rdx # %r11->at_phent + cmpq $5, %rcx # AT_PHNUM + cmoveq 32(%r11), %rdx # %r11->at_phnum + cmpq $9, %rcx # AT_ENTRY + cmoveq 16(%r11), %rdx # %r11->at_entry + cmpq $7, %rcx # AT_BASE + cmoveq 48(%r11), %rdx # %r11->at_base + cmpq $31, %rcx # AT_EXECFN + jne 1f + movq -8(%r11), %rdx # string +1: movq %rdx, 8(%rdi) # AT_NULL value + addq $16, %rdi # next entry + jmp copy_auxv +cleanup: + /* Copy the filename. */ + movq -8(%r11), %rdi # destination of file name + leaq 1(%r9), %rcx # length (including termination) + rep movsb + movq %rdx, 8(%rdi) # AT_NULL value + leaq 56(%r11), %r13 # restore original stack pointer movq $3, %rax # SYS_close cmpq $-1, %r12 # see if interpreter fd is set - je .cleanup_1 + je cleanup_1 movq %r12, %rdi syscall movq $3, %rax # SYS_close -.cleanup_1: +cleanup_1: movq %rbx, %rdi syscall -.enter: + /* Enter the program. */ pushq $0 popfq # clear FP state movq %r13, %rsp # restore SP xorq %rdx, %rdx # clear rtld_fini - jmpq *8(%r8) # entry + jmpq *-48(%rsp) # entry error: - .ascii "_start: internal error." -timespec: - .quad 10 - .quad 10 + .ascii "_start: internal error.\n" +#timespec: +# .quad 10 +# .quad 10 + +# Local Variables: +# asm-comment-char: ?# +# End: diff --git a/exec/trace.c b/exec/trace.c index ff67ed5d941..2421785a80a 100644 --- a/exec/trace.c +++ b/exec/trace.c @@ -909,6 +909,18 @@ finish_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs) tracee->pid, 0, 0)) goto error; + /* Enable this block to debug the executable loader. */ +#if 0 + { + int rc, wstatus; + again1: + rc = waitpid (tracee->pid, &wstatus, __WALL); + if (rc == -1 && errno == EINTR) + goto again1; + ptrace (PTRACE_DETACH, tracee->pid, 0, 0); + } +#endif /* 0 */ + error: free (tracee->exec_data); tracee->exec_data = NULL; @@ -1234,7 +1246,11 @@ process_system_call (struct exec_tracee *tracee) set, this must be exec, whatever the value of SYSCALL_NUM_REG, which is erased when exec loads another image. */ - callno = (!tracee->exec_data ? regs.SYSCALL_NUM_REG : EXEC_SYSCALL); + callno = (!tracee->exec_data + ? (!tracee->waiting_for_syscall + ? regs.SYSCALL_NUM_REG : tracee->callno) + : EXEC_SYSCALL); + tracee->callno = callno; switch (callno) { case EXEC_SYSCALL: @@ -1641,6 +1657,11 @@ seccomp_system_call (struct exec_tracee *tracee) /* Now dispatch based on the system call. */ callno = regs.SYSCALL_NUM_REG; + + /* Record the call number, which may be required if one of the + following handlers should arrange for process_system_call to + intercede after the system call completes. */ + tracee->callno = callno; switch (callno) { case EXEC_SYSCALL: @@ -1703,7 +1724,7 @@ seccomp_system_call (struct exec_tracee *tracee) if (rc < 0) return; - tracee->waiting_for_syscall = !tracee->waiting_for_syscall; + tracee->waiting_for_syscall = true; break; default: @@ -2021,6 +2042,7 @@ after_fork (pid_t pid) return 1; tracee->pid = pid; + tracee->callno = 0; tracee->next = tracing_processes; tracee->waiting_for_syscall = false; tracee->new_child = false; diff --git a/java/README.res b/java/README.res new file mode 100644 index 00000000000..ac981dbebc3 --- /dev/null +++ b/java/README.res @@ -0,0 +1,4 @@ +* The wrench icon that is superimposed on Emacs's own icon in + res/drawable/emacs_wrench.png was released into the Public Domain by the + Tango Desktop Project. + diff --git a/java/org/gnu/emacs/EmacsNative.java b/java/org/gnu/emacs/EmacsNative.java index 94df9ff39b4..49a21ce1c4d 100644 --- a/java/org/gnu/emacs/EmacsNative.java +++ b/java/org/gnu/emacs/EmacsNative.java @@ -196,6 +196,10 @@ public final class EmacsNative /* Send an ANDROID_NOTIFICATION_ACTION event. */ public static native void sendNotificationAction (String tag, String action); + /* Send an ANDROID_CONFIGURATION_CHANGED event. */ + public static native void sendConfigurationChanged (float dpiX, float dpiY, + float dpiScaled); + /* Return the file name associated with the specified file descriptor, or NULL if there is none. */ public static native byte[] getProcName (int fd); diff --git a/java/org/gnu/emacs/EmacsSdk7FontDriver.java b/java/org/gnu/emacs/EmacsSdk7FontDriver.java index 2fc40551984..b426c3ba74e 100644 --- a/java/org/gnu/emacs/EmacsSdk7FontDriver.java +++ b/java/org/gnu/emacs/EmacsSdk7FontDriver.java @@ -29,6 +29,7 @@ import android.graphics.Rect; import android.graphics.Typeface; import android.graphics.Canvas; +import android.util.DisplayMetrics; import android.util.Log; @@ -103,6 +104,8 @@ public class EmacsSdk7FontDriver extends EmacsFontDriver public Sdk7FontEntity (Sdk7Typeface typeface) { + DisplayMetrics metrics; + foundry = "Google"; family = typeface.familyName; adstyle = null; @@ -110,7 +113,8 @@ public class EmacsSdk7FontDriver extends EmacsFontDriver slant = typeface.slant; spacing = typeface.spacing; width = typeface.width; - dpi = Math.round (EmacsService.SERVICE.metrics.scaledDensity * 160f); + metrics = EmacsService.SERVICE.getResources ().getDisplayMetrics (); + dpi = Math.round (metrics.scaledDensity * 160f); this.typeface = typeface; } @@ -127,6 +131,7 @@ public class EmacsSdk7FontDriver extends EmacsFontDriver { float totalWidth; String testWidth, testString; + DisplayMetrics metrics; this.typeface = typeface; this.pixelSize = pixelSize; @@ -137,7 +142,8 @@ public class EmacsSdk7FontDriver extends EmacsFontDriver slant = typeface.slant; spacing = typeface.spacing; width = typeface.width; - dpi = Math.round (EmacsService.SERVICE.metrics.scaledDensity * 160f); + metrics = EmacsService.SERVICE.getResources ().getDisplayMetrics (); + dpi = Math.round (metrics.scaledDensity * 160f); /* Compute the ascent and descent. */ typeface.typefacePaint.setTextSize (pixelSize); diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java index babf2626ba5..3630329839f 100644 --- a/java/org/gnu/emacs/EmacsService.java +++ b/java/org/gnu/emacs/EmacsService.java @@ -123,9 +123,6 @@ public final class EmacsService extends Service public static final int IC_MODE_TEXT = 2; public static final int IC_MODE_PASSWORD = 3; - /* Display metrics used by font backends. */ - public DisplayMetrics metrics; - /* Flag that says whether or not to print verbose debugging information when responding to an input method. */ public static final boolean DEBUG_IC = false; @@ -149,8 +146,9 @@ public final class EmacsService extends Service thread. */ private Thread mainThread; - /* "Resources" object required by GContext bookkeeping. */ - public static Resources resources; + /* The display's horizontal and vertical density and that which is + consulted for font scaling. */ + private double dpiX, dpiY, dpiScaled; static { @@ -236,10 +234,12 @@ public final class EmacsService extends Service final AssetManager manager; Context app_context; final String filesDir, libDir, cacheDir, classPath; - final double pixelDensityX; - final double pixelDensityY; - final double scaledDensity; - double tempScaledDensity; + final float pixelDensityX; + final float pixelDensityY; + final float scaledDensity; + float tempScaledDensity; + Resources resources; + DisplayMetrics metrics; super.onCreate (); @@ -265,13 +265,18 @@ public final class EmacsService extends Service corresponds to 1 pixel, not 72 or 96 as used elsewhere. This difference is codified in PT_PER_INCH defined in font.h. */ - if (tempScaledDensity < 160) - tempScaledDensity = 160; + if (tempScaledDensity < 160.0f) + tempScaledDensity = 160.0f; /* scaledDensity is const as required to refer to it from within the nested function below. */ scaledDensity = tempScaledDensity; + /* Save these fields for future reference. */ + dpiX = pixelDensityX; + dpiY = pixelDensityY; + dpiScaled = scaledDensity; + /* Remove all tasks from previous Emacs sessions but the task created by the system at startup. */ EmacsWindowManager.MANAGER.removeOldTasks (this); @@ -304,9 +309,8 @@ public final class EmacsService extends Service run () { EmacsNative.setEmacsParams (manager, filesDir, libDir, - cacheDir, (float) pixelDensityX, - (float) pixelDensityY, - (float) scaledDensity, + cacheDir, pixelDensityX, + pixelDensityY, scaledDensity, classPath, EmacsService.this, Build.VERSION.SDK_INT); } @@ -344,6 +348,40 @@ public final class EmacsService extends Service super.onLowMemory (); } + @Override + public void + onConfigurationChanged (Configuration newConfig) + { + DisplayMetrics metrics; + float pixelDensityX, pixelDensityY, scaledDensity; + + metrics = getResources ().getDisplayMetrics (); + + /* The display configuration may have been altered. Retrieve the + revised display density and deliver an event if so. */ + pixelDensityX = metrics.xdpi; + pixelDensityY = metrics.ydpi; + scaledDensity = ((getScaledDensity (metrics) + / metrics.density) * pixelDensityX); + + /* A density below 160 probably indicates a system bug. See + onCreate for more commentary. */ + if (scaledDensity < 160.0f) + scaledDensity = 160.0f; + + if (pixelDensityX != dpiX || pixelDensityY != dpiY + || scaledDensity != dpiScaled) + { + dpiX = pixelDensityX; + dpiY = pixelDensityY; + dpiScaled = scaledDensity; + EmacsNative.sendConfigurationChanged (pixelDensityX, pixelDensityY, + scaledDensity); + } + + super.onConfigurationChanged (newConfig); + } + /* Functions from here on must only be called from the Emacs diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c index eb98ef6c6e7..801e6f22101 100644 --- a/lib-src/emacsclient.c +++ b/lib-src/emacsclient.c @@ -1715,8 +1715,13 @@ set_socket (bool no_exit_if_error) } #ifdef HAVE_NTGUI -FARPROC set_fg; /* Pointer to AllowSetForegroundWindow. */ -FARPROC get_wc; /* Pointer to RealGetWindowClassA. */ +typedef void (* VOIDFNPTR) (void); +typedef BOOL (WINAPI *AllowSetForegroundWindow_proc) (DWORD); +/* Pointer to AllowSetForegroundWindow. */ +static AllowSetForegroundWindow_proc set_fg; +typedef UINT (WINAPI *RealGetWindowClassA_proc) (HWND, LPSTR, UINT); +/* Pointer to RealGetWindowClassA. */ +static RealGetWindowClassA_proc get_wc; void w32_set_user_model_id (void); @@ -1794,8 +1799,8 @@ w32_give_focus (void) emacsclient can allow Emacs to grab the focus by calling the function AllowSetForegroundWindow. Unfortunately, older Windows (W95, W98 and NT) lack this function, so we have to check its availability. */ - if ((set_fg = GetProcAddress (user32, "AllowSetForegroundWindow")) - && (get_wc = GetProcAddress (user32, "RealGetWindowClassA"))) + if ((set_fg = (AllowSetForegroundWindow_proc) (VOIDFNPTR) GetProcAddress (user32, "AllowSetForegroundWindow")) + && (get_wc = (RealGetWindowClassA_proc) (VOIDFNPTR) GetProcAddress (user32, "RealGetWindowClassA"))) EnumWindows (w32_find_emacs_process, (LPARAM) 0); } #endif /* HAVE_NTGUI */ diff --git a/lib-src/seccomp-filter.c b/lib-src/seccomp-filter.c index d6421f0ebdb..e9f41afbaba 100644 --- a/lib-src/seccomp-filter.c +++ b/lib-src/seccomp-filter.c @@ -42,6 +42,7 @@ variants of those files that can be used to sandbox Emacs before #include #include #include +#include /* mandatory accordingly to latest ioctl_tty(2) */ #include #include @@ -64,6 +65,11 @@ variants of those files that can be used to sandbox Emacs before #define ARCH_CET_STATUS 0x3001 #endif +/* https://github.com/torvalds/linux/commit/9651fcedf7b92d3f7f1ab179e8ab55b85ee10fc1 */ +#ifndef MAP_DROPPABLE +#define MAP_DROPPABLE 0x08 +#endif + static ATTRIBUTE_FORMAT_PRINTF (2, 3) _Noreturn void fail (int error, const char *format, ...) { @@ -187,7 +193,7 @@ main (int argc, char **argv) some versions of the dynamic loader still use it. Also allow allocating thread stacks. */ SCMP_A3_32 (SCMP_CMP_MASKED_EQ, - ~(MAP_SHARED | MAP_PRIVATE | MAP_FILE + ~(MAP_SHARED | MAP_PRIVATE | MAP_FILE | MAP_DROPPABLE | MAP_ANONYMOUS | MAP_FIXED | MAP_DENYWRITE | MAP_STACK | MAP_NORESERVE), 0)); @@ -274,6 +280,11 @@ main (int argc, char **argv) SCMP_A0_32 (SCMP_CMP_EQ, STDIN_FILENO), SCMP_A1_32 (SCMP_CMP_EQ, TIOCGPGRP)); + /* Allow `tcgetattr' call of glibc on physical terminal devices. */ + RULE (SCMP_ACT_ALLOW, SCMP_SYS (ioctl), + SCMP_A0_32 (SCMP_CMP_EQ, STDERR_FILENO), + SCMP_A1_32 (SCMP_CMP_EQ, TCGETS)); + /* Allow reading (but not setting) file flags. */ RULE (SCMP_ACT_ALLOW, SCMP_SYS (fcntl), SCMP_A1_32 (SCMP_CMP_EQ, F_GETFL)); diff --git a/lib/acl-internal.c b/lib/acl-internal.c index 1a6087b03a9..6c50feacbb8 100644 --- a/lib/acl-internal.c +++ b/lib/acl-internal.c @@ -31,7 +31,7 @@ # include #endif -#if USE_ACL && HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */ +#if USE_ACL && HAVE_ACL_GET_FILE /* Linux, FreeBSD, NetBSD >= 10, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */ # if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ @@ -45,7 +45,7 @@ acl_extended_nontrivial (acl_t acl) return (acl_entries (acl) > 0); } -# else /* Linux, FreeBSD, IRIX, Tru64, Cygwin >= 2.5 */ +# else /* Linux, FreeBSD, NetBSD >= 10, IRIX, Tru64, Cygwin >= 2.5 */ /* ACL is an ACL, from a file, stored as type ACL_TYPE_ACCESS. Return 1 if the given ACL is non-trivial. @@ -59,7 +59,7 @@ acl_access_nontrivial (acl_t acl) at least, allowing us to write return (3 < acl_entries (acl)); but the following code is more robust. */ -# if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD, Cygwin >= 2.5 */ +# if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */ acl_entry_t ace; int got_one; @@ -548,7 +548,7 @@ void free_permission_context (struct permission_context *ctx) { #if USE_ACL -# if HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */ +# if HAVE_ACL_GET_FILE /* Linux, FreeBSD, NetBSD >= 10, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */ if (ctx->acl) acl_free (ctx->acl); # if !HAVE_ACL_TYPE_EXTENDED diff --git a/lib/acl-internal.h b/lib/acl-internal.h index f37b3bcff5b..cb969e9797e 100644 --- a/lib/acl-internal.h +++ b/lib/acl-internal.h @@ -52,10 +52,7 @@ extern int aclsort (int, int, struct acl *); #include #include - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif +#include #ifndef HAVE_FCHMOD # define HAVE_FCHMOD false @@ -121,8 +118,13 @@ rpl_acl_set_fd (int fd, acl_t acl) # endif /* Linux-specific */ -/* Cygwin >= 2.5 implements this function, but it returns 1 for all - directories, thus is unusable. */ +/* Cygwin >= 2.5 implements acl_extended_file(), but it returns 1 for nearly all + directories — for reasons explained in + —, thus is + unusable. For the user, 'ls' should not print a '+' sign, indicating the + presence of an ACL, for 99,9% of the files; this would not be useful. + Therefore, on Cygwin, we ignore the acl_extended_file function and instead + use our own acl_access_nontrivial function. */ # if !defined HAVE_ACL_EXTENDED_FILE || defined __CYGWIN__ # undef HAVE_ACL_EXTENDED_FILE # define HAVE_ACL_EXTENDED_FILE false diff --git a/lib/acl_entries.c b/lib/acl_entries.c index 808ad93fe2c..57b7b4998c0 100644 --- a/lib/acl_entries.c +++ b/lib/acl_entries.c @@ -22,7 +22,7 @@ #include "acl-internal.h" /* This file assumes POSIX-draft like ACLs - (Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5). */ + (Linux, FreeBSD, NetBSD >= 10, Mac OS X, IRIX, Tru64, Cygwin >= 2.5). */ /* Return the number of entries in ACL. Return -1 and set errno upon failure to determine it. */ @@ -34,7 +34,7 @@ acl_entries (acl_t acl) if (acl != NULL) { -#if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD, Mac OS X, Cygwin >= 2.5 */ +#if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD, NetBSD >= 10, Mac OS X, Cygwin >= 2.5 */ # if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */ /* acl_get_entry returns 0 when it successfully fetches an entry, and -1/EINVAL at the end. */ @@ -45,7 +45,7 @@ acl_entries (acl_t acl) got_one >= 0; got_one = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace)) count++; -# else /* Linux, FreeBSD, Cygwin >= 2.5 */ +# else /* Linux, FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */ /* acl_get_entry returns 1 when it successfully fetches an entry, and 0 at the end. */ acl_entry_t ace; diff --git a/lib/fcntl.in.h b/lib/fcntl.in.h index ac61c0865a4..d7f551b30f3 100644 --- a/lib/fcntl.in.h +++ b/lib/fcntl.in.h @@ -22,8 +22,12 @@ #endif @PRAGMA_COLUMNS@ -#if defined __need_system_fcntl_h -/* Special invocation convention. */ +#if defined __need_system_fcntl_h || defined _@GUARD_PREFIX@_ALREADY_INCLUDING_FCNTL_H +/* Special invocation convention: + - On Haiku we have a sequence of nested includes + -> -> + In this situation, GNULIB_defined_O_NONBLOCK gets defined before the + system's definition of O_NONBLOCK is processed. */ /* Needed before . May also define off_t to a 64-bit type on native Windows. */ @@ -50,6 +54,8 @@ #ifndef _@GUARD_PREFIX@_FCNTL_H +#define _@GUARD_PREFIX@_ALREADY_INCLUDING_FCNTL_H + /* Needed before . May also define off_t to a 64-bit type on native Windows. Also defines off64_t on macOS, NetBSD, OpenBSD, MSVC, Cygwin, Haiku. */ @@ -72,6 +78,8 @@ # include #endif +#undef _@GUARD_PREFIX@_ALREADY_INCLUDING_FCNTL_H + #ifndef _@GUARD_PREFIX@_FCNTL_H #define _@GUARD_PREFIX@_FCNTL_H diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c index c02cfee842b..66b920c1ab2 100644 --- a/lib/file-has-acl.c +++ b/lib/file-has-acl.c @@ -50,7 +50,6 @@ static char const UNKNOWN_SECURITY_CONTEXT[] = "?"; # include # endif # include -# include # include # include # include @@ -363,6 +362,29 @@ acl_nfs4_nontrivial (uint32_t *xattr, ssize_t nbytes) } #endif +#if (!USE_LINUX_XATTR && USE_ACL && HAVE_ACL_GET_FD \ + && !HAVE_ACL_EXTENDED_FILE && !HAVE_ACL_TYPE_EXTENDED \ + && !HAVE_ACL_GET_LINK_NP) +# include +# ifdef O_PATH + +/* Like acl_get_file, but do not follow symbolic links. */ +static acl_t +acl_get_link_np (char const *name, acl_type_t type) +{ + int fd = open (name, O_PATH | O_NOFOLLOW); + if (fd < 0) + return NULL; + acl_t r = acl_get_fd (fd); + int err = errno; + close (fd); + errno = err; + return r; +} +# define HAVE_ACL_GET_LINK_NP 1 +# endif +#endif + /* Return 1 if NAME has a nontrivial access control list, 0 if ACLs are not supported, or if NAME has no or only a base ACL, and -1 (setting errno) on error. Note callers can determine @@ -468,7 +490,7 @@ file_has_aclinfo (MAYBE_UNUSED char const *restrict name, ret = -1; # else /* FreeBSD, NetBSD >= 10, IRIX, Tru64, Cygwin >= 2.5 */ acl_t (*acl_get_file_or_link) (char const *, acl_type_t) = acl_get_file; -# if HAVE_ACL_GET_LINK_NP /* FreeBSD, NetBSD >= 10 */ +# if HAVE_ACL_GET_LINK_NP /* FreeBSD, NetBSD >= 10, Cygwin >= 2.5 */ if (! (flags & ACL_SYMLINK_FOLLOW)) acl_get_file_or_link = acl_get_link_np; # endif diff --git a/lib/fpending.c b/lib/fpending.c index 7614b607832..be8a9877349 100644 --- a/lib/fpending.c +++ b/lib/fpending.c @@ -26,7 +26,7 @@ /* This file is not used on systems that already have the __fpending function, namely glibc >= 2.2, Solaris >= 7, UnixWare >= 7.1.4.MP4, Cygwin >= 1.7.34, - Android API >= 23. */ + Android API >= 23, musl libc, Haiku >= hrev58760. */ /* Return the number of pending (aka buffered, unflushed) bytes on the stream, FP, that is open for writing. */ diff --git a/lib/getloadavg.c b/lib/getloadavg.c index a7966462c73..1cb1c01097d 100644 --- a/lib/getloadavg.c +++ b/lib/getloadavg.c @@ -47,8 +47,6 @@ N_NAME_POINTER The nlist n_name element is a pointer, not an array. HAVE_STRUCT_NLIST_N_UN_N_NAME 'n_un.n_name' is member of 'struct nlist'. - LINUX_LDAV_FILE [__linux__, __ANDROID__, __CYGWIN__]: File - containing load averages. Specific system predefines this file uses, aside from setting default values if not emacs: @@ -65,8 +63,7 @@ UMAX4_3 VMS _WIN32 Native Windows (possibly also defined on Cygwin) - __linux__, __ANDROID__ Linux: assumes /proc file system mounted. - Support from Michael K. Johnson. + __linux__, __ANDROID__ Linux: assumes sysinfo() call. __CYGWIN__ Cygwin emulates linux /proc/loadavg. __NetBSD__ NetBSD: assumes /kern file system mounted. @@ -108,10 +105,10 @@ # endif /* Same issues as for NeXT apply to the HURD-based GNU system. */ -# ifdef __GNU__ +# if defined __gnu_hurd__ || defined NeXT # undef BSD # undef FSCALE -# endif /* __GNU__ */ +# endif /* __gnu_hurd__ || NeXT */ /* Set values that are different from the defaults, which are set a little farther down with #ifndef. */ @@ -312,8 +309,7 @@ # endif # endif -# if defined (__GNU__) && !defined (NeXT) -/* Note that NeXT Openstep defines __GNU__ even though it should not. */ +# if defined __gnu_hurd__ && !defined NeXT /* GNU system acts much like NeXT, for load average purposes, but not exactly. */ # define NeXT @@ -358,6 +354,11 @@ # include # endif +# if defined __linux__ || defined __ANDROID__ +# include +# include +# endif + # if (defined __linux__ || defined __ANDROID__ \ || defined __CYGWIN__ || defined SUNOS_5 \ || (defined LOAD_AVE_TYPE && ! defined __VMS)) @@ -498,20 +499,33 @@ getloadavg (double loadavg[], int nelem) } # endif -# if !defined (LDAV_DONE) && (defined __linux__ || defined __ANDROID__ || defined __CYGWIN__) +# if !defined (LDAV_DONE) && (defined __linux__ || defined __ANDROID__) \ + && (!defined __ANDROID__ || __ANDROID_API__ >= 13) /* Linux without glibc, Android, Cygwin */ # define LDAV_DONE # undef LOAD_AVE_TYPE -# ifndef LINUX_LDAV_FILE -# define LINUX_LDAV_FILE "/proc/loadavg" -# endif + { + struct sysinfo info; + if (sysinfo (&info) < 0) + return -1; + loadavg[0] = info.loads[0] / (double)(1U << SI_LOAD_SHIFT); + loadavg[1] = info.loads[1] / (double)(1U << SI_LOAD_SHIFT); + loadavg[2] = info.loads[2] / (double)(1U << SI_LOAD_SHIFT); + elem = 3; + } +# endif /* __linux__ || __ANDROID__ */ + +# if !defined (LDAV_DONE) && defined __CYGWIN__ + /* Cygwin */ +# define LDAV_DONE +# undef LOAD_AVE_TYPE char ldavgbuf[3 * (INT_STRLEN_BOUND (int) + sizeof ".00 ")]; char const *ptr = ldavgbuf; int fd, count, saved_errno; - fd = open (LINUX_LDAV_FILE, O_RDONLY | O_CLOEXEC); + fd = open ("/proc/loadavg", O_RDONLY | O_CLOEXEC); if (fd == -1) return -1; count = read (fd, ldavgbuf, sizeof ldavgbuf - 1); @@ -554,7 +568,7 @@ getloadavg (double loadavg[], int nelem) return elem; -# endif /* __linux__ || __ANDROID__ || __CYGWIN__ */ +# endif /* __CYGWIN__ */ # if !defined (LDAV_DONE) && defined (__NetBSD__) /* NetBSD < 0.9 */ # define LDAV_DONE diff --git a/lib/getopt-pfx-ext.h b/lib/getopt-pfx-ext.h index 1f2b2d71bf7..a61c68c795e 100644 --- a/lib/getopt-pfx-ext.h +++ b/lib/getopt-pfx-ext.h @@ -38,11 +38,9 @@ # endif # undef getopt_long # undef getopt_long_only -# undef option # undef _getopt_internal # define getopt_long __GETOPT_ID (getopt_long) # define getopt_long_only __GETOPT_ID (getopt_long_only) -# define option __GETOPT_ID (option) # define _getopt_internal __GETOPT_ID (getopt_internal) /* The system's getopt.h may have already included getopt-ext.h to diff --git a/lib/getopt.in.h b/lib/getopt.in.h index 79200ecdab9..4a87a2d53bf 100644 --- a/lib/getopt.in.h +++ b/lib/getopt.in.h @@ -30,7 +30,12 @@ ; our definitions will be present soon enough. */ #if @HAVE_GETOPT_H@ # define _GL_SYSTEM_GETOPT +/* Rename the system's 'struct option' to 'struct sys_option', + so that we don't have to rename ours to 'struct rpl_option' + (which would cause significant trouble in C++ mode). */ +# define option sys_option # @INCLUDE_NEXT@ @NEXT_GETOPT_H@ +# undef option # undef _GL_SYSTEM_GETOPT #endif diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index fa2250cf686..cf7d0470f67 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in @@ -22,6 +22,7 @@ # Generated by gnulib-tool. # Reproduce by: # gnulib-tool --import \ +# --local-dir=./admin/gnulib-patches \ # --lib=libgnu \ # --source-base=lib \ # --m4-base=m4 \ @@ -49,6 +50,7 @@ # --avoid=iswxdigit \ # --avoid=langinfo-h \ # --avoid=libgmp-mpq \ +# --avoid=locale-h \ # --avoid=localename-unsafe-limited \ # --avoid=lock \ # --avoid=mbrtowc \ @@ -624,6 +626,7 @@ 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_L = @GL_GNULIB_STRERROR_L@ GL_GNULIB_STRERROR_R = @GL_GNULIB_STRERROR_R@ GL_GNULIB_STRFTIME = @GL_GNULIB_STRFTIME@ GL_GNULIB_STRNCAT = @GL_GNULIB_STRNCAT@ @@ -916,6 +919,7 @@ HAVE_STR2SIG = @HAVE_STR2SIG@ HAVE_STRCASESTR = @HAVE_STRCASESTR@ HAVE_STRCHRNUL = @HAVE_STRCHRNUL@ HAVE_STRERRORNAME_NP = @HAVE_STRERRORNAME_NP@ +HAVE_STRERROR_L = @HAVE_STRERROR_L@ HAVE_STRPBRK = @HAVE_STRPBRK@ HAVE_STRPTIME = @HAVE_STRPTIME@ HAVE_STRSEP = @HAVE_STRSEP@ @@ -1213,6 +1217,7 @@ REPLACE_GETENTROPY = @REPLACE_GETENTROPY@ REPLACE_GETGROUPS = @REPLACE_GETGROUPS@ REPLACE_GETLINE = @REPLACE_GETLINE@ REPLACE_GETLOADAVG = @REPLACE_GETLOADAVG@ +REPLACE_GETLOGIN = @REPLACE_GETLOGIN@ REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@ REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@ REPLACE_GETPASS = @REPLACE_GETPASS@ @@ -1307,6 +1312,7 @@ REPLACE_STRCHRNUL = @REPLACE_STRCHRNUL@ REPLACE_STRDUP = @REPLACE_STRDUP@ REPLACE_STRERROR = @REPLACE_STRERROR@ REPLACE_STRERRORNAME_NP = @REPLACE_STRERRORNAME_NP@ +REPLACE_STRERROR_L = @REPLACE_STRERROR_L@ REPLACE_STRERROR_R = @REPLACE_STRERROR_R@ REPLACE_STRFTIME = @REPLACE_STRFTIME@ REPLACE_STRNCAT = @REPLACE_STRNCAT@ @@ -1543,6 +1549,7 @@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ standardlisppath = @standardlisppath@ sysconfdir = @sysconfdir@ +systemduserunitdir = @systemduserunitdir@ target_alias = @target_alias@ version = @version@ with_mailutils = @with_mailutils@ @@ -1715,13 +1722,25 @@ libgnu_a_SOURCES += c-ctype.h c-ctype.c endif ## end gnulib module c-ctype -## begin gnulib module c-strcase -ifeq (,$(OMIT_GNULIB_MODULE_c-strcase)) +## begin gnulib module c-strcasecmp +ifeq (,$(OMIT_GNULIB_MODULE_c-strcasecmp)) -libgnu_a_SOURCES += c-strcase.h c-strcasecmp.c c-strncasecmp.c +libgnu_a_SOURCES += c-strcasecmp.c + +EXTRA_DIST += c-strcase.h endif -## end gnulib module c-strcase +## end gnulib module c-strcasecmp + +## begin gnulib module c-strncasecmp +ifeq (,$(OMIT_GNULIB_MODULE_c-strncasecmp)) + +libgnu_a_SOURCES += c-strncasecmp.c + +EXTRA_DIST += c-strcase.h + +endif +## end gnulib module c-strncasecmp ## begin gnulib module canonicalize-lgpl ifeq (,$(OMIT_GNULIB_MODULE_canonicalize-lgpl)) @@ -3681,6 +3700,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's/@''GNULIB_STR_STARTSWITH''@/$(GL_GNULIB_STR_STARTSWITH)/g' \ -e 's/@''GNULIB_STRERROR''@/$(GL_GNULIB_STRERROR)/g' \ -e 's/@''GNULIB_STRERROR_R''@/$(GL_GNULIB_STRERROR_R)/g' \ + -e 's/@''GNULIB_STRERROR_L''@/$(GL_GNULIB_STRERROR_L)/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' \ @@ -3711,6 +3731,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''HAVE_STRCASESTR''@|$(HAVE_STRCASESTR)|g' \ -e 's|@''HAVE_DECL_STRTOK_R''@|$(HAVE_DECL_STRTOK_R)|g' \ -e 's|@''HAVE_DECL_STRERROR_R''@|$(HAVE_DECL_STRERROR_R)|g' \ + -e 's|@''HAVE_STRERROR_L''@|$(HAVE_STRERROR_L)|g' \ -e 's|@''HAVE_STRERRORNAME_NP''@|$(HAVE_STRERRORNAME_NP)|g' \ -e 's|@''HAVE_SIGABBREV_NP''@|$(HAVE_SIGABBREV_NP)|g' \ -e 's|@''HAVE_SIGDESCR_NP''@|$(HAVE_SIGDESCR_NP)|g' \ @@ -3734,6 +3755,7 @@ string.h: string.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''REPLACE_STRTOK_R''@|$(REPLACE_STRTOK_R)|g' \ -e 's|@''REPLACE_STRERROR''@|$(REPLACE_STRERROR)|g' \ -e 's|@''REPLACE_STRERROR_R''@|$(REPLACE_STRERROR_R)|g' \ + -e 's|@''REPLACE_STRERROR_L''@|$(REPLACE_STRERROR_L)|g' \ -e 's|@''REPLACE_STRERRORNAME_NP''@|$(REPLACE_STRERRORNAME_NP)|g' \ -e 's|@''REPLACE_STRSIGNAL''@|$(REPLACE_STRSIGNAL)|g' \ -e 's|@''REPLACE_STRVERSCMP''@|$(REPLACE_STRVERSCMP)|g' \ @@ -4328,6 +4350,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''REPLACE_GETDOMAINNAME''@|$(REPLACE_GETDOMAINNAME)|g' \ -e 's|@''REPLACE_GETDTABLESIZE''@|$(REPLACE_GETDTABLESIZE)|g' \ -e 's|@''REPLACE_GETENTROPY''@|$(REPLACE_GETENTROPY)|g' \ + -e 's|@''REPLACE_GETLOGIN''@|$(REPLACE_GETLOGIN)|g' \ -e 's|@''REPLACE_GETLOGIN_R''@|$(REPLACE_GETLOGIN_R)|g' \ -e 's|@''REPLACE_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \ -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \ diff --git a/lib/intprops.h b/lib/intprops.h index 83efe39910a..2f9fa0a0222 100644 --- a/lib/intprops.h +++ b/lib/intprops.h @@ -39,7 +39,7 @@ then 'switch (INT_PROMOTE (E))' pacifies gcc -Wswitch-enum if some enum values are deliberately omitted from the switch's cases. Here, unary + is safer than a cast or inline function, as unary + - does only integer promotions. */ + does only integer promotions and is disallowed on pointers. */ #define INT_PROMOTE(e) (+ (e)) diff --git a/lib/nproc.c b/lib/nproc.c index d48e4dd94f5..83439aa0eb2 100644 --- a/lib/nproc.c +++ b/lib/nproc.c @@ -398,20 +398,16 @@ parse_omp_threads (char const* threads) /* Convert it from positive decimal to 'unsigned long'. */ if (c_isdigit (*threads)) { - char *endptr = NULL; + char *endptr; 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; - } + 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; @@ -438,6 +434,9 @@ num_processors (enum nproc_query query) query = NPROC_CURRENT; } /* Here query is one of NPROC_ALL, NPROC_CURRENT. */ + if (omp_env_limit == 1) + /* No need to even call num_processors_ignoring_omp (query). */ + return 1; { unsigned long nprocs = num_processors_ignoring_omp (query); return MIN (nprocs, omp_env_limit); diff --git a/lib/readutmp.h b/lib/readutmp.h index b5e8133c7c6..60d63df9598 100644 --- a/lib/readutmp.h +++ b/lib/readutmp.h @@ -45,7 +45,7 @@ # include #endif -/* Needed for BOOT_TIME and USER_PROCESS. */ +/* Needed for BOOT_TIME, USER_PROCESS, LOGIN_PROCESS. */ #if HAVE_UTMPX_H # if defined _THREAD_SAFE && defined UTMP_DATA_INIT /* When including both utmp.h and utmpx.h on AIX 4.3, with _THREAD_SAFE @@ -74,7 +74,8 @@ struct gl_utmp struct timespec ut_ts; /* time */ pid_t ut_pid; /* process ID of ? */ pid_t ut_session; /* process ID of session leader */ - short ut_type; /* BOOT_TIME, USER_PROCESS, or other */ + short ut_type; /* BOOT_TIME, USER_PROCESS, LOGIN_PROCESS, + or other */ struct { int e_termination; int e_exit; } ut_exit; }; @@ -257,19 +258,21 @@ struct utmpx32 # define WTMP_FILE "/etc/wtmp" #endif -/* In early versions of Android, did not define BOOT_TIME, only - USER_PROCESS. We need to use the value that is defined in newer versions - of Android. */ +/* In early versions of Android, did not define BOOT_TIME or + LOGIN_PROCESS, only USER_PROCESS. We need to use the value that is defined + in newer versions of Android. */ #if defined __ANDROID__ && !defined BOOT_TIME # define BOOT_TIME 2 +# define LOGIN_PROCESS 6 #endif /* Some platforms, such as OpenBSD, don't have an ut_type field and don't have - the BOOT_TIME and USER_PROCESS macros. But we want to support them in - 'struct gl_utmp'. */ + the BOOT_TIME, USER_PROCESS, and LOGIN_PROCESS macros. But we want to + support them in 'struct gl_utmp'. */ #if !(HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_TYPE : HAVE_STRUCT_UTMP_UT_TYPE) # define BOOT_TIME 2 # define USER_PROCESS 0 +# define LOGIN_PROCESS 6 #endif /* Macros that test (UT)->ut_type. */ @@ -283,6 +286,11 @@ struct utmpx32 #else # define UT_TYPE_USER_PROCESS(UT) 0 #endif +#ifdef LOGIN_PROCESS +# define UT_TYPE_LOGIN_PROCESS(UT) ((UT)->ut_type == LOGIN_PROCESS) +#else +# define UT_TYPE_LOGIN_PROCESS(UT) 0 +#endif /* Determines whether an entry *UT corresponds to a user process. */ #define IS_USER_PROCESS(UT) \ diff --git a/lib/regcomp.c b/lib/regcomp.c index 41b0f989c03..a23f289d7a1 100644 --- a/lib/regcomp.c +++ b/lib/regcomp.c @@ -831,7 +831,7 @@ init_dfa (re_dfa_t *dfa, size_t pat_len) if (table_size > pat_len) break; - dfa->state_table = calloc (sizeof (struct re_state_table_entry), table_size); + dfa->state_table = calloc (table_size, sizeof (struct re_state_table_entry)); dfa->state_hash_mask = table_size - 1; dfa->mb_cur_max = MB_CUR_MAX; @@ -862,7 +862,7 @@ init_dfa (re_dfa_t *dfa, size_t pat_len) { int i, j, ch; - dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); + dfa->sb_char = (re_bitset_ptr_t) calloc (1, sizeof (bitset_t)); if (__glibc_unlikely (dfa->sb_char == NULL)) return REG_ESPACE; @@ -3055,8 +3055,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, _NL_COLLATE_SYMB_EXTRAMB); } #endif - sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); - mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); + sbcset = (re_bitset_ptr_t) calloc (1, sizeof (bitset_t)); + mbcset = (re_charset_t *) calloc (1, sizeof (re_charset_t)); if (__glibc_unlikely (sbcset == NULL || mbcset == NULL)) { re_free (sbcset); @@ -3548,13 +3548,13 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans, reg_errcode_t ret; bin_tree_t *tree; - sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); + sbcset = (re_bitset_ptr_t) calloc (1, sizeof (bitset_t)); if (__glibc_unlikely (sbcset == NULL)) { *err = REG_ESPACE; return NULL; } - mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); + mbcset = (re_charset_t *) calloc (1, sizeof (re_charset_t)); if (__glibc_unlikely (mbcset == NULL)) { re_free (sbcset); diff --git a/lib/regex.h b/lib/regex.h index 67a3aa70a51..e9ab85e8b5a 100644 --- a/lib/regex.h +++ b/lib/regex.h @@ -66,15 +66,14 @@ typedef unsigned long int active_reg_t; /* The following bits are used to determine the regexp syntax we recognize. The set/not-set meanings are chosen so that Emacs syntax - remains the value 0. The bits are given in alphabetical order, and - the definitions shifted by one from the previous bit; thus, when we - add or remove a bit, only one other definition need change. */ + is the value 0 for Emacs 20 (2000) and earlier, and the value + RE_SYNTAX_EMACS for Emacs 21 (2001) and later. */ typedef unsigned long int reg_syntax_t; #ifdef __USE_GNU /* If this bit is not set, then \ inside a bracket expression is literal. If set, then such a \ quotes the following character. */ -# define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1) +# define RE_BACKSLASH_ESCAPE_IN_LISTS 1ul /* If this bit is not set, then + and ? are operators, and \+ and \? are literals. @@ -215,7 +214,8 @@ extern reg_syntax_t re_syntax_options; (The [[[ comments delimit what gets put into the Texinfo file, so don't delete them!) */ /* [[[begin syntaxes]]] */ -# define RE_SYNTAX_EMACS 0 +# define RE_SYNTAX_EMACS \ + (RE_CHAR_CLASSES | RE_INTERVALS) # define RE_SYNTAX_AWK \ (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ @@ -522,20 +522,6 @@ 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) @@ -682,8 +668,7 @@ 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_ - _REGEX_NELTS (__nmatch)], + regmatch_t __pmatch[_Restrict_arr_], int __eflags); extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg, @@ -692,10 +677,6 @@ extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg, extern void regfree (regex_t *__preg); -#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__) -# pragma GCC diagnostic pop -#endif - #ifdef __cplusplus } #endif /* C++ */ diff --git a/lib/regex_internal.c b/lib/regex_internal.c index 8bf761c7616..9b89cc9372b 100644 --- a/lib/regex_internal.c +++ b/lib/regex_internal.c @@ -1595,7 +1595,7 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes, reg_errcode_t err; re_dfastate_t *newstate; - newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); + newstate = (re_dfastate_t *) calloc (1, sizeof (re_dfastate_t)); if (__glibc_unlikely (newstate == NULL)) return NULL; err = re_node_set_init_copy (&newstate->nodes, nodes); @@ -1643,7 +1643,7 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, reg_errcode_t err; re_dfastate_t *newstate; - newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); + newstate = (re_dfastate_t *) calloc (1, sizeof (re_dfastate_t)); if (__glibc_unlikely (newstate == NULL)) return NULL; err = re_node_set_init_copy (&newstate->nodes, nodes); diff --git a/lib/regexec.c b/lib/regexec.c index 58215bd3766..c5ab9b6649f 100644 --- a/lib/regexec.c +++ b/lib/regexec.c @@ -185,7 +185,7 @@ static reg_errcode_t extend_buffers (re_match_context_t *mctx, int min_len); int regexec (const regex_t *__restrict preg, const char *__restrict string, - size_t nmatch, regmatch_t pmatch[_REGEX_NELTS (nmatch)], int eflags) + size_t nmatch, regmatch_t pmatch[], int eflags) { reg_errcode_t err; Idx start, length; @@ -229,7 +229,7 @@ int attribute_compat_text_section __compat_regexec (const regex_t *__restrict preg, const char *__restrict string, size_t nmatch, - regmatch_t pmatch[_REGEX_NELTS (nmatch)], int eflags) + regmatch_t pmatch[], int eflags) { return regexec (preg, string, nmatch, pmatch, eflags & (REG_NOTBOL | REG_NOTEOL)); @@ -2721,8 +2721,8 @@ get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx) continue; /* No. */ if (sub_top->path == NULL) { - sub_top->path = calloc (sizeof (state_array_t), - sl_str - sub_top->str_idx + 1); + sub_top->path = calloc (sl_str - sub_top->str_idx + 1, + sizeof (state_array_t)); if (sub_top->path == NULL) return REG_ESPACE; } @@ -3266,7 +3266,7 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) if (ndests == 0) { state->trtable = (re_dfastate_t **) - calloc (sizeof (re_dfastate_t *), SBC_MAX); + calloc (SBC_MAX, sizeof (re_dfastate_t *)); if (__glibc_unlikely (state->trtable == NULL)) return false; return true; @@ -3338,7 +3338,7 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) discern by looking at the character code: allocate a 256-entry transition table. */ trtable = state->trtable = - (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX); + (re_dfastate_t **) calloc (SBC_MAX, sizeof (re_dfastate_t *)); if (__glibc_unlikely (trtable == NULL)) goto out_free; @@ -3369,7 +3369,7 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) transition tables, one starting at trtable[0] and one starting at trtable[SBC_MAX]. */ trtable = state->word_trtable = - (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX); + (re_dfastate_t **) calloc (2 * SBC_MAX, sizeof (re_dfastate_t *)); if (__glibc_unlikely (trtable == NULL)) goto out_free; diff --git a/lib/stdio-impl.h b/lib/stdio-impl.h index 878e9f8c97d..4b4263fe908 100644 --- a/lib/stdio-impl.h +++ b/lib/stdio-impl.h @@ -30,6 +30,49 @@ # endif #endif +/* Haiku stdio implementation. */ +#if defined __HAIKU__ +# include +/* This FILE structure was made into an incomplete type in 2025. + See . */ +# define fp_ ((struct { int _flags; \ + char *_IO_read_ptr; \ + char *_IO_read_end; \ + char *_IO_read_base; \ + char *_IO_write_base; \ + char *_IO_write_ptr; \ + char *_IO_write_end; \ + char *_IO_buf_base; \ + char *_IO_buf_end; \ + char *_IO_save_base; \ + char *_IO_backup_base; \ + char *_IO_save_end; \ + void *_markers; \ + void *_chain; \ + int _fileno; \ + int _flags2; \ + off_t _old_offset; \ + unsigned short _cur_column; \ + signed char _vtable_offset; \ + char _shortbuf[1]; \ + void *_lock; \ + int64_t _offset; \ + /* More fields, not relevant here. */ \ + } *) fp) +# if !defined _IO_UNBUFFERED +# define _IO_UNBUFFERED 0x2 +# endif +# if !defined _IO_EOF_SEEN +# define _IO_EOF_SEEN 0x10 +# endif +# if !defined _IO_IN_BACKUP +# define _IO_IN_BACKUP 0x100 +# endif +# if !defined _IO_LINE_BUF +# define _IO_LINE_BUF 0x200 +# endif +#endif + /* BSD stdio derived implementations. */ #if defined __NetBSD__ /* NetBSD */ diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h index bd82086ff37..dbe8ebc8502 100644 --- a/lib/stdlib.in.h +++ b/lib/stdlib.in.h @@ -63,7 +63,7 @@ #include /* MirBSD 10 defines WEXITSTATUS in , not in . - glibc 2.40 defines WCOREDUMP in , not in . */ + glibc 2.41 defines WCOREDUMP in , not in . */ #if @GNULIB_SYSTEM_POSIX@ && !(defined WEXITSTATUS && defined WCOREDUMP) # include #endif @@ -120,14 +120,14 @@ struct random_data # include #endif -#if ((@GNULIB_STRTOL@ && @REPLACE_STRTOL@) || (@GNULIB_STRTOLL@ && @REPLACE_STRTOLL@) || (@GNULIB_STRTOUL@ && @REPLACE_STRTOUL@) || (@GNULIB_STRTOULL@ && @REPLACE_STRTOULL@)) && defined __cplusplus && !defined GNULIB_NAMESPACE && defined __GNUG__ && !defined __clang__ && defined __sun +#if ((@GNULIB_STRTOL@ && @REPLACE_STRTOL@) || (@GNULIB_STRTOLL@ && @REPLACE_STRTOLL@) || (@GNULIB_STRTOUL@ && @REPLACE_STRTOUL@) || (@GNULIB_STRTOULL@ && @REPLACE_STRTOULL@)) && defined __cplusplus && !defined GNULIB_NAMESPACE && defined __GNUG__ && !defined __clang__ && (defined __sun || defined _AIX) /* When strtol, strtoll, strtoul, or strtoull is going to be defined as a macro below, this may cause compilation errors later in the libstdc++ header files (that are part of GCC), such as: error: 'rpl_strtol' is not a member of 'std' To avoid this, include the relevant header files here, before these symbols - get defined as macros. But do so only on Solaris 11 (where it is needed), - not on mingw (where it would cause other compilation errors). */ + get defined as macros. But do so only on Solaris 11 and AIX (where it is + needed), not on mingw (where it would cause other compilation errors). */ # include #endif @@ -1473,11 +1473,17 @@ _GL_WARN_ON_USE (setstate_r, "setstate_r is unportable - " # if @REPLACE_REALLOC_FOR_REALLOC_POSIX@ # if @REPLACE_REALLOC_FOR_REALLOC_POSIX@ == 2 # define _GL_INLINE_RPL_REALLOC 1 +# ifdef __cplusplus +extern "C" { +# endif _GL_REALLOC_INLINE void * rpl_realloc (void *ptr, size_t size) { return realloc (ptr, size ? size : 1); } +# ifdef __cplusplus +} +# endif # endif # if !((defined __cplusplus && defined GNULIB_NAMESPACE) \ || _GL_USE_STDLIB_ALLOC) diff --git a/lib/string.in.h b/lib/string.in.h index ce488299006..44b9497d802 100644 --- a/lib/string.in.h +++ b/lib/string.in.h @@ -54,6 +54,11 @@ /* NetBSD 5.0 mis-defines NULL. */ #include +#if @GNULIB_STRERROR_L@ +/* Get locale_t. */ +# include +#endif + /* MirBSD defines mbslen as a macro. */ #if @GNULIB_MBSLEN@ && defined __MirBSD__ # include @@ -429,7 +434,9 @@ _GL_FUNCDECL_SYS (memset_explicit, void *, # endif _GL_CXXALIAS_SYS (memset_explicit, void *, (void *__dest, int __c, size_t __n)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (memset_explicit); +# endif #elif defined GNULIB_POSIXCHECK # undef memset_explicit # if HAVE_RAW_DECL_MEMSET_EXPLICIT @@ -1178,6 +1185,33 @@ _GL_CXXALIASWARN (mbsrchr); _GL_EXTERN_C char * mbsstr (const char *haystack, const char *needle) _GL_ATTRIBUTE_PURE _GL_ARG_NONNULL ((1, 2)); +# ifndef _GL_NO_CONST_GENERICS +/* Don't silently convert a 'const char *' to a 'char *'. Programmers want + compiler warnings for 'const' related mistakes. */ +# ifdef __cplusplus +extern "C++" { /* needed for AIX */ +template + T * mbsstr_template (T* haystack, const char *needle); +template <> + inline char * mbsstr_template (char *haystack, const char *needle) + { return mbsstr (haystack, needle); } +template <> + inline const char * mbsstr_template (const char *haystack, const char *needle) + { return mbsstr (haystack, needle); } +} +# undef mbsstr +# define mbsstr mbsstr_template +# elif !defined mbsstr +# if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \ + || defined __ICC || defined __TINYC__ \ + || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__))) +# define mbsstr(h,n) \ + _Generic ((h), \ + char const *: (char const *) mbsstr ((h), (n)), \ + default : mbsstr ((h), (n))) +# endif +# endif +# endif #endif #if @GNULIB_MBSCASECMP@ @@ -1219,6 +1253,33 @@ _GL_EXTERN_C int mbsncasecmp (const char *s1, const char *s2, size_t n) _GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix) _GL_ATTRIBUTE_PURE _GL_ARG_NONNULL ((1, 2)); +# ifndef _GL_NO_CONST_GENERICS +/* Don't silently convert a 'const char *' to a 'char *'. Programmers want + compiler warnings for 'const' related mistakes. */ +# ifdef __cplusplus +extern "C++" { /* needed for AIX */ +template + T * mbspcasecmp_template (T* string, const char *prefix); +template <> + inline char * mbspcasecmp_template (char *string, const char *prefix) + { return mbspcasecmp (string, prefix); } +template <> + inline const char * mbspcasecmp_template (const char *string, const char *prefix) + { return mbspcasecmp (string, prefix); } +} +# undef mbspcasecmp +# define mbspcasecmp mbspcasecmp_template +# elif !defined mbspcasecmp +# if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \ + || defined __ICC || defined __TINYC__ \ + || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__))) +# define mbspcasecmp(s,p) \ + _Generic ((s), \ + char const *: (char const *) mbspcasecmp ((s), (p)), \ + default : mbspcasecmp ((s), (p))) +# endif +# endif +# endif #endif #if @GNULIB_MBSCASESTR@ @@ -1230,6 +1291,33 @@ _GL_EXTERN_C char * mbspcasecmp (const char *string, const char *prefix) _GL_EXTERN_C char * mbscasestr (const char *haystack, const char *needle) _GL_ATTRIBUTE_PURE _GL_ARG_NONNULL ((1, 2)); +# ifndef _GL_NO_CONST_GENERICS +/* Don't silently convert a 'const char *' to a 'char *'. Programmers want + compiler warnings for 'const' related mistakes. */ +# ifdef __cplusplus +extern "C++" { /* needed for AIX */ +template + T * mbscasestr_template (T* haystack, const char *needle); +template <> + inline char * mbscasestr_template (char *haystack, const char *needle) + { return mbscasestr (haystack, needle); } +template <> + inline const char * mbscasestr_template (const char *haystack, const char *needle) + { return mbscasestr (haystack, needle); } +} +# undef mbscasestr +# define mbscasestr mbscasestr_template +# elif !defined mbscasestr +# if ((__GNUC__ + (__GNUC_MINOR__ >= 9) > 4) || (__clang_major__ >= 3) \ + || defined __ICC || defined __TINYC__ \ + || (__STDC_VERSION__ >= 201112L && !(defined __GNUC__ || defined __clang__))) +# define mbscasestr(h,n) \ + _Generic ((h), \ + char const *: (char const *) mbscasestr ((h), (n)), \ + default : mbscasestr ((h), (n))) +# endif +# endif +# endif #endif #if @GNULIB_MBSCSPN@ @@ -1388,6 +1476,44 @@ _GL_WARN_ON_USE (strerror_r, "strerror_r is unportable - " # endif #endif +/* Map any int, typically from errno, into an error message. + With locale_t argument. */ +#if @GNULIB_STRERROR_L@ +# if @REPLACE_STRERROR_L@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef strerror_l +# define strerror_l rpl_strerror_l +# endif +_GL_FUNCDECL_RPL (strerror_l, char *, (int errnum, locale_t locale), + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (strerror_l, char *, (int errnum, locale_t locale)); +# else +# if !@HAVE_STRERROR_L@ +_GL_FUNCDECL_SYS (strerror_l, char *, (int errnum, locale_t locale), + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (strerror_l, char *, (int errnum, locale_t locale)); +# endif +# if __GLIBC__ >= 2 +_GL_CXXALIASWARN (strerror_l); +# endif +#elif defined GNULIB_POSIXCHECK +# undef strerror_l +# if HAVE_RAW_DECL_STRERROR_L +_GL_WARN_ON_USE (strerror_l, "strerror_l is unportable - " + "use gnulib module strerror_l for portability"); +# endif +#endif + +/* Map any int, typically from errno, into an error message. Multithread-safe, + with locale_t argument. + Not portable! Only provided by gnulib. */ +#if @GNULIB_STRERROR_L@ +_GL_FUNCDECL_SYS (strerror_l_r, int, + (int errnum, char *buf, size_t buflen, locale_t locale), + _GL_ARG_NONNULL ((2, 4))); +#endif + /* Return the name of the system error code ERRNUM. */ #if @GNULIB_STRERRORNAME_NP@ # if @REPLACE_STRERRORNAME_NP@ @@ -1403,7 +1529,9 @@ _GL_FUNCDECL_SYS (strerrorname_np, const char *, (int errnum), ); # endif _GL_CXXALIAS_SYS (strerrorname_np, const char *, (int errnum)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (strerrorname_np); +# endif #elif defined GNULIB_POSIXCHECK # undef strerrorname_np # if HAVE_RAW_DECL_STRERRORNAME_NP diff --git a/lib/time.in.h b/lib/time.in.h index 60801c972c9..3ff16e3b3e4 100644 --- a/lib/time.in.h +++ b/lib/time.in.h @@ -186,7 +186,9 @@ _GL_FUNCDECL_SYS (timespec_getres, int, (struct timespec *ts, int base), # endif _GL_CXXALIAS_SYS (timespec_getres, int, (struct timespec *ts, int base)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (timespec_getres); +# endif # elif defined GNULIB_POSIXCHECK # undef timespec_getres # if HAVE_RAW_DECL_TIMESPEC_GETRES diff --git a/lib/unistd.in.h b/lib/unistd.in.h index 3f96e10d7e7..c135a770dc1 100644 --- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -95,12 +95,15 @@ # include #endif +/* FreeBSD 14.0, NetBSD 10.0, OpenBSD 7.5, Solaris 11.4, and glibc 2.41 + do not define O_CLOEXEC in . */ /* Cygwin 1.7.1 and Android 4.3 declare unlinkat in , not in . */ /* But avoid namespace pollution on glibc systems. */ -#if (@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) \ - && (defined __CYGWIN__ || defined __ANDROID__) \ - && ! defined __GLIBC__ +#if ! defined O_CLOEXEC \ + || ((@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) \ + && (defined __CYGWIN__ || defined __ANDROID__) \ + && ! defined __GLIBC__) # include #endif @@ -463,7 +466,9 @@ _GL_CXXALIAS_SYS (copy_file_range, ssize_t, (int ifd, off_t *ipos, int ofd, off_t *opos, size_t len, unsigned flags)); # endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (copy_file_range); +# endif #elif defined GNULIB_POSIXCHECK # undef copy_file_range # if HAVE_RAW_DECL_COPY_FILE_RANGE @@ -1362,11 +1367,21 @@ _GL_WARN_ON_USE (gethostname, "gethostname is unportable - " ${LOGNAME-$USER} on Unix platforms, $USERNAME on native Windows platforms. */ -# if !@HAVE_DECL_GETLOGIN@ +# if @REPLACE_GETLOGIN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# define getlogin rpl_getlogin +# endif +_GL_FUNCDECL_RPL (getlogin, char *, (void), ); +_GL_CXXALIAS_RPL (getlogin, char *, (void)); +# else +# if !@HAVE_DECL_GETLOGIN@ _GL_FUNCDECL_SYS (getlogin, char *, (void), ); -# endif +# endif _GL_CXXALIAS_SYS (getlogin, char *, (void)); +# endif +# if __GLIBC__ >= 2 _GL_CXXALIASWARN (getlogin); +# endif #elif defined GNULIB_POSIXCHECK # undef getlogin # if HAVE_RAW_DECL_GETLOGIN @@ -2405,7 +2420,7 @@ _GL_WARN_ON_USE (unlinkat, "unlinkat is not portable - " #if @GNULIB_USLEEP@ /* Pause the execution of the current thread for N microseconds. Returns 0 on completion, or -1 on range error. - See the POSIX:2001 specification + See the POSIX.1-2004 specification . */ # if @REPLACE_USLEEP@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) diff --git a/lib/utimens.h b/lib/utimens.h index 007958dd933..62ea7d8f5fd 100644 --- a/lib/utimens.h +++ b/lib/utimens.h @@ -25,7 +25,7 @@ #include #if HAVE_UTIMENS || HAVE_LUTIMENS -# include +# include #endif #ifdef __cplusplus diff --git a/lib/utimensat.c b/lib/utimensat.c index 227474fdaa5..ca1d39e5900 100644 --- a/lib/utimensat.c +++ b/lib/utimensat.c @@ -136,8 +136,9 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2], } # endif # endif -# if defined __APPLE__ && defined __MACH__ - /* macOS 10.13 does not reject invalid tv_nsec values either. */ +# if (defined __APPLE__ && defined __MACH__) || defined __gnu_hurd__ + /* macOS 10.13 and GNU Hurd do not reject invalid tv_nsec values + either. */ if (times && ((times[0].tv_nsec != UTIME_OMIT && times[0].tv_nsec != UTIME_NOW @@ -151,6 +152,7 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2], errno = EINVAL; return -1; } +# if defined __APPLE__ && defined __MACH__ size_t len = strlen (file); if (len > 0 && file[len - 1] == '/') { @@ -163,6 +165,7 @@ rpl_utimensat (int fd, char const *file, struct timespec const times[2], return -1; } } +# endif # endif result = utimensat (fd, file, times, flag); /* Linux kernel 2.6.25 has a bug where it returns EINVAL for diff --git a/lib/verify.h b/lib/verify.h index 96fde0b9c81..3b01d7c2fb3 100644 --- a/lib/verify.h +++ b/lib/verify.h @@ -157,9 +157,10 @@ #define _GL_CONCAT0(x, y) x##y /* _GL_COUNTER is an integer, preferably one that changes each time we - use it. Use __COUNTER__ if it works, falling back on __LINE__ - otherwise. __LINE__ isn't perfect, but it's better than a - constant. */ + use it. Use __COUNTER__ if it works (it does so with most compilers, + see ), + falling back on __LINE__ otherwise. __LINE__ isn't perfect, but it's + better than a constant. */ #if defined __COUNTER__ && __COUNTER__ != __COUNTER__ # define _GL_COUNTER __COUNTER__ #else diff --git a/lisp/abbrev.el b/lisp/abbrev.el index 93eb086da7a..c4d35496cee 100644 --- a/lisp/abbrev.el +++ b/lisp/abbrev.el @@ -42,7 +42,7 @@ (defcustom abbrev-file-name (locate-user-emacs-file "abbrev_defs" ".abbrev_defs") "Default name of file from which to read and where to save abbrevs." - :initialize 'custom-initialize-delay + :initialize #'custom-initialize-delay :type 'file) (defcustom only-global-abbrevs nil @@ -62,7 +62,7 @@ be replaced by its expansion." ;; defining it again. :variable abbrev-mode) -(put 'abbrev-mode 'safe-local-variable 'booleanp) +(put 'abbrev-mode 'safe-local-variable #'booleanp) (define-obsolete-variable-alias 'edit-abbrevs-map @@ -225,7 +225,8 @@ about loading the abbrevs." (list (read-file-name (format-prompt "Read abbrev file" abbrev-file-name) nil abbrev-file-name t))) - (load (or file abbrev-file-name) nil quietly) + (let ((warning-inhibit-types '((files missing-lexbind-cookie)))) + (load (or file abbrev-file-name) nil quietly)) (setq abbrevs-changed nil)) (defun quietly-read-abbrev-file (&optional file) @@ -270,7 +271,8 @@ abbrevs have been saved." (when (unencodable-char-position (point-min) (point-max) 'utf-8) (setq coding-system-for-write 'utf-8-emacs)) (goto-char (point-min)) - (insert (format ";;-*-coding: %s;-*-\n" coding-system-for-write)) + (insert (format ";; -*- coding: %S; lexical-binding: t -*-\n" + coding-system-for-write)) (write-region nil nil file nil (and (not verbose) 0))))) (defun abbrev-edit-save-to-file (file) @@ -494,13 +496,13 @@ A prefix argument means don't query; expand all abbrevs." (set sym nil) ; Make sure it won't be confused for an abbrev. (put sym prop val))) -(defalias 'abbrev-get 'get +(defalias 'abbrev-get #'get "Get the property PROP of abbrev ABBREV See `define-abbrev' for the effect of some special properties. \(fn ABBREV PROP)") -(defalias 'abbrev-put 'put +(defalias 'abbrev-put #'put "Set the property PROP of abbrev ABBREV to value VAL. See `define-abbrev' for the effect of some special properties. @@ -573,8 +575,7 @@ This causes `save-some-buffers' to offer to save the abbrevs.") (defcustom abbrev-all-caps nil "Non-nil means expand multi-word abbrevs in all caps if the abbrev was so." - :type 'boolean - :group 'abbrev-mode) + :type 'boolean) (defvar abbrev-start-location nil "Buffer position for `expand-abbrev' to use as the start of the abbrev. @@ -691,7 +692,7 @@ current (if global is nil) or standard syntax table." (cl-pushnew (aref abbrev (match-beginning 0)) badchars) (setq pos (1+ pos))) (error "Some abbrev characters (%s) are not word constituents %s" - (apply 'string (nreverse badchars)) + (apply #'string (nreverse badchars)) (if global "in the standard syntax" "in this mode")))))) (defun define-global-abbrev (abbrev expansion) @@ -1096,8 +1097,7 @@ This differs from ordinary undo in that other editing done since then is not undone." (interactive) (save-excursion - (unless (or (< last-abbrev-location (point-min)) - (> last-abbrev-location (point-max))) + (when (<= (point-min) last-abbrev-location (point-max)) (goto-char last-abbrev-location) (when (stringp last-abbrev-text) ;; This isn't correct if last-abbrev's hook was used @@ -1106,9 +1106,9 @@ is not undone." (unless (stringp val) (error "Value of abbrev-symbol must be a string")) ;; Don't inherit properties here; just copy from old contents. - (insert last-abbrev-text) - ;; Delete after inserting, to better preserve markers. - (delete-region (point) (+ (point) (length val))) + (replace-region-contents (point) (+ (point) (length val)) + last-abbrev-text 0) + (goto-char (+ (point) (length last-abbrev-text))) (setq last-abbrev-text nil)))))) (defun abbrev--write (sym) @@ -1158,21 +1158,21 @@ a call to `define-abbrev-table' that, when evaluated, will define the abbrev table NAME exactly as it is currently defined. Abbrevs marked as \"system abbrevs\" are ignored." (let ((symbols (abbrev--table-symbols name readable))) - (setq symbols (sort symbols 'string-lessp)) + (setq symbols (sort symbols #'string-lessp)) (let ((standard-output (current-buffer))) (if readable (progn (insert "(") (prin1 name) (insert ")\n\n") - (mapc 'abbrev--describe symbols) + (mapc #'abbrev--describe symbols) (insert "\n\n")) (insert "(define-abbrev-table '") (prin1 name) (if (null symbols) (insert " '())\n\n") (insert "\n '(\n") - (mapc 'abbrev--write symbols) + (mapc #'abbrev--write symbols) (insert " ))\n\n"))) nil))) @@ -1215,7 +1215,7 @@ Properties with special meaning: ;; There is really no docstring, instead the docstring arg ;; is a property name. (push docstring props) (setq docstring nil)) - (eval `(defvar ,tablename nil ,@(if docstring (list docstring)))) + (defvar-1 tablename nil docstring) (let ((table (if (boundp tablename) (symbol-value tablename)))) (unless table (setq table (make-abbrev-table)) @@ -1229,7 +1229,7 @@ Properties with special meaning: (unless (cdr props) (error "Missing value for property %S" (car props))) (abbrev-table-put table (pop props) (pop props))) (dolist (elt definitions) - (apply 'define-abbrev table elt)))) + (apply #'define-abbrev table elt)))) (defun abbrev-table-menu (table &optional prompt sortfun) "Return a menu that shows all abbrevs in TABLE. diff --git a/lisp/arc-mode.el b/lisp/arc-mode.el index 28be1e9c617..646df770de2 100644 --- a/lisp/arc-mode.el +++ b/lisp/arc-mode.el @@ -792,7 +792,15 @@ archive. ;; The funny [] here make it unlikely that the .elc file will be treated ;; as an archive by other software. (let (case-fold-search) - (cond ((looking-at "\\(PK00\\)?[P]K\003\004") 'zip) + ;; See APPNOTE.txt (version 6.3.10) from PKWARE for the zip + ;; file signatures: + ;; - PK\003\004 == 0x04034b50: local file header signature + ;; (section 4.3.7) + ;; - PK\007\010 == 0x08074b50 (followed by local header): + ;; spanned/split archive signature (section 8.5.3) + ;; - PK00 == 0x30304b50 (followed by local header): temporary + ;; spanned/split archive signature (section 8.5.4) + (cond ((looking-at "\\(?:PK\007\010\\|PK00\\)?[P]K\003\004") 'zip) ((looking-at "..-l[hz][0-9ds]-") 'lzh) ((looking-at "....................[\334]\247\304\375") 'zoo) ((and (looking-at "\C-z") ; signature too simple, IMHO diff --git a/lisp/auth-source-pass.el b/lisp/auth-source-pass.el index e68a3e9129e..50f80288288 100644 --- a/lisp/auth-source-pass.el +++ b/lisp/auth-source-pass.el @@ -149,7 +149,6 @@ HOSTS can be a string or a list of strings." (defvar auth-source-pass-backend (auth-source-backend - (when (<= emacs-major-version 25) "password-store") :source "." ;; not used :type 'password-store :search-function #'auth-source-pass-search) diff --git a/lisp/auth-source.el b/lisp/auth-source.el index 1d039d8b0d1..45f2a488dd5 100644 --- a/lisp/auth-source.el +++ b/lisp/auth-source.el @@ -708,7 +708,11 @@ must call it to obtain the actual value." (condition-case nil (unless (auth-source-search-collection (plist-get spec key) - (slot-value backend key)) + (slot-value + backend + (if (keywordp key) + (intern-soft (substring (symbol-name key) 1)) + key))) (setq filtered-backends (delq backend filtered-backends)) (cl-return)) (invalid-slot-name nil)))) @@ -2391,21 +2395,21 @@ See `auth-source-search' for details on SPEC." :version "28.1") (defvar authinfo--keywords - '(("^#.*" . font-lock-comment-face) + '(("^#.*" (0 'font-lock-comment-face)) ("^\\(machine\\)[ \t]+\\([^ \t\n]+\\)" - (1 font-lock-variable-name-face) - (2 font-lock-builtin-face)) + (1 'font-lock-variable-name-face) + (2 'font-lock-builtin-face)) ("\\(login\\)[ \t]+\\([^ \t\n]+\\)" - (1 font-lock-comment-delimiter-face) - (2 font-lock-keyword-face)) + (1 'font-lock-comment-delimiter-face) + (2 'font-lock-keyword-face)) ("\\(password\\)[ \t]+\\([^ \t\n]+\\)" - (1 font-lock-comment-delimiter-face) - (2 font-lock-doc-face)) + (1 'font-lock-comment-delimiter-face) + (2 'font-lock-doc-face)) ("\\(port\\)[ \t]+\\([^ \t\n]+\\)" - (1 font-lock-comment-delimiter-face) - (2 font-lock-type-face)) + (1 'font-lock-comment-delimiter-face) + (2 'font-lock-type-face)) ("\\([^ \t\n]+\\)[, \t]+\\([^ \t\n]+\\)" - (1 font-lock-constant-face) + (1 'font-lock-constant-face) (2 nil)))) ;;;###autoload diff --git a/lisp/bindings.el b/lisp/bindings.el index 9707ce4b474..8b021a05ce2 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -429,6 +429,145 @@ a menu, so this function is not useful for non-menu keymaps." (bindings--menu-item-string (cdr-safe b)))))) (nconc (make-sparse-keymap prompt) bindings))) +(defcustom mode-line-collapse-minor-modes nil + "Minor modes for which mode line lighters are hidden. +Hidden lighters are collapsed into one, which latter is customizable +using the option `mode-line-collapse-minor-modes-to'. + +The value could be a list (MODES ...) which means to collapse lighters +only for MODES, or a list (not MODES ...) which means to collapse all +lighters for minor modes not in MODES. Other non-nil values make all +lighters hidden." + :type '(choice (const :tag "No modes" nil) + (repeat :tag "Modes" symbol) + (cons :tag "All modes except" + (const not) (repeat symbol)) + (const :tag "All modes" t)) + :group 'mode-line + :version "31.1") + +(defcustom mode-line-collapse-minor-modes-to + (if (char-displayable-p ?…) " …" " ...") + "Lighter for collapsed minor modes. +This is effective only when `mode-line-collapse-minor-modes' is non-nil." + :type 'string + :initialize #'custom-initialize-delay + :group 'mode-line + :version "31.1") + +(defcustom mode-line-modes-delimiters '("(" . ")") + "Strings placed around the modes displayed in the mode line. +These elements are placed around `mode-name' and `mode-line-modes'." + :type '(choice (const :tag "No delimiters") + (cons (string :tag "Left delimiter") + (string :tag "Right delimiter"))) + :group 'mode-line + :version "31.1") + +(defvar mode-line-minor-modes '(:eval (mode-line--minor-modes)) + "Mode line construct for minor mode lighters.") +;;;###autoload +(put 'mode-line-minor-modes 'risky-local-variable t) + +(defun mode-line--make-lighter-menu (alist) + "Return a menu keymap for minor mode lighters in ALIST. +ALIST should be in the same format as `minor-mode-alist'. + +Return nil if no lighters in ALIST should be visible, for example, there +are no active minor modes or non-empty lighters." + (let ((menu (make-sparse-keymap "Minor Modes")) + (empty t)) + (dolist (item alist) + (when-let* ((variable (car item)) + ((and (boundp variable) + (symbol-value variable))) + (lighter (format-mode-line `("" ,@(cdr-safe item)))) + ((not (string= lighter ""))) + (toggle (or (get variable :minor-mode-function) variable)) + ;; Follow the format in `mouse-minor-mode-menu' + (name (format "%s - %s" lighter + (capitalize + (string-replace + "-" " " (symbol-name toggle)))))) + (when (eq ? (aref name 0)) + (setq name (substring name 1))) + (let* ((map (cdr-safe (assq variable minor-mode-map-alist))) + (mm-menu (and (keymapp map) + (keymap-lookup map "")))) + (setq mm-menu + (cond (mm-menu (mouse-menu-non-singleton mm-menu)) + ((fboundp toggle) + (define-keymap :name name + "" (list 'menu-item + "Help for minor mode" + (lambda () (interactive) + (describe-function toggle))) + "" (list 'menu-item + "Turn off minor mode" + toggle))) + ;; No menu and not a minor mode function, so just + ;; display the label without a sub-menu. + (t nil))) + (keymap-set menu (format "<%s>" toggle) + (list 'menu-item name mm-menu)) + (setq empty nil)))) + (and (not empty) menu))) + +(defun mode-line--minor-modes () + "Compute mode line constructs for minor mode lighters." + (let (visible hidden) + (cond + ((not mode-line-collapse-minor-modes) + (setq visible minor-mode-alist + hidden nil)) + ((eq 'not (car-safe mode-line-collapse-minor-modes)) + (let ((modes (cdr mode-line-collapse-minor-modes))) + (dolist (item minor-mode-alist) + (if (memq (car item) modes) + (push item visible) + (push item hidden))) + (setq visible (nreverse visible) + hidden (nreverse hidden)))) + ((listp mode-line-collapse-minor-modes) + (let ((modes mode-line-collapse-minor-modes)) + (dolist (item minor-mode-alist) + (if (memq (car item) modes) + (push item hidden) + (push item visible))) + (setq visible (nreverse visible) + hidden (nreverse hidden)))) + (t (setq visible nil + hidden minor-mode-alist))) + (list "" + `(:propertize ("" ,visible) + mouse-face mode-line-highlight + help-echo "Minor mode\n\ +mouse-1: Display minor mode menu\n\ +mouse-2: Show help for minor mode\n\ +mouse-3: Toggle minor modes" + local-map ,mode-line-minor-mode-keymap) + (unless (string= "" (format-mode-line `("" ,hidden))) + (let* ((menu + ;; FIXME: This is to defer the computation of the + ;; menu, but may not play well with touchscreen. + (lambda (e) + (interactive "@e") + (if-let* ((m (mode-line--make-lighter-menu hidden))) + (popup-menu m e) + (message "No menu available")))) + (keymap + (define-keymap + :parent mode-line-minor-mode-keymap + " " menu + " " #'describe-mode))) + `(:propertize mode-line-collapse-minor-modes-to + mouse-face mode-line-highlight + help-echo "Hidden minor modes\n\ +mouse-1: Display hidden minor modes\n\ +mouse-2: Show help for enabled minor modes\n\ +mouse-3: Toggle minor modes" + local-map ,keymap)))))) + (defvar mode-line-major-mode-keymap (let ((map (make-sparse-keymap))) (define-key map [mode-line down-mouse-1] @@ -457,7 +596,7 @@ Keymap to display on minor modes.") (let ((recursive-edit-help-echo "Recursive edit, type C-M-c to get out")) (list (propertize "%[" 'help-echo recursive-edit-help-echo) - "(" + '(:eval (car mode-line-modes-delimiters)) `(:propertize ("" mode-name) help-echo "Major mode\n\ mouse-1: Display major mode menu\n\ @@ -466,18 +605,12 @@ mouse-3: Toggle minor modes" mouse-face mode-line-highlight local-map ,mode-line-major-mode-keymap) '("" mode-line-process) - `(:propertize ("" minor-mode-alist) - mouse-face mode-line-highlight - help-echo "Minor mode\n\ -mouse-1: Display minor mode menu\n\ -mouse-2: Show help for minor mode\n\ -mouse-3: Toggle minor modes" - local-map ,mode-line-minor-mode-keymap) (propertize "%n" 'help-echo "mouse-2: Remove narrowing from buffer" 'mouse-face 'mode-line-highlight 'local-map (make-mode-line-mouse-map 'mouse-2 #'mode-line-widen)) - ")" + '("" mode-line-minor-modes) + '(:eval (cdr mode-line-modes-delimiters)) (propertize "%]" 'help-echo recursive-edit-help-echo) " ")) "Mode line construct for displaying major and minor modes.") diff --git a/lisp/calc/calc-mode.el b/lisp/calc/calc-mode.el index 1ca6bb7dca2..d68daee1e48 100644 --- a/lisp/calc/calc-mode.el +++ b/lisp/calc/calc-mode.el @@ -290,22 +290,16 @@ (goto-char (point-max)) (insert "\n\n") (forward-char -1)) + (save-excursion + (goto-char (point-max)) + (skip-chars-backward " \n\t ") + (when (bobp) + (insert ";;; -*- mode: emacs-lisp; lexical-binding:t -*-\n"))) (insert ";;; Mode settings stored by Calc on " (current-time-string) "\n") - (let ((list calc-mode-var-list)) - (while list - (let* ((v (car (car list))) - (def (nth 1 (car list))) - (val (car vals))) - (or (equal val def) - (progn - (insert "(setq " (symbol-name v) " ") - (if (and (or (listp val) - (symbolp val)) - (not (memq val '(nil t)))) - (insert "'")) - (insert (prin1-to-string val) ")\n")))) - (setq list (cdr list) - vals (cdr vals)))) + (pcase-dolist (`(,v ,def) calc-mode-var-list) + (let* ((val (pop vals))) + (or (equal val def) + (pp `(setq ,v ,(macroexp-quote val)) (current-buffer))))) (run-hooks 'calc-mode-save-hook) (insert ";;; End of mode settings\n") (save-buffer) @@ -332,7 +326,8 @@ (equal user-init-file calc-settings-file) (> arg 0)) (< arg 0) - (load name t) + (let ((warning-inhibit-types '((files missing-lexbind-cookie)))) + (load name t)) (message "New file"))))) (defun math-get-modes-vec () diff --git a/lisp/calc/calc-trail.el b/lisp/calc/calc-trail.el index f134a7b16b9..433d3983b12 100644 --- a/lisp/calc/calc-trail.el +++ b/lisp/calc/calc-trail.el @@ -167,14 +167,7 @@ (interactive "p") (calc-with-trail-buffer (let ((buffer-read-only nil)) - (save-restriction - (narrow-to-region ; don't delete "Emacs Trail" header - (save-excursion - (goto-char (point-min)) - (forward-line 1) - (point)) - (point-max)) - (kill-line n))) + (kill-line n)) (calc-trail-here))) (provide 'calc-trail) diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el index 80559c1657c..a7bd671998e 100644 --- a/lisp/calc/calc.el +++ b/lisp/calc/calc.el @@ -1347,7 +1347,8 @@ Notations: 3.14e6 3.14 * 10^6 (equal calc-settings-file user-init-file) (progn (setq calc-loaded-settings-file t) - (load (file-name-sans-extension calc-settings-file) t))) ; t = missing-ok + (let ((warning-inhibit-types '((files missing-lexbind-cookie)))) + (load (file-name-sans-extension calc-settings-file) t)))) ; t = missing-ok (let ((p command-line-args)) (while p (and (equal (car p) "-f") diff --git a/lisp/calendar/calendar.el b/lisp/calendar/calendar.el index 08ecd586ec1..058982647fe 100644 --- a/lisp/calendar/calendar.el +++ b/lisp/calendar/calendar.el @@ -2515,9 +2515,9 @@ ATTRLIST is a list with elements of the form :face face :foreground color." (if (not faceinfo) ;; No attributes to apply, so just use an existing-face. face - ;; FIXME should we be using numbered temp-faces, reusing where poss? + ;; Compute temp face name. (setq temp-face - (make-symbol + (intern (concat ":caltemp" (mapconcat (lambda (sym) (cond @@ -2525,10 +2525,12 @@ ATTRLIST is a list with elements of the form :face face :foreground color." ((numberp sym) (number-to-string sym)) (t sym))) attrlist "")))) - (make-face temp-face) - (copy-face face temp-face) - ;; Apply the font aspects. - (apply #'set-face-attribute temp-face nil (nreverse faceinfo)) + ;; Create this new face if it does not already exist. + (unless (member temp-face (face-list)) + (make-face temp-face) + (copy-face face temp-face) + ;; Apply the font aspects. + (apply #'set-face-attribute temp-face nil (nreverse faceinfo))) temp-face))) (defun calendar-mark-visible-date (date &optional mark) diff --git a/lisp/cedet/ede/base.el b/lisp/cedet/ede/base.el index 4e27cd0cb69..599b855991d 100644 --- a/lisp/cedet/ede/base.el +++ b/lisp/cedet/ede/base.el @@ -627,14 +627,14 @@ instead of the current project." "Fills :directory or :file slots if they're missing in project THIS. The other slot will be used to calculate values. PROJECT-FILE-NAME is a name of project file (short name, like `pom.xml', etc." - (when (and (or (not (slot-boundp this :file)) - (not (oref this file))) - (slot-boundp this :directory) + (when (and (not (and (slot-boundp this 'file) + (oref this file))) + (slot-boundp this 'directory) (oref this directory)) (oset this file (expand-file-name project-file-name (oref this directory)))) - (when (and (or (not (slot-boundp this :directory)) - (not (oref this directory))) - (slot-boundp this :file) + (when (and (not (and (slot-boundp this 'directory) + (oref this directory))) + (slot-boundp this 'file) (oref this file)) (oset this directory (file-name-directory (oref this file)))) ) diff --git a/lisp/cedet/ede/config.el b/lisp/cedet/ede/config.el index 89e83386879..fb21baf2985 100644 --- a/lisp/cedet/ede/config.el +++ b/lisp/cedet/ede/config.el @@ -154,14 +154,9 @@ the directory isn't on the `safe' list, ask to add it to the safe list." (when (file-exists-p fname) (message "Ignoring EDE config file for now and creating a new one. Use C-c . g to load it.") ;; Set how it was ignored. - (if loadask - (setq ignore-type 'manual) - (setq ignore-type 'auto)) - ) + (setq ignore-type (if loadask 'manual 'auto))) ;; Create a new one. - (setq config (make-instance class - "Configuration" - :file fname)) + (setq config (make-instance class :file fname)) (oset config ignored-file ignore-type) ;; Set initial values based on project. diff --git a/lisp/cedet/ede/cpp-root.el b/lisp/cedet/ede/cpp-root.el index a43bd2f6f2a..4616d196716 100644 --- a/lisp/cedet/ede/cpp-root.el +++ b/lisp/cedet/ede/cpp-root.el @@ -327,7 +327,7 @@ If one doesn't exist, create a new one for this directory." (ans (object-assoc dir :path targets)) ) (when (not ans) - (setq ans (ede-cpp-root-target dir + (setq ans (ede-cpp-root-target :name (file-name-nondirectory (directory-file-name dir)) :path dir diff --git a/lisp/cedet/ede/emacs.el b/lisp/cedet/ede/emacs.el index c51968ebb8c..ca91a7e4ffb 100644 --- a/lisp/cedet/ede/emacs.el +++ b/lisp/cedet/ede/emacs.el @@ -118,7 +118,7 @@ All directories need at least one target.") "Make sure the targets slot is bound." (cl-call-next-method) (unless (slot-boundp this 'targets) - (oset this :targets nil))) + (oset this targets nil))) ;;; File Stuff ;; diff --git a/lisp/cedet/ede/generic.el b/lisp/cedet/ede/generic.el index 162f37f9373..7c6e2ec715f 100644 --- a/lisp/cedet/ede/generic.el +++ b/lisp/cedet/ede/generic.el @@ -153,7 +153,7 @@ The class allocated value is replace by different sub classes.") "Make sure the targets slot is bound." (cl-call-next-method) (unless (slot-boundp this 'targets) - (oset this :targets nil)) + (oset this targets nil)) ) (cl-defmethod ede-project-root ((this ede-generic-project)) diff --git a/lisp/cedet/ede/linux.el b/lisp/cedet/ede/linux.el index d42f91c7500..34296972ddd 100644 --- a/lisp/cedet/ede/linux.el +++ b/lisp/cedet/ede/linux.el @@ -227,7 +227,7 @@ All directories need at least one target.") "Make sure the targets slot is bound." (cl-call-next-method) (unless (slot-boundp this 'targets) - (oset this :targets nil))) + (oset this targets nil))) ;;; File Stuff ;; @@ -377,9 +377,9 @@ Argument COMMAND is the command to use for compiling the target." (inc (ede-linux--include-path dir bdir arch)) (ver (ede-linux-version dir))) (oset this version ver) - (oset this :build-directory bdir) - (oset this :architecture arch) - (oset this :include-path inc) + (oset this build-directory bdir) + (oset this architecture arch) + (oset this include-path inc) )) (provide 'ede/linux) diff --git a/lisp/cedet/ede/locate.el b/lisp/cedet/ede/locate.el index bad8952ec60..1651b4d3ad3 100644 --- a/lisp/cedet/ede/locate.el +++ b/lisp/cedet/ede/locate.el @@ -89,7 +89,7 @@ based on `ede-locate-setup-options'." (when (called-interactively-p 'interactive) (message "Setting locator to ede-locate-base")) (setq ans 'ede-locate-base)) - (oset proj locate-obj (make-instance ans "Loc" :root root)) + (oset proj locate-obj (make-instance ans :root root)) (when (called-interactively-p 'interactive) (message "Setting locator to %s" ans)) )) diff --git a/lisp/cedet/ede/project-am.el b/lisp/cedet/ede/project-am.el index f45cf1b8616..e66751ba9b1 100644 --- a/lisp/cedet/ede/project-am.el +++ b/lisp/cedet/ede/project-am.el @@ -480,7 +480,7 @@ This is used when subprojects are made in named subdirectories." (bug (nth 2 pi)) (cof (nth 3 pi)) (ampf (project-am-makefile - pn :name pn + :name pn :version ver :mailinglist (or bug "") :file fn))) diff --git a/lisp/cedet/ede/simple.el b/lisp/cedet/ede/simple.el index f1f61c50421..3f7a359a445 100644 --- a/lisp/cedet/ede/simple.el +++ b/lisp/cedet/ede/simple.el @@ -86,7 +86,7 @@ ROOTPROJ is nil, since we will only create a single EDE project here." (obj nil)) (when pf (setq obj (eieio-persistent-read pf)) - (oset obj :directory dir) + (oset obj directory dir) ) obj)) diff --git a/lisp/cedet/semantic/analyze/refs.el b/lisp/cedet/semantic/analyze/refs.el index 45e74c2b27a..3d3dfdc7975 100644 --- a/lisp/cedet/semantic/analyze/refs.el +++ b/lisp/cedet/semantic/analyze/refs.el @@ -89,8 +89,7 @@ Use `semantic-analyze-current-tag' to debug this fcn." (setq allhits (semantic--analyze-refs-full-lookup tag scope t)) - (semantic-analyze-references (semantic-tag-name tag) - :tag tag + (semantic-analyze-references :tag tag :tagdb db :scope scope :rawsearchdata allhits) diff --git a/lisp/cedet/semantic/bovine/c.el b/lisp/cedet/semantic/bovine/c.el index 81639b98176..659e30a45d9 100644 --- a/lisp/cedet/semantic/bovine/c.el +++ b/lisp/cedet/semantic/bovine/c.el @@ -1256,8 +1256,7 @@ Use `semantic-analyze-current-tag' to debug this fcn." (setq allhits (semantic--analyze-refs-full-lookup tag scope t))) ;; (setq refs - (semantic-analyze-references (semantic-tag-name tag) - :tag tag + (semantic-analyze-references :tag tag :tagdb db :scope scope :rawsearchdata allhits)))) ;;) diff --git a/lisp/cedet/semantic/complete.el b/lisp/cedet/semantic/complete.el index 736025e1d54..e0d16d6fbce 100644 --- a/lisp/cedet/semantic/complete.el +++ b/lisp/cedet/semantic/complete.el @@ -1899,7 +1899,7 @@ completion text in ghost text." (mapcar (lambda (class) (let* ((C (intern (car class))) - (doc (documentation-property C 'variable-documentation)) + (doc (cl--class-docstring (cl--find-class C))) (doc1 (car (split-string doc "\n"))) ) (list 'const @@ -1930,7 +1930,7 @@ DEFAULT-TAG is a semantic tag or string to use as the default value. If INITIAL-INPUT is non-nil, insert it in the minibuffer initially. HISTORY is a symbol representing a variable to store the history in." (semantic-complete-read-tag-engine - (semantic-collector-buffer-deep prompt :buffer (current-buffer)) + (semantic-collector-buffer-deep :buffer (current-buffer)) (semantic-displayer-traditional-with-focus-highlight) ;;(semantic-displayer-tooltip) prompt @@ -1952,7 +1952,7 @@ DEFAULT-TAG is a semantic tag or string to use as the default value. If INITIAL-INPUT is non-nil, insert it in the minibuffer initially. HISTORY is a symbol representing a variable to store the history in." (semantic-complete-read-tag-engine - (semantic-collector-local-members prompt :buffer (current-buffer)) + (semantic-collector-local-members :buffer (current-buffer)) (semantic-displayer-traditional-with-focus-highlight) ;;(semantic-displayer-tooltip) prompt @@ -1974,8 +1974,7 @@ DEFAULT-TAG is a semantic tag or string to use as the default value. If INITIAL-INPUT is non-nil, insert it in the minibuffer initially. HISTORY is a symbol representing a variable to store the history in." (semantic-complete-read-tag-engine - (semantic-collector-project-brutish prompt - :buffer (current-buffer) + (semantic-collector-project-brutish :buffer (current-buffer) :path (current-buffer) ) (semantic-displayer-traditional-with-focus-highlight) @@ -2049,7 +2048,6 @@ prompts. these are calculated from the CONTEXT variable passed in." (setq syms (nreverse (cdr (nreverse syms)))) (semantic-complete-read-tag-engine (semantic-collector-analyze-completions - prompt :buffer (oref context buffer) :context context) (semantic-displayer-traditional-with-focus-highlight) diff --git a/lisp/cedet/semantic/db-ebrowse.el b/lisp/cedet/semantic/db-ebrowse.el index 3e34f4a1ea1..51e52afa64a 100644 --- a/lisp/cedet/semantic/db-ebrowse.el +++ b/lisp/cedet/semantic/db-ebrowse.el @@ -309,11 +309,7 @@ If there is no database for DIRECTORY available, then ) (if found (setq db found) - (setq db (make-instance - dbeC - directory - :ebrowse-struct ebd - )) + (setq db (make-instance dbeC :ebrowse-struct ebd)) (oset db reference-directory directory)) ;; Once we recycle or make a new DB, refresh the diff --git a/lisp/cedet/semantic/db-file.el b/lisp/cedet/semantic/db-file.el index f15e6e69cb0..3edbc4a2fcd 100644 --- a/lisp/cedet/semantic/db-file.el +++ b/lisp/cedet/semantic/db-file.el @@ -138,10 +138,6 @@ If DIRECTORY doesn't exist, create a new one." (unless db (setq db (make-instance dbc ; Create the database requested. Perhaps - (concat (file-name-nondirectory - (directory-file-name - directory)) - "/") :file fn :tables nil :semantic-tag-version semantic-tag-version :semanticdb-version semanticdb-file-version))) diff --git a/lisp/cedet/semantic/db-typecache.el b/lisp/cedet/semantic/db-typecache.el index 62eb72af08f..92ddb65ef68 100644 --- a/lisp/cedet/semantic/db-typecache.el +++ b/lisp/cedet/semantic/db-typecache.el @@ -136,7 +136,7 @@ If there is no table, create one, and fill it in." ;; Make sure we have a cache object in the DB index. (when (not cache) ;; The object won't change as we fill it with stuff. - (setq cache (semanticdb-typecache (semanticdb-full-filename table))) + (setq cache (semanticdb-typecache)) (oset idx type-cache cache)) cache)) diff --git a/lisp/cedet/semantic/db.el b/lisp/cedet/semantic/db.el index ffbb3431a81..375e43f2561 100644 --- a/lisp/cedet/semantic/db.el +++ b/lisp/cedet/semantic/db.el @@ -188,7 +188,6 @@ If one doesn't exist, create it." (oref obj index) (let ((idx nil)) (setq idx (funcall semanticdb-default-find-index-class - (concat (eieio-object-name obj) " index") ;; Fill in the defaults :table obj )) @@ -413,7 +412,6 @@ If the table for FILE does not exist, create one." ;; This implementation will satisfy autoloaded classes ;; for tables. (setq newtab (funcall (oref db new-table-class) - (file-name-nondirectory file) :file (file-name-nondirectory file) )) (setf (slot-value newtab 'parent-db) db) @@ -486,7 +484,7 @@ other than :table." (if obj obj ;; Just return it. ;; No object, let's create a new one and return that. - (setq obj (funcall desired-class "Cache" :table table)) + (setq obj (make-instance desired-class :table table)) (object-add-to-list table 'cache obj) obj))) diff --git a/lisp/cedet/semantic/doc.el b/lisp/cedet/semantic/doc.el index fad020ec330..0fbc5f5f6db 100644 --- a/lisp/cedet/semantic/doc.el +++ b/lisp/cedet/semantic/doc.el @@ -110,12 +110,6 @@ If NOSNARF is `lex', then return the lex token." (while (string-match "^\\s-*\\s.+\\s-*" ct) (setq ct (concat (substring ct 0 (match-beginning 0)) (substring ct (match-end 0))))) - ;; End of a block comment. - (if (and (boundp 'block-comment-end) - block-comment-end - (string-match block-comment-end ct)) - (setq ct (concat (substring ct 0 (match-beginning 0)) - (substring ct (match-end 0))))) ;; In case it's a real string, STRIPIT. (while (string-match "\\s-*\\s\"+\\s-*" ct) (setq ct (concat (substring ct 0 (match-beginning 0)) diff --git a/lisp/cedet/semantic/mru-bookmark.el b/lisp/cedet/semantic/mru-bookmark.el index edb8e091a2a..edb2fe414e6 100644 --- a/lisp/cedet/semantic/mru-bookmark.el +++ b/lisp/cedet/semantic/mru-bookmark.el @@ -197,7 +197,7 @@ The resulting bookmark is then sorted within the ring." (ring-remove ring idx)) (setq idx (1+ idx))) ;; Create a new mark - (let ((sbm (semantic-bookmark (semantic-tag-name tag) + (let ((sbm (semantic-bookmark :object-name (semantic-tag-name tag) :tag tag))) ;; Take the mark, and update it for the current state. (ring-insert ring sbm) diff --git a/lisp/cedet/srecode/compile.el b/lisp/cedet/srecode/compile.el index 08082b9ecc1..95e86c63a90 100644 --- a/lisp/cedet/srecode/compile.el +++ b/lisp/cedet/srecode/compile.el @@ -199,8 +199,7 @@ STATE is the current compilation state." (tag nil) (class nil) (table nil) - (STATE (srecode-compile-state (file-name-nondirectory - (buffer-file-name)))) + (STATE (srecode-compile-state)) (mode nil) (application nil) (framework nil) @@ -263,7 +262,7 @@ STATE is the current compilation state." ;; Create a compound dictionary value from "value". (require 'srecode/dictionary) (let ((cv (srecode-dictionary-compound-variable - name :value value))) + :value value))) (setq vars (cons (cons name cv) vars))) )) ) @@ -361,7 +360,7 @@ STATE is the current compile state as an object of class :where 'end))))))) ;; Construct and return the template object. - (srecode-template (semantic-tag-name tag) + (srecode-template :object-name (semantic-tag-name tag) :context context :args (nreverse addargs) :dictionary root-dict @@ -504,7 +503,8 @@ PROPS are additional properties that might need to be passed to the inserter constructor." ;;(message "Compile: %s %S" name props) (if (not key) - (apply #'make-instance 'srecode-template-inserter-variable name props) + (apply #'make-instance 'srecode-template-inserter-variable + :object-name name props) (let ((classes (eieio-class-children 'srecode-template-inserter)) (new nil)) ;; Loop over the various subclasses and @@ -515,7 +515,8 @@ to the inserter constructor." (when (and (not (class-abstract-p (car classes))) (equal (oref-default (car classes) key) key)) ;; Create the new class, and apply state. - (setq new (apply #'make-instance (car classes) name props)) + (setq new (apply #'make-instance (car classes) + :object-name name props)) (srecode-inserter-apply-state new STATE) ) (setq classes (cdr classes))) @@ -589,7 +590,7 @@ A list of defined variables VARS provides a variable table." (cl-defmethod srecode-dump ((tmp srecode-template)) "Dump the contents of the SRecode template tmp." (princ "== Template \"") - (princ (eieio-object-name-string tmp)) + (princ (slot-value tmp 'object-name)) (princ "\" in context ") (princ (oref tmp context)) (princ "\n") @@ -635,7 +636,7 @@ Argument INDENT specifies the indentation level for the list." (cl-defmethod srecode-dump ((ins srecode-template-inserter) _indent) "Dump the state of the SRecode template inserter INS." (princ "INS: \"") - (princ (eieio-object-name-string ins)) + (princ (slot-value ins 'object-name)) (when (oref ins secondname) (princ "\" : \"") (princ (oref ins secondname))) diff --git a/lisp/cedet/srecode/cpp.el b/lisp/cedet/srecode/cpp.el index d49ccde24fa..63613969191 100644 --- a/lisp/cedet/srecode/cpp.el +++ b/lisp/cedet/srecode/cpp.el @@ -146,8 +146,7 @@ specified in a C file." (value-dict (srecode-dictionary-add-section-dictionary dict "VALUE"))) (srecode-semantic-apply-tag-to-dict - (srecode-semantic-tag (semantic-tag-name value-tag) - :prime value-tag) + (srecode-semantic-tag :prime value-tag) value-dict)) ;; Discriminate using statements referring to namespaces and @@ -224,8 +223,7 @@ specified in a C file." (let ((template-dict (srecode-dictionary-add-section-dictionary templates-dict "ARGS"))) (srecode-semantic-apply-tag-to-dict - (srecode-semantic-tag (semantic-tag-name template) - :prime template) + (srecode-semantic-tag :prime template) template-dict))))) ) diff --git a/lisp/cedet/srecode/dictionary.el b/lisp/cedet/srecode/dictionary.el index 2fbed835bdd..bac3b7c48d3 100644 --- a/lisp/cedet/srecode/dictionary.el +++ b/lisp/cedet/srecode/dictionary.el @@ -369,7 +369,7 @@ values but STATE is nil." (srecode-dictionary-set-value dict name (srecode-dictionary-compound-variable - name :value value :state state))))) + :value value :state state))))) (setq entries (nthcdr 2 entries))) dict) @@ -536,7 +536,7 @@ inserted with a new editable field.") (error "Unknown default value for value %S" name))) ;; Create a field from the inserter. - (srecode-field name :name name + (srecode-field :name name :start start :end (point) :prompt (oref sti prompt) diff --git a/lisp/cedet/srecode/insert.el b/lisp/cedet/srecode/insert.el index 2e70469fa39..3b4da876a2c 100644 --- a/lisp/cedet/srecode/insert.el +++ b/lisp/cedet/srecode/insert.el @@ -648,8 +648,7 @@ Use DICTIONARY to resolve values." Use DICTIONARY to resolve values." (let* ((default (srecode-insert-ask-default sti dictionary)) (compound-value - (srecode-field-value (oref sti object-name) - :firstinserter sti + (srecode-field-value :firstinserter sti :defaultvalue default)) ) ;; Return this special compound value as the thing to insert. @@ -806,7 +805,7 @@ Arguments ESCAPE-START and ESCAPE-END are the current escape sequences in use." (srecode-insert-report-error dict "Only section dictionaries allowed for `%s'" - (eieio-object-name-string sti))) + (slot-value sti 'object-name))) ;; Output the code from the sub-template. (srecode-insert-method (slot-value sti slot) dict)) @@ -860,10 +859,10 @@ applied to the text between the section start and the "For the section inserter INS, parse INPUT. Shorten input until the END token is found. Return the remains of INPUT." - (let* ((out (srecode-compile-split-code tag input STATE - (oref ins object-name)))) + (let* ((name (oref ins object-name)) + (out (srecode-compile-split-code tag input STATE name))) (oset ins template (srecode-template - (eieio-object-name-string ins) + :object-name name :context nil :args nil :code (cdr out))) diff --git a/lisp/cedet/srecode/map.el b/lisp/cedet/srecode/map.el index 784e0c2d931..923cca4be0c 100644 --- a/lisp/cedet/srecode/map.el +++ b/lisp/cedet/srecode/map.el @@ -338,7 +338,7 @@ if that file is NEW, otherwise assume the mode has not changed." ;; Only do the save if we are dirty, or if we are in an interactive ;; Emacs. (when (and dirty (not noninteractive) - (slot-boundp srecode-current-map :file)) + (slot-boundp srecode-current-map 'file)) (eieio-persistent-save srecode-current-map)) )) diff --git a/lisp/cedet/srecode/mode.el b/lisp/cedet/srecode/mode.el index e266a7a679a..573f1f6afd7 100644 --- a/lisp/cedet/srecode/mode.el +++ b/lisp/cedet/srecode/mode.el @@ -207,7 +207,7 @@ MENU-DEF is the menu to bind this into." (ctxtcons (assoc ctxt alltabs)) (bind (if (slot-boundp temp 'binding) (oref temp binding))) - (name (eieio-object-name-string temp))) + (name (slot-value temp 'object-name))) (when (not ctxtcons) (if (string= context ctxt) diff --git a/lisp/cedet/srecode/semantic.el b/lisp/cedet/srecode/semantic.el index bfacda54557..1db041cdfd0 100644 --- a/lisp/cedet/srecode/semantic.el +++ b/lisp/cedet/srecode/semantic.el @@ -129,8 +129,7 @@ variable default values, and other things." larg nil nil))) ;; Apply the sub-argument to the subdictionary. (srecode-semantic-apply-tag-to-dict - (srecode-semantic-tag (semantic-tag-name larg) - :prime larg) + (srecode-semantic-tag :prime larg) subdict) ) ;; Next! @@ -203,8 +202,7 @@ variable default values, and other things." (when (not tag) (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) + (srecode-semantic-tag :prime tag) dict))) ;;; :tagtype ARGUMENT HANDLING @@ -394,7 +392,7 @@ as `function' will leave point where code might be inserted." ;; Resolve TAG into the dictionary. We may have a :tag arg ;; from the macro such that we don't need to do this. (when (not (srecode-dictionary-lookup-name dict "TAG")) - (let ((tagobj (srecode-semantic-tag (semantic-tag-name tag) :prime tag)) + (let ((tagobj (srecode-semantic-tag :prime tag)) ) (srecode-semantic-apply-tag-to-dict tagobj dict))) diff --git a/lisp/cedet/srecode/srt-mode.el b/lisp/cedet/srecode/srt-mode.el index 44c82e55b53..45040246fb2 100644 --- a/lisp/cedet/srecode/srt-mode.el +++ b/lisp/cedet/srecode/srt-mode.el @@ -276,7 +276,7 @@ we can tell font lock about them.") (prin1 (format "%c" key)) ))) (terpri) - (princ (documentation-property C 'variable-documentation)) + (princ (cl--class-docstring (cl--find-class C))) (terpri) (when showexample (princ "Example:") @@ -503,7 +503,7 @@ section or ? for an ask variable." (when inserter (let ((base (cons (oref inserter object-name) - (if (and (slot-boundp inserter :secondname) + (if (and (slot-boundp inserter 'secondname) (oref inserter secondname)) (split-string (oref inserter secondname) ":") diff --git a/lisp/cedet/srecode/table.el b/lisp/cedet/srecode/table.el index ba87c0a01d2..6f98038b614 100644 --- a/lisp/cedet/srecode/table.el +++ b/lisp/cedet/srecode/table.el @@ -180,7 +180,6 @@ INIT are the initialization parameters for the new template table." (old (srecode-mode-table-find mt file)) (attr (file-attributes file)) (new (apply #'srecode-template-table - (file-name-nondirectory file) :file file :filesize (file-attribute-size attr) :filedate (file-attribute-modification-time attr) diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el index b260ea5fe95..e029e2610b0 100644 --- a/lisp/cus-edit.el +++ b/lisp/cus-edit.el @@ -5919,7 +5919,9 @@ This stores EXP (without evaluating it) as the saved spec for SYMBOL." (defvar-local custom-dirlocals-file-widget nil "Widget that holds the name of the dir-locals file being customized.") -(defvar-keymap custom-dirlocals-map +(define-obsolete-variable-alias 'custom-dirlocals-map + 'Custom-dirlocals-mode-map "31.1") +(defvar-keymap Custom-dirlocals-mode-map :doc "Keymap used in the \"*Customize Dirlocals*\" buffer." :full t :parent widget-keymap @@ -5951,7 +5953,7 @@ This stores EXP (without evaluating it) as the saved spec for SYMBOL." See `custom-commands' for further explanation.") (easy-menu-define - Custom-dirlocals-menu (list custom-dirlocals-map + Custom-dirlocals-menu (list Custom-dirlocals-mode-map custom-dirlocals-field-map) "Menu used in dirlocals customization buffers." (nconc (list "Custom" @@ -6062,31 +6064,45 @@ Moves point into the widget that holds the value." (custom--initialize-widget-variables) (add-hook 'widget-forward-hook #'custom-dirlocals-maybe-update-cons nil t)) +(define-derived-mode Custom-dirlocals-mode nil "Custom dirlocals" + "Major mode for customizing Directory Local Variables in current directory." + (custom-dirlocals--set-widget-vars) + (setq-local text-conversion-style 'action) + (setq-local touch-screen-keyboard-function + #'Custom-display-on-screen-keyboard-p) + (setq-local revert-buffer-function #'Custom-dirlocals-revert-buffer) + (setq-local tool-bar-map + (or custom-dirlocals-tool-bar-map + ;; Set up `custom-dirlocals-tool-bar-map'. + (let ((map (make-sparse-keymap))) + (mapc + (lambda (arg) + (tool-bar-local-item-from-menu + (nth 1 arg) (nth 4 arg) map Custom-dirlocals-mode-map + :label (nth 5 arg))) + custom-dirlocals-commands) + (setq custom-dirlocals-tool-bar-map map)))) + (run-mode-hooks 'Custom-mode-hook)) + +;; As discussed in bug#77228, deriving from `Custom-mode' would +;; include all the settings that are not necessary for +;; `customize-dirlocals' and that can break it. +;; FIXME: Introduce a `Custom-base-mode', which could be useful +;; also for `gnus-custom-mode'. +(derived-mode-add-parents 'Custom-dirlocals-mode '(Custom-mode)) + (defmacro custom-dirlocals-with-buffer (&rest body) "Arrange to execute BODY in a \"*Customize Dirlocals*\" buffer." ;; We don't use `custom-buffer-create' because the settings here ;; don't go into the `custom-file'. `(progn (switch-to-buffer "*Customize Dirlocals*") - (kill-all-local-variables) + (let ((inhibit-read-only t)) (erase-buffer)) (remove-overlays) - (custom-dirlocals--set-widget-vars) + (Custom-dirlocals-mode) ,@body - (setq-local tool-bar-map - (or custom-dirlocals-tool-bar-map - ;; Set up `custom-dirlocals-tool-bar-map'. - (let ((map (make-sparse-keymap))) - (mapc - (lambda (arg) - (tool-bar-local-item-from-menu - (nth 1 arg) (nth 4 arg) map custom-dirlocals-map - :label (nth 5 arg))) - custom-dirlocals-commands) - (setq custom-dirlocals-tool-bar-map map)))) - (setq-local revert-buffer-function #'Custom-dirlocals-revert-buffer) - (use-local-map custom-dirlocals-map) (widget-setup))) (defun custom-dirlocals-get-options () diff --git a/lisp/desktop.el b/lisp/desktop.el index 761d4558700..b82a9dc9626 100644 --- a/lisp/desktop.el +++ b/lisp/desktop.el @@ -174,7 +174,7 @@ to t, or add this line in your init file: (desktop-save-mode 1) When this mode is enabled, Emacs will save the desktop when it exits -(this may prompt you, see the option `desktop-save'). The next time +\(this may prompt you, see the option `desktop-save'). The next time Emacs starts, if this mode is active it will restore the desktop. To manually save the desktop at any time, use the command \\[desktop-save]. @@ -187,7 +187,6 @@ To see all the options you can set, browse the `desktop' customization group. For further details, see info node `(emacs)Saving Emacs Sessions'." :global t - :group 'desktop (if desktop-save-mode (desktop-auto-save-enable) (desktop-auto-save-disable))) @@ -217,7 +216,6 @@ determine where the desktop is saved." (const :tag "Ask if desktop file exists, else don't save" ask-if-exists) (const :tag "Save if desktop file exists, else don't" if-exists) (const :tag "Never save" nil)) - :group 'desktop :version "22.1") (defcustom desktop-auto-save-timeout auto-save-timeout @@ -234,7 +232,6 @@ Zero or nil means disable auto-saving due to idleness." (if (and (integerp value) (> value 0)) (desktop-auto-save-enable value) (desktop-auto-save-disable)))) - :group 'desktop :version "24.4") (defcustom desktop-load-locked-desktop 'ask @@ -260,27 +257,23 @@ case if you have remotely mounted (NFS) paths in (const :tag "Don't load" nil) (const :tag "Ask the user" ask) (const :tag "Load if no local process" check-pid)) - :group 'desktop :version "22.2") (defcustom desktop-base-file-name (convert-standard-filename ".emacs.desktop") "Name of file for Emacs desktop, excluding the directory part." - :type 'file - :group 'desktop) + :type 'file) (defcustom desktop-base-lock-name (convert-standard-filename ".emacs.desktop.lock") "Name of lock file for Emacs desktop, excluding the directory part." :type 'file - :group 'desktop :version "22.2") (defcustom desktop-path (list user-emacs-directory "~") "List of directories to search for the desktop file. The base name of the file is specified in `desktop-base-file-name'." :type '(repeat directory) - :group 'desktop :version "23.2") ; user-emacs-directory added (defcustom desktop-missing-file-warning nil @@ -290,7 +283,6 @@ Also pause for a moment to display message about errors signaled in If nil, just print error messages in the message buffer." :type 'boolean - :group 'desktop :version "22.1") (defcustom desktop-no-desktop-file-hook nil @@ -298,7 +290,6 @@ If nil, just print error messages in the message buffer." Run in the directory in which the desktop file was sought. May be used to show a Dired buffer." :type 'hook - :group 'desktop :version "22.1") (defcustom desktop-not-loaded-hook nil @@ -306,7 +297,6 @@ May be used to show a Dired buffer." Run in the directory in which the desktop file was found. May be used to deal with accidental multiple Emacs jobs." :type 'hook - :group 'desktop :options '(desktop-save-mode-off save-buffers-kill-emacs) :version "22.2") @@ -314,7 +304,6 @@ May be used to deal with accidental multiple Emacs jobs." "Normal hook run after a successful `desktop-read'. May be used to show a buffer list." :type 'hook - :group 'desktop :options '(list-buffers) :version "22.1") @@ -323,8 +312,7 @@ May be used to show a buffer list." Run with the desktop buffer current with only the header present. May be used to add to the desktop code or to truncate history lists, for example." - :type 'hook - :group 'desktop) + :type 'hook) (defcustom desktop-globals-to-save '(desktop-missing-file-warning @@ -339,8 +327,7 @@ An element may be variable name (a symbol) or a cons cell of the form \(VAR . MAX-SIZE), which means to truncate VAR's value to at most MAX-SIZE elements (if the value is a list) before saving the value. Feature: Saving `kill-ring' implies saving `kill-ring-yank-pointer'." - :type '(repeat (restricted-sexp :match-alternatives (symbolp consp))) - :group 'desktop) + :type '(repeat (restricted-sexp :match-alternatives (symbolp consp)))) (defcustom desktop-globals-to-clear '(kill-ring @@ -354,7 +341,6 @@ An element may be variable name (a symbol) or a cons cell of the form \(VAR . FORM). Symbols are set to nil and for cons cells VAR is set to the value obtained by evaluating FORM." :type '(repeat (restricted-sexp :match-alternatives (symbolp consp))) - :group 'desktop :version "22.1") (defcustom desktop-clear-preserve-buffers @@ -364,8 +350,7 @@ to the value obtained by evaluating FORM." Each element is a regular expression. Buffers with a name matched by any of these won't be deleted." :version "23.3" ; added Warnings - bug#6336 - :type '(repeat regexp) - :group 'desktop) + :type '(repeat regexp)) ;;;###autoload (defcustom desktop-locals-to-save @@ -389,8 +374,7 @@ these won't be deleted." "List of local variables to save for each buffer. The variables are saved only when they really are local. Conventional minor modes are restored automatically; they should not be listed here." - :type '(repeat symbol) - :group 'desktop) + :type '(repeat symbol)) (defcustom desktop-buffers-not-to-save "\\` " "Regexp identifying buffers that are to be excluded from saving. @@ -399,8 +383,7 @@ To exclude buffers that visit files, use `desktop-files-not-to-save' or `desktop-modes-not-to-save'." :type '(choice (const :tag "None" nil) regexp) - :version "24.4" ; skip invisible temporary buffers - :group 'desktop) + :version "24.4") ; skip invisible temporary buffers ;; Skip tramp and ange-ftp files (defcustom desktop-files-not-to-save @@ -413,23 +396,24 @@ you may wish customizing `remote-file-name-access-timeout' to a non-nil value, to avoid hanging the desktop restoration because some remote host is off-line." :type '(choice (const :tag "None" nil) - regexp) - :group 'desktop) + regexp)) ;; We skip TAGS files to save time (tags-file-name is saved instead). (defcustom desktop-modes-not-to-save '(tags-table-mode) "List of major modes whose buffers should not be saved." - :type '(repeat symbol) - :group 'desktop) + :type '(repeat symbol)) -(defcustom desktop-restore-frames t +(defcustom desktop-restore-frames (not (featurep 'android)) "When non-nil, save and restore the frame and window configuration. See related options `desktop-restore-reuses-frames', -`desktop-restore-in-current-display', and `desktop-restore-forces-onscreen'." +`desktop-restore-in-current-display', and `desktop-restore-forces-onscreen'. + +This option is enabled by default, except on Android. It is disabled by +default on Android because the window manager there prevents programs from +restoring frames." :type 'boolean - :group 'desktop - :version "24.4") + :version "31.1") (defcustom desktop-restore-in-current-display t "Controls how restoring of frames treats displays. @@ -439,7 +423,6 @@ If `delete', deletes frames on other displays instead of restoring them." :type '(choice (const :tag "Restore in current display" t) (const :tag "Restore in original display" nil) (const :tag "Delete frames in other displays" delete)) - :group 'desktop :version "24.4") (defcustom desktop-restore-forces-onscreen t @@ -455,7 +438,6 @@ no effect on restoring frames in a non-GUI session." :type '(choice (const :tag "Only fully offscreen frames" t) (const :tag "Also partially offscreen frames" all) (const :tag "Do not force frames onscreen" nil)) - :group 'desktop :version "24.4") (defcustom desktop-restore-reuses-frames t @@ -465,7 +447,6 @@ If `keep', keeps existing frames and does not reuse them." :type '(choice (const :tag "Reuse existing frames" t) (const :tag "Delete existing frames" nil) (const :tag "Keep existing frames" keep)) - :group 'desktop :version "24.4") (defcustom desktop-file-name-format 'absolute @@ -475,7 +456,6 @@ Possible values are: tilde -- Relative to ~. local -- Relative to directory of desktop file." :type '(choice (const absolute) (const tilde) (const local)) - :group 'desktop :version "22.1") (defcustom desktop-restore-eager t @@ -483,20 +463,17 @@ Possible values are: Remaining buffers are restored lazily (when Emacs is idle). If value is t, all buffers are restored immediately." :type '(choice (const t) integer) - :group 'desktop :version "22.1") (defcustom desktop-lazy-verbose t "Verbose reporting of lazily created buffers." :type 'boolean - :group 'desktop :version "22.1") (defcustom desktop-lazy-idle-delay 5 "Idle delay before starting to create buffers. See `desktop-restore-eager'." :type 'natnum - :group 'desktop :version "22.1") ;;;###autoload @@ -574,8 +551,7 @@ and the name of the minor mode function are different have to be added to this table. See also `desktop-minor-mode-handlers'." :type '(alist :key-type (symbol :tag "Minor mode") :value-type (list :tag "Restore function" - (choice (const nil) function))) - :group 'desktop) + (choice (const nil) function)))) ;;;###autoload (defvar desktop-minor-mode-handlers nil @@ -678,7 +654,7 @@ Used to detect desktop file conflicts.") (lambda (mr) (mapcar #'copy-marker mr)))) "Table of serialization/deserialization functions for variables. -Each record is a list of form: (var serializer deserializer). +Each record is a list of form: (VAR SERIALIZER DESERIALIZER). These records can be freely reordered, deleted, or new ones added. However, for compatibility, don't modify the functions for existing records.") @@ -770,7 +746,9 @@ if different)." (dolist (var desktop-globals-to-clear) (if (symbolp var) (set-default var nil) - (set-default var (eval (cdr var))))) + ;; FIXME: To avoid maiming kitten we should also support `funcall' + ;; instead of only `eval' here. + (set-default var (eval (cdr var) t)))) (let ((preserve-regexp (concat "\\`\\(" (mapconcat (lambda (regexp) (concat "\\(" regexp "\\)")) @@ -862,7 +840,7 @@ buffer, which is (in order): `buffer-file-name'; `buffer-name'; `major-mode'; - list of minor-modes,; + list of minor-modes; `point'; `mark'; `buffer-read-only'; @@ -976,7 +954,7 @@ QUOTE may be `may' (value may be quoted), (cons 'must `(,@(mapcar #'cdr (nreverse (if use-list* (cdr newlist) newlist))) - ,@(if use-list* (cdar newlist))))))) + . ,(if use-list* (cdar newlist))))))) ((subrp value) (cons nil `(symbol-function ',(intern-soft (substring (prin1-to-string value) 7 -1))))) @@ -1022,8 +1000,8 @@ which means to truncate VAR's value to at most MAX-SIZE elements (when (boundp var) (when (and (integerp size) (> size 0) - (listp (eval var))) - (desktop-truncate (eval var) size)) + (listp (symbol-value var))) + (desktop-truncate (symbol-value var) size)) (insert "(setq " (symbol-name var) " " @@ -1042,7 +1020,7 @@ have its state saved in the desktop file.") "Return t if buffer should have its state saved in the desktop file. FILENAME is the visited file name, BUFNAME is the buffer name, and MODE is the major mode. -\n\(fn FILENAME BUFNAME MODE)" +\n(fn FILENAME BUFNAME MODE)" (let ((case-fold-search nil) (no-regexp-to-check (not (stringp desktop-files-not-to-save))) dired-skip) @@ -1335,14 +1313,10 @@ It returns t if a desktop file was loaded, nil otherwise. ;; Else, with a prefix arg, ask for a directory name. (and ask (read-directory-name "Directory for desktop file: " nil nil t)) ;; Otherwise search desktop file in desktop-path. - (let ((dirs desktop-path)) - (while (and dirs - (not (file-exists-p - (desktop-full-file-name (car dirs))))) - (setq dirs (cdr dirs))) - (and dirs (car dirs))) + (when-let* ((file (locate-file desktop-base-file-name desktop-path))) + (file-name-directory file)) ;; If not found and `desktop-path' is non-nil, use its first element. - (and desktop-path (car desktop-path)) + (car desktop-path) ;; Default: .emacs.d. user-emacs-directory)))) (if (file-exists-p (desktop-full-file-name)) @@ -1494,7 +1468,7 @@ This function is called from `window-configuration-change-hook'." (> desktop-auto-save-timeout 0)) (setq desktop-auto-save-timer (run-with-idle-timer desktop-auto-save-timeout nil - 'desktop-auto-save)))) + #'desktop-auto-save)))) (defun desktop-auto-save-cancel-timer () (when desktop-auto-save-timer @@ -1653,8 +1627,16 @@ and try to load that." (condition-case err ;; Evaluate point. Thus point can be something like ;; '(search-forward ... - (eval desktop-buffer-point) - (error (message "%s" (error-message-string err)) 1)))) + ;; FIXME: How/where could this happen? AFAICT this var + ;; is lexical has been lexical since 2013 and thus equal + ;; to the arg `buffer-point' which always comes from the + ;; corresponding entry in `desktop-buffer-info' where we + ;; put just an integer. + ;; FIXME: If we want to keep this feature, we should + ;; also allow `desktop-buffer-point' to be a function. + (eval desktop-buffer-point t) + (error (message "%s" (error-message-string err)) + (point-min))))) (when desktop-buffer-mark (if (consp desktop-buffer-mark) (progn @@ -1697,6 +1679,8 @@ and try to load that." ;; Backward compatibility -- update parameters to 205 standards. (defun desktop-buffer (buffer-filename buffer-name buffer-majormode mim pt mk ro tl fc cfs cr buffer-misc) + ;; FIXME: Actually, it's been obsolete since 1994 (commit ec4c6f225a81)! + (declare (obsolete desktop-create-buffer "31")) (desktop-create-buffer 205 buffer-filename buffer-name buffer-majormode (cdr mim) pt mk ro buffer-misc @@ -1712,7 +1696,8 @@ ARGS must be an argument list for `desktop-create-buffer'." (setq desktop-buffer-args-list (nconc desktop-buffer-args-list (list args))) (unless desktop-lazy-timer (setq desktop-lazy-timer - (run-with-idle-timer desktop-lazy-idle-delay t 'desktop-idle-create-buffers)))) + (run-with-idle-timer desktop-lazy-idle-delay t + #'desktop-idle-create-buffers)))) (defun desktop-lazy-create-buffer () "Pop args from `desktop-buffer-args-list', create buffer and bury it." diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index d7d4a394c4a..e5b08af2a30 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -490,9 +490,11 @@ List has a form of (file-name full-file-name (attribute-list))." (defun dired-do-chmod (&optional arg) "Change the mode of the marked (or next ARG) files. Both octal numeric modes like `644' and symbolic modes like `g+w' -are supported. Type \\\ -\\[next-history-element] to pull the file attributes of the file -at point into the minibuffer. +are supported. +After invoking the command, \ +type \\\\[next-history-element] \ +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(1)\". @@ -541,9 +543,10 @@ has no effect on MS-Windows." ;;;###autoload (defun dired-do-chgrp (&optional arg) "Change the group of the marked (or next ARG) files. -Type \\\\[next-history-element] \ -to pull the file attributes of the file at point -into the minibuffer." +After invoking the command, \ +type \\\\[next-history-element] \ +to pull the file attributes +of the file at point into the minibuffer." (interactive "P" dired-mode) (if (and (memq system-type '(ms-dos windows-nt)) (not (file-remote-p default-directory))) @@ -553,9 +556,10 @@ into the minibuffer." ;;;###autoload (defun dired-do-chown (&optional arg) "Change the owner of the marked (or next ARG) files. -Type \\\\[next-history-element] \ -to pull the file attributes of the file at point -into the minibuffer." +After invoking the command, \ +type \\\\[next-history-element] \ +to pull the file attributes +of the file at point into the minibuffer." (interactive "P" dired-mode) (if (and (memq system-type '(ms-dos windows-nt)) (not (file-remote-p default-directory))) @@ -566,9 +570,10 @@ into the minibuffer." (defun dired-do-touch (&optional arg) "Change the timestamp of the marked (or next ARG) files. This calls touch. -Type Type \\\\[next-history-element] \ -to pull the file attributes of the file at point -into the minibuffer." +After invoking the command, \ +type \\\\[next-history-element] \ +to pull the file attributes +of the file at point into the minibuffer." (interactive "P" dired-mode) (dired-do-chxxx "Timestamp" dired-touch-program 'touch arg)) @@ -2867,13 +2872,33 @@ If DIRECTORY already exists, signal an error." (dired-add-file new) (dired-move-to-filename)))) +(defcustom dired-create-empty-file-in-current-directory nil + "Whether `dired-create-empty-file' acts on the current directory. +If non-nil, `dired-create-empty-file' creates a new empty file and adds +an entry for it (or its topmost new parent directory if created) under +the current subdirectory in the Dired buffer by default (otherwise, it +adds the new file (and new subdirectories if provided) to whichever +directory the user enters at the prompt). If nil, +`dired-create-empty-file' acts on the default directory by default." + :type 'boolean + :group 'dired + :version "31.1") + ;;;###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. +Add an entry in the Dired buffer for the topmost new parent +directory of FILE, if created, otherwise for the new file. +If user option `dired-create-empty-file-in-current-directory' is +non-nil, act on the current subdirectory by default, otherwise act on +the default directory by default. If FILE already exists, signal an error." - (interactive (list (read-file-name "Create empty file: ")) dired-mode) + (interactive + (list (read-file-name "Create empty file: " + (and dired-create-empty-file-in-current-directory + (dired-current-directory)))) + dired-mode) (let* ((expanded (expand-file-name file)) new) (if (file-exists-p expanded) @@ -3963,12 +3988,12 @@ If only regular files are in the fileset, call `vc-next-action' with the same value of the VERBOSE argument (interactively, the prefix argument). -If one or more directories are in the fileset, start `vc-dir' in the root -directory of the repository that includes the current directory, with -the same files/directories marked in the VC-Directory buffer that were -marked in the original Dired buffer. If the current directory doesn't -belong to a VCS repository, prompt for a repository directory. In this -case, the VERBOSE argument is ignored." +If one or more directories are in the fileset, start `vc-dir' in the +root directory of the repository that includes the current directory, +with all directories in the fileset marked in the VC-Directory buffer +that were marked in the original Dired buffer. If the current directory +doesn't belong to a VCS repository, prompt for a repository directory. +In this case, the VERBOSE argument is ignored." (interactive "P" dired-mode) (let* ((marked-files (dired-get-marked-files nil nil nil nil t)) @@ -3992,31 +4017,25 @@ case, the VERBOSE argument is ignored." (add-hook 'vc-dir-refresh-hook transient-hook nil t)) (vc-next-action verbose)))) -(declare-function vc-compatible-state "vc") +(declare-function vc-only-files-state-and-model "vc") ;;;###autoload -(defun dired-vc-deduce-fileset (&optional state-model-only-files not-state-changing) +(defun dired-vc-deduce-fileset + (&optional state-model-only-files not-state-changing) (let ((backend (vc-responsible-backend default-directory)) - (files (dired-get-marked-files nil nil nil nil t)) - only-files-list - state - model) - (when (and (not not-state-changing) (cl-some #'file-directory-p files)) - (user-error "State changing VC operations on directories supported only in `vc-dir'")) - - (when state-model-only-files - (setq only-files-list (mapcar (lambda (file) (cons file (vc-state file))) files)) - (setq state (cdar only-files-list)) - ;; Check that all files are in a consistent state, since we use that - ;; state to decide which operation to perform. - (dolist (crt (cdr only-files-list)) - (unless (vc-compatible-state (cdr crt) state) - (error "When applying VC operations to multiple files, the files are required\nto be in similar VC states.\n%s in state %s clashes with %s in state %s" - (car crt) (cdr crt) (caar only-files-list) state))) - (setq only-files-list (mapcar 'car only-files-list)) - (when (and state (not (eq state 'unregistered))) - (setq model (vc-checkout-model backend only-files-list)))) - (list backend files only-files-list state model))) + (files (dired-get-marked-files nil nil nil nil t))) + (when (and (not not-state-changing) + (cl-some #'file-directory-p files)) + (user-error "\ +State-changing VC operations on directories supported only from VC-Dir")) + (if state-model-only-files + (let ((only-files-list (mapcar (lambda (file) + (cons file (vc-state file))) + files))) + (cl-list* backend files + (vc-only-files-state-and-model only-files-list + backend))) + (list backend files)))) (provide 'dired-aux) diff --git a/lisp/dynamic-setting.el b/lisp/dynamic-setting.el index 3681df0b8f5..c38f4656e37 100644 --- a/lisp/dynamic-setting.el +++ b/lisp/dynamic-setting.el @@ -46,7 +46,8 @@ the current form for the frame (i.e. hinting or somesuch changed)." (let ((new-font (and (fboundp 'font-get-system-font) (font-get-system-font))) (frame-list (frames-on-display-list display-or-frame))) - (when (and new-font (display-graphic-p display-or-frame)) + (when (and (or (not set-font) new-font) + (display-graphic-p display-or-frame)) (clear-font-cache) (if set-font ;; Set the font on all current and future frames, as though diff --git a/lisp/electric.el b/lisp/electric.el index da5fa973757..39e13e1ca0c 100644 --- a/lisp/electric.el +++ b/lisp/electric.el @@ -731,38 +731,6 @@ use `electric-quote-local-mode'." (setq-default electric-quote-mode nil) ; But keep it globally disabled. ))) -;;; Electric comment block - -(defun electric-block-comment-post-self-insert-function () - "Function that `electric-block-comment' adds to `post-self-insert-hook'. -This closes block comment with `block-comment-end' when `block-comment-start' -is typed." - (when (and block-comment-start block-comment-end - ;; Check if we are exactly behind a `block-comment-start' - (save-excursion - (save-match-data - (re-search-backward (regexp-quote block-comment-start) - (- (point) (length block-comment-start)) - t))) - ;; And if there is not anything front us - (looking-at-p (concat "[^[:space:]]"))) - (insert " ") - (save-excursion - (insert (concat " " block-comment-end))))) - -(define-minor-mode electric-block-comment-mode - "Toggle automatic closing of block comments (Electric Block Comment mode). - -When enabled, typing `block-comment-start' closes it inserting their -corresponding `block-comment-end'." - :group 'electricity - :version "31.1" - (if electric-block-comment-mode - (add-hook 'post-self-insert-hook - #'electric-block-comment-post-self-insert-function 10 t) - (remove-hook 'post-self-insert-hook - #'electric-block-comment-post-self-insert-function t))) - (provide 'electric) ;;; electric.el ends here diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el index d1d57fe40bd..4c6c6a0007c 100644 --- a/lisp/emacs-lisp/cl-generic.el +++ b/lisp/emacs-lisp/cl-generic.el @@ -644,22 +644,24 @@ The set of acceptable TYPEs (also called \"specializers\") is defined ;; FIXME: Try to avoid re-constructing a new function if the old one ;; is still valid (e.g. still empty method cache)? (gfun (cl--generic-make-function generic))) - (unless (symbol-function sym) - (defalias sym 'dummy)) ;Record definition into load-history. (cl-pushnew `(cl-defmethod . ,(cl--generic-load-hist-format (cl--generic-name generic) qualifiers specializers)) current-load-list :test #'equal) (let ((old-adv-cc (get-advertised-calling-convention - (symbol-function sym))) - ;; Prevent `defalias' from recording this as the definition site of - ;; the generic function. - current-load-list) + (symbol-function sym)))) (when (listp old-adv-cc) - (set-advertised-calling-convention gfun old-adv-cc nil)) - ;; But do use `defalias', so that it interacts properly with nadvice, - ;; e.g. for tracing/debug-on-entry. - (defalias sym gfun))))) + (set-advertised-calling-convention gfun old-adv-cc nil))) + (if (not (symbol-function sym)) + ;; If this is the first definition, use it as "the definition site of + ;; the generic function" since we don't know if a `cl-defgeneric' + ;; will follow or not. + (defalias sym gfun) + ;; Prevent `defalias' from recording this as the definition site of + ;; the generic function. But do use `defalias', so it interacts + ;; properly with nadvice, e.g. for ;; tracing/debug-on-entry. + (let (current-load-list) + (defalias sym gfun)))))) (defvar cl--generic-dispatchers (make-hash-table :test #'equal)) @@ -1440,6 +1442,7 @@ Used internally for the (major-mode MODE) context specializers." (cl-call-next-method))) (cl--generic-prefill-dispatchers 0 oclosure) +(cl--generic-prefill-dispatchers 0 (eql 'x) oclosure integer) ;;; Support for unloading. diff --git a/lisp/emacs-lisp/cl-print.el b/lisp/emacs-lisp/cl-print.el index 62cda07ac73..ba699f75b71 100644 --- a/lisp/emacs-lisp/cl-print.el +++ b/lisp/emacs-lisp/cl-print.el @@ -518,7 +518,9 @@ BUTTON can also be a buffer position or nil (to mean point)." (user-error "No ellipsis to expand here"))) (let* ((end (next-single-property-change (point) 'cl-print-ellipsis)) (begin (previous-single-property-change end 'cl-print-ellipsis)) - (value (get-text-property begin 'cl-print-ellipsis))) + (value (get-text-property begin 'cl-print-ellipsis)) + ;; Ensure clicking the button works even in read only buffers. + (inhibit-read-only t)) ;; FIXME: Rather than `t' (i.e. reuse the print-length/level unchanged), ;; I think it would make sense to increase the level by 1 and to ;; double the length at each expansion step. diff --git a/lisp/emacs-lisp/comp-run.el b/lisp/emacs-lisp/comp-run.el index 061f1767b74..e0e00d88f83 100644 --- a/lisp/emacs-lisp/comp-run.el +++ b/lisp/emacs-lisp/comp-run.el @@ -282,6 +282,7 @@ display a message." (mapcar #'prin1-to-string expr))) (_ (progn (with-temp-file temp-file + (insert ";;; -*- lexical-binding: t -*-\n") (mapc #'insert expr-strings)) (comp-log "\n") (mapc #'comp-log expr-strings))) diff --git a/lisp/emacs-lisp/eieio-base.el b/lisp/emacs-lisp/eieio-base.el index 7975cdf280d..e2065b65095 100644 --- a/lisp/emacs-lisp/eieio-base.el +++ b/lisp/emacs-lisp/eieio-base.el @@ -207,11 +207,12 @@ All slots are unbound, except those initialized with PARAMS." nobj)) (cl-defmethod make-instance ((class (subclass eieio-named)) &rest args) - (if (not (stringp (car args))) + (if (not (and eieio-backward-compatibility args + (let ((x (car args))) (or (stringp x) (null x))))) (cl-call-next-method) - (funcall (if eieio-backward-compatibility #'ignore #'message) - "Obsolete: name passed without :object-name to %S constructor" - class) + (when (eq eieio-backward-compatibility 'warn) + (message "Obsolete: name passed without :object-name to %S constructor" + class)) (apply #'cl-call-next-method class :object-name args))) ;;; eieio-persistent @@ -345,6 +346,8 @@ objects found there." (object-of-class-p newobj 'eieio-named) (not (oref newobj object-name)) name) + (when (eq eieio-backward-compatibility 'warn) + (message "Obsolete name slot initialized for %S" newobj)) (oset newobj object-name name)) newobj)))) diff --git a/lisp/emacs-lisp/eieio-core.el b/lisp/emacs-lisp/eieio-core.el index f95fd65fa5c..a06c36e5b72 100644 --- a/lisp/emacs-lisp/eieio-core.el +++ b/lisp/emacs-lisp/eieio-core.el @@ -63,12 +63,14 @@ default setting for optimization purposes.") (defvar eieio-optimize-primary-methods-flag t "Non-nil means to optimize the method dispatch on primary methods.") -(defvar eieio-backward-compatibility t +(defvar eieio-backward-compatibility 'warn "If nil, drop support for some behaviors of older versions of EIEIO. Currently under control of this var: - Define every class as a var whose value is the class symbol. - Define -child-p and -list-p predicates. -- Allow object names in constructors.") +- Allow object names in constructors. +When `warn', also emit warnings at run-time when code uses those +deprecated features.") (define-obsolete-variable-alias 'eieio-unbound 'eieio--unbound "28.1") (defvar eieio--unbound (make-symbol "eieio--unbound") @@ -208,9 +210,7 @@ It creates an autoload function for CNAME's constructor." ;; turn this into a usable self-pointing symbol (when eieio-backward-compatibility (set cname cname) - (make-obsolete-variable cname (format "\ -use '%s or turn off `eieio-backward-compatibility' instead" cname) - "25.1")) + (make-obsolete-variable cname (format "use '%s instead" cname) "25.1")) (when (memq nil parents) ;; If some parents aren't yet fully defined, just ignore them for now. @@ -361,6 +361,8 @@ See `defclass' for more information." (internal--format-docstring-line "Test OBJ to see if it a list of objects which are a child of type `%s'." cname)) + (when (eq eieio-backward-compatibility 'warn) + (message "Use of obsolete function %S" csym)) (when (listp obj) (let ((ans t)) ;; nil is valid ;; Loop over all the elements of the input list, test @@ -740,18 +742,19 @@ Argument FN is the function calling this verifier." ;;; Get/Set slots in an object. +(eval-and-compile + (defun eieio--check-slot-name (exp _obj slot &rest _) + (pcase slot + ((and (or `',name (and name (pred keywordp))) + (guard (not (eieio--known-slot-name-p name)))) + (macroexp-warn-and-return + (format-message "Unknown slot `%S'" name) + exp nil 'compile-only name)) + (_ exp)))) + (defun eieio-oref (obj slot) "Return the value in OBJ at SLOT in the object vector." - (declare (compiler-macro - (lambda (exp) - (ignore obj) - (pcase slot - ((and (or `',name (and name (pred keywordp))) - (guard (not (eieio--known-slot-name-p name)))) - (macroexp-warn-and-return - (format-message "Unknown slot `%S'" name) - exp nil 'compile-only name)) - (_ exp)))) + (declare (compiler-macro eieio--check-slot-name) ;; FIXME: Make it a gv-expander such that the hash-table lookup is ;; only performed once when used in `push' and friends? (gv-setter eieio-oset)) @@ -822,6 +825,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." + (declare (compiler-macro eieio--check-slot-name)) (cl-check-type slot symbol) (cond ((cl-typep obj '(or eieio-object cl-structure-object)) @@ -909,12 +913,15 @@ reverse-lookup that name, and recurse with the associated slot value." (let* ((fsi (gethash slot (cl--class-index-table class)))) (if (integerp fsi) fsi - (let ((fn (eieio--initarg-to-attribute class slot))) - (if fn + (when eieio-backward-compatibility + (let ((fn (eieio--initarg-to-attribute class slot))) + (when fn + (when (eq eieio-backward-compatibility 'warn) + (message "Accessing slot `%S' via obsolete initarg name `%S'" + fn slot)) ;; Accessing a slot via its :initarg is accepted by EIEIO ;; (but not CLOS) but is a bad idea (for one: it's slower). - (eieio--slot-name-index class fn) - nil))))) + (eieio--slot-name-index class fn))))))) (defun eieio--class-slot-name-index (class slot) "In CLASS find the index of the named SLOT. diff --git a/lisp/emacs-lisp/eieio-custom.el b/lisp/emacs-lisp/eieio-custom.el index 3f5291d0dee..375a1652d3d 100644 --- a/lisp/emacs-lisp/eieio-custom.el +++ b/lisp/emacs-lisp/eieio-custom.el @@ -31,6 +31,7 @@ ;; `:custom'. (require 'eieio) +(require 'eieio-base) ;; For `eieio-named's slot. (require 'widget) (require 'wid-edit) diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index 424baafc503..e1051eb7d4e 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el @@ -216,6 +216,9 @@ and reference them using the function `class-option'." "Retrieve the class slot `%S' from a class `%S'." sname name) "\nThis method is obsolete.") + (when (eq eieio-backward-compatibility 'warn) + (message "Use of obsolete method %S on %S" + ',acces '(subclass ,name))) (if (slot-boundp this ',sname) (eieio-oref-default this ',sname))) accessors))) @@ -293,18 +296,21 @@ and reference them using the function `class-option'." (apply #'make-instance ',name slots)))))) (defun eieio--constructor-macro (whole &rest slots) + ;; When `eieio-backward-compatibility' is removed, we should + ;; remove this compiler-macro, until then, it's best to emit a compile-time + ;; warning even if `eieio-backward-compatibility' is nil, I think. (if (or (null slots) (keywordp (car slots)) ;; Detect the second pass! (eq 'identity (car-safe (car slots)))) whole (macroexp-warn-and-return - (format "Obsolete name arg %S to constructor %S" + (format "Obsolete name argument %S to constructor %S" (car slots) (car whole)) ;; Keep the name arg, for backward compatibility, ;; but hide it so we don't trigger indefinitely. `(,(car whole) (identity ,(car slots)) ,@(cdr slots)) - nil nil (car slots)))) + '(obsolete eieio-constructor-name-arg) nil (car slots)))) ;;; Get/Set slots in an object. ;; @@ -405,7 +411,7 @@ contents of field NAME is matched against PAT, or they can be of (cl-defgeneric eieio-object-name-string (obj) "Return a string which is OBJ's name." (or (gethash obj eieio--object-names) - (format "%s-%x" (eieio-object-class obj) (sxhash-eq obj)))) + (format "%x" (sxhash-eq obj)))) (define-obsolete-function-alias 'object-name-string #'eieio-object-name-string "24.4") @@ -554,6 +560,7 @@ after they are created." Setting a slot's value makes it bound. Calling `slot-makeunbound' will make a slot unbound. OBJECT can be an instance or a class." + (declare (compiler-macro eieio--check-slot-name)) ;; Skip typechecking while retrieving this value. (let ((eieio-skip-typecheck t)) ;; Return nil if the magic symbol is in there. @@ -700,6 +707,23 @@ for each slot. For example: (make-instance \\='foo :slot1 value1 :slotN valueN)") +(put 'make-instance 'compiler-macro + ;; When `eieio-backward-compatibility' is removed, we should + ;; remove this compiler-macro, until then, it's best to emit a compile-time + ;; warning even if `eieio-backward-compatibility' is nil, I think. + (lambda (whole class &rest slots) + (if (or (null slots) (keywordp (car slots)) + ;; Detect the second pass! + (eq 'identity (car-safe (car slots)))) + whole + (macroexp-warn-and-return + (format "Obsolete name arg %S to `make-instance'" (car slots)) + ;; Keep the name arg, for backward compatibility, + ;; but hide it so we don't trigger indefinitely. + `(,(car whole) ,class (identity ,(car slots)) + ,@(cdr slots)) + '(obsolete eieio-constructor-name-arg) nil (car slots))))) + (define-obsolete-function-alias 'constructor #'make-instance "25.1") (cl-defmethod make-instance @@ -711,12 +735,13 @@ It allocates the vector used to represent an EIEIO object, and then calls `initialize-instance' on that object." (let* ((new-object (copy-sequence (eieio--class-default-object-cache (eieio--class-object class))))) - (if (and slots - (let ((x (car slots))) - (or (stringp x) (null x)))) - (funcall (if eieio-backward-compatibility #'ignore #'message) - "Obsolete name %S passed to %S constructor" - (pop slots) class)) + (when (and eieio-backward-compatibility slots + (let ((x (car slots))) + (or (stringp x) (null x)))) + (let ((name (pop slots))) + (when (eq eieio-backward-compatibility 'warn) + (message "Obsolete name argument %S passed to %S constructor" + name class)))) ;; Call the initialize method on the new object with the slots ;; that were passed down to us. (initialize-instance new-object slots) @@ -820,9 +845,12 @@ first and modify the returned object.") (cl-defmethod clone ((obj eieio-default-superclass) &rest params) "Make a copy of OBJ, and then apply PARAMS." (let ((nobj (copy-sequence obj))) - (if (stringp (car params)) - (funcall (if eieio-backward-compatibility #'ignore #'message) - "Obsolete name %S passed to clone" (pop params))) + (when (and eieio-backward-compatibility params + (let ((x (car params))) + (or (stringp x) (null x)))) + (let ((name (pop params))) + (when (eq eieio-backward-compatibility 'warn) + (message "Obsolete name argument %S passed to clone" name)))) (if params (shared-initialize nobj params)) nobj)) diff --git a/lisp/emacs-lisp/find-func.el b/lisp/emacs-lisp/find-func.el index 8f488a9c00a..6bdfb4bc38b 100644 --- a/lisp/emacs-lisp/find-func.el +++ b/lisp/emacs-lisp/find-func.el @@ -487,11 +487,14 @@ The search is done in the source for library LIBRARY." ;; If the regexp search didn't find the location of ;; the symbol (for example, because it is generated by ;; a macro), try a slightly more expensive search that - ;; expands macros until it finds the symbol. + ;; expands macros until it finds the symbol. Since + ;; macro-expansion involves arbitrary code execution, + ;; only attempt it in trusted buffers. (cons (current-buffer) - (find-function--search-by-expanding-macros - (current-buffer) symbol type - form-matcher-factory)))))))))) + (when (trusted-content-p) + (find-function--search-by-expanding-macros + (current-buffer) symbol type + form-matcher-factory))))))))))) ;;;###autoload (defun find-function-update-type-alist (symbol type variable) diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el index 64ec634620a..533b3a3a1b8 100644 --- a/lisp/emacs-lisp/macroexp.el +++ b/lisp/emacs-lisp/macroexp.el @@ -489,7 +489,7 @@ Assumes the caller has bound `macroexpand-all-environment'." (macroexp--unfold-lambda `(,fn ,eexp . ,eargs))) (_ `(,fn ,eexp . ,eargs))))) (`(funcall . ,_) form) ;bug#53227 - (`(,func . ,_) + (`(,(and func (pred symbolp)) . ,_) (let ((handler (function-get func 'compiler-macro))) ;; Macro expand compiler macros. This cannot be delayed to ;; byte-optimize-form because the output of the compiler-macro can diff --git a/lisp/emacs-lisp/package-vc.el b/lisp/emacs-lisp/package-vc.el index daceb4eb9c0..babc0b71524 100644 --- a/lisp/emacs-lisp/package-vc.el +++ b/lisp/emacs-lisp/package-vc.el @@ -219,7 +219,9 @@ asynchronously." ;; FIXME: vc should be extended to allow querying the commit of a ;; directory (as is possible when dealing with git repositories). ;; This should be a fallback option. - (cl-loop with dir = (package-desc-dir pkg-desc) + (cl-loop with dir = (let ((pkg-spec (package-vc--desc->spec pkg-desc))) + (or (plist-get pkg-spec :lisp-dir) + (package-desc-dir pkg-desc))) for file in (directory-files dir t "\\.el\\'" t) when (vc-working-revision file) return it finally return "unknown")) @@ -241,10 +243,10 @@ asynchronously." (cl-assert (package-vc-p pkg-desc)) (let* ((pkg-spec (package-vc--desc->spec pkg-desc)) (name (symbol-name (package-desc-name pkg-desc))) - (directory (file-name-concat + (directory (expand-file-name + (or (plist-get pkg-spec :lisp-dir) ".") (or (package-desc-dir pkg-desc) - (expand-file-name name package-user-dir)) - (plist-get pkg-spec :lisp-dir))) + (expand-file-name name package-user-dir)))) (file (expand-file-name (or (plist-get pkg-spec :main-file) (concat name ".el")) @@ -460,7 +462,7 @@ identify a package as a VC package later on), building documentation and marking the package as installed." (let* ((pkg-spec (package-vc--desc->spec pkg-desc)) (lisp-dir (plist-get pkg-spec :lisp-dir)) - (lisp-path (file-name-concat pkg-dir lisp-dir)) + (lisp-path (expand-file-name (or lisp-dir ".") pkg-dir)) missing) ;; In case the package was installed directly from source, the @@ -508,7 +510,7 @@ documentation and marking the package as installed." (with-temp-buffer (insert ";; Autoload indirection for package-vc\n\n") (prin1 `(load (expand-file-name - ,(file-name-concat lisp-dir auto-name) + ,(expand-file-name auto-name lisp-dir) (or (and load-file-name (file-name-directory load-file-name)) (car load-path)))) @@ -924,16 +926,17 @@ for the NAME of the package to set up." (read-string (format-prompt "Package name" base) nil nil base))))) - (unless (vc-responsible-backend dir) - (user-error "Directory %S is not under version control" dir)) (package-vc--archives-initialize) (let* ((name (or name (file-name-base (directory-file-name dir)))) - (pkg-dir (expand-file-name name package-user-dir))) + (pkg-dir (expand-file-name name package-user-dir)) + (package-vc-selected-packages + (cons (list name :lisp-dir (expand-file-name dir)) + package-vc-selected-packages))) (when (file-exists-p pkg-dir) (if (yes-or-no-p (format "Overwrite previous checkout for package `%s'?" name)) (package--delete-directory pkg-dir) (error "There already exists a checkout for %s" name))) - (make-symbolic-link (expand-file-name dir) pkg-dir) + (make-directory pkg-dir t) (package-vc--unpack-1 (package-desc-create :name (intern name) diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index b9a8dacab15..b1987731308 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -1007,8 +1007,9 @@ untar into a directory named DIR; otherwise, signal an error." ('dir (make-directory pkg-dir t) (let ((file-list - (directory-files - default-directory 'full "\\`[^.].*\\.el\\'" 'nosort))) + (or (and (derived-mode-p 'dired-mode) + (dired-get-marked-files)) + (directory-files-recursively default-directory "" nil)))) (dolist (source-file file-list) (let ((target-el-file (expand-file-name (file-name-nondirectory source-file) pkg-dir))) @@ -1252,7 +1253,9 @@ The return result is a `package-desc'." (with-temp-buffer (insert-file-contents desc-file) (package--read-pkg-desc 'dir)) - (let ((files (directory-files default-directory t "\\.el\\'" t)) + (let ((files (or (and (derived-mode-p 'dired-mode) + (dired-get-marked-files)) + (directory-files-recursively default-directory "\\.el\\'"))) info) (while files (with-temp-buffer @@ -2374,7 +2377,8 @@ info node `(elisp)Packaging'). Specially, if current buffer is a directory, the -pkg.el description file is not mandatory, in which case the information -is derived from the main .el file in the directory. +is derived from the main .el file in the directory. Using Dired, +you can restrict what files to install by marking specific files. Downloads and installs required packages as needed." (interactive) @@ -4591,6 +4595,19 @@ activations need to be changed, such as when `package-load-list' is modified." (delete-file (concat package-quickstart-file "c")) (delete-file package-quickstart-file))) +(defvar package--quickstart-dir nil + "Set by `package-quickstart-file' to the directory containing it.") + +(defun package--quickstart-rel (file) + "Return an expr depending on `package--quickstart-dir' which evaluates to FILE. + +If FILE is in `package--quickstart-dir', returns an expression that is +relative to that directory, so if that directory is moved we can still +find FILE." + (if (file-in-directory-p file package--quickstart-dir) + `(file-name-concat package--quickstart-dir ,(file-relative-name file package--quickstart-dir)) + file)) + (defun package-quickstart-refresh () "(Re)Generate the `package-quickstart-file'." (interactive) @@ -4605,7 +4622,8 @@ activations need to be changed, such as when `package-load-list' is modified." ;; aren't truncated. (print-length nil) (print-level nil) - (Info-directory-list '(""))) + (Info-directory-list '("")) + (package--quickstart-dir nil)) (dolist (elt package-alist) (condition-case err (package-activate (car elt)) @@ -4617,12 +4635,17 @@ activations need to be changed, such as when `package-load-list' is modified." (emacs-lisp-mode) ;For `syntax-ppss'. (insert ";;; Quickstart file to activate all packages at startup -*- lexical-binding:t -*-\n") (insert ";; ¡¡ This file is autogenerated by `package-quickstart-refresh', DO NOT EDIT !!\n\n") + (setq package--quickstart-dir + (file-name-directory (expand-file-name package-quickstart-file))) + (pp '(setq package--quickstart-dir + (file-name-directory (expand-file-name load-file-name))) + (current-buffer)) (dolist (pkg package--quickstart-pkgs) (let* ((file ;; Prefer uncompiled files (and don't accept .so files). (let ((load-suffixes '(".el" ".elc"))) (locate-library (package--autoloads-file-name pkg)))) - (pfile (prin1-to-string file))) + (pfile (prin1-to-string (package--quickstart-rel file)))) (insert "(let* ((load-file-name " pfile ")\ \(load-true-file-name load-file-name))\n") (insert-file-contents file) @@ -4638,12 +4661,13 @@ activations need to be changed, such as when `package-load-list' is modified." (append ',(mapcar #'package-desc-name package--quickstart-pkgs) package-activated-list))) (current-buffer)) - (let ((info-dirs (butlast Info-directory-list))) + (let ((info-dirs + (mapcar #'package--quickstart-rel (butlast Info-directory-list)))) (when info-dirs (pp `(progn (require 'info) (info-initialize) (setq Info-directory-list - (append ',info-dirs Info-directory-list))) + (append (list . ,info-dirs) Info-directory-list))) (current-buffer)))) ;; Use `\s' instead of a space character, so this code chunk is not ;; mistaken for an actual file-local section of package.el. diff --git a/lisp/emacs-lisp/warnings.el b/lisp/emacs-lisp/warnings.el index 2e930f6bbc8..6c77d57a6ba 100644 --- a/lisp/emacs-lisp/warnings.el +++ b/lisp/emacs-lisp/warnings.el @@ -176,6 +176,9 @@ also call that function before the next warning.") "Format for displaying the warning type in the warning message. The result of formatting the type this way gets included in the message under the control of the string in `warning-levels'.") +;;;###autoload +(defvar warning-inhibit-types nil + "Like `warning-suppress-log-types', but intended for programs to let-bind.") (defun warning-numeric-level (level) "Return a numeric measure of the warning severity level LEVEL." @@ -277,9 +280,10 @@ disable automatic display of the warning or disable the warning entirely by setting `warning-suppress-types' or `warning-suppress-log-types' on their behalf." (if (not (or after-init-time noninteractive (daemonp))) - ;; Ensure warnings that happen early in the startup sequence - ;; are visible when startup completes (bug#20792). - (delay-warning type message level buffer-name) + (or (warning-suppress-p type warning-inhibit-types) + ;; Ensure warnings that happen early in the startup sequence + ;; are visible when startup completes (bug#20792). + (delay-warning type message level buffer-name)) (unless level (setq level :warning)) (unless buffer-name @@ -290,6 +294,7 @@ entirely by setting `warning-suppress-types' or (setq level new))) (or (< (warning-numeric-level level) (warning-numeric-level warning-minimum-log-level)) + (warning-suppress-p type warning-inhibit-types) (warning-suppress-p type warning-suppress-log-types) (let* ((typename (if (consp type) (car type) type)) (old (get-buffer buffer-name)) diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index e9b39a6f3f4..81907ffa462 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el @@ -832,17 +832,23 @@ Make sure you are in an ERC buffer when running this." (with-current-buffer buffer (erc-server-reconnect)))) -(defun erc-server--reconnect-opened (buffer process) +(defun erc--server-reconnect-opened (buffer process) "Reconnect session for server BUFFER using open PROCESS." (when (buffer-live-p buffer) (with-current-buffer buffer - (let ((erc-session-connector (lambda (&rest _) process))) + (let* ((orig erc-session-connector) + (erc-session-connector + (lambda (&rest _) + (setq erc-session-connector orig) + process))) (erc-server-reconnect))))) (defvar-local erc--server-reconnect-timeout nil) -(defvar-local erc--server-reconnect-timeout-check 10) -(defvar-local erc--server-reconnect-timeout-scale-function - #'erc--server-reconnect-timeout-double) + +;; These variables exist for use in unit tests. +(defvar erc--server-reconnect-timeout-check 10) +(defvar erc--server-reconnect-timeout-scale-function + #'erc--server-reconnect-timeout-double) (defun erc--server-reconnect-timeout-double (existing) "Double EXISTING timeout, but cap it at 5 minutes." @@ -851,84 +857,57 @@ Make sure you are in an ERC buffer when running this." (defun erc--recon-probe-reschedule (proc) "Print a message saying PROC's intended peer can't be reached. Then call `erc-schedule-reconnect'." - (let ((buffer (process-buffer proc))) - (when (buffer-live-p buffer) - (with-current-buffer buffer - (let ((erc-server-reconnect-timeout erc--server-reconnect-timeout)) - ;; FIXME either remove this deletion or explain why the one - ;; performed by `erc-schedule-reconnect' is insufficient. - ;; Perhaps because `proc' may not equal `erc-server-process'? - (when proc ; conn refused w/o :nowait - (delete-process proc)) - (erc-display-message nil '(notice error) buffer - 'recon-probe-nobody-home) - (erc-schedule-reconnect buffer 0)))))) + (let ((buffer (or (and-let* ((proc) + (buffer (process-buffer proc)) + ((buffer-live-p buffer)) + (buffer))) + (current-buffer)))) + (with-current-buffer buffer + (let ((erc-server-reconnect-timeout + (or erc--server-reconnect-timeout + erc-server-reconnect-timeout))) + (when (and proc (not (eq proc erc-server-process))) + (set-process-sentinel proc #'ignore) + (delete-process proc)) + (erc-display-message nil '(notice error) buffer + 'recon-probe-nobody-home) + (erc-schedule-reconnect buffer 0))))) + +(defvar erc-server-delayed-check-reconnect-reuse-process-p t + "Whether to reuse a successful probe as the session process.") (defun erc--recon-probe-sentinel (proc event) "Send a \"PING\" to PROC's peer on an \"open\" EVENT. Otherwise, try connecting from scratch again after timeout." (pcase event ("open\n" - (let ((cookie (time-convert nil 'integer))) - (process-put proc 'erc--reconnect-cookie cookie) - ;; FIXME account for possible `file-error' when sending. - (run-at-time nil nil #'process-send-string proc - (format "PING %d\r\n" cookie)))) - ((and "connection broken by remote peer\n" - (guard (process-get proc 'erc--reconnect-cookie)) - (let buffer (process-buffer proc)) - (guard (buffer-live-p buffer))) - ;; This can run, for example, if the client dials a TLS-terminating - ;; endpoint with a non-TLS opener, like `erc-open-tls-stream', or - ;; if the server doesn't take kindly to an opening "PING" during - ;; connection registration. - (with-current-buffer buffer - (delete-process proc) - ;; Undo latest penalizing timeout increment. - (setq erc--server-reconnect-timeout - (max 1 (/ erc--server-reconnect-timeout 2))) - (erc-display-message nil '(notice error) buffer 'recon-probe-hung-up - ?t erc--server-reconnect-timeout) - (run-at-time erc--server-reconnect-timeout - nil #'erc-server-delayed-reconnect buffer))) + (set-process-sentinel proc #'ignore) + ;; This has been observed to possibly raise a `file-error'. + (if erc-server-delayed-check-reconnect-reuse-process-p + (run-at-time nil nil #'erc--server-reconnect-opened + (process-buffer proc) proc) + (run-at-time nil nil #'delete-process proc) + (run-at-time nil nil #'erc-server-delayed-reconnect + (process-buffer proc)))) ((or "connection broken by remote peer\n" (rx bot "failed")) (run-at-time nil nil #'erc--recon-probe-reschedule proc)))) -(defun erc--recon-probe-filter (proc string) - "Reconnect, reusing PROC if STRING contains a \"PONG\"." - (when-let* ((buffer (process-buffer proc)) - (buffer-live-p buffer)) - (with-current-buffer buffer - (setq erc--server-reconnect-timeout nil)) - (if-let* ; reuse proc if string has complete message - ((cookie (process-get proc 'erc--reconnect-cookie)) - ;; Accommodate a leading ": ". - ((string-suffix-p (format "PONG %d\r\n" cookie) string))) - (progn - (erc-log-irc-protocol string nil) - (set-process-sentinel proc #'ignore) - (set-process-filter proc nil) - (run-at-time nil nil #'erc-server--reconnect-opened buffer proc)) - (delete-process proc) - (run-at-time nil nil #'erc-server-delayed-reconnect buffer)))) - -(defun erc--recon-probe-check (proc tmrx) - "Restart auto-reconnect probe if PROC has failed or TIMER has EXPIRE'd. -Expect TMRX to be a cons cell of (EXPIRE . TIMER)." - (let* ((status (process-status proc)) - (expiredp (time-less-p (pop tmrx) (current-time))) - (buffer (process-buffer proc))) - (when (or expiredp - (not (eq 'connect status)) ; e.g., `closed' - (not (buffer-live-p buffer))) - (cancel-timer tmrx)) +(defun erc--recon-probe-check (proc expire) + "Restart reconnect probe if PROC has failed or EXPIRE time has passed. +Otherwise, if PROC's buffer is live and its status is `connect', arrange +for running again in 1 second." + (let* ((buffer (process-buffer proc)) + ;; + status) (cond ((not (buffer-live-p buffer))) - (expiredp + ((time-less-p expire (current-time)) + ;; TODO convert into proper catalog message for i18n. (erc-display-message nil 'error buffer "Timed out while dialing...") - (delete-process proc) (erc--recon-probe-reschedule proc)) - ((eq 'failed status) - (erc--recon-probe-reschedule proc))))) + ((eq (setq status (process-status proc)) 'failed) + (erc--recon-probe-reschedule proc)) + ((eq status 'connect) + (run-at-time 1 nil #'erc--recon-probe-check proc expire))))) ;; This probing strategy may appear to hang at various junctures. It's ;; assumed that when *Messages* contains "Waiting for socket ..." or @@ -951,26 +930,31 @@ this function as their reconnector." erc-server-reconnect-timeout))) (condition-case _ (let* ((cert erc-session-client-certificate) - (tmrx (list (time-add erc--server-reconnect-timeout-check - (current-time)))) (server (if (string-match erc--server-connect-dumb-ipv6-regexp erc-session-server) (match-string 1 erc-session-server) erc-session-server)) - (proc (apply erc-session-connector "*erc-connectivity-check*" + (name (if erc-server-delayed-check-reconnect-reuse-process-p + (format "erc-%s-%s" server erc-session-port) + "*erc-connectivity-check*")) + (proc (apply erc-session-connector name nil server erc-session-port - (and cert (list :client-certificate cert))))) - (setcdr tmrx (run-at-time 1 1 #'erc--recon-probe-check proc tmrx)) - (set-process-filter proc #'erc--recon-probe-filter) - (set-process-sentinel proc #'erc--recon-probe-sentinel) + (and cert (list :client-certificate cert)))) + (status (process-status proc))) (set-process-buffer proc buffer) - ;; Should `erc-server-process' also be set to `proc' here so - ;; that `erc-schedule-reconnect' can use it? - (cl-assert (processp proc)) - (when (eq (process-status proc) 'open) ; :nowait is nil - (erc--recon-probe-sentinel proc "open\n"))) + (set-process-filter proc #'ignore) + (if (not (eq status 'connect)) ; :nowait is nil + (erc--recon-probe-sentinel proc (if (eq status 'open) + "open\n" + "failed")) + (run-at-time 1 nil #'erc--recon-probe-check proc + (time-add erc--server-reconnect-timeout-check + (current-time))) + (set-process-sentinel proc #'erc--recon-probe-sentinel))) ;; E.g., "make client process failed" "Connection refused". - (file-error (erc--recon-probe-reschedule nil)))))) + (file-error (erc--recon-probe-reschedule nil)) + ;; C-g during blocking connect, like with the SOCKS connector. + (quit (erc--cancel-auto-reconnect-timer)))))) (defun erc-server-prefer-check-reconnect (buffer) "Defer to another reconnector based on BUFFER's `erc-session-connector'. @@ -1085,7 +1069,6 @@ When `erc-server-reconnect-attempts' is a number, increment ?i (if count erc-server-reconnect-count "N") ?n (if count erc-server-reconnect-attempts "A")) (set-process-sentinel proc #'ignore) - (set-process-filter proc nil) (delete-process proc) (erc-update-mode-line) (setq erc-server-reconnecting nil diff --git a/lisp/files-x.el b/lisp/files-x.el index ee15993978b..45159cac269 100644 --- a/lisp/files-x.el +++ b/lisp/files-x.el @@ -159,7 +159,10 @@ is not `delete' then this function adds the first line containing the string `Local Variables:' and the last line containing the string `End:'. If OP is `delete' then delete all existing settings of VARIABLE -from the Local Variables list ignoring the input argument VALUE." +from the Local Variables list ignoring the input argument VALUE. + +If optional variable INTERACTIVE is non-nil, display a message telling +the user how to make the new value take effect." (catch 'exit (let ((beg (point)) end replaced-pos) (unless enable-local-variables @@ -250,7 +253,10 @@ containing the string `End:'. For adding local variables on the first line of a file, for example for settings like `lexical-binding, which must be specified there, -use the `add-file-local-variable-prop-line' command instead." +use the `add-file-local-variable-prop-line' command instead. + +If optional variable INTERACTIVE is non-nil, display a message telling +the user how to make the new value take effect." (interactive (let ((variable (read-file-local-variable "Add file-local variable"))) ;; Error before reading value. @@ -265,7 +271,10 @@ use the `add-file-local-variable-prop-line' command instead." ;;;###autoload (defun delete-file-local-variable (variable &optional interactive) - "Delete all settings of file-local VARIABLE from the Local Variables list." + "Delete all settings of file-local VARIABLE from the Local Variables list. + +If optional variable INTERACTIVE is non-nil, display a message telling +the user how to make the new value take effect." (interactive (list (read-file-local-variable "Delete file-local variable") t)) (modify-file-local-variable variable nil 'delete interactive)) @@ -281,7 +290,10 @@ If there is no -*- line at the beginning of the current file buffer and OP is not `delete' then this function adds the -*- line. If OP is `delete' then delete all existing settings of VARIABLE -from the -*- line ignoring the input argument VALUE." +from the -*- line ignoring the input argument VALUE. + +If optional variable INTERACTIVE is non-nil, display a message telling +the user how to make the new value take effect." (catch 'exit (let ((beg (point)) end replaced-pos) (unless enable-local-variables @@ -409,7 +421,10 @@ If there is no -*- line at the beginning of the current file buffer then this function adds it. To add variables to the Local Variables list at the end of the file, -use the `add-file-local-variable' command instead." +use the `add-file-local-variable' command instead. + +If optional variable INTERACTIVE is non-nil, display a message telling +the user how to make the new value take effect." (interactive (let ((variable (read-file-local-variable "Add -*- file-local variable"))) (list variable (read-file-local-variable-value variable) t))) @@ -417,7 +432,10 @@ use the `add-file-local-variable' command instead." ;;;###autoload (defun delete-file-local-variable-prop-line (variable &optional interactive) - "Delete all settings of file-local VARIABLE from the -*- line." + "Delete all settings of file-local VARIABLE from the -*- line. + +If optional variable INTERACTIVE is non-nil, display a message telling +the user how to make the new value take effect." (interactive (list (read-file-local-variable "Delete -*- file-local variable") t)) (modify-file-local-variable-prop-line variable nil 'delete interactive)) diff --git a/lisp/files.el b/lisp/files.el index eb49f25ee27..56d998410d3 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -2344,6 +2344,9 @@ If PREDICATE is non-nil, only buffers satisfying it are eligible, and others are ignored. PREDICATE is called with the buffer as the only argument, but not with the buffer as the current buffer. +Note that indirect buffers don't count as visiting files, +and that therefore this function only ever returns base buffers. + If there is no such live buffer, return nil." (or (let ((buf (get-file-buffer filename))) (when (and buf (or (not predicate) (funcall predicate buf))) buf)) @@ -4277,6 +4280,52 @@ all the specified local variables, but ignores any settings of \"mode:\"." (push elem file-local-variables-alist))) (hack-local-variables-apply)))))) +(defun internal--get-default-lexical-binding (from) + (let ((mib (lambda (node) (buttonize node (lambda (_) (info node)) + nil "mouse-2: Jump to Info node")))) + (or (and (bufferp from) (zerop (buffer-size from))) + (and (stringp from) + (eql 0 (file-attribute-size (file-attributes from)))) + (let ((source + (if (not (and (bufferp from) + (string-match-p "\\` \\*load\\*\\(-[0-9]+\\)?\\'" + (buffer-name from)) + load-file-name)) + from + (abbreviate-file-name load-file-name)))) + (condition-case nil + (display-warning + `(files missing-lexbind-cookie + ,(if (bufferp source) 'eval-buffer source)) + (format-message "Missing `lexical-binding' cookie in %S. +You can add one with `M-x %s RET'. +See `%s' and `%s' +for more information." + source + (buttonize "elisp-enable-lexical-binding" + (lambda (_) + (pop-to-buffer + (if (bufferp source) source + (find-file-noselect source))) + (call-interactively + #'elisp-enable-lexical-binding)) + nil "mouse-2: Add cookie") + (funcall mib "(elisp)Selecting Lisp Dialect") + (funcall mib "(elisp)Converting to Lexical Binding")) + :warning) + ;; In various corner-case situations, `display-warning' may + ;; fail (e.g. not yet defined, or can't be (auto)loaded), + ;; so use a simple fallback that won't get in the way. + (error + ;; But not if this particular warning is disabled. + (unless (equal warning-inhibit-types + '((files missing-lexbind-cookie))) + (message "Missing `lexical-binding' cookie in %S" source)))))) + (default-toplevel-value 'lexical-binding))) + +(setq internal--get-default-lexical-binding-function + #'internal--get-default-lexical-binding) + (defun hack-local-variables--find-variables (&optional handle-mode) "Return all local variables in the current buffer. If HANDLE-MODE is nil, we gather all the specified local @@ -7067,14 +7116,21 @@ A customized `revert-buffer-function' need not run this hook.") (defvar revert-buffer-preserve-modes) (defvar revert-buffer-restore-functions '(revert-buffer-restore-read-only) - "Functions to preserve any state during `revert-buffer'. -The value of this variable is a list of functions that are called before -reverting the buffer. Each of these functions are called without -arguments and should return a lambda that can restore a previous state -of the buffer. Then after reverting the buffer each of these lambdas -will be called one by one in the order of the list to restore previous -states of the buffer. An example of the buffer state is keeping the -buffer read-only, or keeping minor modes, etc.") + "Functions to preserve buffer state during `revert-buffer'. +The value of this variable is a list of functions that are called +before reverting the buffer. Each of these functions is called without +arguments and should return a lambda form that can restore a previous +state of the buffer. After reverting the buffer, each of these lambda +forms will be called in order to restore previous states of the buffer. +An example of the buffer state is keeping the buffer read-only, or +keeping minor modes, etc. + +The default value restores the buffer's read-only state to what it +was before reverting. + +Set this variable to nil to disable restoring any buffer state +attributes from before reverting. Then only the file from which the +buffer is reverted will determine the buffer's state after reverting.") (defun revert-buffer-restore-read-only () "Preserve read-only state for `revert-buffer'." diff --git a/lisp/filesets.el b/lisp/filesets.el index 5318374fae0..c1a4499388c 100644 --- a/lisp/filesets.el +++ b/lisp/filesets.el @@ -671,69 +671,70 @@ In order to view pdf or rtf files in an Emacs buffer, you could use these: (boolean :tag "Boolean"))))))) (defcustom filesets-ingroup-patterns - '(("^.+\\.tex$" t + ;; FIXME: This value does not seem realistically editable via the Custom UI. + `(("^.+\\.tex$" t (((:name "Package") (:pattern "\\\\usepackage\\W*\\(\\[[^]]*\\]\\W*\\)?{\\W*\\(.+\\)\\W*}") (:match-number 2) (:stub-flag t) - (:get-file-name (lambda (master file) - (filesets-which-file master - (concat file ".sty") - (filesets-convert-path-list - (or (getenv "MY_TEXINPUTS") - (getenv "TEXINPUTS"))))))) + (:get-file-name ,(lambda (master file) + (filesets-which-file master + (concat file ".sty") + (filesets-convert-path-list + (or (getenv "MY_TEXINPUTS") + (getenv "TEXINPUTS"))))))) ((:name "Include") (:pattern "\\\\include\\W*{\\W*\\(.+\\)\\W*}") - (:get-file-name (lambda (master file) - (filesets-which-file master - (concat file ".tex") - (filesets-convert-path-list - (or (getenv "MY_TEXINPUTS") - (getenv "TEXINPUTS")))))) + (:get-file-name ,(lambda (master file) + (filesets-which-file master + (concat file ".tex") + (filesets-convert-path-list + (or (getenv "MY_TEXINPUTS") + (getenv "TEXINPUTS")))))) (:scan-depth 5)) ((:name "Input") (:pattern "\\\\input\\W*{\\W*\\(.+\\)\\W*}") - (:stubp (lambda (a b) (not (filesets-files-in-same-directory-p a b)))) - (:get-file-name (lambda (master file) - (filesets-which-file master - (concat file ".tex") - (filesets-convert-path-list - (or (getenv "MY_TEXINPUTS") - (getenv "TEXINPUTS")))))) + (:stubp ,(lambda (a b) (not (filesets-files-in-same-directory-p a b)))) + (:get-file-name ,(lambda (master file) + (filesets-which-file master + (concat file ".tex") + (filesets-convert-path-list + (or (getenv "MY_TEXINPUTS") + (getenv "TEXINPUTS")))))) (:scan-depth 5)) ((:name "Bibliography") (:pattern "\\\\bibliography\\W*{\\W*\\(.+\\)\\W*}") - (:get-file-name (lambda (master file) - (filesets-which-file master - (concat file ".bib") - (filesets-convert-path-list - (or (getenv "MY_BIBINPUTS") - (getenv "BIBINPUTS"))))))))) + (:get-file-name ,(lambda (master file) + (filesets-which-file master + (concat file ".bib") + (filesets-convert-path-list + (or (getenv "MY_BIBINPUTS") + (getenv "BIBINPUTS"))))))))) ("^.+\\.el$" t (((:name "Require") (:pattern "(require\\W+'\\(.+\\))") - (:stubp (lambda (a b) (not (filesets-files-in-same-directory-p a b)))) - (:get-file-name (lambda (master file) - (filesets-which-file master - (concat file ".el") - load-path)))) + (:stubp ,(lambda (a b) (not (filesets-files-in-same-directory-p a b)))) + (:get-file-name ,(lambda (master file) + (filesets-which-file master + (concat file ".el") + load-path)))) ((:name "Load") (:pattern "(load\\(-library\\)?\\W+\"\\(.+\\)\")") (:match-number 2) - (:get-file-name (lambda (master file) - (filesets-which-file master file load-path)))))) + (:get-file-name ,(lambda (master file) + (filesets-which-file master file load-path)))))) ("^\\([A-ZÄÖÜ][a-zäöüß]+\\([A-ZÄÖÜ][a-zäöüß]+\\)+\\)$" t (((:pattern "\\<\\([A-ZÄÖÜ][a-zäöüß]+\\([A-ZÄÖÜ][a-zäöüß]+\\)+\\)\\>") (:scan-depth 5) - (:stubp (lambda (a b) (not (filesets-files-in-same-directory-p a b)))) + (:stubp ,(lambda (a b) (not (filesets-files-in-same-directory-p a b)))) (:case-sensitive t) - (:get-file-name (lambda (master file) - (filesets-which-file - master - file - (if (boundp 'emacs-wiki-directories) - emacs-wiki-directories - nil)))))))) + (:get-file-name ,(lambda (master file) + (filesets-which-file + master + file + (if (boundp 'emacs-wiki-directories) + emacs-wiki-directories + nil)))))))) "Inclusion group definitions. @@ -1227,7 +1228,7 @@ Use the viewer defined in EV-ENTRY (a valid element of (shell-quote-argument (if (functionp this) (funcall this) this)))) - fmt "") + fmt) (shell-quote-argument file)))) (output (cond @@ -2335,6 +2336,7 @@ fileset thinks this is necessary or not." (delete-file filesets-menu-cache-file)) ;;(message "Filesets: saving menu cache") (with-temp-buffer + (insert ";; -*- mode: emacs-lisp; lexical-binding: t -*-\n") (dolist (this filesets-menu-cache-contents) (if (get this 'custom-type) (progn @@ -2427,7 +2429,8 @@ We apologize for the inconvenience."))) (cond ((and (not (equal filesets-menu-cache-file "")) (file-readable-p filesets-menu-cache-file)) - (load-file filesets-menu-cache-file) + (let ((warning-inhibit-types '((files missing-lexbind-cookie)))) + (load-file filesets-menu-cache-file)) (if (and (equal filesets-cache-version filesets-version) (if filesets-cache-hostname-flag (equal filesets-cache-hostname (system-name)) diff --git a/lisp/frameset.el b/lisp/frameset.el index 1796d2af072..ee30f77c3ba 100644 --- a/lisp/frameset.el +++ b/lisp/frameset.el @@ -1412,15 +1412,15 @@ All keyword parameters default to nil." :reuse-frames (if arg t 'match) :cleanup-frames (if arg ;; delete frames - nil + t ;; iconify frames (lambda (frame action) (pcase action - ('rejected (iconify-frame frame)) + (:rejected (iconify-frame frame)) ;; In the unexpected case that a frame was a candidate ;; (matching frame id) and yet not restored, remove it ;; because it is in fact a duplicate. - ('ignored (delete-frame frame)))))) + (:ignored (delete-frame frame)))))) ;; Restore selected frame, buffer and point. (let ((frame (frameset-frame-with-id (frameset-register-frame-id data))) diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el index d167a7c4dd6..7133df15322 100644 --- a/lisp/gnus/gnus-start.el +++ b/lisp/gnus/gnus-start.el @@ -892,9 +892,9 @@ If REGEXP is given, lines that match it will be deleted." (when (or (file-exists-p auto) (file-exists-p dribble-file)) ;; Load whichever file is newest -- the auto save file ;; or the "real" file. - (if (file-newer-than-file-p auto dribble-file) - (nnheader-insert-file-contents auto) - (nnheader-insert-file-contents dribble-file)) + (nnheader-insert-file-contents + (if (file-newer-than-file-p auto dribble-file) + auto dribble-file)) (unless (zerop (buffer-size)) (set-buffer-modified-p t)) ;; Set the file modes to reflect the .newsrc file modes. @@ -916,9 +916,10 @@ If REGEXP is given, lines that match it will be deleted." (defun gnus-dribble-eval-file () (when gnus-dribble-eval-file (setq gnus-dribble-eval-file nil) - (let ((gnus-dribble-ignore t)) - (with-current-buffer gnus-dribble-buffer - (eval-buffer (current-buffer)))))) + (with-current-buffer gnus-dribble-buffer + (let ((gnus-dribble-ignore t) + (warning-inhibit-types '((files missing-lexbind-cookie)))) + (eval-buffer (current-buffer)))))) (defun gnus-dribble-delete-file () (when (file-exists-p (gnus-dribble-file-name)) diff --git a/lisp/gnus/nnfeed.el b/lisp/gnus/nnfeed.el index 3ae3d759fdb..6a65633b7e0 100644 --- a/lisp/gnus/nnfeed.el +++ b/lisp/gnus/nnfeed.el @@ -294,7 +294,7 @@ group names to their data, which should be a vector of the form ((hash-table-p s))) (with-temp-file f (insert ";;;; -*- mode: lisp-data -*- DO NOT EDIT\n") - (prin1 s (current-buffer)) + (prin1 s (current-buffer) t) (insert "\n") t) t) @@ -609,15 +609,17 @@ Only HEADERS of a type included in MIME are considered." (deffoo nnfeed-request-list (&optional server) (with-current-buffer nntp-server-buffer (erase-buffer) - (when-let* ((p (point)) - (s (nnfeed--parse-feed - (or server (nnfeed--current-server-no-prefix)))) - ((hash-table-p s))) - (maphash (lambda (group g) - (insert (format "\"%s\" %s %s y\n" - group (aref g 3) (aref g 4)))) - s) - (not (= (point) p))))) + (if-let* ((p (point)) + (s (nnfeed--parse-feed + (or server (nnfeed--current-server-no-prefix)))) + ((hash-table-p s))) + (progn + (maphash (lambda (group g) + (insert (format "\"%s\" %s %s y\n" + group (aref g 3) (aref g 4)))) + s) + (not (= (point) p))) + (nnheader-report 'nnfeed (nnheader-get-report nnfeed-backend))))) (deffoo nnfeed-request-post (&optional _server) (nnheader-report nnfeed-backend "%s is a read only backend" nnfeed-backend)) diff --git a/lisp/help-fns.el b/lisp/help-fns.el index ee615bfea29..e7bbd25b413 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -135,11 +135,11 @@ with the current prefix. The files are chosen according to :version "26.3") (defcustom help-enable-variable-value-editing nil - "If non-nil, allow editing values in *Help* buffers. + "If non-nil, allow editing variable values in *Help* buffers. To edit the value of a variable, use \\[describe-variable] to display a \"*Help*\" buffer, move point after the text -\"Its value is\" and type \\`e'. +\"Its value is\" and type \\`e' to invoke `help-fns-edit-variable'. Values that aren't readable by the Emacs Lisp reader can't be edited even if this option is enabled." @@ -875,20 +875,6 @@ the C sources, too." (function-get function 'disabled)) (insert " This function is disabled.\n"))) -(add-hook 'help-fns-describe-variable-functions #'help--recommend-setopt) -(defun help--recommend-setopt (symbol) - ;; TODO: This would be better if added to the docstring itself, but I - ;; ran into `byte-compile-dynamic-docstring' and gave up. - (when (and (get symbol 'custom-set) - ;; Don't override manually written documentation. - (not (string-match (rx word-start "setopt" word-end) - (documentation-property - symbol 'variable-documentation)))) - ;; FIXME: `princ` removes text properties added by s-c-k. - (princ (substitute-command-keys "\ -Setting this variable with `setq' has no effect; use either `setopt' -or \\[customize-option] to change its value.\n\n")))) - (defun help-fns--first-release-regexp (symbol) (let* ((name (symbol-name symbol)) (quoted (regexp-quote name))) @@ -1569,17 +1555,35 @@ it is displayed along with the global value." (put 'help-fns-edit-variable 'disabled t) (defun help-fns-edit-variable () - "Edit the variable under point." + "Edit the variable value at point in \"*Help*\" buffer. +This command only works if `help-enable-variable-value-editing' is non-nil. + +To edit the value of a variable, use \\[describe-variable] followed by the name +of a variable, to display a \"*Help*\" buffer, move point to +the variable's value, usually after the text \"Its value is\", and +type \\`e' to invoke this command. + +Values that aren't readable by the Emacs Lisp reader can't be edited +by this command." (declare (completion ignore)) (interactive) (let ((var (get-text-property (point) 'help-fns--edit-variable))) (unless var (error "No variable under point")) - (let ((str (read-string-from-buffer - (format ";; Edit the `%s' variable." (nth 0 var)) - (prin1-to-string (nth 1 var))))) - (set (nth 0 var) (read str)) - (revert-buffer)))) + (string-edit + (format ";; Edit the `%s' variable." (nth 0 var)) + (prin1-to-string (nth 1 var)) + (lambda (edited) + (set (nth 0 var) edited) + (exit-recursive-edit)) + :abort-callback + (lambda () + (exit-recursive-edit) + (error "Aborted edit, variable unchanged")) + :major-mode #'emacs-lisp-mode + :read #'read) + (recursive-edit) + (revert-buffer))) (autoload 'shortdoc-help-fns-examples-function "shortdoc") @@ -1602,12 +1606,28 @@ it is displayed along with the global value." (defun help-fns--customize-variable (variable &optional text) ;; Make a link to customize if this variable can be customized. (when (custom-variable-p variable) - (let ((customize-label "customize")) + (let ((customize-label "customize") + (custom-set (get variable 'custom-set)) + (opoint (with-current-buffer standard-output + (point)))) (princ (concat " You can " customize-label (or text " this variable."))) + (when (and custom-set + ;; Don't override manually written documentation. + (not (string-match (rx word-start "setopt" word-end) + (documentation-property + variable 'variable-documentation)))) + (princ (substitute-quotes + (concat "\n Setting this variable directly with `setq' may not take effect;" + "\n use either customize or `setopt'" + ;; Skip text if `custom-set' property is an + ;; anonymous function. + (when (symbolp custom-set) + (concat ", or call `" (symbol-name custom-set) "'")) + ".")))) (with-current-buffer standard-output (save-excursion - (re-search-backward (concat "\\(" customize-label "\\)")) - (help-xref-button 1 'help-customize-variable variable))) + (while (re-search-backward (concat "\\(" customize-label "\\)") opoint t) + (help-xref-button 1 'help-customize-variable variable)))) (terpri)))) (add-hook 'help-fns-describe-variable-functions @@ -1965,7 +1985,8 @@ current buffer and the selected frame, respectively." (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)) + (let ((help-mode--current-data help-mode--current-data)) + (help-setup-xref (list #'describe-symbol symbol) nil))) (goto-char (point-max)) (help-xref--navigation-buttons) (goto-char (point-min)))))) diff --git a/lisp/help.el b/lisp/help.el index b0c003ed16a..15e7cecf156 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -2191,7 +2191,10 @@ The `temp-buffer-window-setup-hook' hook is called." (let ((msg (eval help-form t))) (if (stringp msg) (with-output-to-temp-buffer " *Char Help*" - (princ msg))))) + ;; Use `insert' instead of `princ' so that keys in `help-form' + ;; are displayed with `help-key-binding' face (bug#77118). + (with-current-buffer standard-output + (insert msg)))))) (defun help--append-keystrokes-help (str) (let* ((keys (this-single-command-keys)) diff --git a/lisp/icomplete.el b/lisp/icomplete.el index d0cc5674ba7..35842b53e6b 100644 --- a/lisp/icomplete.el +++ b/lisp/icomplete.el @@ -884,7 +884,7 @@ by `group-function''s second \"transformation\" protocol." else collect (list tr prefix suffix )) annotated))) -(defun icomplete-vertical--adjust-lines-for-column (lines buffer data) +(defun icomplete--adjust-lines-for-column (lines buffer data) "Adjust the LINES to align with the column in BUFFER based on DATA." (if icomplete-vertical-in-buffer-adjust-list (let* ((column (current-column)) @@ -914,7 +914,7 @@ by `group-function''s second \"transformation\" protocol." lines)) lines)) -(defun icomplete-vertical--ensure-visible-lines-inside-buffer () +(defun icomplete--ensure-visible-lines-inside-buffer () "Ensure the completion list is visible in regular buffers only. Scrolls the screen to be at least `icomplete-prospects-height' real lines away from the bottom. Counts wrapped lines as real lines." @@ -925,10 +925,9 @@ away from the bottom. Counts wrapped lines as real lines." (when (< lines-to-bottom icomplete-prospects-height) (scroll-up (- icomplete-prospects-height lines-to-bottom)))))) -(defun icomplete-vertical--add-indicator-to-selected (comp) - "Add indicators to the selected/unselected COMP completions." - (if (and icomplete-vertical-render-prefix-indicator - (get-text-property 0 'icomplete-selected comp)) +(defun icomplete--add-indicator-to-selected (comp) + "Add indicator to completion COMP according to its selection state." + (if (get-text-property 0 'icomplete-selected comp) (concat (propertize icomplete-vertical-selected-prefix-indicator 'face 'icomplete-vertical-selected-prefix-indicator-face) comp) @@ -957,11 +956,11 @@ away from the bottom. Counts wrapped lines as real lines." (when (and icomplete-scroll (not icomplete--scrolled-completions) (not icomplete--scrolled-past)) - (icomplete-vertical--ensure-visible-lines-inside-buffer)) + (icomplete--ensure-visible-lines-inside-buffer)) (when (and icomplete-scroll icomplete--scrolled-completions (null icomplete--scrolled-past)) - (icomplete-vertical--ensure-visible-lines-inside-buffer) + (icomplete--ensure-visible-lines-inside-buffer) (cl-loop with preds for (comp . rest) on comps when (equal comp (car icomplete--scrolled-completions)) @@ -1012,8 +1011,11 @@ away from the bottom. Counts wrapped lines as real lines." ;; Serialize completions and section titles into a list ;; of lines to render (cl-loop - for (comp prefix suffix section) in tuples - do (setq comp (icomplete-vertical--add-indicator-to-selected comp)) + for (comp-no-indicator prefix suffix section) in tuples + for comp = + (if icomplete-vertical-render-prefix-indicator + (icomplete--add-indicator-to-selected comp-no-indicator) + comp-no-indicator) when section collect (propertize section 'face 'icomplete-section) into lines-aux and count 1 into nsections-aux @@ -1039,7 +1041,7 @@ away from the bottom. Counts wrapped lines as real lines." (t (min (ceiling nsections 2) (length scroll-above)))) lines)) (when icomplete--in-region-buffer - (setq lines (icomplete-vertical--adjust-lines-for-column + (setq lines (icomplete--adjust-lines-for-column lines icomplete--in-region-buffer completion-in-region--data))) ;; At long last, render final string return value. This may still ;; kick out lines at the end. diff --git a/lisp/indent-aux.el b/lisp/indent-aux.el index 27d5875bc22..eeb8f1ee6bb 100644 --- a/lisp/indent-aux.el +++ b/lisp/indent-aux.el @@ -45,10 +45,14 @@ is yanked." end (max a b))) (let ((indentation (save-excursion (goto-char beg) (current-column))) + (i-t-m indent-tabs-mode) (text (if delete (delete-and-extract-region beg end) (buffer-substring beg end)))) (with-temp-buffer + ;; Indent/deindent the same as the major mode in the original + ;; buffer. + (setq indent-tabs-mode i-t-m) (insert text) (indent-rigidly (point-min) (point-max) (- indentation)) diff --git a/lisp/international/fontset.el b/lisp/international/fontset.el index aaa72f961bc..083c3b1ad3c 100644 --- a/lisp/international/fontset.el +++ b/lisp/international/fontset.el @@ -244,6 +244,8 @@ (lydian #x10920) (kharoshthi #x10A00) (manichaean #x10AC0) + (avestan #x10B00) + (old-turkic #x10C00 #x10C01) (hanifi-rohingya #x10D00 #x10D24 #x10D39) (garay #x10D50 #x10D70 #x10D4A #x10D41) (yezidi #x10E80) @@ -254,6 +256,7 @@ (old-uyghur #x10F70) (brahmi #x11013 #x11045 #x11052 #x11065) (kaithi #x1108D #x110B0 #x110BD) + (chakma #x11103 #x11127) (mahajani #x11150) (sharada #x11191 #x111B3 #x111CD) (khojki #x11200) @@ -846,11 +849,13 @@ yezidi kharoshthi manichaean + avestan chorasmian elymaic old-uyghur brahmi kaithi + chakma sharada grantha tirhuta @@ -871,6 +876,7 @@ mahajani sogdian old-sogdian + old-turkic nabataean palmyrene linear-a diff --git a/lisp/international/mule.el b/lisp/international/mule.el index f72cc815287..cb2aa5b9480 100644 --- a/lisp/international/mule.el +++ b/lisp/international/mule.el @@ -528,6 +528,32 @@ per-character basis, this may not be accurate." (throw 'tag3 charset))) charset-list) nil))))))))))) + +(defun char-displayable-on-frame-p (char &optional frame) + "Return non-nil if CHAR can be displayed in FRAME. +FRAME nil means the selected frame. + +This function provides a stricter test than `char-displayable-p' does +for determining if a character will display properly: in the graphical +case, it does not check whether the underlying terminal can encode the +character. + +Specifically, this function returns non-nil: + +- for a text terminal, if `char-displayable-p' returns non-nil. + +- for a graphical terminal, if `char-displayable-p' returns either t or + a font object. + +The two functions differ in behavior (i.e., `char-displayable-strict-p' +returns nil but `char-displayable-p' does not) if the underlying +terminal is graphical and can encode the character, but FRAME cannot." + (let ((display-capability (with-selected-frame (or frame (selected-frame)) + (char-displayable-p char)))) + (if (display-graphic-p frame) + (or (eq display-capability t) + (fontp display-capability)) + display-capability))) ;; Save the ASCII case table in case we need it later. Some locales ;; (such as Turkish) modify the case behavior of ASCII characters, diff --git a/lisp/isearch.el b/lisp/isearch.el index e37d1814eb7..6b759f4ad3e 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -1950,7 +1950,14 @@ Use `isearch-exit' to quit without signaling." (funcall isearch-wrap-function) (goto-char (if isearch-forward (point-min) (point-max)))))) ;; C-s in reverse or C-r in forward, change direction. - (if (and isearch-other-end isearch-repeat-on-direction-change) + (if (and isearch-other-end isearch-repeat-on-direction-change + (or (null isearch-cmds) + ;; Go to 'isearch-other-end' only when point is still + ;; on the current match. However, after scrolling + ;; (when 'isearch-allow-scroll' is 'unlimited'), + ;; repeat the reversed search from a new position + ;; where point was moved during scrolling (bug#78074). + (eq (isearch--state-point (car isearch-cmds)) (point)))) (goto-char isearch-other-end)) (setq isearch-forward (not isearch-forward) isearch-success t)) @@ -3051,11 +3058,11 @@ See also the related option `isearch-allow-motion'." (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 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'." @@ -3068,8 +3075,8 @@ See also the related options `isearch-motion-changes-direction' and "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 +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)) @@ -4618,7 +4625,13 @@ defaults to the value of `isearch-search-fun-default' when nil." ;; Otherwise, try to search for the next property. (unless beg (setq beg (funcall next-fun old)) - (when beg (goto-char beg))) + (when beg + (if (or (null bound) + (if isearch-forward + (< beg bound) + (> beg bound))) + (goto-char beg) + (setq beg nil)))) ;; Non-nil `beg' means there are more properties. (while (and beg (not found)) ;; Search for the end of the current property. @@ -4668,7 +4681,13 @@ defaults to the value of `isearch-search-fun-default' when nil." ;; Get the next text property. (unless found (setq beg (funcall next-fun end)) - (when beg (goto-char beg)))) + (when beg + (if (or (null bound) + (if isearch-forward + (< beg bound) + (> beg bound))) + (goto-char beg) + (setq beg nil))))) (unless found (goto-char old)) found)) diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index c1deb84754d..709e12176d4 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -1452,7 +1452,7 @@ point is moved into the passwords (see `authinfo-hide-elements'). (fn)" t) (autoload 'read-passwd "auth-source" "\ -Read a password, prompting with PROMPT, and return it. +Read a password, prompting with PROMPT, and return password as a string. If optional CONFIRM is non-nil, read the password twice to make sure. Optional DEFAULT is a default password to use instead of empty input. @@ -2296,7 +2296,7 @@ Optional second arg NO-HISTORY means don't record this in the minibuffer history list `bookmark-history'. (fn BOOKMARK-NAME &optional NO-HISTORY)" t) -(defalias 'bookmark-locate 'bookmark-insert-location) +(defalias 'bookmark-locate #'bookmark-insert-location) (autoload 'bookmark-rename "bookmark" "\ Change the name of OLD-NAME bookmark to NEW-NAME name. If called from keyboard, prompt for OLD-NAME and NEW-NAME. @@ -2314,6 +2314,8 @@ name. (autoload 'bookmark-insert "bookmark" "\ Insert the text of the file pointed to by bookmark BOOKMARK-NAME. BOOKMARK-NAME is a bookmark name (a string), not a bookmark record. +Refuse to insert bookmarks if its handler's property `bookmark-inhibit', +which is a list, contains `insert'. You may have a problem using this function if the value of variable `bookmark-alist' is nil. If that happens, you need to load in some @@ -2383,8 +2385,8 @@ Display a list of existing bookmarks. The list is displayed in a buffer named `*Bookmark List*'. The leftmost column displays a D if the bookmark is flagged for deletion, or > if it is flagged for displaying." t) -(defalias 'list-bookmarks 'bookmark-bmenu-list) -(defalias 'edit-bookmarks 'bookmark-bmenu-list) +(defalias 'list-bookmarks #'bookmark-bmenu-list) +(defalias 'edit-bookmarks #'bookmark-bmenu-list) (autoload 'bookmark-bmenu-search "bookmark" "\ Incremental search of bookmarks, hiding the non-matches as we go." '(bookmark-bmenu-mode)) (defvar menu-bar-bookmark-map (let ((map (make-sparse-keymap "Bookmark functions"))) (define-key map [load] '(menu-item "Load a Bookmark File..." bookmark-load :help "Load bookmarks from a bookmark file)")) (define-key map [write] '(menu-item "Save Bookmarks As..." bookmark-write :help "Write bookmarks to a file (reading the file name with the minibuffer)")) (define-key map [save] '(menu-item "Save Bookmarks" bookmark-save :help "Save currently defined bookmarks")) (define-key map [edit] '(menu-item "Edit Bookmark List" bookmark-bmenu-list :help "Display a list of existing bookmarks")) (define-key map [delete] '(menu-item "Delete Bookmark..." bookmark-delete :help "Delete a bookmark from the bookmark list")) (define-key map [delete-all] '(menu-item "Delete all Bookmarks..." bookmark-delete-all :help "Delete all bookmarks from the bookmark list")) (define-key map [rename] '(menu-item "Rename Bookmark..." bookmark-rename :help "Change the name of a bookmark")) (define-key map [locate] '(menu-item "Insert Location..." bookmark-locate :help "Insert the name of the file associated with a bookmark")) (define-key map [insert] '(menu-item "Insert Contents..." bookmark-insert :help "Insert the text of the file pointed to by a bookmark")) (define-key map [set] '(menu-item "Set Bookmark..." bookmark-set :help "Set a bookmark named inside a file.")) (define-key map [jump] '(menu-item "Jump to Bookmark..." bookmark-jump :help "Jump to a bookmark (a point in some file)")) map)) @@ -4081,11 +4083,6 @@ See the documentation of `define-ccl-program' for the detail of CCL program. (fn CCL-PROG &rest ARGS)") (register-definition-prefixes "ccl" '("ccl-")) - -;;; Generated autoloads from cdl.el - -(register-definition-prefixes "cdl" '("cdl-")) - ;;; Generated autoloads from cedet/cedet.el @@ -4222,7 +4219,9 @@ Returns non-nil if any false statements are found. (put 'checkdoc-arguments-in-order-flag 'safe-local-variable #'booleanp) (put 'checkdoc-package-keywords-flag 'safe-local-variable #'booleanp) (put 'checkdoc-verb-check-experimental-flag 'safe-local-variable #'booleanp) +(put 'checkdoc-allow-quoting-nil-and-t 'safe-local-variable #'booleanp) (put 'checkdoc-symbol-words 'safe-local-variable #'list-of-strings-p) +(put 'checkdoc-arguments-missing-flag 'safe-local-variable 'booleanp) (put 'checkdoc-proper-noun-regexp 'safe-local-variable 'stringp) (put 'checkdoc-common-verbs-regexp 'safe-local-variable 'stringp) (autoload 'checkdoc "checkdoc" "\ @@ -4578,7 +4577,7 @@ printer proceeds to the next function on the list. This variable is not used at present, but it is defined in hopes that a future Emacs interpreter will be able to use it.") -(autoload 'cl-incf "cl-lib" "\ +(defalias 'cl-incf #'incf "\ Increment PLACE by X (1 by default). PLACE may be a symbol, or any generalized variable allowed by `setf'. The return value is the incremented value of PLACE. @@ -4586,7 +4585,8 @@ The return value is the incremented value of PLACE. If X is specified, it should be an expression that should evaluate to a number. -(fn PLACE &optional X)" nil t) +This macro is considered deprecated in favor of the built-in macro +`incf' that was added in Emacs 31.1.") (defvar cl-old-struct-compat-mode nil "\ Non-nil if Cl-Old-Struct-Compat mode is enabled. See the `cl-old-struct-compat-mode' command @@ -5392,27 +5392,29 @@ list.") ;;; Generated autoloads from emacs-lisp/cond-star.el +(push '(cond-star 1 0) package--builtin-versions) (autoload 'cond* "cond-star" "\ Extended form of traditional Lisp `cond' construct. A `cond*' construct is a series of clauses, and a clause normally has the form (CONDITION BODY...). CONDITION can be a Lisp expression, as in `cond'. -Or it can be one of `(pcase* PATTERN DATUM)', -`(bind* BINDINGS...)', or `(match* PATTERN DATUM)', +Or it can be one of`(bind* BINDINGS...)', `(match* PATTERN DATUM)', +or `(pcase* PATTERN DATUM)', + +`(bind* BINDINGS...)' means to bind BINDINGS (as if they were in `let*') +for the body of the clause, and all subsequent clauses, since the `bind*' +clause is always a non-exit clause. As a condition, it counts as true +and runs the body of the clause if the first binding's value is non-nil. + +`(match* PATTERN DATUM)' means to match DATUM against the pattern PATTERN +For its patterns, see `match*'. +The condition counts as true if PATTERN matches DATUM. `(pcase* PATTERN DATUM)' means to match DATUM against the pattern PATTERN, using the same pattern syntax as `pcase'. The condition counts as true if PATTERN matches DATUM. -`(bind* BINDINGS...)' means to bind BINDINGS (as if they were in `let*') -for the body of the clause. As a condition, it counts as true -if the first binding's value is non-nil. All the bindings are made -unconditionally for whatever scope they cover. - -`(match* PATTERN DATUM)' is an alternative to `pcase*' that uses another -syntax for its patterns, see `match*'. - When a clause's condition is true, and it exits the `cond*' or is the last clause, the value of the last expression in its body becomes the return value of the `cond*' construct. @@ -5420,12 +5422,12 @@ in its body becomes the return value of the `cond*' construct. Non-exit clause: If a clause has only one element, or if its first element is -a `bind*' clause, this clause never exits the `cond*' construct. +t or a `bind*' clause, this clause never exits the `cond*' construct. Instead, control always falls through to the next clause (if any). All bindings made in CONDITION for the BODY of the non-exit clause are passed along to the rest of the clauses in this `cond*' construct. -\\[match*\\] for documentation of the patterns for use in `match*'. +\\[match*] for documentation of the patterns for use in `match*'. (fn &rest CLAUSES)" nil t) (register-definition-prefixes "cond-star" '("cond*-" "match*")) @@ -5584,6 +5586,10 @@ For details see `conf-mode'. Exec=gimp-2.8 %U Terminal=false +(fn)" t) +(autoload 'conf-npmrc-mode "conf-mode" "\ + + (fn)" t) (register-definition-prefixes "conf-mode" '("conf-")) @@ -7716,7 +7722,7 @@ The directory name or wildcard spec that this Dired directory lists. Local to each Dired buffer. May be a list, in which case the car is the directory name and the cdr is the list of files to mention. The directory name must be absolute, but need not be fully expanded.") - (define-key ctl-x-map "d" 'dired) + (keymap-set ctl-x-map "d" #'dired) (autoload 'dired "dired" "\ \"Edit\" directory DIRNAME--delete, rename, print, etc. some files in it. Optional second argument SWITCHES specifies the options to be used @@ -7741,17 +7747,17 @@ Type \\[describe-mode] after entering Dired for more info. If DIRNAME is already in a Dired buffer, that buffer is used without refresh. (fn DIRNAME &optional SWITCHES)" t) - (define-key ctl-x-4-map "d" 'dired-other-window) + (keymap-set ctl-x-4-map "d" #'dired-other-window) (autoload 'dired-other-window "dired" "\ \"Edit\" directory DIRNAME. Like `dired' but select in another window. (fn DIRNAME &optional SWITCHES)" t) - (define-key ctl-x-5-map "d" 'dired-other-frame) + (keymap-set ctl-x-5-map "d" #'dired-other-frame) (autoload 'dired-other-frame "dired" "\ \"Edit\" directory DIRNAME. Like `dired' but make a new frame. (fn DIRNAME &optional SWITCHES)" t) - (define-key tab-prefix-map "d" 'dired-other-tab) + (keymap-set tab-prefix-map "d" #'dired-other-tab) (autoload 'dired-other-tab "dired" "\ \"Edit\" directory DIRNAME. Like `dired' but make a new tab. @@ -8117,7 +8123,7 @@ modes derived from `text-mode'\". An element with value t means \"use\" and nil means \"don't use\". There's an implicit nil at the end of the list.") (custom-autoload 'global-display-fill-column-indicator-modes "display-fill-column-indicator" t) -(register-definition-prefixes "display-fill-column-indicator" '("display-fill-column-indicator--turn-on")) +(register-definition-prefixes "display-fill-column-indicator" '("display-fill-column-indicator-" "fill-indicator--set-warning")) ;;; Generated autoloads from display-line-numbers.el @@ -8509,7 +8515,6 @@ INIT-VALUE LIGHTER KEYMAP. (fn MODE DOC [KEYWORD VAL ... &rest BODY])" nil t) (function-put 'define-minor-mode 'doc-string-elt 2) (function-put 'define-minor-mode 'lisp-indent-function 'defun) -(defalias 'define-global-minor-mode #'define-globalized-minor-mode) (autoload 'define-globalized-minor-mode "easy-mmode" "\ Make a global mode GLOBAL-MODE corresponding to buffer-local minor MODE. TURN-ON is a function that will be called with no args in every buffer @@ -8592,6 +8597,7 @@ CSS contains a list of syntax specifications of the form (CHAR . SYNTAX). (function-put 'easy-mmode-defsyntax 'lisp-indent-function 1) (define-obsolete-function-alias 'easy-mmode-define-minor-mode #'define-minor-mode "30.1") (define-obsolete-function-alias 'easy-mmode-define-global-mode #'define-globalized-minor-mode "30.1") +(define-obsolete-function-alias 'define-global-minor-mode #'define-globalized-minor-mode "31.1") (register-definition-prefixes "easy-mmode" '("easy-mmode-")) @@ -8987,16 +8993,6 @@ Run hooks in `electric-buffer-menu-mode-hook' on entry. (fn ARG)" t) (register-definition-prefixes "ebuff-menu" '("Electric-buffer-menu-" "electric-buffer-")) - -;;; Generated autoloads from echistory.el - -(autoload 'Electric-command-history-redo-expression "echistory" "\ -Edit current history line in minibuffer and execute result. -With prefix arg NOCONFIRM, execute current line as-is without editing. - -(fn &optional NOCONFIRM)" t) -(register-definition-prefixes "echistory" '("Electric-history-" "electric-")) - ;;; Generated autoloads from ecomplete.el @@ -9117,7 +9113,12 @@ arguments after setting up the Ediff buffers. (autoload 'ediff-current-file "ediff" "\ Start ediff between current buffer and its file on disk. This command can be used instead of `revert-buffer'. If there is -nothing to revert then this command fails." t) +nothing to revert then this command fails. + +Non-interactively, STARTUP-HOOKS is a list of functions that Emacs calls +without arguments after setting up the Ediff buffers. + +(fn &optional STARTUP-HOOKS)" t) (autoload 'ediff-backup "ediff" "\ Run Ediff on FILE and its backup file. Uses the latest backup, if there are several numerical backups. @@ -9687,7 +9688,62 @@ BUFFER is put back into its original major mode. ;;; Generated autoloads from emacs-lisp/eieio.el -(push '(eieio 1 4) package--builtin-versions) +(autoload 'defclass "eieio" "\ +Define NAME as a new class derived from SUPERCLASS with SLOTS. +OPTIONS-AND-DOC is used as the class' options and base documentation. +SUPERCLASSES is a list of superclasses to inherit from, with SLOTS +being the slots residing in that class definition. Supported tags are: + + :initform - Initializing form. + :initarg - Tag used during initialization. + :accessor - Tag used to create a function to access this slot. + :allocation - Specify where the value is stored. + Defaults to `:instance', but could also be `:class'. + :writer - A function symbol which will `write' an object's slot. + :reader - A function symbol which will `read' an object. + :type - The type of data allowed in this slot (see `typep'). + :documentation + - A string documenting use of this slot. + +The following are extensions on CLOS: + :custom - When customizing an object, the custom :type. Public only. + :label - A text string label used for a slot when customizing. + :group - Name of a customization group this slot belongs in. + :printer - A function to call to print the value of a slot. + See `eieio-override-prin1' as an example. + +A class can also have optional options. These options happen in place +of documentation (including a :documentation tag), in addition to +documentation, or not at all. Supported options are: + + :documentation - The doc-string used for this class. + +Options added to EIEIO: + + :allow-nil-initform - Non-nil to skip typechecking of null initforms. + :custom-groups - List of custom group names. Organizes slots into + reasonable groups for customizations. + :abstract - Non-nil to prevent instances of this class. + If a string, use as an error string if someone does + try to make an instance. + :method-invocation-order + - Control the method invocation order if there is + multiple inheritance. Valid values are: + :breadth-first - The default. + :depth-first + +Options in CLOS not supported in EIEIO: + + :metaclass - Class to use in place of `standard-class' + :default-initargs - Initargs to use when initializing new objects of + this class. + +Due to the way class options are set up, you can add any tags you wish, +and reference them using the function `class-option'. + +(fn NAME SUPERCLASSES SLOTS &rest OPTIONS-AND-DOC)" nil t) +(function-put 'defclass 'doc-string-elt 4) +(function-put 'defclass 'lisp-indent-function 'defun) (autoload 'make-instance "eieio" "\ Make a new instance of CLASS based on INITARGS. For example: @@ -9700,7 +9756,7 @@ for each slot. For example: (make-instance \\='foo :slot1 value1 :slotN valueN) (fn CLASS &rest INITARGS)") -(register-definition-prefixes "eieio" '("child-of-class-p" "defclass" "eieio-" "find-class" "obj" "oref" "oset" "same-class-p" "set-slot-value" "slot-" "with-slots")) +(register-definition-prefixes "eieio" '("child-of-class-p" "eieio-" "find-class" "obj" "oref" "oset" "same-class-p" "set-slot-value" "slot-" "with-slots")) ;;; Generated autoloads from emacs-lisp/eieio-base.el @@ -10134,7 +10190,7 @@ name (which will be attached to the mail). You will end up in a Message buffer where you can explain more about the patch. (fn SUBJECT FILE)" t) -(register-definition-prefixes "emacsbug" '("report-emacs-bug-")) +(register-definition-prefixes "emacsbug" '("report-emacs-bug-" "submit-emacs-patch-excluded-maintainers")) ;;; Generated autoloads from vc/emerge.el @@ -10658,8 +10714,8 @@ Example client certificate (CertFP) usage: (erc-tls :server \"irc.libera.chat\" :port 6697 :client-certificate - \\='(\"/home/bandali/my-cert.key\" - \"/home/bandali/my-cert.crt\")) + \\='(\"/home/bandali/my-key.pem\" + \"/home/bandali/my-cert.pem\")) See the alternative entry-point command `erc' as well as Info node `(erc) Connecting' for a fuller description of the various @@ -10939,26 +10995,29 @@ Display the documentation for TEST-OR-TEST-NAME (a symbol or ert-test). (autoload 'ert-font-lock-deftest "ert-font-lock" "\ Define test NAME (a symbol) using assertions from TEST-STR. -Other than MAJOR-MODE and TEST-STR parameters, this macro accepts -the same parameters and keywords as `ert-deftest' and is intended -to be used through `ert'. +The MAJOR-MODE symbol determines the syntax and font lock of TEST-STR. -(fn NAME () [DOCSTRING] [:expected-result RESULT-TYPE] [:tags \\='(TAG...)] MAJOR-MODE TEST-STR)" nil t) -(function-put 'ert-font-lock-deftest 'doc-string-elt 3) -(function-put 'ert-font-lock-deftest 'lisp-indent-function 2) +Except for the MAJOR-MODE and TEST-STR parameters, this macro accepts +the same arguments and keywords as `ert-deftest' and is intended to be +used through `ert'. + +(fn NAME [DOCSTRING] [:expected-result RESULT-TYPE] [:tags \\='(TAG...)] MAJOR-MODE TEST-STR)" nil t) +(function-put 'ert-font-lock-deftest 'doc-string-elt 2) +(function-put 'ert-font-lock-deftest 'lisp-indent-function 1) (autoload 'ert-font-lock-deftest-file "ert-font-lock" "\ Define test NAME (a symbol) using assertions from FILE. -FILE - path to a file with assertions in ERT resource director as -return by `ert-resource-directory'. +FILE names a file with assertions in the ERT resource directory, as +returned by `ert-resource-directory'. The MAJOR-MODE symbol determines +the syntax and font lock of FILE's contents. -Other than MAJOR-MODE and FILE parameters, this macro accepts the -same parameters and keywords as `ert-deftest' and is intended to -be used through `ert'. +Except for the MAJOR-MODE and FILE parameters, this macro accepts the +same arguments and keywords as `ert-deftest' and is intended to be used +through `ert'. -(fn NAME () [DOCSTRING] [:expected-result RESULT-TYPE] [:tags \\='(TAG...)] MAJOR-MODE FILE)" nil t) -(function-put 'ert-font-lock-deftest-file 'doc-string-elt 3) -(function-put 'ert-font-lock-deftest-file 'lisp-indent-function 2) +(fn NAME [DOCSTRING] [:expected-result RESULT-TYPE] [:tags \\='(TAG...)] MAJOR-MODE FILE)" nil t) +(function-put 'ert-font-lock-deftest-file 'doc-string-elt 2) +(function-put 'ert-font-lock-deftest-file 'lisp-indent-function 1) (autoload 'ert-font-lock-test-string "ert-font-lock" "\ Check font faces in TEST-STRING set by MODE. @@ -10976,8 +11035,6 @@ The function is meant to be run from within an ERT test. ;;; Generated autoloads from emacs-lisp/ert-x.el -(autoload 'ert-kill-all-test-buffers "ert-x" "\ -Kill all test buffers that are still live." t) (register-definition-prefixes "ert-x" '("ert-")) @@ -11893,7 +11950,11 @@ instead of `browse-url-new-window-flag'. (fn URL &optional NEW-WINDOW)") (autoload 'eww-list-bookmarks "eww" "\ -Display the bookmarks." t) +Display the eww bookmarks. +Optional argument BUILD-ONLY, when non-nil, means to build the buffer +without popping it. + +(fn &optional BUILD-ONLY)" t) (autoload 'eww-bookmark-jump "eww" "\ Default bookmark handler for EWW buffers. @@ -13372,10 +13433,6 @@ The mode's hook is called both when the mode is enabled and when it is disabled. (fn &optional ARG)" t) -(autoload 'turn-on-flyspell "flyspell" "\ -Unconditionally turn on Flyspell mode.") -(autoload 'turn-off-flyspell "flyspell" "\ -Unconditionally turn off Flyspell mode.") (autoload 'flyspell--mode-off "flyspell" "\ Turn Flyspell mode off.") (autoload 'flyspell-region "flyspell" "\ @@ -13387,6 +13444,10 @@ of a misspelled word removed when you've corrected it. (fn BEG END)" t) (autoload 'flyspell-buffer "flyspell" "\ Flyspell whole buffer." t) +(define-obsolete-function-alias 'turn-on-flyspell #'flyspell-mode "31.1") +(autoload 'turn-off-flyspell "flyspell" "\ +Unconditionally turn off Flyspell mode.") +(make-obsolete 'turn-off-flyspell 'flyspell-mode "31.1") (register-definition-prefixes "flyspell" '("flyspell-" "mail-mode-flyspell-verify" "make-flyspell-overlay" "sgml-mode-flyspell-verify" "tex")) @@ -15041,6 +15102,11 @@ Major mode for editing Go, powered by tree-sitter. Major mode for editing go.mod files, powered by tree-sitter. (fn)" t) +(autoload 'go-work-ts-mode "go-ts-mode" "\ +Major mode for editing go.work files, powered by tree-sitter. + +(fn)" t) +(add-to-list 'auto-mode-alist '("/go\\.work\\'" . go-work-ts-mode)) (register-definition-prefixes "go-ts-mode" '("go-")) @@ -15624,6 +15690,30 @@ For example, (setf (cadr x) y) is equivalent to (setcar (cdr x) y). The return value is the last VAL in the list. (fn PLACE VAL PLACE VAL ...)" nil t) +(autoload 'incf "gv" "\ +Increment generalized variable PLACE by DELTA (default to 1). + +The DELTA is first added to PLACE, and then stored in PLACE. +Return the incremented value of PLACE. + +For more information about generalized variables, see Info node +`(elisp) Generalized Variables'. + +See also `decf'. + +(fn PLACE &optional DELTA)" nil t) +(autoload 'decf "gv" "\ +Decrement generalized variable PLACE by DELTA (default to 1). + +The DELTA is first subtracted from PLACE, and then stored in PLACE. +Return the decremented value of PLACE. + +For more information about generalized variables, see Info node +`(elisp) Generalized Variables'. + +See also `incf'. + +(fn PLACE &optional DELTA)" nil t) (def-edebug-elem-spec 'gv-place '(form)) (autoload 'gv-ref "gv" "\ Return a reference to PLACE. @@ -15682,42 +15772,6 @@ Repent before ring 31 moves." t) Like `hanoi-unix', but with a 64-bit clock." t) (register-definition-prefixes "hanoi" '("hanoi-")) - -;;; Generated autoloads from mail/hashcash.el - -(autoload 'hashcash-insert-payment "hashcash" "\ -Insert X-Payment and X-Hashcash headers with a payment for ARG. - -(fn ARG)" t) -(autoload 'hashcash-insert-payment-async "hashcash" "\ -Insert X-Payment and X-Hashcash headers with a payment for ARG -Only start calculation. Results are inserted when ready. - -(fn ARG)" t) -(autoload 'hashcash-verify-payment "hashcash" "\ -Verify a hashcash payment. - -(fn TOKEN &optional RESOURCE AMOUNT)") -(autoload 'mail-add-payment "hashcash" "\ -Add X-Payment: and X-Hashcash: headers with a hashcash payment -for each recipient address. Prefix arg sets default payment temporarily. -Set ASYNC to t to start asynchronous calculation. (See -`mail-add-payment-async'). - -(fn &optional ARG ASYNC)" t) -(autoload 'mail-add-payment-async "hashcash" "\ -Add X-Payment: and X-Hashcash: headers with a hashcash payment -for each recipient address. Prefix arg sets default payment temporarily. -Calculation is asynchronous. - -(fn &optional ARG)" t) -(autoload 'mail-check-payment "hashcash" "\ -Look for a valid X-Payment: or X-Hashcash: header. -Prefix arg sets default accept amount temporarily. - -(fn &optional ARG)" t) -(register-definition-prefixes "hashcash" '("hashcash-")) - ;;; Generated autoloads from progmodes/heex-ts-mode.el @@ -15797,7 +15851,12 @@ list of properties through Custom will set the timer, thus enabling buffer local values. It sets the actual value to nil. Thus, Custom distinguishes between a nil value and other values that disable the feature, which Custom identifies with `never'. -The default is `never'.") +The default is `never'. + +Eldoc uses the echo area to display documentation. As such it +conflicts with `help-at-pt-display-when-idle' due to the use of +the echo area. If you use Eldoc, consider setting +`eldoc-help-at-pt' instead.") (custom-autoload 'help-at-pt-display-when-idle "help-at-pt" nil) (autoload 'scan-buf-move-to-region "help-at-pt" "\ Go to the start of the next region with non-nil PROP property. @@ -16499,7 +16558,7 @@ disabled. ;;; Generated autoloads from progmodes/hideshow.el -(defvar hs-special-modes-alist '((c-mode "{" "}" "/[*/]" nil nil) (c-ts-mode "{" "}" "/[*/]" nil nil) (c++-mode "{" "}" "/[*/]" nil nil) (c++-ts-mode "{" "}" "/[*/]" nil nil) (bibtex-mode ("@\\S(*\\(\\s(\\)" 1)) (java-mode "{" "}" "/[*/]" nil nil) (java-ts-mode "{" "}" "/[*/]" nil nil) (js-mode "{" "}" "/[*/]" nil) (js-ts-mode "{" "}" "/[*/]" nil) (lua-ts-mode "{\\|\\[\\[" "}\\|\\]\\]" "--" nil) (mhtml-mode "{\\|<[^/>]*?" "}\\|]*[^/]>" "