Commit 5d5d5d49 authored by Glenn Morris's avatar Glenn Morris

Merge from origin/emacs-27

d66331ae (origin/emacs-27) Don't build the Gnulib 'utimens' module ...
f2351a68 Add Harfbuzz dependency
8944310d Don't signal during backtrace unrewind (Bug#40088)
8709aadd Fix a couple of problems in changelog generating functions
9ab85f08 Fix cl-concatenate (Bug#40180)
561e9fb9 Improve documentation of project.el commands
b28a9a6c Make svg images with links valid
7515252c * lisp/tab-line.el (tab-line-new-button-show): New defcustom.

# Conflicts:
#	etc/NEWS
#	nt/gnulib-cfg.mk
parents 7832e619 d66331ae
Pipeline #5071 failed with stage
in 52 minutes and 44 seconds
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
# This list derives from the features we want Emacs to compile with. # This list derives from the features we want Emacs to compile with.
PKG_REQ='''mingw-w64-x86_64-giflib PKG_REQ='''mingw-w64-x86_64-giflib
mingw-w64-x86_64-gnutls mingw-w64-x86_64-gnutls
mingw-w64-x86_64-harfbuzz
mingw-w64-x86_64-lcms2 mingw-w64-x86_64-lcms2
mingw-w64-x86_64-libjpeg-turbo mingw-w64-x86_64-libjpeg-turbo
mingw-w64-x86_64-libpng mingw-w64-x86_64-libpng
......
...@@ -785,6 +785,7 @@ GDB Graphical Interface ...@@ -785,6 +785,7 @@ GDB Graphical Interface
Maintaining Large Programs Maintaining Large Programs
* Version Control:: Using version control systems. * Version Control:: Using version control systems.
* Projects:: Commands for handling source files in a project.
* Change Log:: Maintaining a change history for your program. * Change Log:: Maintaining a change history for your program.
* Xref:: Find definitions and references of any function, * Xref:: Find definitions and references of any function,
method, struct, macro, @dots{} in your program. method, struct, macro, @dots{} in your program.
......
...@@ -13,6 +13,9 @@ large-size programs and packages. These features include: ...@@ -13,6 +13,9 @@ large-size programs and packages. These features include:
Unified interface to Support for Version Control Systems Unified interface to Support for Version Control Systems
(@acronym{VCS}) that record the history of changes to source files. (@acronym{VCS}) that record the history of changes to source files.
@item
Commands for handling programming projects.
@item @item
A specialized mode for maintaining @file{ChangeLog} files that provide A specialized mode for maintaining @file{ChangeLog} files that provide
a chronological log of program changes. a chronological log of program changes.
...@@ -38,6 +41,7 @@ Lisp Regression Testing}). ...@@ -38,6 +41,7 @@ Lisp Regression Testing}).
@menu @menu
* Version Control:: Using version control systems. * Version Control:: Using version control systems.
* Projects:: Commands for handling source files in a project.
* Change Log:: Maintaining a change history for your program. * Change Log:: Maintaining a change history for your program.
* Xref:: Find definitions and references of any function, * Xref:: Find definitions and references of any function,
method, struct, macro, @dots{} in your program. method, struct, macro, @dots{} in your program.
...@@ -1630,6 +1634,77 @@ different revision with @kbd{C-u C-x v v}. ...@@ -1630,6 +1634,77 @@ different revision with @kbd{C-u C-x v v}.
@include vc1-xtra.texi @include vc1-xtra.texi
@end ifnottex @end ifnottex
@node Projects
@section Working with Projects
@cindex projects
@cindex project root
A @dfn{project} is a collection of files used for producing one or
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
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 (@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 back-end doesn't consider
``ignored'' files (@pxref{VC Ignore}) to be part of the project.
Emacs provides commands for handling project files conveniently.
This section describes these commands.
@cindex current project
All of the commands described here share the notion of the
@dfn{current project}. The current project is determined by the
@code{default-directory} (@pxref{File Names}) of the buffer that is
the current buffer when the command is invoked. If that directory
doesn't seem to belong to a recognizable project, these commands
prompt you for the project directory.
@findex project-find-file
The command @code{project-find-file} is a convenient way of visiting
files (@pxref{Visiting}) that belong to the current project. Unlike
@kbd{C-x C-f}, this command doesn't require to type the full file name
of the file to visit, you can type only the file's base name (i.e.,
omit the leading directories). In addition, the completion candidates
considered by the command include only the files belonging to the
current project, and nothing else. If there's a file name at point,
this command offers that file as the default to visit.
@findex project-find-regexp
The command @code{project-find-regexp} is similar to @code{rgrep}
(@pxref{Grep Searching}), but it searches only the files that belong
to the current project. The command prompts for the regular
expression to search, and pops up an Xref mode buffer with the search
results, where you can select a match using the Xref mode commands
(@pxref{Xref Commands}). When invoked with a prefix argument, this
command additionally prompts for the base directory from which to
start the search; this allows, for example, to limit the search only
to project files under a certain subdirectory of the project root.
@findex project-search
@kbd{M-x project-search} is an interactive variant of
@code{project-find-regexp}. It prompts for a regular expression to
search in the current project's files, but instead of finding all the
matches and displaying them, it stops when it finds a match and visits
the matched file at the locus of the match, allowing you to edit the
matched file. To find the rest of the matches, type @w{@kbd{M-x
fileloop-continue @key{RET}}}.
@findex project-query-replace-regexp
@kbd{M-x project-query-replace-regexp} is similar to
@code{project-search}, but it prompts you for whether to replace each
match it finds, like @code{query-replace} does (@pxref{Query
Replace}), and continues to the next match after you respond. If your
response causes Emacs to exit the query-replace loop, you can later
continue with @w{@kbd{M-x fileloop-continue @key{RET}}}.
@node Change Log @node Change Log
@section Change Logs @section Change Logs
......
...@@ -978,7 +978,10 @@ The mode is automatically enabled in files that start with the ...@@ -978,7 +978,10 @@ The mode is automatically enabled in files that start with the
** project.el ** project.el
+++
*** New commands 'project-search' and 'project-query-replace-regexp'. *** New commands 'project-search' and 'project-query-replace-regexp'.
---
*** New user option 'project-read-file-name-function'. *** New user option 'project-read-file-name-function'.
** Etags ** Etags
......
...@@ -555,7 +555,7 @@ too large if positive or too small if negative)." ...@@ -555,7 +555,7 @@ too large if positive or too small if negative)."
(defun cl-concatenate (type &rest sequences) (defun cl-concatenate (type &rest sequences)
"Concatenate, into a sequence of type TYPE, the argument SEQUENCEs. "Concatenate, into a sequence of type TYPE, the argument SEQUENCEs.
\n(fn TYPE SEQUENCE...)" \n(fn TYPE SEQUENCE...)"
(seq-concatenate type sequences)) (apply #'seq-concatenate type sequences))
;;; List functions. ;;; List functions.
......
...@@ -437,6 +437,7 @@ triggers completion when entering a pattern, including it ...@@ -437,6 +437,7 @@ triggers completion when entering a pattern, including it
requires quoting, e.g. `\\[quoted-insert]<space>'." requires quoting, e.g. `\\[quoted-insert]<space>'."
(interactive (list (project--read-regexp))) (interactive (list (project--read-regexp)))
(require 'xref) (require 'xref)
(require 'grep)
(let* ((pr (project-current t)) (let* ((pr (project-current t))
(files (files
(if (not current-prefix-arg) (if (not current-prefix-arg)
...@@ -606,7 +607,8 @@ PREDICATE, HIST, and DEFAULT have the same meaning as in ...@@ -606,7 +607,8 @@ PREDICATE, HIST, and DEFAULT have the same meaning as in
(defun project-search (regexp) (defun project-search (regexp)
"Search for REGEXP in all the files of the project. "Search for REGEXP in all the files of the project.
Stops when a match is found. Stops when a match is found.
To continue searching for next match, use command \\[fileloop-continue]." To continue searching for the next match, use the
command \\[fileloop-continue]."
(interactive "sSearch (regexp): ") (interactive "sSearch (regexp): ")
(fileloop-initialize-search (fileloop-initialize-search
regexp (project-files (project-current t)) 'default) regexp (project-files (project-current t)) 'default)
...@@ -614,9 +616,10 @@ To continue searching for next match, use command \\[fileloop-continue]." ...@@ -614,9 +616,10 @@ To continue searching for next match, use command \\[fileloop-continue]."
;;;###autoload ;;;###autoload
(defun project-query-replace-regexp (from to) (defun project-query-replace-regexp (from to)
"Search for REGEXP in all the files of the project. "Query-replace REGEXP in all the files of the project.
Stops when a match is found. Stops when a match is found and prompts for whether to replace it.
To continue searching for next match, use command \\[fileloop-continue]." If you exit the query-replace, you can later continue the query-replace
loop using the command \\[fileloop-continue]."
(interactive (interactive
(pcase-let ((`(,from ,to) (pcase-let ((`(,from ,to)
(query-replace-read-args "Query replace (regexp)" t t))) (query-replace-read-args "Query replace (regexp)" t t)))
......
...@@ -70,7 +70,8 @@ any further elements added." ...@@ -70,7 +70,8 @@ any further elements added."
(height . ,height) (height . ,height)
(version . "1.1") (version . "1.1")
(xmlns . "http://www.w3.org/2000/svg") (xmlns . "http://www.w3.org/2000/svg")
,@(svg--arguments nil args)))) (xmlns:xlink . "http://www.w3.org/1999/xlink")
,@(svg--arguments nil args))))
(defun svg-gradient (svg id type stops) (defun svg-gradient (svg id type stops)
"Add a gradient with ID to SVG. "Add a gradient with ID to SVG.
......
...@@ -142,11 +142,19 @@ ...@@ -142,11 +142,19 @@
(defcustom tab-line-new-tab-choice t (defcustom tab-line-new-tab-choice t
"Defines what to show in a new tab. "Defines what to show in a new tab.
If t, display a selection menu with all available buffers. If t, display a selection menu with all available buffers.
If the value is a function, call it with no arguments. If the value is a function, call it with no arguments."
If nil, don't show the new tab button."
:type '(choice (const :tag "Buffer menu" t) :type '(choice (const :tag "Buffer menu" t)
(function :tag "Function") (function :tag "Function"))
(const :tag "No button" nil)) :group 'tab-line
:version "27.1")
(defcustom tab-line-new-button-show t
"If non-nil, show the \"New tab\" button in the tab line."
:type 'boolean
:initialize 'custom-initialize-default
:set (lambda (sym val)
(set-default sym val)
(force-mode-line-update))
:group 'tab-line :group 'tab-line
:version "27.1") :version "27.1")
...@@ -211,7 +219,8 @@ If nil, don't show it at all." ...@@ -211,7 +219,8 @@ If nil, don't show it at all."
'help-echo "Click to scroll right") 'help-echo "Click to scroll right")
"Button for scrolling horizontally to the right.") "Button for scrolling horizontally to the right.")
(defvar tab-line-separator nil) (defvar tab-line-separator nil
"String that delimits tabs.")
(defcustom tab-line-tab-name-function #'tab-line-tab-name-buffer (defcustom tab-line-tab-name-function #'tab-line-tab-name-buffer
...@@ -455,7 +464,8 @@ variable `tab-line-tabs-function'." ...@@ -455,7 +464,8 @@ variable `tab-line-tabs-function'."
(if hscroll (nthcdr (truncate hscroll) strings) strings) (if hscroll (nthcdr (truncate hscroll) strings) strings)
(list separator) (list separator)
(when (and (eq tab-line-tabs-function #'tab-line-tabs-window-buffers) (when (and (eq tab-line-tabs-function #'tab-line-tabs-window-buffers)
tab-line-new-tab-choice) tab-line-new-button-show
tab-line-new-button)
(list tab-line-new-button))))) (list tab-line-new-button)))))
(defvar tab-line-auto-hscroll) (defvar tab-line-auto-hscroll)
......
...@@ -2247,29 +2247,32 @@ The elements of the alist are of the form (FILE . (DEFUN...)), ...@@ -2247,29 +2247,32 @@ The elements of the alist are of the form (FILE . (DEFUN...)),
where DEFUN... is a list of function names found in FILE." where DEFUN... is a list of function names found in FILE."
(save-excursion (save-excursion
(goto-char (point-min)) (goto-char (point-min))
(let ((defuns nil) (let* ((defuns nil)
(hunk-end nil) (hunk-end nil)
(hunk-mismatch-files nil) (hunk-mismatch-files nil)
(make-defun-context-follower (make-defun-context-follower
(lambda (goline) (lambda (goline)
(let ((eodefun nil) (let ((eodefun nil)
(defname nil)) (defname nil))
(list (list
(lambda () ;; Check for end of current defun. (lambda () ;; Check for end of current defun.
(when (and eodefun (when (and eodefun
(funcall goline) (funcall goline)
(>= (point) eodefun)) (>= (point) eodefun))
(setq defname nil) (setq defname nil)
(setq eodefun nil))) (setq eodefun nil)))
(lambda (&optional get-current) ;; Check for new defun. (lambda (&optional get-current) ;; Check for new defun.
(if get-current (if get-current
defname defname
(when-let* ((def (and (not eodefun) (when-let* ((def (and (not eodefun)
(funcall goline) (funcall goline)
(add-log-current-defun))) (add-log-current-defun)))
(eof (save-excursion (end-of-defun) (point)))) (eof (save-excursion
(setq eodefun eof) (condition-case ()
(setq defname def))))))))) (progn (end-of-defun) (point))
(scan-error hunk-end)))))
(setq eodefun eof)
(setq defname def)))))))))
(while (while
;; Might need to skip over file headers between diff ;; Might need to skip over file headers between diff
;; hunks (e.g., "diff --git ..." etc). ;; hunks (e.g., "diff --git ..." etc).
......
...@@ -788,18 +788,20 @@ This command will generate a ChangeLog entries listing the ...@@ -788,18 +788,20 @@ This command will generate a ChangeLog entries listing the
functions. You can then add a description where needed, and use functions. You can then add a description where needed, and use
\\[fill-paragraph] to join consecutive function names." \\[fill-paragraph] to join consecutive function names."
(interactive) (interactive)
(let* ((diff-buf nil) (change-log-insert-entries
;; Unfortunately, `log-edit-show-diff' doesn't have a NO-SHOW (with-current-buffer
;; option, so we try to work around it via display-buffer (let* ((diff-buf nil)
;; machinery. ;; Unfortunately, `log-edit-show-diff' doesn't have a
(display-buffer-overriding-action ;; NO-SHOW option, so we try to work around it via
`(,(lambda (buf alist) ;; display-buffer machinery.
(setq diff-buf buf) (display-buffer-overriding-action
(display-buffer-no-window buf alist)) `(,(lambda (buf alist)
. ((allow-no-window . t))))) (setq diff-buf buf)
(change-log-insert-entries (display-buffer-no-window buf alist))
(with-current-buffer (progn (log-edit-show-diff) diff-buf) . ((allow-no-window . t)))))
(diff-add-log-current-defuns))))) (log-edit-show-diff)
diff-buf)
(diff-add-log-current-defuns))))
(defun log-edit-insert-changelog (&optional use-first) (defun log-edit-insert-changelog (&optional use-first)
"Insert a log message by looking at the ChangeLog. "Insert a log message by looking at the ChangeLog.
......
...@@ -63,6 +63,7 @@ OMIT_GNULIB_MODULE_sys_time = true ...@@ -63,6 +63,7 @@ OMIT_GNULIB_MODULE_sys_time = true
OMIT_GNULIB_MODULE_sys_types = true OMIT_GNULIB_MODULE_sys_types = true
OMIT_GNULIB_MODULE_unistd = true OMIT_GNULIB_MODULE_unistd = true
OMIT_GNULIB_MODULE_canonicalize-lgpl = true OMIT_GNULIB_MODULE_canonicalize-lgpl = true
OMIT_GNULIB_MODULE_utimens = true
OMIT_GNULIB_MODULE_fchmodat = true OMIT_GNULIB_MODULE_fchmodat = true
OMIT_GNULIB_MODULE_lchmod = true OMIT_GNULIB_MODULE_lchmod = true
OMIT_GNULIB_MODULE_futimens = true OMIT_GNULIB_MODULE_futimens = true
......
...@@ -1567,7 +1567,7 @@ notify_variable_watchers (Lisp_Object symbol, ...@@ -1567,7 +1567,7 @@ notify_variable_watchers (Lisp_Object symbol,
/* Return the default value of SYMBOL, but don't check for voidness. /* Return the default value of SYMBOL, but don't check for voidness.
Return Qunbound if it is void. */ Return Qunbound if it is void. */
static Lisp_Object Lisp_Object
default_value (Lisp_Object symbol) default_value (Lisp_Object symbol)
{ {
struct Lisp_Symbol *sym; struct Lisp_Symbol *sym;
......
...@@ -3816,7 +3816,7 @@ backtrace_eval_unrewind (int distance) ...@@ -3816,7 +3816,7 @@ backtrace_eval_unrewind (int distance)
{ {
Lisp_Object sym = specpdl_symbol (tmp); Lisp_Object sym = specpdl_symbol (tmp);
Lisp_Object old_value = specpdl_old_value (tmp); Lisp_Object old_value = specpdl_old_value (tmp);
set_specpdl_old_value (tmp, Fdefault_value (sym)); set_specpdl_old_value (tmp, default_value (sym));
Fset_default (sym, old_value); Fset_default (sym, old_value);
} }
break; break;
...@@ -3832,7 +3832,7 @@ backtrace_eval_unrewind (int distance) ...@@ -3832,7 +3832,7 @@ backtrace_eval_unrewind (int distance)
if (!NILP (Flocal_variable_p (symbol, where))) if (!NILP (Flocal_variable_p (symbol, where)))
{ {
set_specpdl_old_value set_specpdl_old_value
(tmp, Fbuffer_local_value (symbol, where)); (tmp, buffer_local_value (symbol, where));
set_internal (symbol, old_value, where, SET_INTERNAL_UNBIND); set_internal (symbol, old_value, where, SET_INTERNAL_UNBIND);
} }
} }
......
...@@ -595,6 +595,7 @@ extern void char_table_set (Lisp_Object, int, Lisp_Object); ...@@ -595,6 +595,7 @@ extern void char_table_set (Lisp_Object, int, Lisp_Object);
/* Defined in data.c. */ /* Defined in data.c. */
extern AVOID wrong_type_argument (Lisp_Object, Lisp_Object); extern AVOID wrong_type_argument (Lisp_Object, Lisp_Object);
extern Lisp_Object default_value (Lisp_Object symbol);
/* Defined in emacs.c. */ /* Defined in emacs.c. */
......
...@@ -99,4 +99,12 @@ ...@@ -99,4 +99,12 @@
;; Test for Bug#33731. ;; Test for Bug#33731.
(should-not (eq s (cl-make-random-state s))))) (should-not (eq s (cl-make-random-state s)))))
(ert-deftest cl-concatenate ()
(should (equal (cl-concatenate 'list '(1 2 3) '(4 5 6))
'(1 2 3 4 5 6)))
(should (equal (cl-concatenate 'vector [1 2 3] [4 5 6])
[1 2 3 4 5 6]))
(should (equal (cl-concatenate 'string "123" "456")
"123456")))
;;; cl-extra-tests.el ends here ;;; cl-extra-tests.el ends here
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment