From f26afdb0c543d2fe5299aa7c45a321d63534d687 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Fri, 26 Jul 2013 20:29:42 -0400 Subject: [PATCH 001/449] * lisp/format.el (format-annotate-function): Handle read-only text properties in the source. Fixes: debbugs:14887 --- lisp/ChangeLog | 5 +++++ lisp/format.el | 10 ++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 0c5b857d374..14af1cfbda9 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2013-07-27 Glenn Morris + + * format.el (format-annotate-function): + Handle read-only text properties in the source. (Bug#14887) + 2013-07-24 Glenn Morris * dired-x.el (dired-mark-extension): Convert comment to doc string. diff --git a/lisp/format.el b/lisp/format.el index 221eaadcdd8..fc8dcb97b01 100644 --- a/lisp/format.el +++ b/lisp/format.el @@ -225,10 +225,12 @@ For most purposes, consider using `format-encode-region' instead." (setq selective-display sel-disp) (set-buffer-multibyte multibyte) (setq buffer-file-coding-system coding-system)) - (copy-to-buffer copy-buf from to) - (set-buffer copy-buf) - (format-insert-annotations write-region-annotations-so-far from) - (format-encode-run-method to-fn (point-min) (point-max) orig-buf) + (let ((inhibit-read-only t)) ; bug#14887 + (copy-to-buffer copy-buf from to) + (set-buffer copy-buf) + (format-insert-annotations write-region-annotations-so-far from) + (format-encode-run-method to-fn (point-min) (point-max) + orig-buf)) (when (buffer-live-p copy-buf) (with-current-buffer copy-buf ;; Set write-region-post-annotation-function to From 2f3ac208bbacc09623798d43d7ed4eadc0fbf347 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Tue, 30 Jul 2013 23:58:16 -0700 Subject: [PATCH 002/449] Reduce use of mailto: in html versions of manuals * doc/emacs/macos.texi (GNUstep Support): * doc/emacs/trouble.texi (Checklist, Contributing, Service): * doc/lispintro/emacs-lisp-intro.texi (Thank You): * doc/misc/woman.texi (Top): Avoid mailto: in html output. --- doc/emacs/ChangeLog | 6 ++++ doc/emacs/macos.texi | 6 ++++ doc/emacs/trouble.texi | 46 ++++++++++++++++++++++------- doc/lispintro/ChangeLog | 4 +++ doc/lispintro/emacs-lisp-intro.texi | 5 ++++ doc/misc/ChangeLog | 4 +++ doc/misc/woman.texi | 5 ++++ 7 files changed, 65 insertions(+), 11 deletions(-) diff --git a/doc/emacs/ChangeLog b/doc/emacs/ChangeLog index e7d7c4ea2e7..ccb9451bd7a 100644 --- a/doc/emacs/ChangeLog +++ b/doc/emacs/ChangeLog @@ -1,3 +1,9 @@ +2013-07-31 Glenn Morris + + * macos.texi (GNUstep Support): + * trouble.texi (Checklist, Contributing, Service): + Avoid mailto: in html output. + 2013-07-02 Glenn Morris * maintaining.texi (EDE): Fix cross-reference. diff --git a/doc/emacs/macos.texi b/doc/emacs/macos.texi index 4483c91802d..6247df23216 100644 --- a/doc/emacs/macos.texi +++ b/doc/emacs/macos.texi @@ -207,4 +207,10 @@ restart Emacs to access newly-available services. Emacs can be built and run under GNUstep, but there are still issues to be addressed. Interested developers should contact +@ifnothtml @email{emacs-devel@@gnu.org}. +@end ifnothtml +@ifhtml +@url{http://lists.gnu.org/mailman/listinfo/emacs-devel, the +emacs-devel mailing list}. +@end ifhtml diff --git a/doc/emacs/trouble.texi b/doc/emacs/trouble.texi index ad321e74e68..a1774458bc7 100644 --- a/doc/emacs/trouble.texi +++ b/doc/emacs/trouble.texi @@ -650,7 +650,13 @@ absolutely sure it is best to leave it, so that the developers can decide for themselves. When you have finished writing your report, type @kbd{C-c C-c} and it -will be sent to the Emacs maintainers at @email{bug-gnu-emacs@@gnu.org}. +will be sent to the Emacs maintainers at +@ifnothtml +@email{bug-gnu-emacs@@gnu.org}. +@end ifnothtml +@ifhtml +@url{http://lists.gnu.org/mailman/listinfo/bug-gnu-emacs, bug-gnu-emacs}. +@end ifhtml (If you want to suggest an improvement or new feature, use the same address.) If you cannot send mail from inside Emacs, you can copy the text of your report to your normal mail client (if your system @@ -1130,15 +1136,26 @@ form that is clearly safe to install. @section Contributing to Emacs Development @cindex contributing to Emacs -If you would like to work on improving Emacs, please contact -the maintainers at @email{emacs-devel@@gnu.org}. You can ask for -suggested projects or suggest your own ideas. +If you would like to work on improving Emacs, please contact the maintainers at +@ifnothtml +@email{emacs-devel@@gnu.org}. +@end ifnothtml +@ifhtml +@url{http://lists.gnu.org/mailman/listinfo/emacs-devel, the +emacs-devel mailing list}. +@end ifhtml +You can ask for suggested projects or suggest your own ideas. If you have already written an improvement, please tell us about it. If you have not yet started work, it is useful to contact -@email{emacs-devel@@gnu.org} before you start; it might be -possible to suggest ways to make your extension fit in better with the -rest of Emacs. +@ifnothtml +@email{emacs-devel@@gnu.org} +@end ifnothtml +@ifhtml +@url{http://lists.gnu.org/mailman/listinfo/emacs-devel, emacs-devel} +@end ifhtml +before you start; it might be possible to suggest ways to make your +extension fit in better with the rest of Emacs. The development version of Emacs can be downloaded from the repository where it is actively maintained by a group of developers. @@ -1156,10 +1173,17 @@ ways to find it: @itemize @bullet @item -Send a message to the mailing list -@email{help-gnu-emacs@@gnu.org}, or post your request on -newsgroup @code{gnu.emacs.help}. (This mailing list and newsgroup -interconnect, so it does not matter which one you use.) +Send a message to +@ifnothtml +the mailing list @email{help-gnu-emacs@@gnu.org}, +@end ifnothtml +@ifhtml +@url{http://lists.gnu.org/mailman/listinfo/help-gnu-emacs, the +help-gnu-emacs mailing list}, +@end ifhtml +or post your request on newsgroup @code{gnu.emacs.help}. (This +mailing list and newsgroup interconnect, so it does not matter which +one you use.) @item Look in the service directory for someone who might help you for a fee. diff --git a/doc/lispintro/ChangeLog b/doc/lispintro/ChangeLog index de326f362c7..ead243558f2 100644 --- a/doc/lispintro/ChangeLog +++ b/doc/lispintro/ChangeLog @@ -1,3 +1,7 @@ +2013-07-31 Glenn Morris + + * emacs-lisp-intro.texi (Thank You): Avoid mailto: in html output. + 2013-07-05 Glenn Morris * emacs-lisp-intro.texi (Top): diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi index ebb82dab3f1..33bf301c35c 100644 --- a/doc/lispintro/emacs-lisp-intro.texi +++ b/doc/lispintro/emacs-lisp-intro.texi @@ -1070,7 +1070,12 @@ encouragement. My mistakes are my own. @flushright Robert J. Chassell +@ifnothtml @email{bob@@gnu.org} +@end ifnothtml +@ifhtml +bob@@gnu.org +@end ifhtml @end flushright @c ================ Beginning of main text ================ diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog index 959e426ea01..1ef5730674e 100644 --- a/doc/misc/ChangeLog +++ b/doc/misc/ChangeLog @@ -1,3 +1,7 @@ +2013-07-31 Glenn Morris + + * woman.texi (Top): Avoid mailto: in html output. + 2013-07-25 Glenn Morris * erc.texi (Special Features): Update contact information. diff --git a/doc/misc/woman.texi b/doc/misc/woman.texi index 2dbcc6dcd47..35afdefb83a 100644 --- a/doc/misc/woman.texi +++ b/doc/misc/woman.texi @@ -75,7 +75,12 @@ modify this GNU manual.'' Software Version @value{VERSION} Manual Last Updated @value{UPDATED} +@ifnothtml @email{F.J.Wright@@qmw.ac.uk, Francis J. Wright} +@end ifnothtml +@ifhtml +Francis J. Wright +@end ifhtml @uref{http://centaur.maths.qmw.ac.uk/, School of Mathematical Sciences} Queen Mary and Westfield College (University of London) Mile End Road, London E1 4NS, UK From b309175d2d790fb8fc8d4a60ab957517a99ce09b Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Sat, 3 Aug 2013 12:43:59 -0700 Subject: [PATCH 003/449] * emacs-lisp-intro.texi (Complete copy-region-as-kill): Fix typo. --- doc/lispintro/ChangeLog | 4 ++++ doc/lispintro/emacs-lisp-intro.texi | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/lispintro/ChangeLog b/doc/lispintro/ChangeLog index ead243558f2..ec259497fee 100644 --- a/doc/lispintro/ChangeLog +++ b/doc/lispintro/ChangeLog @@ -1,3 +1,7 @@ +2013-08-03 Glenn Morris + + * emacs-lisp-intro.texi (Complete copy-region-as-kill): Fix typo. + 2013-07-31 Glenn Morris * emacs-lisp-intro.texi (Thank You): Avoid mailto: in html output. diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi index 33bf301c35c..db08740fcbf 100644 --- a/doc/lispintro/emacs-lisp-intro.texi +++ b/doc/lispintro/emacs-lisp-intro.texi @@ -8437,7 +8437,7 @@ As usual, this function can be divided into its component parts: The arguments are @code{beg} and @code{end} and the function is interactive with @code{"r"}, so the two arguments must refer to the -beginning and end of the region. If you have been reading though this +beginning and end of the region. If you have been reading through this document from the beginning, understanding these parts of a function is almost becoming routine. From a04d36a0689a9c246aef0f816f78b7af4bc648fe Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Sun, 4 Aug 2013 04:57:45 +0200 Subject: [PATCH 004/449] lisp/frameset.el (frameset--reuse-frame): Use correct frame-id to find frame. (frameset--set-id, frameset--process-minibuffer-frames) (frameset-restore): Rename parameter `frameset-id' to `frame-id'. --- lisp/ChangeLog | 3 +++ lisp/frameset.el | 28 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 15e0ad745b1..a4453838399 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -3,6 +3,9 @@ * frameset.el (frameset-p, frameset-save): Fix autoload cookies. (frameset-filter-minibuffer): Doc fix. (frameset-restore): Fix autoload cookie. Fix typo in docstring. + (frameset--set-id, frameset--process-minibuffer-frames) + (frameset-restore): Rename parameter `frameset-id' to `frame-id'. + (frameset--reuse-frame): Pass correct frame-id to frameset--find-frame. * desktop.el (desktop-clear): Only delete frames when called interactively and desktop-restore-frames is non-nil. Doc fix. diff --git a/lisp/frameset.el b/lisp/frameset.el index 63ee9af23fc..2a6a0d2dfb8 100644 --- a/lisp/frameset.el +++ b/lisp/frameset.el @@ -265,11 +265,11 @@ nil while the filtering is done to restore it." ;; Saving framesets (defun frameset--set-id (frame) - "Set FRAME's `frameset-id' if not yet set. + "Set FRAME's `frame-id' if not yet set. Internal use only." - (unless (frame-parameter frame 'frameset-id) + (unless (frame-parameter frame 'frame-id) (set-frame-parameter frame - 'frameset-id + 'frame-id (mapconcat (lambda (n) (format "%04X" n)) (cl-loop repeat 4 collect (random 65536)) "-")))) @@ -292,11 +292,11 @@ FRAME-LIST is a list of frames." (unless (frame-parameter frame 'frameset--mini) (frameset--set-id frame) (let* ((mb-frame (window-frame (minibuffer-window frame))) - (id (and mb-frame (frame-parameter mb-frame 'frameset-id)))) + (id (and mb-frame (frame-parameter mb-frame 'frame-id)))) (if (null id) (error "Minibuffer frame %S for %S is excluded" mb-frame frame) ;; For minibufferless frames, frameset--mini is a cons - ;; (nil . FRAME-ID), where FRAME-ID is the frameset-id of + ;; (nil . FRAME-ID), where FRAME-ID is the frame-id of ;; the frame containing its minibuffer window. (set-frame-parameter frame 'frameset--mini @@ -430,8 +430,8 @@ is the parameter list of the frame being restored. Internal use only." ;; M-x desktop-read). (setq frame (frameset--find-frame (lambda (f id) - (string= (frame-parameter f 'frameset-id) id)) - display (cdr mini))) + (string= (frame-parameter f 'frame-id) id)) + display (cdr (assq 'frame-id frame-cfg)))) ;; If it has not been loaded, and it is not a minibuffer-only frame, ;; let's look for an existing non-minibuffer-only frame to reuse. (unless (or frame (eq (cdr (assq 'minibuffer frame-cfg)) 'only)) @@ -446,12 +446,12 @@ is the parameter list of the frame being restored. Internal use only." ;; For minibufferless frames, check whether they already exist, ;; and that they are linked to the right minibuffer frame. (setq frame (frameset--find-frame - (lambda (f id mini-id) - (and (string= (frame-parameter f 'frameset-id) id) - (string= (frame-parameter (window-frame (minibuffer-window f)) - 'frameset-id) - mini-id))) - display (cdr (assq 'frameset-id frame-cfg)) (cdr mini)))) + (lambda (f id mini-id) + (and (string= (frame-parameter f 'frame-id) id) + (string= (frame-parameter (window-frame (minibuffer-window f)) + 'frame-id) + mini-id))) + display (cdr (assq 'frame-id frame-cfg)) (cdr mini)))) (t ;; Default to just finding a frame in the same display. (setq frame (frameset--find-frame nil display)))) @@ -647,7 +647,7 @@ All keywords default to nil." (t ;; Frame depends on other frame's minibuffer window. (let* ((mb-frame (or (cl-find-if (lambda (f) - (string= (frame-parameter f 'frameset-id) + (string= (frame-parameter f 'frame-id) mb-id)) (frame-list)) (error "Minibuffer frame %S not found" mb-id))) From f0b79313d9be108a17b8a8c689fbf64f6ba75044 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Sun, 4 Aug 2013 08:07:18 +0400 Subject: [PATCH 005/449] * dispnew.c (glyph_matrix_count, glyph_pool_count): Move under GLYPH_DEBUG and ENABLE_CHECKING. (new_glyph_matrix, free_glyph_matrix, new_glyph_pool) (free_glyph_pool, check_glyph_memory): Likewise for all users. Adjust comments where appropriate. --- src/ChangeLog | 8 ++++++++ src/dispnew.c | 49 ++++++++++++++++++++++++++++++------------------- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 69e00cadbe9..8a9de96358d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2013-08-04 Dmitry Antipov + + * dispnew.c (glyph_matrix_count, glyph_pool_count): + Move under GLYPH_DEBUG and ENABLE_CHECKING. + (new_glyph_matrix, free_glyph_matrix, new_glyph_pool) + (free_glyph_pool, check_glyph_memory): Likewise for + all users. Adjust comments where appropriate. + 2013-08-03 Paul Eggert * composite.h: Minor fixups. diff --git a/src/dispnew.c b/src/dispnew.c index 522a0e6a30d..c69f4b3bed5 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -148,12 +148,16 @@ int updated_area; struct glyph space_glyph; +#if defined GLYPH_DEBUG && defined ENABLE_CHECKING + /* Counts of allocated structures. These counts serve to diagnose memory leaks and double frees. */ static int glyph_matrix_count; static int glyph_pool_count; +#endif /* GLYPH_DEBUG and ENABLE_CHECKING */ + /* If non-null, the frame whose frame matrices are manipulated. If null, window matrices are worked on. */ @@ -307,9 +311,11 @@ new_glyph_matrix (struct glyph_pool *pool) { struct glyph_matrix *result = xzalloc (sizeof *result); +#if defined GLYPH_DEBUG && defined ENABLE_CHECKING /* Increment number of allocated matrices. This count is used to detect memory leaks. */ ++glyph_matrix_count; +#endif /* Set pool and return. */ result->pool = pool; @@ -319,10 +325,10 @@ new_glyph_matrix (struct glyph_pool *pool) /* Free glyph matrix MATRIX. Passing in a null MATRIX is allowed. - The global counter glyph_matrix_count is decremented when a matrix - is freed. If the count gets negative, more structures were freed - than allocated, i.e. one matrix was freed more than once or a bogus - pointer was passed to this function. + If GLYPH_DEBUG and ENABLE_CHECKING are in effect, the global counter + glyph_matrix_count is decremented when a matrix is freed. If the count + gets negative, more structures were freed than allocated, i.e. one matrix + was freed more than once or a bogus pointer was passed to this function. If MATRIX->pool is null, this means that the matrix manages its own glyph memory---this is done for matrices on X frames. Freeing the @@ -335,10 +341,12 @@ free_glyph_matrix (struct glyph_matrix *matrix) { int i; +#if defined GLYPH_DEBUG && defined ENABLE_CHECKING /* Detect the case that more matrices are freed than were allocated. */ - if (--glyph_matrix_count < 0) - emacs_abort (); + --glyph_matrix_count; + eassert (glyph_matrix_count >= 0); +#endif /* Free glyph memory if MATRIX owns it. */ if (matrix->pool == NULL) @@ -1310,38 +1318,41 @@ row_equal_p (struct glyph_row *a, struct glyph_row *b, bool mouse_face_p) See dispextern.h for an overall explanation of glyph pools. ***********************************************************************/ -/* Allocate a glyph_pool structure. The structure returned is - initialized with zeros. The global variable glyph_pool_count is - incremented for each pool allocated. */ +/* Allocate a glyph_pool structure. The structure returned is initialized + with zeros. If GLYPH_DEBUG and ENABLE_CHECKING are in effect, the global + variable glyph_pool_count is incremented for each pool allocated. */ static struct glyph_pool * new_glyph_pool (void) { struct glyph_pool *result = xzalloc (sizeof *result); +#if defined GLYPH_DEBUG && defined ENABLE_CHECKING /* For memory leak and double deletion checking. */ ++glyph_pool_count; +#endif return result; } /* Free a glyph_pool structure POOL. The function may be called with - a null POOL pointer. The global variable glyph_pool_count is - decremented with every pool structure freed. If this count gets - negative, more structures were freed than allocated, i.e. one - structure must have been freed more than once or a bogus pointer - was passed to free_glyph_pool. */ + a null POOL pointer. If GLYPH_DEBUG and ENABLE_CHECKING are in effect, + global variable glyph_pool_count is decremented with every pool structure + freed. If this count gets negative, more structures were freed than + allocated, i.e. one structure must have been freed more than once or + a bogus pointer was passed to free_glyph_pool. */ static void free_glyph_pool (struct glyph_pool *pool) { if (pool) { +#if defined GLYPH_DEBUG && defined ENABLE_CHECKING /* More freed than allocated? */ --glyph_pool_count; eassert (glyph_pool_count >= 0); - +#endif xfree (pool->glyphs); xfree (pool); } @@ -2254,11 +2265,11 @@ check_glyph_memory (void) FOR_EACH_FRAME (tail, frame) free_glyphs (XFRAME (frame)); +#if defined GLYPH_DEBUG && defined ENABLE_CHECKING /* Check that nothing is left allocated. */ - if (glyph_matrix_count) - emacs_abort (); - if (glyph_pool_count) - emacs_abort (); + eassert (glyph_matrix_count == 0); + eassert (glyph_pool_count == 0); +#endif } From f8654242f1a06b4fd7a07ac261ecee240c9b3d69 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Sat, 3 Aug 2013 21:34:01 -0700 Subject: [PATCH 006/449] * test/automated/icalendar-tests.el (icalendar-tests--test-export) (icalendar-tests--test-import): Remove debug messages. --- test/ChangeLog | 1 + test/automated/icalendar-tests.el | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/test/ChangeLog b/test/ChangeLog index f3d14786bd9..65e7683dd54 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -2,6 +2,7 @@ * automated/icalendar-tests.el (icalendar-tests--test-export) (icalendar-tests--test-import): Try more precise TZ specification. + Remove debug messages. 2013-08-03 Glenn Morris diff --git a/test/automated/icalendar-tests.el b/test/automated/icalendar-tests.el index 227855681e8..f83052f5ea1 100644 --- a/test/automated/icalendar-tests.el +++ b/test/automated/icalendar-tests.el @@ -433,9 +433,11 @@ and ISO style input data must use english month names." (icalendar-recurring-start-year 2000)) (unwind-protect (progn - (message "Current time zone: %s" (current-time-zone)) +;;; (message "Current time zone: %s" (current-time-zone)) + ;; Use this form so as not to rely on system tz database. + ;; Eg hydra.nixos.org. (setenv "TZ" "CET-1CEST,M3.5.0/2,M10.5.0/3") - (message "Current time zone: %s" (current-time-zone)) +;;; (message "Current time zone: %s" (current-time-zone)) (when input-iso (let ((calendar-month-name-array ["January" "February" "March" "April" "May" "June" "July" "August" @@ -676,9 +678,11 @@ Argument EXPECTED-AMERICAN expected american style diary string." (let ((timezone (getenv "TZ"))) (unwind-protect (progn - (message "Current time zone: %s" (current-time-zone)) +;;; (message "Current time zone: %s" (current-time-zone)) + ;; Use this form so as not to rely on system tz database. + ;; Eg hydra.nixos.org. (setenv "TZ" "CET-1CEST,M3.5.0/2,M10.5.0/3") - (message "Current time zone: %s" (current-time-zone)) +;;; (message "Current time zone: %s" (current-time-zone)) (with-temp-buffer (if (string-match "^BEGIN:VCALENDAR" input) (insert input) From dc8dfa8a70df6ccb9d265ea98203cc0efe5d2fff Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Sat, 3 Aug 2013 21:37:10 -0700 Subject: [PATCH 007/449] * ert-tests.el: Disable failing test that no-one seems to know how to fix. --- test/ChangeLog | 3 +++ test/automated/ert-tests.el | 22 ++++++++++++---------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/test/ChangeLog b/test/ChangeLog index 65e7683dd54..32fc077459b 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,5 +1,8 @@ 2013-08-04 Glenn Morris + * automated/ert-tests.el: Disable failing test that no-one seems + to know how to fix. (Bug#13064) + * automated/icalendar-tests.el (icalendar-tests--test-export) (icalendar-tests--test-import): Try more precise TZ specification. Remove debug messages. diff --git a/test/automated/ert-tests.el b/test/automated/ert-tests.el index 36864377ec9..a2be534c25c 100644 --- a/test/automated/ert-tests.el +++ b/test/automated/ert-tests.el @@ -353,16 +353,18 @@ This macro is used to test if macroexpansion in `should' works." (should-error (macroexpand '(ert-deftest ghi () :documentation "foo")))) -(ert-deftest ert-test-record-backtrace () - (let ((test (make-ert-test :body (lambda () (ert-fail "foo"))))) - (let ((result (ert-run-test test))) - (should (ert-test-failed-p result)) - (with-temp-buffer - (ert--print-backtrace (ert-test-failed-backtrace result)) - (goto-char (point-min)) - (end-of-line) - (let ((first-line (buffer-substring-no-properties (point-min) (point)))) - (should (equal first-line " signal(ert-test-failed (\"foo\"))"))))))) +;; FIXME Test disabled due to persistent failure owing to lexical binding. +;; http://debbugs.gnu.org/13064 +;;; (ert-deftest ert-test-record-backtrace () +;;; (let ((test (make-ert-test :body (lambda () (ert-fail "foo"))))) +;;; (let ((result (ert-run-test test))) +;;; (should (ert-test-failed-p result)) +;;; (with-temp-buffer +;;; (ert--print-backtrace (ert-test-failed-backtrace result)) +;;; (goto-char (point-min)) +;;; (end-of-line) +;;; (let ((first-line (buffer-substring-no-properties (point-min) (point)))) +;;; (should (equal first-line " signal(ert-test-failed (\"foo\"))"))))))) (ert-deftest ert-test-messages () :tags '(:causes-redisplay) From 1d44e9dcad7b0e4d884287288895916718bbd663 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Sun, 4 Aug 2013 02:48:00 -0400 Subject: [PATCH 008/449] * lisp/emacs-lisp/nadvice.el (advice-function-mapc): Rename from advice-mapc. (advice-mapc): New function, using it. (advice-function-member-p): New function. (advice--normalize): Store the cdr in advice--saved-rewrite since that's the part that will be changed. (advice--symbol-function): New function. (advice-remove): Handle removal before the function is defined. Adjust to new advice--saved-rewrite. (advice-member-p): Use advice-function-member-p and advice--symbol-function. --- lisp/ChangeLog | 13 ++++++ lisp/emacs-lisp/nadvice.el | 85 ++++++++++++++++++++++++++------------ 2 files changed, 72 insertions(+), 26 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 848c4e85407..dc1fa09b316 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,16 @@ +2013-08-04 Stefan Monnier + + * emacs-lisp/nadvice.el (advice-function-mapc): Rename from advice-mapc. + (advice-mapc): New function, using it. + (advice-function-member-p): New function. + (advice--normalize): Store the cdr in advice--saved-rewrite since + that's the part that will be changed. + (advice--symbol-function): New function. + (advice-remove): Handle removal before the function is defined. + Adjust to new advice--saved-rewrite. + (advice-member-p): Use advice-function-member-p and + advice--symbol-function. + 2013-08-04 Juanma Barranquero * frameset.el (frameset-p, frameset-save): Fix autoload cookies. diff --git a/lisp/emacs-lisp/nadvice.el b/lisp/emacs-lisp/nadvice.el index edcfc409085..660eb0365ae 100644 --- a/lisp/emacs-lisp/nadvice.el +++ b/lisp/emacs-lisp/nadvice.el @@ -193,7 +193,11 @@ WHERE is a symbol to select an entry in `advice--where-alist'." (equal function (cdr (assq 'name props)))) (list rest)))))) -(defvar advice--buffer-local-function-sample nil) +(defvar advice--buffer-local-function-sample nil + "keeps an example of the special \"run the default value\" functions. +These functions play the same role as t in buffer-local hooks, and to recognize +them, we keep a sample here against which to compare. Each instance is +different, but `function-equal' will hopefully ignore those differences.") (defun advice--set-buffer-local (var val) (if (function-equal val advice--buffer-local-function-sample) @@ -206,6 +210,7 @@ WHERE is a symbol to select an entry in `advice--where-alist'." (declare (gv-setter advice--set-buffer-local)) (if (local-variable-p var) (symbol-value var) (setq advice--buffer-local-function-sample + ;; This function acts like the t special value in buffer-local hooks. (lambda (&rest args) (apply (default-value var) args))))) ;;;###autoload @@ -284,6 +289,20 @@ of the piece of advice." (macroexp-let2 nil new `(advice--remove-function ,getter ,function) `(unless (eq ,new ,getter) ,(funcall setter new))))) +(defun advice-function-mapc (f function-def) + "Apply F to every advice function in FUNCTION-DEF. +F is called with two arguments: the function that was added, and the +properties alist that was specified when it was added." + (while (advice--p function-def) + (funcall f (advice--car function-def) (advice--props function-def)) + (setq function-def (advice--cdr function-def)))) + +(defun advice-function-member-p (advice function-def) + "Return non-nil if ADVICE is already in FUNCTION-DEF. +Instead of ADVICE being the actual function, it can also be the `name' +of the piece of advice." + (advice--member-p advice advice function-def)) + ;;;; Specific application of add-function to `symbol-function' for advice. (defun advice--subst-main (old new) @@ -294,11 +313,11 @@ of the piece of advice." (cond ((special-form-p def) ;; Not worth the trouble trying to handle this, I think. - (error "advice-add failure: %S is a special form" symbol)) + (error "Advice impossible: %S is a special form" symbol)) ((and (symbolp def) (eq 'macro (car-safe (ignore-errors (indirect-function def))))) (let ((newval (cons 'macro (cdr (indirect-function def))))) - (put symbol 'advice--saved-rewrite (cons def newval)) + (put symbol 'advice--saved-rewrite (cons def (cdr newval))) newval)) ;; `f' might be a pure (hence read-only) cons! ((and (eq 'macro (car-safe def)) @@ -309,7 +328,26 @@ of the piece of advice." (defsubst advice--strip-macro (x) (if (eq 'macro (car-safe x)) (cdr x) x)) +(defun advice--symbol-function (symbol) + ;; The value conceptually stored in `symbol-function' is split into two + ;; parts: + ;; - the normal function definition. + ;; - the list of advice applied to it. + ;; `advice--symbol-function' is intended to return the second part (i.e. the + ;; list of advice, which includes a hole at the end which typically holds the + ;; first part, but this function doesn't care much which value is found + ;; there). + ;; In the "normal" state both parts are combined into a single value stored + ;; in the "function slot" of the symbol. But the way they are combined is + ;; different depending on whether the definition is a function or a macro. + ;; Also if the function definition is nil (i.e. unbound) or is an autoload, + ;; the second part is stashed away temporarily in the `advice--pending' + ;; symbol property. + (or (get symbol 'advice--pending) + (advice--strip-macro (symbol-function symbol)))) + (defun advice--defalias-fset (fsetfun symbol newdef) + (unless fsetfun (setq fsetfun #'fset)) (when (get symbol 'advice--saved-rewrite) (put symbol 'advice--saved-rewrite nil)) (setq newdef (advice--normalize symbol newdef)) @@ -330,11 +368,11 @@ of the piece of advice." (let* ((snewdef (advice--strip-macro newdef)) (snewadv (advice--subst-main oldadv snewdef))) (put symbol 'advice--pending nil) - (funcall (or fsetfun #'fset) symbol + (funcall fsetfun symbol (if (eq snewdef newdef) snewadv (cons 'macro snewadv)))) (unless (eq oldadv (get symbol 'advice--pending)) (put symbol 'advice--pending (advice--subst-main oldadv nil))) - (funcall (or fsetfun #'fset) symbol newdef)))) + (funcall fsetfun symbol newdef)))) ;;;###autoload @@ -349,8 +387,7 @@ is defined as a macro, alias, command, ..." ;; - obsolete advice.el. (let* ((f (symbol-function symbol)) (nf (advice--normalize symbol f))) - (unless (eq f nf) ;; Most importantly, if nf == nil! - (fset symbol nf)) + (unless (eq f nf) (fset symbol nf)) (add-function where (cond ((eq (car-safe nf) 'macro) (cdr nf)) ;; Reasons to delay installation of the advice: @@ -377,39 +414,35 @@ or an autoload and it preserves `fboundp'. Instead of the actual function to remove, FUNCTION can also be the `name' of the piece of advice." (let ((f (symbol-function symbol))) - ;; Can't use the `if' place here, because the body is too large, - ;; resulting in use of code that only works with lexical-scoping. - (remove-function (if (eq (car-safe f) 'macro) - (cdr f) - (symbol-function symbol)) + (remove-function (cond ;This is `advice--symbol-function' but as a "place". + ((get symbol 'advice--pending) + (get symbol 'advice--pending)) + ((eq (car-safe f) 'macro) (cdr f)) + (t (symbol-function symbol))) function) (unless (advice--p (if (eq (car-safe f) 'macro) (cdr f) (symbol-function symbol))) ;; Not advised any more. (remove-function (get symbol 'defalias-fset-function) #'advice--defalias-fset) - (if (eq (symbol-function symbol) - (cdr (get symbol 'advice--saved-rewrite))) - (fset symbol (car (get symbol 'advice--saved-rewrite)))))) + (let ((asr (get symbol 'advice--saved-rewrite))) + (and asr (eq (cdr-safe (symbol-function symbol)) + (cdr asr)) + (fset symbol (car (get symbol 'advice--saved-rewrite))))))) nil) -(defun advice-mapc (fun def) - "Apply FUN to every advice function in DEF. +(defun advice-mapc (fun symbol) + "Apply FUN to every advice function in SYMBOL. FUN is called with a two arguments: the function that was added, and the properties alist that was specified when it was added." - (while (advice--p def) - (funcall fun (advice--car def) (advice--props def)) - (setq def (advice--cdr def)))) + (advice-function-mapc fun (advice--symbol-function symbol))) ;;;###autoload -(defun advice-member-p (advice function-name) - "Return non-nil if ADVICE has been added to FUNCTION-NAME. +(defun advice-member-p (advice symbol) + "Return non-nil if ADVICE has been added to SYMBOL. Instead of ADVICE being the actual function, it can also be the `name' of the piece of advice." - (advice--member-p advice advice - (or (get function-name 'advice--pending) - (advice--strip-macro - (symbol-function function-name))))) + (advice-function-member-p advice (advice--symbol-function symbol))) ;; When code is advised, called-interactively-p needs to be taught to skip ;; the advising frames. From 63f5c6c20d393e05d517c5c02155d03694c41291 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sun, 4 Aug 2013 18:32:12 +0300 Subject: [PATCH 009/449] Implement mkostemp for MS-Windows. nt/mingw-cfg.site (ac_cv_func_mkostemp): New var with value of "yes". nt/inc/ms-w32.h (mkostemp): Declare prototype. nt/config.nt (HAVE_MKOSTEMP): Define to 1. src/w32.c (mkostemp): New function. (mktemp): Remove, no longer used. Most of the code reused in mkostemp. Fixes: debbugs:15015 --- nt/ChangeLog | 9 ++++ nt/config.nt | 3 ++ nt/inc/ms-w32.h | 2 + nt/mingw-cfg.site | 1 + src/ChangeLog | 6 +++ src/w32.c | 105 ++++++++++++++++++++++++---------------------- 6 files changed, 76 insertions(+), 50 deletions(-) diff --git a/nt/ChangeLog b/nt/ChangeLog index c0598dd5630..23c0c74b6f1 100644 --- a/nt/ChangeLog +++ b/nt/ChangeLog @@ -1,3 +1,12 @@ +2013-08-04 Eli Zaretskii + + * mingw-cfg.site (ac_cv_func_mkostemp): New var with value of + "yes". + + * inc/ms-w32.h (mkostemp): Declare prototype. + + * config.nt (HAVE_MKOSTEMP): Define to 1. (Bug#15015) + 2013-07-07 Eli Zaretskii * inc/sys/socket.h (F_SETFD, O_CLOEXEC, F_DUPFD_CLOEXEC) diff --git a/nt/config.nt b/nt/config.nt index 95b56f2dc64..3ba60a85752 100644 --- a/nt/config.nt +++ b/nt/config.nt @@ -796,6 +796,9 @@ along with GNU Emacs. If not, see . */ systems that support xmenu.c. */ #undef HAVE_MENUS +/* Define to 1 if you have the `mkostemp' function. */ +#define HAVE_MKOSTEMP 1 + /* Define to 1 if you have the `mkstemp' function. */ #undef HAVE_MKSTEMP diff --git a/nt/inc/ms-w32.h b/nt/inc/ms-w32.h index 3e50c78f145..f01f254d81c 100644 --- a/nt/inc/ms-w32.h +++ b/nt/inc/ms-w32.h @@ -450,6 +450,8 @@ extern int getpagesize (void); extern void * memrchr (void const *, int, size_t); +extern int mkostemp (char *, int); + #if defined (__MINGW32__) diff --git a/nt/mingw-cfg.site b/nt/mingw-cfg.site index cf55fe04ed8..325bba29ae5 100644 --- a/nt/mingw-cfg.site +++ b/nt/mingw-cfg.site @@ -60,6 +60,7 @@ ac_cv_func_getpeername=yes # Implemented as sys_socket in w32.c ac_cv_func_socket=yes # Implemented in w32.c +ac_cv_func_mkostemp=yes ac_cv_func_readlink=yes ac_cv_func_symlink=yes # Avoid run-time tests of readlink and symlink, which will fail diff --git a/src/ChangeLog b/src/ChangeLog index 8a9de96358d..0fe6b4e6ce3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2013-08-04 Eli Zaretskii + + * w32.c (mkostemp): New function. + (mktemp): Remove, no longer used. Most of the code reused in + mkostemp. (Bug#15015) + 2013-08-04 Dmitry Antipov * dispnew.c (glyph_matrix_count, glyph_pool_count): diff --git a/src/w32.c b/src/w32.c index fb2d7c75972..af42c6f39c2 100644 --- a/src/w32.c +++ b/src/w32.c @@ -3414,56 +3414,6 @@ sys_mkdir (const char * path) return _mkdir (map_w32_filename (path, NULL)); } -/* Because of long name mapping issues, we need to implement this - ourselves. Also, MSVC's _mktemp returns NULL when it can't generate - a unique name, instead of setting the input template to an empty - string. - - Standard algorithm seems to be use pid or tid with a letter on the - front (in place of the 6 X's) and cycle through the letters to find a - unique name. We extend that to allow any reasonable character as the - first of the 6 X's. */ -char * -sys_mktemp (char * template) -{ - char * p; - int i; - unsigned uid = GetCurrentThreadId (); - static char first_char[] = "abcdefghijklmnopqrstuvwyz0123456789!%-_@#"; - - if (template == NULL) - return NULL; - p = template + strlen (template); - i = 5; - /* replace up to the last 5 X's with uid in decimal */ - while (--p >= template && p[0] == 'X' && --i >= 0) - { - p[0] = '0' + uid % 10; - uid /= 10; - } - - if (i < 0 && p[0] == 'X') - { - i = 0; - do - { - int save_errno = errno; - p[0] = first_char[i]; - if (faccessat (AT_FDCWD, template, F_OK, AT_EACCESS) < 0) - { - errno = save_errno; - return template; - } - } - while (++i < sizeof (first_char)); - } - - /* Template is badly formed or else we can't generate a unique name, - so return empty string */ - template[0] = 0; - return template; -} - int sys_open (const char * path, int oflag, int mode) { @@ -3481,6 +3431,61 @@ sys_open (const char * path, int oflag, int mode) return res; } +/* Implementation of mkostemp for MS-Windows, to avoid race conditions + when using mktemp. + + Standard algorithm for generating a temporary file name seems to be + use pid or tid with a letter on the front (in place of the 6 X's) + and cycle through the letters to find a unique name. We extend + that to allow any reasonable character as the first of the 6 X's, + so that the number of simultaneously used temporary files will be + greater. */ + +int +mkostemp (char * template, int flags) +{ + char * p; + int i, fd = -1; + unsigned uid = GetCurrentThreadId (); + int save_errno = errno; + static char first_char[] = "abcdefghijklmnopqrstuvwyz0123456789!%-_@#"; + + errno = EINVAL; + if (template == NULL) + return -1; + + p = template + strlen (template); + i = 5; + /* replace up to the last 5 X's with uid in decimal */ + while (--p >= template && p[0] == 'X' && --i >= 0) + { + p[0] = '0' + uid % 10; + uid /= 10; + } + + if (i < 0 && p[0] == 'X') + { + i = 0; + do + { + p[0] = first_char[i]; + if ((fd = sys_open (template, + flags | _O_CREAT | _O_EXCL | _O_RDWR, + S_IRUSR | S_IWUSR)) >= 0 + || errno != EEXIST) + { + if (fd >= 0) + errno = save_errno; + return fd; + } + } + while (++i < sizeof (first_char)); + } + + /* Template is badly formed or else we can't generate a unique name. */ + return -1; +} + int fchmod (int fd, mode_t mode) { From 484ab23924d39b3e26d54074fd659633e1660ef4 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sun, 4 Aug 2013 18:43:10 +0300 Subject: [PATCH 010/449] Minor fix of the last commit. --- nt/ChangeLog | 1 + nt/inc/ms-w32.h | 2 -- src/ChangeLog | 1 + src/w32.c | 1 - 4 files changed, 2 insertions(+), 3 deletions(-) diff --git a/nt/ChangeLog b/nt/ChangeLog index 23c0c74b6f1..8ed5caa4aab 100644 --- a/nt/ChangeLog +++ b/nt/ChangeLog @@ -4,6 +4,7 @@ "yes". * inc/ms-w32.h (mkostemp): Declare prototype. + (mktemp): Don't redirect to sys_mktemp. * config.nt (HAVE_MKOSTEMP): Define to 1. (Bug#15015) diff --git a/nt/inc/ms-w32.h b/nt/inc/ms-w32.h index f01f254d81c..e670079eb35 100644 --- a/nt/inc/ms-w32.h +++ b/nt/inc/ms-w32.h @@ -207,8 +207,6 @@ extern struct tm * sys_localtime (const time_t *); #define link sys_link #define localtime sys_localtime #define mkdir sys_mkdir -#undef mktemp -#define mktemp sys_mktemp #undef open #define open sys_open #undef read diff --git a/src/ChangeLog b/src/ChangeLog index 0fe6b4e6ce3..c29c4c8da59 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -3,6 +3,7 @@ * w32.c (mkostemp): New function. (mktemp): Remove, no longer used. Most of the code reused in mkostemp. (Bug#15015) + (mktemp): Don't undef. 2013-08-04 Dmitry Antipov diff --git a/src/w32.c b/src/w32.c index af42c6f39c2..bb2f0acd99a 100644 --- a/src/w32.c +++ b/src/w32.c @@ -47,7 +47,6 @@ along with GNU Emacs. If not, see . */ #undef fopen #undef link #undef mkdir -#undef mktemp #undef open #undef rename #undef rmdir From e0fdb6943066032db294720915c3bd644bf2bcd1 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 4 Aug 2013 09:56:56 -0700 Subject: [PATCH 011/449] Fix some minor races in hosts lacking mkostemp. Gnulib's emulation of mkostemp doesn't have races that Emacs's does. * configure.ac (mkostemp): Remove check for this function; gnulib does the check now. (mkstemp): Remove check for this no-longer-used function. * lib/mkostemp.c, lib/secure_getenv.c, lib/tempname.c, lib/tempname.h: * m4/mkostemp.m4, m4/secure_getenv.m4, m4/tempname.m4: New files, copied from Gnulib. * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. * admin/merge-gnulib (GNULIB_MODULES): Add mkostemp. * lib-src/movemail.c (main): * lib-src/update-game-score.c (write_scores): Use mkostemp (which now works on all platforms, due to changes in the portability layer) rather than mktemp (which has a race) or mkstemp (which we no longer bother with). * src/callproc.c (create_temp_file): * src/filelock.c (create_lock_file): Assume mkostemp, since it's now provided by Gnulib. Fixes: debbugs:15015 --- ChangeLog | 12 ++ admin/ChangeLog | 5 + admin/merge-gnulib | 2 +- configure.ac | 2 +- lib-src/ChangeLog | 9 ++ lib-src/movemail.c | 17 +- lib-src/update-game-score.c | 12 +- lib/gnulib.mk | 32 +++- lib/mkostemp.c | 46 ++++++ lib/secure_getenv.c | 41 +++++ lib/tempname.c | 306 ++++++++++++++++++++++++++++++++++++ lib/tempname.h | 50 ++++++ m4/gnulib-comp.m4 | 44 ++++++ m4/mkostemp.m4 | 23 +++ m4/secure_getenv.m4 | 25 +++ m4/tempname.m4 | 19 +++ src/ChangeLog | 7 + src/callproc.c | 14 +- src/filelock.c | 18 +-- 19 files changed, 632 insertions(+), 52 deletions(-) create mode 100644 lib/mkostemp.c create mode 100644 lib/secure_getenv.c create mode 100644 lib/tempname.c create mode 100644 lib/tempname.h create mode 100644 m4/mkostemp.m4 create mode 100644 m4/secure_getenv.m4 create mode 100644 m4/tempname.m4 diff --git a/ChangeLog b/ChangeLog index bc70b1e4446..cd8ce1a25ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2013-08-04 Paul Eggert + + Fix some minor races in hosts lacking mkostemp (Bug#15015). + Gnulib's emulation of mkostemp doesn't have races that Emacs's does. + * configure.ac (mkostemp): Remove check for this function; + gnulib does the check now. + (mkstemp): Remove check for this no-longer-used function. + * lib/mkostemp.c, lib/secure_getenv.c, lib/tempname.c, lib/tempname.h: + * m4/mkostemp.m4, m4/secure_getenv.m4, m4/tempname.m4: + New files, copied from Gnulib. + * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. + 2013-07-29 Michael Albinus * INSTALL (DETAILED BUILDING AND INSTALLATION): Add diff --git a/admin/ChangeLog b/admin/ChangeLog index cbcd698e8b1..5373a9d20b6 100644 --- a/admin/ChangeLog +++ b/admin/ChangeLog @@ -1,3 +1,8 @@ +2013-08-04 Paul Eggert + + Fix some minor races in hosts lacking mkostemp (Bug#15015). + * merge-gnulib (GNULIB_MODULES): Add mkostemp. + 2013-07-12 Glenn Morris * admin.el (manual-style-string): Use non-abbreviated url. diff --git a/admin/merge-gnulib b/admin/merge-gnulib index 82e0cd77fca..97126704d10 100755 --- a/admin/merge-gnulib +++ b/admin/merge-gnulib @@ -32,7 +32,7 @@ GNULIB_MODULES=' fcntl fcntl-h fdatasync fdopendir filemode fstatat fsync getloadavg getopt-gnu gettime gettimeofday intprops largefile lstat - manywarnings memrchr mktime + manywarnings memrchr mkostemp mktime pipe2 pselect pthread_sigmask putenv qacl readlink readlinkat sig2str socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat diff --git a/configure.ac b/configure.ac index d8557f29898..89aba556bb3 100644 --- a/configure.ac +++ b/configure.ac @@ -3277,7 +3277,7 @@ select getpagesize setlocale \ getrlimit setrlimit shutdown getaddrinfo \ strsignal setitimer \ sendto recvfrom getsockname getpeername getifaddrs freeifaddrs \ -gai_strerror mkostemp mkstemp getline getdelim sync \ +gai_strerror getline getdelim sync \ difftime posix_memalign \ getpwent endpwent getgrent endgrent \ touchlock \ diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index f41c23df5d2..2cfe46f5352 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog @@ -1,3 +1,12 @@ +2013-08-04 Paul Eggert + + Fix some minor races in hosts lacking mkostemp (Bug#15015). + * movemail.c (main): + * update-game-score.c (write_scores): + Use mkostemp (which now works on all platforms, due to changes + in the portability layer) rather than mktemp (which has a race) + or mkstemp (which we no longer bother with). + 2013-07-10 Paul Eggert Port to C89. diff --git a/lib-src/movemail.c b/lib-src/movemail.c index 81ac8aa187c..9434782cb17 100644 --- a/lib-src/movemail.c +++ b/lib-src/movemail.c @@ -304,24 +304,13 @@ main (int argc, char **argv) memcpy (tempname, inname, inname_dirlen); strcpy (tempname + inname_dirlen, "EXXXXXX"); -#ifdef HAVE_MKSTEMP - desc = mkstemp (tempname); -#else - mktemp (tempname); - if (!*tempname) - desc = -1; - else - { - unlink (tempname); - desc = open (tempname, O_WRONLY | O_CREAT | O_EXCL, 0600); - } -#endif + desc = mkostemp (tempname, 0); if (desc < 0) { - int mkstemp_errno = errno; + int mkostemp_errno = errno; error ("error while creating what would become the lock file", 0, 0); - errno = mkstemp_errno; + errno = mkostemp_errno; pfatal_with_name (tempname); } close (desc); diff --git a/lib-src/update-game-score.c b/lib-src/update-game-score.c index ec8b4317770..1699e305c8d 100644 --- a/lib-src/update-game-score.c +++ b/lib-src/update-game-score.c @@ -383,6 +383,7 @@ sort_scores (struct score_entry *scores, int count, int reverse) static int write_scores (const char *filename, const struct score_entry *scores, int count) { + int fd; FILE *f; int i; char *tempfile = malloc (strlen (filename) + strlen (".tempXXXXXX") + 1); @@ -390,12 +391,11 @@ write_scores (const char *filename, const struct score_entry *scores, int count) return -1; strcpy (tempfile, filename); strcat (tempfile, ".tempXXXXXX"); -#ifdef HAVE_MKSTEMP - if (mkstemp (tempfile) < 0 -#else - if (mktemp (tempfile) != tempfile -#endif - || !(f = fopen (tempfile, "w"))) + fd = mkostemp (tempfile, 0); + if (fd < 0) + return -1; + f = fdopen (fd, "w"); + if (! f) return -1; for (i = 0; i < count; i++) if (fprintf (f, "%ld %s %s\n", scores[i].score, scores[i].username, diff --git a/lib/gnulib.mk b/lib/gnulib.mk index d053e15efc1..32255181fb4 100644 --- a/lib/gnulib.mk +++ b/lib/gnulib.mk @@ -21,7 +21,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat close-stream crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode fstatat fsync getloadavg getopt-gnu gettime gettimeofday intprops largefile lstat manywarnings memrchr mktime pipe2 pselect pthread_sigmask putenv qacl readlink readlinkat sig2str socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub unsetenv utimens warnings +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat close-stream crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode fstatat fsync getloadavg getopt-gnu gettime gettimeofday intprops largefile lstat manywarnings memrchr mkostemp mktime pipe2 pselect pthread_sigmask putenv qacl readlink readlinkat sig2str socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub unsetenv utimens warnings MOSTLYCLEANFILES += core *.stackdump @@ -560,6 +560,15 @@ EXTRA_libgnu_a_SOURCES += memrchr.c ## end gnulib module memrchr +## begin gnulib module mkostemp + + +EXTRA_DIST += mkostemp.c + +EXTRA_libgnu_a_SOURCES += mkostemp.c + +## end gnulib module mkostemp + ## begin gnulib module mktime @@ -657,6 +666,17 @@ EXTRA_DIST += root-uid.h ## end gnulib module root-uid +## begin gnulib module secure_getenv + +if gl_GNULIB_ENABLED_secure_getenv + +endif +EXTRA_DIST += secure_getenv.c + +EXTRA_libgnu_a_SOURCES += secure_getenv.c + +## end gnulib module secure_getenv + ## begin gnulib module sig2str @@ -1480,6 +1500,16 @@ EXTRA_DIST += sys_time.in.h ## end gnulib module sys_time +## begin gnulib module tempname + +if gl_GNULIB_ENABLED_tempname +libgnu_a_SOURCES += tempname.c + +endif +EXTRA_DIST += tempname.h + +## end gnulib module tempname + ## begin gnulib module time BUILT_SOURCES += time.h diff --git a/lib/mkostemp.c b/lib/mkostemp.c new file mode 100644 index 00000000000..2188ff5dd61 --- /dev/null +++ b/lib/mkostemp.c @@ -0,0 +1,46 @@ +/* Copyright (C) 1998-1999, 2001, 2005-2007, 2009-2013 Free Software + Foundation, Inc. + This file is derived from the one in the GNU C Library. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#if !_LIBC +# include +#endif + +#include + +#if !_LIBC +# include "tempname.h" +# define __gen_tempname gen_tempname +# ifndef __GTFILE +# define __GT_FILE GT_FILE +# endif +#endif + +#include + +#ifndef __GT_FILE +# define __GT_FILE 0 +#endif + +/* Generate a unique temporary file name from XTEMPLATE. + The last six characters of XTEMPLATE must be "XXXXXX"; + they are replaced with a string that makes the file name unique. + Then open the file and return a fd. */ +int +mkostemp (char *xtemplate, int flags) +{ + return __gen_tempname (xtemplate, 0, flags, __GT_FILE); +} diff --git a/lib/secure_getenv.c b/lib/secure_getenv.c new file mode 100644 index 00000000000..6c11c5e0edb --- /dev/null +++ b/lib/secure_getenv.c @@ -0,0 +1,41 @@ +/* Look up an environment variable more securely. + + Copyright 2013 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +#include + +#if !HAVE___SECURE_GETENV +# if HAVE_ISSETUGID +# include +# else +# undef issetugid +# define issetugid() 1 +# endif +#endif + +char * +secure_getenv (char const *name) +{ +#if HAVE___SECURE_GETENV + return __secure_getenv (name); +#else + if (issetugid ()) + return 0; + return getenv (name); +#endif +} diff --git a/lib/tempname.c b/lib/tempname.c new file mode 100644 index 00000000000..087b79b31fe --- /dev/null +++ b/lib/tempname.c @@ -0,0 +1,306 @@ +/* tempname.c - generate the name of a temporary file. + + Copyright (C) 1991-2003, 2005-2007, 2009-2013 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Extracted from glibc sysdeps/posix/tempname.c. See also tmpdir.c. */ + +#if !_LIBC +# include +# include "tempname.h" +#endif + +#include +#include + +#include +#ifndef __set_errno +# define __set_errno(Val) errno = (Val) +#endif + +#include +#ifndef P_tmpdir +# define P_tmpdir "/tmp" +#endif +#ifndef TMP_MAX +# define TMP_MAX 238328 +#endif +#ifndef __GT_FILE +# define __GT_FILE 0 +# define __GT_DIR 1 +# define __GT_NOCREATE 2 +#endif +#if !_LIBC && (GT_FILE != __GT_FILE || GT_DIR != __GT_DIR \ + || GT_NOCREATE != __GT_NOCREATE) +# error report this to bug-gnulib@gnu.org +#endif + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#if _LIBC +# define struct_stat64 struct stat64 +#else +# define struct_stat64 struct stat +# define __gen_tempname gen_tempname +# define __getpid getpid +# define __gettimeofday gettimeofday +# define __mkdir mkdir +# define __open open +# define __lxstat64(version, file, buf) lstat (file, buf) +# define __secure_getenv secure_getenv +#endif + +#ifdef _LIBC +# include +# if HP_TIMING_AVAIL +# define RANDOM_BITS(Var) \ + if (__builtin_expect (value == UINT64_C (0), 0)) \ + { \ + /* If this is the first time this function is used initialize \ + the variable we accumulate the value in to some somewhat \ + random value. If we'd not do this programs at startup time \ + might have a reduced set of possible names, at least on slow \ + machines. */ \ + struct timeval tv; \ + __gettimeofday (&tv, NULL); \ + value = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; \ + } \ + HP_TIMING_NOW (Var) +# endif +#endif + +/* Use the widest available unsigned type if uint64_t is not + available. The algorithm below extracts a number less than 62**6 + (approximately 2**35.725) from uint64_t, so ancient hosts where + uintmax_t is only 32 bits lose about 3.725 bits of randomness, + which is better than not having mkstemp at all. */ +#if !defined UINT64_MAX && !defined uint64_t +# define uint64_t uintmax_t +#endif + +#if _LIBC +/* Return nonzero if DIR is an existent directory. */ +static int +direxists (const char *dir) +{ + struct_stat64 buf; + return __xstat64 (_STAT_VER, dir, &buf) == 0 && S_ISDIR (buf.st_mode); +} + +/* Path search algorithm, for tmpnam, tmpfile, etc. If DIR is + non-null and exists, uses it; otherwise uses the first of $TMPDIR, + P_tmpdir, /tmp that exists. Copies into TMPL a template suitable + for use with mk[s]temp. Will fail (-1) if DIR is non-null and + doesn't exist, none of the searched dirs exists, or there's not + enough space in TMPL. */ +int +__path_search (char *tmpl, size_t tmpl_len, const char *dir, const char *pfx, + int try_tmpdir) +{ + const char *d; + size_t dlen, plen; + + if (!pfx || !pfx[0]) + { + pfx = "file"; + plen = 4; + } + else + { + plen = strlen (pfx); + if (plen > 5) + plen = 5; + } + + if (try_tmpdir) + { + d = __secure_getenv ("TMPDIR"); + if (d != NULL && direxists (d)) + dir = d; + else if (dir != NULL && direxists (dir)) + /* nothing */ ; + else + dir = NULL; + } + if (dir == NULL) + { + if (direxists (P_tmpdir)) + dir = P_tmpdir; + else if (strcmp (P_tmpdir, "/tmp") != 0 && direxists ("/tmp")) + dir = "/tmp"; + else + { + __set_errno (ENOENT); + return -1; + } + } + + dlen = strlen (dir); + while (dlen > 1 && dir[dlen - 1] == '/') + dlen--; /* remove trailing slashes */ + + /* check we have room for "${dir}/${pfx}XXXXXX\0" */ + if (tmpl_len < dlen + 1 + plen + 6 + 1) + { + __set_errno (EINVAL); + return -1; + } + + sprintf (tmpl, "%.*s/%.*sXXXXXX", (int) dlen, dir, (int) plen, pfx); + return 0; +} +#endif /* _LIBC */ + +/* These are the characters used in temporary file names. */ +static const char letters[] = +"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + +/* Generate a temporary file name based on TMPL. TMPL must match the + rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix). + The name constructed does not exist at the time of the call to + __gen_tempname. TMPL is overwritten with the result. + + KIND may be one of: + __GT_NOCREATE: simply verify that the name does not exist + at the time of the call. + __GT_FILE: create the file using open(O_CREAT|O_EXCL) + and return a read-write fd. The file is mode 0600. + __GT_DIR: create a directory, which will be mode 0700. + + We use a clever algorithm to get hard-to-predict names. */ +int +__gen_tempname (char *tmpl, int suffixlen, int flags, int kind) +{ + int len; + char *XXXXXX; + static uint64_t value; + uint64_t random_time_bits; + unsigned int count; + int fd = -1; + int save_errno = errno; + struct_stat64 st; + + /* A lower bound on the number of temporary files to attempt to + generate. The maximum total number of temporary file names that + can exist for a given template is 62**6. It should never be + necessary to try all of these combinations. Instead if a reasonable + number of names is tried (we define reasonable as 62**3) fail to + give the system administrator the chance to remove the problems. */ +#define ATTEMPTS_MIN (62 * 62 * 62) + + /* The number of times to attempt to generate a temporary file. To + conform to POSIX, this must be no smaller than TMP_MAX. */ +#if ATTEMPTS_MIN < TMP_MAX + unsigned int attempts = TMP_MAX; +#else + unsigned int attempts = ATTEMPTS_MIN; +#endif + + len = strlen (tmpl); + if (len < 6 + suffixlen || memcmp (&tmpl[len - 6 - suffixlen], "XXXXXX", 6)) + { + __set_errno (EINVAL); + return -1; + } + + /* This is where the Xs start. */ + XXXXXX = &tmpl[len - 6 - suffixlen]; + + /* Get some more or less random data. */ +#ifdef RANDOM_BITS + RANDOM_BITS (random_time_bits); +#else + { + struct timeval tv; + __gettimeofday (&tv, NULL); + random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; + } +#endif + value += random_time_bits ^ __getpid (); + + for (count = 0; count < attempts; value += 7777, ++count) + { + uint64_t v = value; + + /* Fill in the random bits. */ + XXXXXX[0] = letters[v % 62]; + v /= 62; + XXXXXX[1] = letters[v % 62]; + v /= 62; + XXXXXX[2] = letters[v % 62]; + v /= 62; + XXXXXX[3] = letters[v % 62]; + v /= 62; + XXXXXX[4] = letters[v % 62]; + v /= 62; + XXXXXX[5] = letters[v % 62]; + + switch (kind) + { + case __GT_FILE: + fd = __open (tmpl, + (flags & ~O_ACCMODE) + | O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); + break; + + case __GT_DIR: + fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR); + break; + + case __GT_NOCREATE: + /* This case is backward from the other three. __gen_tempname + succeeds if __xstat fails because the name does not exist. + Note the continue to bypass the common logic at the bottom + of the loop. */ + if (__lxstat64 (_STAT_VER, tmpl, &st) < 0) + { + if (errno == ENOENT) + { + __set_errno (save_errno); + return 0; + } + else + /* Give up now. */ + return -1; + } + continue; + + default: + assert (! "invalid KIND in __gen_tempname"); + abort (); + } + + if (fd >= 0) + { + __set_errno (save_errno); + return fd; + } + else if (errno != EEXIST) + return -1; + } + + /* We got out of the loop because we ran out of combinations to try. */ + __set_errno (EEXIST); + return -1; +} diff --git a/lib/tempname.h b/lib/tempname.h new file mode 100644 index 00000000000..333267dfd09 --- /dev/null +++ b/lib/tempname.h @@ -0,0 +1,50 @@ +/* Create a temporary file or directory. + + Copyright (C) 2006, 2009-2013 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* header written by Eric Blake */ + +#ifndef GL_TEMPNAME_H +# define GL_TEMPNAME_H + +# include + +# ifdef __GT_FILE +# define GT_FILE __GT_FILE +# define GT_DIR __GT_DIR +# define GT_NOCREATE __GT_NOCREATE +# else +# define GT_FILE 0 +# define GT_DIR 1 +# define GT_NOCREATE 2 +# endif + +/* Generate a temporary file name based on TMPL. TMPL must match the + rules for mk[s]temp (i.e. end in "XXXXXX", possibly with a suffix). + The name constructed does not exist at the time of the call to + gen_tempname. TMPL is overwritten with the result. + + KIND may be one of: + GT_NOCREATE: simply verify that the name does not exist + at the time of the call. + GT_FILE: create a large file using open(O_CREAT|O_EXCL) + and return a read-write fd. The file is mode 0600. + GT_DIR: create a directory, which will be mode 0700. + + We use a clever algorithm to get hard-to-predict names. */ +extern int gen_tempname (char *tmpl, int suffixlen, int flags, int kind); + +#endif /* GL_TEMPNAME_H */ diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index d7062e862de..af9a9ca3ae0 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -89,6 +89,7 @@ AC_DEFUN([gl_EARLY], # Code from module lstat: # Code from module manywarnings: # Code from module memrchr: + # Code from module mkostemp: # Code from module mktime: # Code from module multiarch: # Code from module nocrash: @@ -102,6 +103,7 @@ AC_DEFUN([gl_EARLY], # Code from module readlink: # Code from module readlinkat: # Code from module root-uid: + # Code from module secure_getenv: # Code from module sig2str: # Code from module signal-h: # Code from module snippet/_Noreturn: @@ -134,6 +136,7 @@ AC_DEFUN([gl_EARLY], # Code from module sys_select: # Code from module sys_stat: # Code from module sys_time: + # Code from module tempname: # Code from module time: # Code from module time_r: # Code from module timer-time: @@ -274,6 +277,13 @@ AC_DEFUN([gl_INIT], gl_PREREQ_MEMRCHR fi gl_STRING_MODULE_INDICATOR([memrchr]) + gl_FUNC_MKOSTEMP + if test $HAVE_MKOSTEMP = 0; then + AC_LIBOBJ([mkostemp]) + gl_PREREQ_MKOSTEMP + fi + gl_MODULE_INDICATOR([mkostemp]) + gl_STDLIB_MODULE_INDICATOR([mkostemp]) gl_FUNC_MKTIME if test $REPLACE_MKTIME = 1; then AC_LIBOBJ([mktime]) @@ -381,9 +391,11 @@ AC_DEFUN([gl_INIT], gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7=false gl_gnulib_enabled_pathmax=false gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=false + gl_gnulib_enabled_secure_getenv=false gl_gnulib_enabled_stat=false gl_gnulib_enabled_strtoll=false gl_gnulib_enabled_strtoull=false + gl_gnulib_enabled_tempname=false gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec=false func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b () { @@ -485,6 +497,18 @@ AC_DEFUN([gl_INIT], gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=true fi } + func_gl_gnulib_m4code_secure_getenv () + { + if ! $gl_gnulib_enabled_secure_getenv; then + gl_FUNC_SECURE_GETENV + if test $HAVE_SECURE_GETENV = 0; then + AC_LIBOBJ([secure_getenv]) + gl_PREREQ_SECURE_GETENV + fi + gl_STDLIB_MODULE_INDICATOR([secure_getenv]) + gl_gnulib_enabled_secure_getenv=true + fi + } func_gl_gnulib_m4code_stat () { if ! $gl_gnulib_enabled_stat; then @@ -527,6 +551,14 @@ AC_DEFUN([gl_INIT], gl_gnulib_enabled_strtoull=true fi } + func_gl_gnulib_m4code_tempname () + { + if ! $gl_gnulib_enabled_tempname; then + gl_FUNC_GEN_TEMPNAME + gl_gnulib_enabled_tempname=true + func_gl_gnulib_m4code_secure_getenv + fi + } func_gl_gnulib_m4code_682e609604ccaac6be382e4ee3a4eaec () { if ! $gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec; then @@ -569,6 +601,9 @@ AC_DEFUN([gl_INIT], if test $REPLACE_LSTAT = 1; then func_gl_gnulib_m4code_stat fi + if test $HAVE_MKOSTEMP = 0; then + func_gl_gnulib_m4code_tempname + fi if test $HAVE_READLINK = 0 || test $REPLACE_READLINK = 1; then func_gl_gnulib_m4code_stat fi @@ -598,9 +633,11 @@ AC_DEFUN([gl_INIT], AM_CONDITIONAL([gl_GNULIB_ENABLED_03e0aaad4cb89ca757653bd367a6ccb7], [$gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7]) AM_CONDITIONAL([gl_GNULIB_ENABLED_pathmax], [$gl_gnulib_enabled_pathmax]) AM_CONDITIONAL([gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c], [$gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c]) + AM_CONDITIONAL([gl_GNULIB_ENABLED_secure_getenv], [$gl_gnulib_enabled_secure_getenv]) AM_CONDITIONAL([gl_GNULIB_ENABLED_stat], [$gl_gnulib_enabled_stat]) AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoll], [$gl_gnulib_enabled_strtoll]) AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoull], [$gl_gnulib_enabled_strtoull]) + AM_CONDITIONAL([gl_GNULIB_ENABLED_tempname], [$gl_gnulib_enabled_tempname]) AM_CONDITIONAL([gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec], [$gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec]) # End of code from modules m4_ifval(gl_LIBSOURCES_LIST, [ @@ -806,6 +843,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/md5.c lib/md5.h lib/memrchr.c + lib/mkostemp.c lib/mktime-internal.h lib/mktime.c lib/openat-priv.h @@ -821,6 +859,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/readlink.c lib/readlinkat.c lib/root-uid.h + lib/secure_getenv.c lib/sha1.c lib/sha1.h lib/sha256.c @@ -853,6 +892,8 @@ AC_DEFUN([gl_FILE_LIST], [ lib/sys_select.in.h lib/sys_stat.in.h lib/sys_time.in.h + lib/tempname.c + lib/tempname.h lib/time.in.h lib/time_r.c lib/timespec-add.c @@ -908,6 +949,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/manywarnings.m4 m4/md5.m4 m4/memrchr.m4 + m4/mkostemp.m4 m4/mktime.m4 m4/multiarch.m4 m4/nocrash.m4 @@ -919,6 +961,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/putenv.m4 m4/readlink.m4 m4/readlinkat.m4 + m4/secure_getenv.m4 m4/setenv.m4 m4/sha1.m4 m4/sha256.m4 @@ -948,6 +991,7 @@ AC_DEFUN([gl_FILE_LIST], [ m4/sys_socket_h.m4 m4/sys_stat_h.m4 m4/sys_time_h.m4 + m4/tempname.m4 m4/time_h.m4 m4/time_r.m4 m4/timer_time.m4 diff --git a/m4/mkostemp.m4 b/m4/mkostemp.m4 new file mode 100644 index 00000000000..6d101eeda39 --- /dev/null +++ b/m4/mkostemp.m4 @@ -0,0 +1,23 @@ +# mkostemp.m4 serial 2 +dnl Copyright (C) 2009-2013 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_MKOSTEMP], +[ + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + + dnl Persuade glibc to declare mkostemp(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_FUNCS_ONCE([mkostemp]) + if test $ac_cv_func_mkostemp != yes; then + HAVE_MKOSTEMP=0 + fi +]) + +# Prerequisites of lib/mkostemp.c. +AC_DEFUN([gl_PREREQ_MKOSTEMP], +[ +]) diff --git a/m4/secure_getenv.m4 b/m4/secure_getenv.m4 new file mode 100644 index 00000000000..5da5298f669 --- /dev/null +++ b/m4/secure_getenv.m4 @@ -0,0 +1,25 @@ +# Look up an environment variable more securely. +dnl Copyright 2013 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_SECURE_GETENV], +[ + dnl Persuade glibc to declare secure_getenv(). + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) + + AC_REQUIRE([gl_STDLIB_H_DEFAULTS]) + AC_CHECK_FUNCS_ONCE([secure_getenv]) + if test $ac_cv_func_secure_getenv = no; then + HAVE_SECURE_GETENV=0 + fi +]) + +# Prerequisites of lib/secure_getenv.c. +AC_DEFUN([gl_PREREQ_SECURE_GETENV], [ + AC_CHECK_FUNCS([__secure_getenv]) + if test $ac_cv_func___secure_getenv = no; then + AC_CHECK_FUNCS([issetugid]) + fi +]) diff --git a/m4/tempname.m4 b/m4/tempname.m4 new file mode 100644 index 00000000000..a6e42dcea81 --- /dev/null +++ b/m4/tempname.m4 @@ -0,0 +1,19 @@ +#serial 5 + +# Copyright (C) 2006-2007, 2009-2013 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# glibc provides __gen_tempname as a wrapper for mk[ds]temp. Expose +# it as a public API, and provide it on systems that are lacking. +AC_DEFUN([gl_FUNC_GEN_TEMPNAME], +[ + gl_PREREQ_TEMPNAME +]) + +# Prerequisites of lib/tempname.c. +AC_DEFUN([gl_PREREQ_TEMPNAME], +[ + : +]) diff --git a/src/ChangeLog b/src/ChangeLog index c29c4c8da59..f8f2fa47089 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2013-08-04 Paul Eggert + + Fix some minor races in hosts lacking mkostemp (Bug#15015). + * callproc.c (create_temp_file): + * filelock.c (create_lock_file): + Assume mkostemp, since it's now provided by Gnulib. + 2013-08-04 Eli Zaretskii * w32.c (mkostemp): New function. diff --git a/src/callproc.c b/src/callproc.c index 450fc57f929..54bc5cd9dc0 100644 --- a/src/callproc.c +++ b/src/callproc.c @@ -1009,23 +1009,11 @@ create_temp_file (ptrdiff_t nargs, Lisp_Object *args) tempfile = SSDATA (filename_string); { - int fd; - -#ifdef HAVE_MKOSTEMP - fd = mkostemp (tempfile, O_CLOEXEC); -#elif defined HAVE_MKSTEMP - fd = mkstemp (tempfile); -#else - errno = EEXIST; - mktemp (tempfile); - fd = *tempfile ? 0 : -1; -#endif + int fd = mkostemp (tempfile, O_CLOEXEC); if (fd < 0) report_file_error ("Failed to open temporary file using pattern", pattern); -#if defined HAVE_MKOSTEMP || defined HAVE_MKSTEMP emacs_close (fd); -#endif } record_unwind_protect (delete_temp_file, filename_string); diff --git a/src/filelock.c b/src/filelock.c index b9c991e4baf..0f31b7d4deb 100644 --- a/src/filelock.c +++ b/src/filelock.c @@ -411,28 +411,14 @@ create_lock_file (char *lfname, char *lock_info_str, bool force) memcpy (nonce, lfname, lfdirlen); strcpy (nonce + lfdirlen, nonce_base); -#if HAVE_MKOSTEMP - /* Prefer mkostemp to mkstemp, as it avoids a window where FD is - temporarily open without close-on-exec. */ fd = mkostemp (nonce, O_BINARY | O_CLOEXEC); -#elif HAVE_MKSTEMP - /* Prefer mkstemp to mktemp, as it avoids a race between - mktemp and emacs_open. */ - fd = mkstemp (nonce); -#else - mktemp (nonce); - fd = emacs_open (nonce, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, - S_IRUSR | S_IWUSR); -#endif - if (fd < 0) err = errno; else { ptrdiff_t lock_info_len; -#if ! (HAVE_MKOSTEMP && O_CLOEXEC) - fcntl (fd, F_SETFD, FD_CLOEXEC); -#endif + if (! O_CLOEXEC) + fcntl (fd, F_SETFD, FD_CLOEXEC); lock_info_len = strlen (lock_info_str); err = 0; /* Use 'write', not 'emacs_write', as garbage collection From e443729d658ee2b9e0f55bbbb90241819bf516a6 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sun, 4 Aug 2013 20:52:25 +0300 Subject: [PATCH 012/449] MS-Windows followup to last commit. lib-src/ntlib.h: Include fcntl.h. (mkostemp): Declare prototype. (mktemp): Don't redefine. lib-src/ntlib.c (mkostemp): New function. Fixes: debbugs:15015 --- lib-src/ChangeLog | 8 +++++++ lib-src/ntlib.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++ lib-src/ntlib.h | 4 ++-- 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index 2cfe46f5352..ace62d9d8f7 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog @@ -1,3 +1,11 @@ +2013-08-04 Eli Zaretskii + + * ntlib.h: Include fcntl.h. + (mkostemp): Declare prototype. + (mktemp): Don't redefine. + + * ntlib.c (mkostemp): New function. (Bug#15015) + 2013-08-04 Paul Eggert Fix some minor races in hosts lacking mkostemp (Bug#15015). diff --git a/lib-src/ntlib.c b/lib-src/ntlib.c index 41b4e3a0cbc..0d0642d1bf2 100644 --- a/lib-src/ntlib.c +++ b/lib-src/ntlib.c @@ -422,3 +422,58 @@ lstat (const char * path, struct stat * buf) { return stat (path, buf); } + +/* Implementation of mkostemp for MS-Windows, to avoid race conditions + when using mktemp. + + Standard algorithm for generating a temporary file name seems to be + use pid or tid with a letter on the front (in place of the 6 X's) + and cycle through the letters to find a unique name. We extend + that to allow any reasonable character as the first of the 6 X's, + so that the number of simultaneously used temporary files will be + greater. */ + +int +mkostemp (char * template, int flags) +{ + char * p; + int i, fd = -1; + unsigned uid = GetCurrentThreadId (); + int save_errno = errno; + static char first_char[] = "abcdefghijklmnopqrstuvwyz0123456789!%-_@#"; + + errno = EINVAL; + if (template == NULL) + return -1; + + p = template + strlen (template); + i = 5; + /* replace up to the last 5 X's with uid in decimal */ + while (--p >= template && p[0] == 'X' && --i >= 0) + { + p[0] = '0' + uid % 10; + uid /= 10; + } + + if (i < 0 && p[0] == 'X') + { + i = 0; + do + { + p[0] = first_char[i]; + if ((fd = open (template, + flags | _O_CREAT | _O_EXCL | _O_RDWR, + S_IRUSR | S_IWUSR)) >= 0 + || errno != EEXIST) + { + if (fd >= 0) + errno = save_errno; + return fd; + } + } + while (++i < sizeof (first_char)); + } + + /* Template is badly formed or else we can't generate a unique name. */ + return -1; +} diff --git a/lib-src/ntlib.h b/lib-src/ntlib.h index 3e48d2997e0..c30958365ca 100644 --- a/lib-src/ntlib.h +++ b/lib-src/ntlib.h @@ -22,6 +22,7 @@ along with GNU Emacs. If not, see . */ /* Include these headers now so we don't have to worry about include order dependencies in common source files. */ #include +#include #include #include @@ -41,6 +42,7 @@ int setuid (unsigned uid); int setregid (unsigned rgid, unsigned gid); char * getpass (const char * prompt); int fchown (int fd, unsigned uid, unsigned gid); +int mkostemp (char * template, int flags); /* redirect or undo interceptions created by config.h */ #undef access @@ -61,8 +63,6 @@ int fchown (int fd, unsigned uid, unsigned gid); #undef fopen #undef mkdir #define mkdir _mkdir -#undef mktemp -#define mktemp _mktemp #undef open #define open _open #undef pipe From df0d73aa8da0a8cb6fd01e2f2604a6022e8f3d63 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Sun, 4 Aug 2013 11:42:50 -0700 Subject: [PATCH 013/449] Backport icalendar-tests fixes from trunk * test/automated/icalendar-tests.el (icalendar-tests--test-export) (icalendar-tests--test-import): Use getenv/setenv rather than set-time-zone-rule. (icalendar-tests--test-import): Reset zone even if error occurred. (icalendar-tests--do-test-cycle): Use with-current-buffer. --- test/ChangeLog | 8 +++ test/automated/icalendar-tests.el | 83 +++++++++++++++++-------------- 2 files changed, 54 insertions(+), 37 deletions(-) diff --git a/test/ChangeLog b/test/ChangeLog index d8b8fb661b5..9b6859e9ba6 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,11 @@ +2013-08-04 Glenn Morris + + * automated/icalendar-tests.el (icalendar-tests--test-export) + (icalendar-tests--test-import): + Use getenv/setenv rather than set-time-zone-rule. + (icalendar-tests--test-import): Reset zone even if error occurred. + (icalendar-tests--do-test-cycle): Use with-current-buffer. + 2013-03-26 Fabián Ezequiel Gallina * automated/python-tests.el diff --git a/test/automated/icalendar-tests.el b/test/automated/icalendar-tests.el index bca462da4d9..f83052f5ea1 100644 --- a/test/automated/icalendar-tests.el +++ b/test/automated/icalendar-tests.el @@ -428,12 +428,16 @@ Argument EXPECTED-OUTPUT expected iCalendar result string. European style input data must use german month names. American and ISO style input data must use english month names." - (let ((tz (cadr (current-time-zone))) + (let ((tz (getenv "TZ")) (calendar-date-style 'iso) (icalendar-recurring-start-year 2000)) (unwind-protect (progn - (set-time-zone-rule "CET") +;;; (message "Current time zone: %s" (current-time-zone)) + ;; Use this form so as not to rely on system tz database. + ;; Eg hydra.nixos.org. + (setenv "TZ" "CET-1CEST,M3.5.0/2,M10.5.0/3") +;;; (message "Current time zone: %s" (current-time-zone)) (when input-iso (let ((calendar-month-name-array ["January" "February" "March" "April" "May" "June" "July" "August" @@ -461,8 +465,8 @@ and ISO style input data must use english month names." "Saturday"])) (setq calendar-date-style 'american) (icalendar-tests--do-test-export input-american expected-output)))) - ;; restore time-zone if something went terribly wrong - (set-time-zone-rule tz)))) + ;; restore time-zone even if something went terribly wrong + (setenv "TZ" tz)))) (defun icalendar-tests--do-test-export (input expected-output) "Actually perform export test. @@ -671,37 +675,43 @@ Argument INPUT icalendar event string. Argument EXPECTED-ISO expected iso style diary string. Argument EXPECTED-EUROPEAN expected european style diary string. Argument EXPECTED-AMERICAN expected american style diary string." - (let ((timezone (cadr (current-time-zone)))) - (set-time-zone-rule "CET") - (with-temp-buffer - (if (string-match "^BEGIN:VCALENDAR" input) - (insert input) - (insert "BEGIN:VCALENDAR\nPRODID:-//Emacs//NONSGML icalendar.el//EN\n") - (insert "VERSION:2.0\nBEGIN:VEVENT\n") - (insert input) - (unless (eq (char-before) ?\n) - (insert "\n")) - (insert "END:VEVENT\nEND:VCALENDAR\n")) - (let ((icalendar-import-format "%s%d%l%o%t%u%c%U") - (icalendar-import-format-summary "%s") - (icalendar-import-format-location "\n Location: %s") - (icalendar-import-format-description "\n Desc: %s") - (icalendar-import-format-organizer "\n Organizer: %s") - (icalendar-import-format-status "\n Status: %s") - (icalendar-import-format-url "\n URL: %s") - (icalendar-import-format-class "\n Class: %s") - (icalendar-import-format-uid "\n UID: %s") - calendar-date-style) - (when expected-iso - (setq calendar-date-style 'iso) - (icalendar-tests--do-test-import input expected-iso)) - (when expected-european - (setq calendar-date-style 'european) - (icalendar-tests--do-test-import input expected-european)) - (when expected-american - (setq calendar-date-style 'american) - (icalendar-tests--do-test-import input expected-american)))) - (set-time-zone-rule timezone))) + (let ((timezone (getenv "TZ"))) + (unwind-protect + (progn +;;; (message "Current time zone: %s" (current-time-zone)) + ;; Use this form so as not to rely on system tz database. + ;; Eg hydra.nixos.org. + (setenv "TZ" "CET-1CEST,M3.5.0/2,M10.5.0/3") +;;; (message "Current time zone: %s" (current-time-zone)) + (with-temp-buffer + (if (string-match "^BEGIN:VCALENDAR" input) + (insert input) + (insert "BEGIN:VCALENDAR\nPRODID:-//Emacs//NONSGML icalendar.el//EN\n") + (insert "VERSION:2.0\nBEGIN:VEVENT\n") + (insert input) + (unless (eq (char-before) ?\n) + (insert "\n")) + (insert "END:VEVENT\nEND:VCALENDAR\n")) + (let ((icalendar-import-format "%s%d%l%o%t%u%c%U") + (icalendar-import-format-summary "%s") + (icalendar-import-format-location "\n Location: %s") + (icalendar-import-format-description "\n Desc: %s") + (icalendar-import-format-organizer "\n Organizer: %s") + (icalendar-import-format-status "\n Status: %s") + (icalendar-import-format-url "\n URL: %s") + (icalendar-import-format-class "\n Class: %s") + (icalendar-import-format-uid "\n UID: %s") + calendar-date-style) + (when expected-iso + (setq calendar-date-style 'iso) + (icalendar-tests--do-test-import input expected-iso)) + (when expected-european + (setq calendar-date-style 'european) + (icalendar-tests--do-test-import input expected-european)) + (when expected-american + (setq calendar-date-style 'american) + (icalendar-tests--do-test-import input expected-american))))) + (setenv "TZ" timezone)))) (defun icalendar-tests--do-test-import (input expected-output) "Actually perform import test. @@ -1194,8 +1204,7 @@ Argument INPUT icalendar event string." (should (string= org-input cycled))))) ;; clean up (kill-buffer (find-buffer-visiting temp-diary)) - (save-excursion - (set-buffer (find-buffer-visiting temp-ics)) + (with-current-buffer (find-buffer-visiting temp-ics) (set-buffer-modified-p nil) (kill-buffer (current-buffer))) (delete-file temp-diary) From 671d5c16547d16bef2efa056705bd35b5feacc29 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Sun, 4 Aug 2013 16:18:11 -0400 Subject: [PATCH 014/449] * lisp/subr.el (macrop): New function. (text-clone--maintaining): New var. (text-clone--maintain): Rename from text-clone-maintain. Use it instead of inhibit-modification-hooks. * lisp/emacs-lisp/nadvice.el (advice--normalize): For aliases to macros, use a proxy, so as handle autoloads and redefinitions of the target. (advice--defalias-fset, advice-remove): Use advice--symbol-function. * lisp/emacs-lisp/pcase.el (pcase-mutually-exclusive-predicates): Remove bogus (arrayp . stringp) pair. Add entries for `vectorp'. (pcase--mutually-exclusive-p): New function. (pcase--split-consp): Use it. (pcase--split-pred): Use it. Optimize the case where `pat' is a qpat mutually exclusive with the current predicate. * test/automated/advice-tests.el (advice-tests-nadvice): Test removal before definition. (advice-tests-macroaliases): New test. * lisp/emacs-lisp/edebug.el (edebug-lookup-function): Remove function. (edebug-macrop): Remove. Use `macrop' instead. * lisp/emacs-lisp/advice.el (ad-subr-p): Remove. Use `subrp' instead. (ad-macro-p): * lisp/eshell/esh-cmd.el (eshell-macrop): * lisp/apropos.el (apropos-macrop): Remove. Use `macrop' instead. --- etc/NEWS | 2 +- lisp/ChangeLog | 25 +++++++++++++++++++++++++ lisp/apropos.el | 13 +------------ lisp/emacs-lisp/advice.el | 30 +++++++++++------------------- lisp/emacs-lisp/edebug.el | 15 +-------------- lisp/emacs-lisp/nadvice.el | 23 ++++------------------- lisp/emacs-lisp/pcase.el | 31 +++++++++++++++++++++---------- lisp/eshell/esh-cmd.el | 10 +--------- lisp/subr.el | 24 ++++++++++++++++++------ test/ChangeLog | 6 ++++++ test/automated/advice-tests.el | 17 +++++++++++++++++ 11 files changed, 106 insertions(+), 90 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 60a846b459f..507cd04aa10 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -691,7 +691,7 @@ These attributes are only meaningful for coding-systems of type with the same interpretation as the returned value of `visited-file-modtime'. ** time-to-seconds is not obsolete any more. -** New function special-form-p. +** New functions special-form-p and macrop. ** Docstrings can be made dynamic by adding a `dynamic-docstring-function' text-property on the first char. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index dc1fa09b316..66bf7422b0d 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,28 @@ +2013-08-04 Stefan Monnier + + * subr.el (macrop): New function. + (text-clone--maintaining): New var. + (text-clone--maintain): Rename from text-clone-maintain. Use it + instead of inhibit-modification-hooks. + + * emacs-lisp/nadvice.el (advice--normalize): For aliases to macros, use + a proxy, so as handle autoloads and redefinitions of the target. + (advice--defalias-fset, advice-remove): Use advice--symbol-function. + + * emacs-lisp/pcase.el (pcase-mutually-exclusive-predicates): + Remove bogus (arrayp . stringp) pair. Add entries for `vectorp'. + (pcase--mutually-exclusive-p): New function. + (pcase--split-consp): Use it. + (pcase--split-pred): Use it. Optimize the case where `pat' is a qpat + mutually exclusive with the current predicate. + + * emacs-lisp/edebug.el (edebug-lookup-function): Remove function. + (edebug-macrop): Remove. Use `macrop' instead. + * emacs-lisp/advice.el (ad-subr-p): Remove. Use `subrp' instead. + (ad-macro-p): + * eshell/esh-cmd.el (eshell-macrop): + * apropos.el (apropos-macrop): Remove. Use `macrop' instead. + 2013-08-04 Stefan Monnier * emacs-lisp/nadvice.el (advice-function-mapc): Rename from advice-mapc. diff --git a/lisp/apropos.el b/lisp/apropos.el index 000d2d87d05..7a1a6f6a75a 100644 --- a/lisp/apropos.el +++ b/lisp/apropos.el @@ -1121,7 +1121,7 @@ If non-nil TEXT is a string that will be printed as a heading." (apropos-print-doc 2 (if (commandp symbol) 'apropos-command - (if (apropos-macrop symbol) + (if (macrop symbol) 'apropos-macro 'apropos-function)) (not nosubst)) @@ -1139,17 +1139,6 @@ If non-nil TEXT is a string that will be printed as a heading." (prog1 apropos-accumulator (setq apropos-accumulator ()))) ; permit gc -(defun apropos-macrop (symbol) - "Return t if SYMBOL is a Lisp macro." - (and (fboundp symbol) - (consp (setq symbol - (symbol-function symbol))) - (or (eq (car symbol) 'macro) - (if (autoloadp symbol) - (memq (nth 4 symbol) - '(macro t)))))) - - (defun apropos-print-doc (i type do-keys) (let ((doc (nth i apropos-item))) (when (stringp doc) diff --git a/lisp/emacs-lisp/advice.el b/lisp/emacs-lisp/advice.el index eb1d63e788b..861054e777f 100644 --- a/lisp/emacs-lisp/advice.el +++ b/lisp/emacs-lisp/advice.el @@ -2140,14 +2140,6 @@ See Info node `(elisp)Computed Advice' for detailed documentation." "Take a macro function DEFINITION and make a lambda out of it." `(cdr ,definition)) -(defmacro ad-subr-p (definition) - ;;"non-nil if DEFINITION is a subr." - (list 'subrp definition)) - -(defmacro ad-macro-p (definition) - ;;"non-nil if DEFINITION is a macro." - `(eq (car-safe ,definition) 'macro)) - (defmacro ad-lambda-p (definition) ;;"non-nil if DEFINITION is a lambda expression." `(eq (car-safe ,definition) 'lambda)) @@ -2160,12 +2152,12 @@ See Info node `(elisp)Computed Advice' for detailed documentation." (defmacro ad-compiled-p (definition) "Return non-nil if DEFINITION is a compiled byte-code object." `(or (byte-code-function-p ,definition) - (and (ad-macro-p ,definition) - (byte-code-function-p (ad-lambdafy ,definition))))) + (and (macrop ,definition) + (byte-code-function-p (ad-lambdafy ,definition))))) (defmacro ad-compiled-code (compiled-definition) "Return the byte-code object of a COMPILED-DEFINITION." - `(if (ad-macro-p ,compiled-definition) + `(if (macrop ,compiled-definition) (ad-lambdafy ,compiled-definition) ,compiled-definition)) @@ -2173,7 +2165,7 @@ See Info node `(elisp)Computed Advice' for detailed documentation." "Return the lambda expression of a function/macro/advice DEFINITION." (cond ((ad-lambda-p definition) definition) - ((ad-macro-p definition) + ((macrop definition) (ad-lambdafy definition)) ((ad-advice-p definition) (cdr definition)) @@ -2183,7 +2175,7 @@ See Info node `(elisp)Computed Advice' for detailed documentation." "Return the argument list of DEFINITION." (require 'help-fns) (help-function-arglist - (if (or (ad-macro-p definition) (ad-advice-p definition)) + (if (or (macrop definition) (ad-advice-p definition)) (cdr definition) definition) 'preserve-names)) @@ -2229,7 +2221,7 @@ definition (see the code for `documentation')." (defun ad-advised-definition-p (definition) "Return non-nil if DEFINITION was generated from advice information." (if (or (ad-lambda-p definition) - (ad-macro-p definition) + (macrop definition) (ad-compiled-p definition)) (let ((docstring (ad-docstring definition))) (and (stringp docstring) @@ -2242,8 +2234,8 @@ definition (see the code for `documentation')." ;; representations, so cache entries preactivated with version ;; 1 can't be used. (cond - ((ad-macro-p definition) 'macro2) - ((ad-subr-p definition) 'subr2) + ((macrop definition) 'macro2) + ((subrp definition) 'subr2) ((or (ad-lambda-p definition) (ad-compiled-p definition)) 'fun2) ((ad-advice-p definition) 'advice2))) ;; FIXME: Can this ever happen? @@ -2273,7 +2265,7 @@ For that it has to be fbound with a non-autoload definition." "True if FUNCTION has an interpreted definition that can be compiled." (and (ad-has-proper-definition function) (or (ad-lambda-p (symbol-function function)) - (ad-macro-p (symbol-function function))) + (macrop (symbol-function function))) (not (ad-compiled-p (symbol-function function))))) (defvar warning-suppress-types) ;From warnings.el. @@ -2902,7 +2894,7 @@ If COMPILE is nil then the result depends on the value of ((eq ad-default-compilation-action 'never) nil) ((eq ad-default-compilation-action 'always) t) ((eq ad-default-compilation-action 'like-original) - (or (ad-subr-p (ad-get-orig-definition function)) + (or (subrp (ad-get-orig-definition function)) (ad-compiled-p (ad-get-orig-definition function)))) ;; everything else means `maybe': (t (featurep 'byte-compile)))) @@ -3249,7 +3241,7 @@ usage: (defadvice FUNCTION (CLASS NAME [POSITION] [ARGLIST] FLAG...) `((ad-set-cache ',function ;; the function will get compiled: - ,(cond ((ad-macro-p (car preactivation)) + ,(cond ((macrop (car preactivation)) `(ad-macrofy (function ,(ad-lambdafy diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index ae20e5270e1..ac7e5f12a18 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -295,19 +295,6 @@ A lambda list keyword is a symbol that starts with `&'." (eq (selected-window) (next-window (next-window (selected-window)))))) -(defsubst edebug-lookup-function (object) - (while (and (symbolp object) (fboundp object)) - (setq object (symbol-function object))) - object) - -(defun edebug-macrop (object) - "Return the macro named by OBJECT, or nil if it is not a macro." - (setq object (edebug-lookup-function object)) - (if (and (listp object) - (eq 'macro (car object)) - (functionp (cdr object))) - object)) - (defun edebug-sort-alist (alist function) ;; Return the ALIST sorted with comparison function FUNCTION. ;; This uses 'sort so the sorting is destructive. @@ -1416,7 +1403,7 @@ expressions; a `progn' form will be returned enclosing these forms." ; but leave it in for compatibility. )) ;; No edebug-form-spec provided. - ((edebug-macrop head) + ((macrop head) (if edebug-eval-macro-args (edebug-forms cursor) (edebug-sexps cursor))) diff --git a/lisp/emacs-lisp/nadvice.el b/lisp/emacs-lisp/nadvice.el index 660eb0365ae..576e72088e9 100644 --- a/lisp/emacs-lisp/nadvice.el +++ b/lisp/emacs-lisp/nadvice.el @@ -314,9 +314,8 @@ of the piece of advice." ((special-form-p def) ;; Not worth the trouble trying to handle this, I think. (error "Advice impossible: %S is a special form" symbol)) - ((and (symbolp def) - (eq 'macro (car-safe (ignore-errors (indirect-function def))))) - (let ((newval (cons 'macro (cdr (indirect-function def))))) + ((and (symbolp def) (macrop def)) + (let ((newval `(macro . ,(lambda (&rest r) (macroexpand `(,def . ,r)))))) (put symbol 'advice--saved-rewrite (cons def (cdr newval))) newval)) ;; `f' might be a pure (hence read-only) cons! @@ -351,19 +350,7 @@ of the piece of advice." (when (get symbol 'advice--saved-rewrite) (put symbol 'advice--saved-rewrite nil)) (setq newdef (advice--normalize symbol newdef)) - (let* ((olddef (advice--strip-macro (symbol-function symbol))) - (oldadv - (cond - ((null (get symbol 'advice--pending)) - (or olddef - (progn - (message "Delayed advice activation failed for %s: no data" - symbol) - nil))) - ((or (not olddef) (autoloadp olddef)) - (get symbol 'advice--pending)) - (t (message "Dropping left-over advice--pending for %s" symbol) - olddef)))) + (let ((oldadv (advice--symbol-function symbol))) (if (and newdef (not (autoloadp newdef))) (let* ((snewdef (advice--strip-macro newdef)) (snewadv (advice--subst-main oldadv snewdef))) @@ -383,7 +370,6 @@ is defined as a macro, alias, command, ..." ;; TODO: ;; - record the advice location, to display in describe-function. ;; - change all defadvice in lisp/**/*.el. - ;; - rewrite advice.el on top of this. ;; - obsolete advice.el. (let* ((f (symbol-function symbol)) (nf (advice--normalize symbol f))) @@ -420,8 +406,7 @@ of the piece of advice." ((eq (car-safe f) 'macro) (cdr f)) (t (symbol-function symbol))) function) - (unless (advice--p - (if (eq (car-safe f) 'macro) (cdr f) (symbol-function symbol))) + (unless (advice--p (advice--symbol-function symbol)) ;; Not advised any more. (remove-function (get symbol 'defalias-fset-function) #'advice--defalias-fset) diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index 50c92518b02..eb2c7f002e8 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -353,23 +353,34 @@ MATCH is the pattern that needs to be matched, of the form: (symbolp . numberp) (symbolp . consp) (symbolp . arrayp) + (symbolp . vectorp) (symbolp . stringp) (symbolp . byte-code-function-p) (integerp . consp) (integerp . arrayp) + (integerp . vectorp) (integerp . stringp) (integerp . byte-code-function-p) (numberp . consp) (numberp . arrayp) + (numberp . vectorp) (numberp . stringp) (numberp . byte-code-function-p) (consp . arrayp) + (consp . vectorp) (consp . stringp) (consp . byte-code-function-p) - (arrayp . stringp) (arrayp . byte-code-function-p) + (vectorp . byte-code-function-p) + (stringp . vectorp) (stringp . byte-code-function-p))) +(defun pcase--mutually-exclusive-p (pred1 pred2) + (or (member (cons pred1 pred2) + pcase-mutually-exclusive-predicates) + (member (cons pred2 pred1) + pcase-mutually-exclusive-predicates))) + (defun pcase--split-match (sym splitter match) (cond ((eq (car match) 'match) @@ -433,10 +444,7 @@ MATCH is the pattern that needs to be matched, of the form: ;; A QPattern but not for a cons, can only go to the `else' side. ((eq (car-safe pat) '\`) '(:pcase--fail . nil)) ((and (eq (car-safe pat) 'pred) - (or (member (cons 'consp (cadr pat)) - pcase-mutually-exclusive-predicates) - (member (cons (cadr pat) 'consp) - pcase-mutually-exclusive-predicates))) + (pcase--mutually-exclusive-p #'consp (cadr pat))) '(:pcase--fail . nil)))) (defun pcase--split-equal (elem pat) @@ -496,11 +504,14 @@ MATCH is the pattern that needs to be matched, of the form: (not (pcase--fgrep (mapcar #'car vars) (cadr upat))))) '(:pcase--succeed . :pcase--fail)) ((and (eq 'pred (car upat)) - (eq 'pred (car-safe pat)) - (or (member (cons (cadr upat) (cadr pat)) - pcase-mutually-exclusive-predicates) - (member (cons (cadr pat) (cadr upat)) - pcase-mutually-exclusive-predicates))) + (let ((otherpred + (cond ((eq 'pred (car-safe pat)) (cadr pat)) + ((not (eq '\` (car-safe pat))) nil) + ((consp (cadr pat)) #'consp) + ((vectorp (cadr pat)) #'vectorp) + ((byte-code-function-p (cadr pat)) + #'byte-code-function-p)))) + (pcase--mutually-exclusive-p (cadr upat) otherpred))) '(:pcase--fail . nil)) ((and (eq 'pred (car upat)) (eq '\` (car-safe pat)) diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el index 69dc6c76b41..ef8a53f3c0b 100644 --- a/lisp/eshell/esh-cmd.el +++ b/lisp/eshell/esh-cmd.el @@ -993,14 +993,6 @@ at the moment are: ,@commands (eshell-debug-command ,(concat "done " (eval tag)) form)))) -(defsubst eshell-macrop (object) - "Return t if OBJECT is a macro or nil otherwise." - (and (symbolp object) (fboundp object) - (setq object (indirect-function object)) - (listp object) - (eq 'macro (car object)) - (functionp (cdr object)))) - (defun eshell-do-eval (form &optional synchronous-p) "Evaluate form, simplifying it as we go. Unless SYNCHRONOUS-P is non-nil, throws `eshell-defer' if it needs to @@ -1016,7 +1008,7 @@ be finished later after the completion of an asynchronous subprocess." (setq form (cadr (cadr form)))) ;; expand any macros directly into the form. This is done so that ;; we can modify any `let' forms to evaluate only once. - (if (eshell-macrop (car form)) + (if (macrop (car form)) (let ((exp (eshell-copy-tree (macroexpand form)))) (eshell-manipulate (format "expanding macro `%s'" (symbol-name (car form))) diff --git a/lisp/subr.el b/lisp/subr.el index 3b85a9bedb0..bdeee677471 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2750,6 +2750,13 @@ Otherwise, return nil." (setq object (indirect-function object t))) (and (subrp object) (eq (cdr (subr-arity object)) 'unevalled))) +(defun macrop (object) + "Non-nil if and only if OBJECT is a macro." + (let ((def (indirect-function object t))) + (when (consp def) + (or (eq 'macro (car def)) + (and (eq 'autoload (car def)) (memq (nth 4 def) '(macro t))))))) + (defun field-at-pos (pos) "Return the field at position POS, taking stickiness etc into account." (let ((raw-field (get-char-property (field-beginning pos) 'field))) @@ -4050,10 +4057,14 @@ backwards ARG times if negative." ;;;; Text clones -(defun text-clone-maintain (ol1 after beg end &optional _len) +(defvar text-clone--maintaining nil) + +(defun text-clone--maintain (ol1 after beg end &optional _len) "Propagate the changes made under the overlay OL1 to the other clones. This is used on the `modification-hooks' property of text clones." - (when (and after (not undo-in-progress) (overlay-start ol1)) + (when (and after (not undo-in-progress) + (not text-clone--maintaining) + (overlay-start ol1)) (let ((margin (if (overlay-get ol1 'text-clone-spreadp) 1 0))) (setq beg (max beg (+ (overlay-start ol1) margin))) (setq end (min end (- (overlay-end ol1) margin))) @@ -4084,7 +4095,7 @@ This is used on the `modification-hooks' property of text clones." (tail (- (overlay-end ol1) end)) (str (buffer-substring beg end)) (nothing-left t) - (inhibit-modification-hooks t)) + (text-clone--maintaining t)) (dolist (ol2 (overlay-get ol1 'text-clones)) (let ((oe (overlay-end ol2))) (unless (or (eq ol1 ol2) (null oe)) @@ -4095,7 +4106,7 @@ This is used on the `modification-hooks' property of text clones." (unless (> mod-beg (point)) (save-excursion (insert str)) (delete-region mod-beg (point))) - ;;(overlay-put ol2 'modification-hooks '(text-clone-maintain)) + ;;(overlay-put ol2 'modification-hooks '(text-clone--maintain)) )))) (if nothing-left (delete-overlay ol1)))))))) @@ -4126,17 +4137,18 @@ clone should be incorporated in the clone." (>= pt-end (point-max)) (>= start (point-max))) 0 1)) + ;; FIXME: Reuse overlays at point to extend dups! (ol1 (make-overlay (- start start-margin) (+ end end-margin) nil t)) (ol2 (make-overlay (- (point) start-margin) (+ pt-end end-margin) nil t)) (dups (list ol1 ol2))) - (overlay-put ol1 'modification-hooks '(text-clone-maintain)) + (overlay-put ol1 'modification-hooks '(text-clone--maintain)) (when spreadp (overlay-put ol1 'text-clone-spreadp t)) (when syntax (overlay-put ol1 'text-clone-syntax syntax)) ;;(overlay-put ol1 'face 'underline) (overlay-put ol1 'evaporate t) (overlay-put ol1 'text-clones dups) ;; - (overlay-put ol2 'modification-hooks '(text-clone-maintain)) + (overlay-put ol2 'modification-hooks '(text-clone--maintain)) (when spreadp (overlay-put ol2 'text-clone-spreadp t)) (when syntax (overlay-put ol2 'text-clone-syntax syntax)) ;;(overlay-put ol2 'face 'underline) diff --git a/test/ChangeLog b/test/ChangeLog index 32fc077459b..d744a5c788d 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,9 @@ +2013-08-04 Stefan Monnier + + * automated/advice-tests.el (advice-tests-nadvice): Test removal + before definition. + (advice-tests-macroaliases): New test. + 2013-08-04 Glenn Morris * automated/ert-tests.el: Disable failing test that no-one seems diff --git a/test/automated/advice-tests.el b/test/automated/advice-tests.el index 69c15e34ed0..424f447ae4b 100644 --- a/test/automated/advice-tests.el +++ b/test/automated/advice-tests.el @@ -25,7 +25,12 @@ (ert-deftest advice-tests-nadvice () "Test nadvice code." + (advice-add 'sm-test1 :around (lambda (f y) (* (funcall f y) 5))) + (advice-add 'sm-test1 :around (lambda (f y) (* (funcall f y) 2))) + (advice-remove 'sm-test1 (lambda (f y) (* (funcall f y) 5))) (defun sm-test1 (x) (+ x 4)) + (should (equal (sm-test1 6) 20)) + (advice-remove 'sm-test1 (lambda (f y) (* (funcall f y) 2))) (should (equal (sm-test1 6) 10)) (advice-add 'sm-test1 :around (lambda (f y) (* (funcall f y) 5))) (should (equal (sm-test1 6) 50)) @@ -42,6 +47,18 @@ (defmacro sm-test3 (x) `(call-test3 ,x)) (should (equal (macroexpand '(sm-test3 56)) '(toto (call-test3 56))))) +(ert-deftest advice-tests-macroaliases () + "Test nadvice code on aliases to macros." + (defmacro sm-test1 (a) `(list ',a)) + (defalias 'sm-test1-alias 'sm-test1) + (should (equal (macroexpand '(sm-test1-alias 5)) '(list '5))) + (advice-add 'sm-test1-alias :around + (lambda (f &rest args) `(cons 1 ,(apply f args)))) + (should (equal (macroexpand '(sm-test1-alias 5)) '(cons 1 (list '5)))) + (defmacro sm-test1 (a) `(list 0 ',a)) + (should (equal (macroexpand '(sm-test1-alias 5)) '(cons 1 (list 0 '5))))) + + (ert-deftest advice-tests-advice () "Test advice code." (defun sm-test2 (x) (+ x 4)) From 016d3f7ddcc9afd60c455cbf4dd79277080c4d4e Mon Sep 17 00:00:00 2001 From: Stephen Berman Date: Sun, 4 Aug 2013 23:27:49 +0200 Subject: [PATCH 015/449] Add Todo mode user manual. * doc/misc/Makefile.in (INFO_TARGETS, DVI_TARGETS, PDF_TARGETS): Add todo-mode. (todo-mode, $(buildinfodir)/todo-mode$(INFO_EXT)): (todo-mode.dvi, todo-mode.pdf): New rules. * doc/misc/todo-mode.texi: New file. * info/dir: Add todo-mode. --- ChangeLog | 4 + doc/misc/ChangeLog | 8 + doc/misc/Makefile.in | 13 +- doc/misc/todo-mode.texi | 1760 +++++++++++++++++++++++++++++++++++++++ info/dir | 3 +- 5 files changed, 1786 insertions(+), 2 deletions(-) create mode 100644 doc/misc/todo-mode.texi diff --git a/ChangeLog b/ChangeLog index cd8ce1a25ec..1252a7a15a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-08-04 Stephen Berman + + * info/dir: Add todo-mode. + 2013-08-04 Paul Eggert Fix some minor races in hosts lacking mkostemp (Bug#15015). diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog index 7f5c70e07e3..979ec83010e 100644 --- a/doc/misc/ChangeLog +++ b/doc/misc/ChangeLog @@ -1,3 +1,11 @@ +2013-08-04 Stephen Berman + + * Makefile.in (INFO_TARGETS, DVI_TARGETS, PDF_TARGETS): Add todo-mode. + (todo-mode, $(buildinfodir)/todo-mode$(INFO_EXT)): + (todo-mode.dvi, todo-mode.pdf): New rules. + + * todo-mode.texi: New file. + 2013-08-01 Lars Magne Ingebrigtsen * gnus.texi (Basic Usage): Mention that warp means jump here. diff --git a/doc/misc/Makefile.in b/doc/misc/Makefile.in index 67a899af8ce..7e08c5a2088 100644 --- a/doc/misc/Makefile.in +++ b/doc/misc/Makefile.in @@ -48,7 +48,7 @@ INFO_TARGETS = ada-mode auth autotype bovine calc ccmode cl \ flymake forms gnus emacs-gnutls htmlfontify idlwave ido info.info \ mairix-el message mh-e newsticker nxml-mode \ org pcl-cvs pgg rcirc remember reftex sasl \ - sc semantic ses sieve smtpmail speedbar srecode tramp \ + sc semantic ses sieve smtpmail speedbar srecode todo-mode tramp \ url vip viper widget wisent woman DVI_TARGETS = \ @@ -100,6 +100,7 @@ DVI_TARGETS = \ smtpmail.dvi \ speedbar.dvi \ srecode.dvi \ + todo-mode.dvi \ tramp.dvi \ url.dvi \ vip.dvi \ @@ -157,6 +158,7 @@ PDF_TARGETS = \ smtpmail.pdf \ speedbar.pdf \ srecode.pdf \ + todo-mode.pdf \ tramp.pdf \ url.pdf \ vip.pdf \ @@ -645,6 +647,15 @@ srecode.dvi: ${srcdir}/srecode.texi ${gfdl} srecode.pdf: ${srcdir}/srecode.texi ${gfdl} $(ENVADD) $(TEXI2PDF) ${srcdir}/srecode.texi +todo-mode : $(buildinfodir)/todo-mode$(INFO_EXT) +$(buildinfodir)/todo-mode$(INFO_EXT): ${srcdir}/todo-mode.texi ${gfdl} + $(mkinfodir) + $(MAKEINFO) $(MAKEINFO_OPTS) $(INFO_OPTS) -o $@ ${srcdir}/todo-mode.texi +todo-mode.dvi: ${srcdir}/todo-mode.texi ${gfdl} + $(ENVADD) $(TEXI2DVI) ${srcdir}/todo-mode.texi +todo-mode.pdf: ${srcdir}/todo-mode.texi ${gfdl} + $(ENVADD) $(TEXI2PDF) ${srcdir}/todo-mode.texi + tramp : $(buildinfodir)/tramp$(INFO_EXT) $(buildinfodir)/tramp$(INFO_EXT): ${srcdir}/tramp.texi ${srcdir}/trampver.texi ${gfdl} $(mkinfodir) diff --git a/doc/misc/todo-mode.texi b/doc/misc/todo-mode.texi new file mode 100644 index 00000000000..a14802e9181 --- /dev/null +++ b/doc/misc/todo-mode.texi @@ -0,0 +1,1760 @@ +\input texinfo.tex @c -*-texinfo-*- +@c %**start of header +@setfilename ../../info/todo-mode +@settitle Todo Mode User Manual +@syncodeindex fn cp +@syncodeindex vr cp +@syncodeindex ky cp +@c %**end of header + +@copying +Copyright @copyright{} 2013 Free Software Foundation, Inc. + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.3 or +any later version published by the Free Software Foundation; with no +Invariant Sections, with the Front-Cover texts being ``A GNU Manual'', +and with the Back-Cover Texts as in (a) below. A copy of the license +is included in the section entitled ``GNU Free Documentation License''. + +(a) The FSF's Back-Cover Text is: ``You have the freedom to copy and +modify this GNU manual.'' +@end quotation +@end copying + +@dircategory Emacs +@direntry +* Todo Mode: (todo-mode). Make and maintain todo lists. +@end direntry + +@titlepage +@title Todo Mode User Manual +@subtitle Facilities for making and maintaining todo lists. + +@author Stephen Berman +@page + +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@contents + +@ifnottex + +@node Top +@top Todo Mode User Manual + +This manual describes the version of Todo mode first appearing in +Emacs 24.4. + +@insertcopying +@end ifnottex + +@menu +* Overview:: +* Todo Mode Entry Points:: +* Key Binding Conventions:: +* Navigation:: Moving within and between categories. +* Editing:: Adding, deleting and changing todo + files, categories and items. +* Todo Archives:: Files of done todo items. +* Marked Items:: Acting on multiple items simultaneously. +* Todo Categories Mode:: Table of categories and item counts. +* Searching for Items:: +* Todo Filtered Items Mode:: Making virtual categories of items from + different categories and files. +* Todo Display Features:: +* Printing Todo Buffers:: +* Legacy Todo Mode Files:: Converting old-style todo files. + +* GNU Free Documentation License:: + +@detailmenu +--- The Detailed Node Listing --- + +Overview + +* Levels of Organization:: +* Todo Items as Diary Entries:: + +Editing + +* File Editing:: +* Category Editing:: +* Item Editing:: + +Item Editing + +* Inserting New Items:: +* Editing Item Headers and Text:: +* Relocating and Removing Items:: + +Relocating and Removing Items + +* Reprioritizing Items:: +* Moving and Deleting Items:: +* Done Items:: + +Todo Archives + +* Creating and Visiting Archives:: +* Todo Archive Mode:: + +Todo Categories Mode + +* Table of Item Counts:: +* Reordering Categories:: + +Todo Filtered Items Mode + +* Filtering Items:: +* Todo Filtered Items Mode Commands:: +* Files of Filtered Items:: + +Todo Display Features + +* Faces:: +* Item Prefix:: +* Other Display Commands and Options:: +@end detailmenu +@end menu + +@node Overview, Todo Mode Entry Points, Top, Top +@chapter Overview + +The Todo mode package provides facilities for making and maintaining +todo lists. A todo list is a list of todo items---things to do (in the +widest sense)---arranged in order of priority, with the highest priority +item at the top of the list and the lowest priority item at the bottom. + +This manual describes the Todo mode user interface. Todo mode comprises +a large number of commands and user options for creating, displaying, +navigating and editing todo lists, distributed across five major modes. +The principle major mode is Todo mode; the other four (Todo Edit mode, +Todo Archive mode, Todo Categories mode, and Todo Filtered Items mode) +are subsidiary to and accessible from Todo mode. + +This version of Todo mode greatly expands on, and in significant ways +differs from, the original version; for details and consequences of the +most important differences, @xref{Legacy Todo Mode Files}. + +@menu +* Levels of Organization:: +* Todo Items as Diary Entries:: +@end menu + +@node Levels of Organization, Todo Items as Diary Entries, , Overview +@section Levels of Organization + +In Todo mode each todo list is identified with a named category, so you +can group together thematically related todo items. Each category is +stored in a file, which thus provides a further level of organization. +You can create as many todo files, and in each as many categories, as +you want. + +All todo files reside in a single directory, whose location is specified +by the user option @code{todo-directory}. This directory may also +contain other types of Todo files, which are discussed later +(@pxref{Todo Archive Mode} and @ref{Todo Filtered Items Mode}). Emacs +recognizes Todo files by their extension, so when you visit the files +the buffer is in the appropriate mode and the current category is +correctly displayed. + +When you use a Todo mode command to create a todo file, the extension +@samp{.todo} is automatically added to the base name you choose (as a +rule, this name is also used for the other types of Todo files, which +have their own extensions). As a user, you only have to deal with the +base name of a Todo file. + +When you create a new todo file, you must also add at least one category +to it, and each todo item belongs to a category. It is not possible to +have an uncategorized todo list, but you can always make a catch-all +category with a generic name like ``Todo'', which is in fact the default +name assigned to the first category when you create a new todo file, if +you don't provide a different name; you can change the default by +customizing @code{todo-initial-category}. + +The most basic level of organization is the todo item itself, since it +contains the information about what you want to do. As detailed in +subsequent sections of this manual, most Todo mode commands and user +options concern ways of classifying and deploying this information by +associating various kinds of metadata with it, e.g., the category it +belongs to, its priority, whether it is to be included in the Emacs +diary, date and time stamps, whether it is done or still to do. + +@node Todo Items as Diary Entries, , Levels of Organization, Overview +@section Todo Items as Diary Entries + +Each todo item is also a potential diary item: if you include a todo +file in the Emacs diary file (@pxref{Fancy Diary Display,,, emacs}), the +Fancy Diary display will show those todo items that are not marked with +@code{todo-nondiary-marker}. This effectively augments the Emacs diary +with categorized diary entries. For the various options available for +making a todo item a diary entry, @ref{Inserting New Items} and +@xref{Editing Item Headers and Text}. + +To ensure the proper display of todo items in the Fancy Diary display, +they must have the format of diary entries, i.e., they have to begin +with a date string recognized by the Emacs diary,@footnote{Two types of +dates recognized by the Emacs diary are not supported in the current +Todo mode implementation: sexp diary entries and date strings in which +the year is omitted (however, the latter type is equivalent to using +@samp{*} for an arbitrary year, which Todo mode does support).} and if +they are longer than one line, all lines but the first must begin with +white space. Todo mode ensures that these requirements are satisfied +(@pxref{Other Display Commands and Options}). + +The Fancy Diary display is also Todo mode aware: if it contains an item +from a Todo mode file, clicking or typing @key{RET} on this item will +switch to the buffer visiting that file and properly display the item's +category, with point on the item. + +@node Todo Mode Entry Points, Key Binding Conventions, Overview, Top +@chapter Todo Mode Entry Points + +To initialize your first todo file, invoke the command @code{todo-show}. +This prompts you for a file name (defaulting to the value of +@code{todo-initial-file}), prompts you for the name of the first +category (defaulting to the value of @code{todo-initial-category}), +creates and visits the file and displays the category in Todo mode, and +then prompts you to enter the first item. If you choose not to enter an +item now, simply type @kbd{C-g}, which leaves the category empty but +otherwise well-formed. If you prefer not to be prompted to enter an +item on adding a new category, disable the option +@code{todo-add-item-if-new-category}. + +Once at least one todo file exists, invoking @code{todo-show} enters +Todo mode. Invoked with a prefix argument, the command prompts for +which todo file to visit. Otherwise, the first invocation of this +command after loading the Todo mode package visits the default todo file +(option @code{todo-default-todo-file}) and shows its first category. +(You can get a different display with the first invocation of +@code{todo-show} by customizing the option @code{todo-show-first}; +@pxref{Todo Categories Mode} and @ref{Files of Filtered Items}.) + +If you leave Todo mode and later invoke @code{todo-show} to re-enter it, +by default this returns you to the current (i.e., last displayed) +category of the current todo file, which is the one in the most recently +selected and still live buffer visiting a todo file. If you disable the +option @code{todo-show-current-file}, then non-initial invocations of +@code{todo-show} always return to the first or current category of the +default todo file. + +If you want to enter Todo mode and go directly to a specific category +instead the first or current category in the current or default todo +file, use the command @code{todo-jump-to-category}; @ref{Navigation} for +details. You can also enter Todo mode by invoking a todo item insertion +command; @ref{Inserting New Items} for details. + +The most convenient way to use these commands to enter Todo mode is to +define global key bindings for them in your init file. Good choices are +for @code{todo-show} and @code{todo-jump-to-category} are @kbd{C-c t} +and @kbd{C-c j}, since these commands are bound to @kbd{t} and @kbd{j}, +respectively, in Todo mode. For invoking item insertion from outside of +Todo mode, it is useful to bind @code{todo-insertion-map}, which is the +key map containing the bindings of all Todo item insertion commands, to +@kbd{C-c i}, since it is bound to @kbd{i} in Todo mode; to complete the +invocation, supply the rest of the key sequence (@pxref{Inserting New +Items}). + +You can also visit a Todo file via @code{find-file} or Dired, like any +other file, and since Emacs recognizes it, the buffer will automatically +be in the appropriate Todo mode. Moreover, as long as the command you +use to visit the file is listed in the option +@code{todo-visit-files-commands} (which by default contains +@code{find-file} and @code{dired-find-file}), it will also correctly +display the file's first category on first visiting the file (otherwise +you have to use one of the commands for navigating between categories in +order to get a proper display). + +You can leave Todo mode by typing @kbd{q} (@code{todo-quit}), which +buries the current todo file buffer. Doing this also saves any changes +you have made to the file, and leaves both the file and the category +that was displayed on quitting current for subsequent Todo mode commands +(unless the buffer made current by quitting is visiting another file and +category in Todo mode, in which case the latter become current for Todo +mode commands). + +@node Key Binding Conventions, Navigation, Todo Mode Entry Points, Top +@chapter Key Binding Conventions + +For Todo mode commands to function properly, it is essential to maintain +the correct format at all three levels of organization---item, category, +and file. Todo mode tries to minimize the risk of format corruption by +hiding certain parts of the format from the user, making the buffer +read-only and suppressing the self-insertion keys. Consequently, it is +normally impossible to make changes to your todo files without +explicitly invoking Todo mode commands. + +A beneficial side effect of this restrictiveness is that you can invoke +almost all Todo commands by typing ordinary printing characters, either +singly or in specified sequences, without using modifier keys, except +for the shift key for capitalization and the raw prefix argument +@kbd{C-u}; numeric prefix arguments can be entered just by typing a +number key. + +The predefined key bindings in Todo are more or less mnemonic. As a +rule, key sequences beginning with @kbd{C} are bound to commands +applying to categories, sequences beginning with @kbd{F} apply to +(non-archive) file-level commands, and those beginning with @kbd{A} +apply to archives (a special type of Todo file; @ref{Todo Archive +Mode}). Todo commands applying to items, which constitute the majority, +are bound to lower case key sequences. + +@node Navigation, Editing, Key Binding Conventions, Top +@chapter Navigation + +The navigation commands are for making another todo file, category, or +item the current one by moving point to it.@footnote{Many editing +commands can also do this by side effect, but since that is not their +main function, they are not included in this section.} Since these +commands are likely to be used frequently and repetitively, it is +convenient for their key bindings to be single lower case keys, even for +navigation commands applying to categories and files. + +Two of the navigation commands were already mentioned in the section on +Todo mode entry points: + +@table @kbd + +@item t +Display another todo file in the selected window (@code{todo-show}). +When you invoke this command in Todo mode, it prompts for a file name, +which you can choose via minibuffer completion (like invoking +@code{todo-show} with a prefix argument outside of Todo mode). If a +buffer is already visiting that file, it displays its current category; +if invoking @kbd{t} opens the file, it display its first category (by +default; see the option @code{todo-show-first} for other possibilities). + +@item j +Display another todo category in the selected window +(@code{todo-jump-to-category}). When you invoke this command, it +prompts for a category name, which you can choose via minibuffer +completion. The candidates for completion include the categories in the +current todo file as well as those in the files listed in the option +@code{todo-category-completions-files}. If you type @key{RET} without +choosing a category, the current category of the current todo file is +automatically selected (this can be a useful shortcut when you invoke +@code{todo-jump-to-category} outside of Todo mode). If you type the +name of a non-existing category, you can add this to the file as a new +category and jump to it. If you invoke this command with a prefix +argument, it first you prompts for which todo file to jump to (which you +can also choose with minibuffer completion) and then for which category +from that file; in this case, completion is only against the categories +in the selected file. +@end table + +It is also convenient to navigate back and forth sequentially between +the categories of a single todo file. The categories of a todo file are +numbered consecutively starting with @samp{1}.@footnote{A category's +number is automatically assigned when the category is created: the +category is appended to the end of the file, so its number is simply the +highest until another category is added. There is no command in Todo +mode to reorder the numbering of the categories in a todo file, but this +is possible from the file's table of categories; @ref{Todo Categories +Mode}.} The current category's number and name appear in the mode line. + +@table @kbd + +@item f +Move point to the first item of the category numerically directly +following the current category (@code{todo-forward-category}). + +@item b +Move point to the first item of the category numerically directly +preceding the current category (@code{todo-backward-category}). +@end table + +With @kbd{f} and @kbd{b} you can cycle through the categories, so for example, +if the last category is current and you type @kbd{f}, then the first +category becomes current. + +You can also navigate between the items in the current category: + +@table @kbd + +@item n +Move point down to the next item below the current one (i.e., to the +item with the next lower priority) (@code{todo-next-item}). + +@item p +Move point up to the item directly above the current one (i.e., to the +item with the next higher priority) (@code{todo-previous-item}). +@end table + +These commands also accept a positive numeric prefix argument; e.g., +typing @kbd{5 n} or @kbd{5 p} navigates in one step to the item five items lower +or higher than the current one. + +Navigation to other types of Todo files is discussed in the relevant +sections below. + +@node Editing, Todo Archives, Navigation, Top +@chapter Editing + +Editing in Todo mode means making structural or textual changes at one +of the levels of organization (file, category, or item). Structural +editing includes adding, relocating and removing, textual editing includes +renaming files or categories and changing an item's content or date, or +adding certain kinds of marks or tags to items. To save changes you +make to the current todo file, type @kbd{s} (@code{todo-save}). Changes +are also saved on quitting Todo mode with @kbd{q}. + +@menu +* File Editing:: +* Category Editing:: +* Item Editing:: +@end menu + +@node File Editing, Category Editing, , Editing +@section File Editing and Todo Edit Mode + +There are four file-level editing commands: + +@table @kbd + +@item F a +Add a new todo file (@code{todo-add-file}). This command prompts for a +name and creates the file in @code{todo-directory}, adding the +@samp{.todo} extension (so you should not include the extension in the +name you enter). The command also prompts for the file's first category and, if +option @code{todo-add-item-if-new-category} is enabled (the default), +for that category's first item. + +@item F r +Rename the current todo file (@code{todo-rename-file}). If called with +a prefix argument, prompt for a todo file and rename it. If the todo +file has an archive (@pxref{Todo Archive Mode}) or there are +corresponding filtered items files (@pxref{Todo Filtered Items Mode}), +this command renames these accordingly. If there are live buffers +visiting any of these files, the command also rename them accordingly. + +@item F k +Delete the current todo file (@code{todo-delete-file}).@footnote{The key +binding of this command is mnenomic for ``kill'' to parallel the binding +@kbd{k} for item deletion, since @kbd{d} is bound to another item +editing command (@pxref{Done Items}).} If the todo file has an archive +(@pxref{Todo Archive Mode}), prompt whether to delete that as well. +This command also kill the buffers visiting the deleted files. + +@item F e +This command (@code{todo-edit-file}) changes the buffer's major mode to +Todo Edit mode. In this mode the entire file is visible, the buffer is +writeable and you can use the self-insertion keys and standard Emacs +editing commands to make changes. To return to Todo mode, type @kbd{C-x +C-q} (@code{todo-edit-quit}). + +The command @kbd{F e} is not intended for normal editing of items and +categories, as it circumvents the restrictions that Todo imposes to +protect against file format corruption (i.e., all categories, not just +the current one, and all internal formatting are exposed and editable). +It is provided primarily as a convenience for two types of use cases +that are likely to arise infrequently. One is to be able to use +standard Emacs commands like @code{query-replace} to replace a piece of +text that occurs in different categories throughout the file. The other +use case is to recover from a mistake, such as accidentally deleting an +item, since this cannot be undone in Todo mode. + +Using @kbd{C-x C-q} to quit Todo Edit mode provides a measure of safety, +since it runs a file format check, signaling an error if the format has +become invalid. However, this check cannot tell if the number of items +changed, which could result in the file containing inconsistent +information (see the cautionary note in @ref{Reordering Categories} for +more details). For this reason @kbd{F e} should be used with caution. +@end table + +@node Category Editing, Item Editing, File Editing, Editing +@section Category Editing + +The following commands are available for editing at the category level +(for additional category-editing commands, which are extensions of item +commands, @pxref{Editing Item Headers and Text}): + +@table @kbd + +@item C a +Add a new category to the current todo file and make that category +current (@code{todo-add-category}). If called with a prefix argument, +prompt for a file name and add the new category to that file. This +command is similar to using @kbd{j}, but it only accepts category names +that are not the name of an existing category in the file. + +@item C r +Rename the current category (@code{todo-rename-category}). If this +category's file has an archive (@pxref{Todo Archive Mode}) with a +corresponding category, rename the category there as well. + +@item C m +Move the current category (with all its items) to another todo file +(@code{todo-move-category}). If this category's file has an archive +(@pxref{Todo Archive Mode}) with a corresponding category, this command +also moves that category to the archive file corresponding to the moved +to todo file; if there is no such archive file, the command creates it +and adds the category. + +@item C k +Delete the current category (@code{todo-delete-category}).@footnote{This +binding is mnenomic for ``kill'' to parallel the binding @kbd{k} for +item deletion, since @kbd{d} is bound to another item editing command +(@pxref{Done Items}).} To delete a category that contains items, you +have to confirm your intent; if the category is empty, deletion is +immediate. + +@item C g +Merge the items of one category into another category, delete the first +category and make the second category current +(@code{todo-merge-category}). If both the first and second categories +also have archived items (@pxref{Todo Archive Mode}), merge the former +to the latter. If only the first category has archived items, rename +the archive category to the merged to category. Minibuffer completion +of the name of the category merged to works as with the navigation +command @kbd{j}, and as with that command, passing a prefix argument, +i.e., typing @kbd{C-u C g}, prompts for a file and confines merging to a +category in that file. +@end table + +@node Item Editing, , Category Editing, Editing +@section Item Editing + +Todo mode provides a wide variety of commands for adding and textually +changing items, as well as for deleting and relocating items. + +@menu +* Inserting New Items:: +* Editing Item Headers and Text:: +* Relocating and Removing Items:: +@end menu + +@node Inserting New Items, Editing Item Headers and Text, , Item Editing +@subsection Inserting New Items + +There are many commands for adding new todo items. The command names +contain the word ``insert'' instead of ``add'' and their key bindings are +sequences beginning with @kbd{i}. The motivation for this terminology is +that speaking of adding an item to a category suggests appending it to +the top or bottom, whereas you can insert an item into the category +anywhere, giving each new item any priority in the list. + +@table @kbd + +@item i i +This is the basic command for inserting new items into a category +(@code{todo-insert-item}). Called without a prefix argument, it prompts +for the text of the item and its priority (a number between 1 and one +more than the number of items already in the category), both of which +you enter in the minibuffer, and inserts the item into the current +category of the current todo file at the position in the list +corresponding to the priority you chose. Called with one prefix +argument, it also prompts for a category, and called with two prefix +arguments, it prompts for both a file and a category from that file, and +inserts the item accordingly. Category name completion works as with +the navigation command @kbd{j}. +@end table + +Each invocation of @kbd{i i} adds a header string to the item, which +includes at least the current date in the same format used by +@code{diary-insert-entry} (@pxref{Date Formats,,, emacs}). You can +control what other information is included in the header by customizing +the following options: + +@itemize @bullet + +@item +@code{todo-always-add-time-string} is for including or omitting the +current time. The time string is omitted by default. + +@item +@code{todo-include-in-diary} is for specifying whether the item appears +in the Fancy Diary display by adding or omitting +@code{todo-nondiary-marker}. By default, new todo items are marked for +exclusion from the diary. + +@item +@code{todo-diary-nonmarking} is for adding or omitting +@code{diary-nonmarking-symbol} to items displayed in the diary, to +control whether they are marked in the calendar (@pxref{Format of Diary +File,,, emacs}). By default, todo items that are diary entries are +marked in the calendar. +@end itemize + +Instead of always adding the same header information to a new item, you +can use more specific insertion commands that let you decide what to +include in the item header each time you insert a new item. And instead +of always being prompted to choose the new item's priority, you can +invoke a command to insert it at the position (hence with the priority) +of the item at point. Finally, instead of always typing the text of the +new item in the minibuffer, you can invoke a command that makes the +selected region in an Emacs buffer automatically become the new item's +text. The following paragraphs discuss how to invoke these commands by +typing certain key sequences. + +There are eight parameters of item insertion in Todo mode, six +concerning the item header, and one each concerning its priority and its +text. Each unique combination of these parameters produces a different +insertion command. The command @kbd{i i} realizes one of these +combinations. For the commands that realize the remaining combinations +it is convenient to associate each parameter with a mnenomically chosen +key. Then by typing certain sequences of these keys, you complete the +insertion command invocation that realizes the specified combination. +As with @kbd{i i}, the effect of many of these commands also depends on +the values of the item insertion options mentioned above (see the +examples below). + +Here is a list of the parameters and their associated keys, in the order +in which you must type them when building a key sequence (this order +roughly reflects the order in which the corresponding parts of the item +occur in a category listing): + +@enumerate + +@item +@kbd{y} for diary (non)inclusion; +@item +@kbd{k} for adding or omitting `diary-nonmarking-symbol'; +@item +@kbd{c} for adding the date header by clicking a date in the Emacs +calendar, or@* +@kbd{d} for interactively entering the date header as a string of year, +month and day number components in the minibuffer, or@* +@kbd{n} for interactively entering the date header as a weekday name in +the minibuffer; +@item +@kbd{t} for adding a time string to the header in the minibuffer +(including the empty string, which amounts to omitting the time); +@item +@kbd{h} for inserting the new item in the position of the item at point +(``here''), or@* +@kbd{r} to use the text of the selected region as the item's text. +@end enumerate + +Each insertion command key sequence begins (disregarding prefix +arguments) with @kbd{i}, followed by one or more of these eight keys, in +the order listed. But as you can see in the above table, since some of +the insertion parameters are mutually exclusive, they occupy only five +positions, so the complete (unprefixed) sequences are maximally six keys +long. Shorter sequences are also possible, since a parameter may be +omitted. But since the order in any key sequence is fixed, if the last +key in the sequence could be followed by another insertion key, i.e., if +the last key is not @kbd{h} or @kbd{r}, it has to be doubled to complete +the sequence, otherwise it would be interpreted as a prefix sequence +(this is why the binding for the basic item insertion command is @kbd{i +i} and not @kbd{i}). + +Here are some examples of item insertion command key sequences: + +@itemize @bullet + +@item +@kbd{i h} inserts a new item at the position of the item at point (pushing +the latter down) with a header containing the current date and, +depending on the values of the mentioned options, possibly the current +time and diary-related markings. +@item +@kbd{i y h} does the same as the preceding command, except that +@code{todo-nondiary-marker} is added if @code{todo-include-in-diary} is +non-nil and omitted if that option is nil; that is, the diary key @kbd{y} +overrides the setting of this option. +@item +@kbd{i y t h} does the same as the preceding command, except that it +prompts for a time string instead of automatically inserting the +current time; however, typing @key{RET} at the prompt returns the +current time if @code{todo-always-add-time-string} is non-nil, otherwise +the empty string (i.e., no time string). +@item +@kbd{i y t t} does the same as the preceding command, except that it +prompts for the item's priority and inserts it accordingly. +@end itemize + +Note that the commands whose key sequences include @kbd{y}, @kbd{k} or @kbd{t} +reverse the effect of the options @code{todo-include-in-diary}, +@code{todo-diary-nonmarking} and @code{todo-always-add-time-string}, +respectively, thus temporarily overriding their values. + +The names of the item insertion commands correspond to their key +bindings, e.g., @kbd{i h} is bound to @code{todo-insert-item-here}, @kbd{i y h} to +@code{todo-insert-item-diary-here}, etc. But since there are so many +combinations, instead of trying to memorize either the names or the key +sequences, you can, as usual, just type an initial part of a key +sequence (minimally @kbd{i}), followed by @kbd{C-h} to see the valid +completions. + +An alternative to using the key @kbd{c} for choosing the item's date +from the calendar is also available: if point is on a date in the +calendar, typing @kbd{i t} (@code{todo-insert-item-from-calendar}) will +prompt for a new item and its priority and insert it in the current +category. Like @kbd{i i} and the other item insertion commands, this +also accepts one or two prefix arguments for choosing the category via +minibuffer completion. Note, however, that the key sequence @kbd{i t} +is not defined in Todo mode but in the Calendar mode keymap. It is a +convenient shortcut if you happen to be using the calendar when you +decide to make a new todo item. (Contrast this with a command like +@kbd{i c c}, which pops open the calendar after you have entered the +item's text, and then you can choose a date from the calendar.) + +There is one more item insertion command, which does not derive from the +item insertion parameters: + +@table @kbd + +@item i p +This command (@code{todo-copy-item}) makes a complete copy of the item +at point, including its header, prompts for its priority in the current +category and inserts it accordingly. +@end table + +@noindent +This command is useful for quickly adding a todo item whose text or +header you want to differ only partly from that of an existing item: +after inserting the copy, you can quickly edit it as needed by using +commands described in the next section. + +@node Editing Item Headers and Text, Relocating and Removing Items, Inserting New Items, Item Editing +@subsection Editing Item Headers and Text + +There are a number of commands for editing an existing item's text or +header; these commands are bound to key sequences with @kbd{e}. + +There are two commands for editing an item's text (and manually editing +its header), one appropriate for short items and simple edits and one +better suited for more complex changes or for editing lengthy items: + +@table @kbd + +@item e e +Edit the text of the current item in the minibuffer +(@code{todo-edit-item}). If called with a prefix argument (@kbd{C-u e +e}), the item's header is also included in the minibuffer and so can be +edited manually. + +@item e m +Edit the text of the current item in a special buffer in Todo Edit mode +(@code{todo-edit-multiline-item}). When you have finished editing, type +@kbd{C-x C-q} to return to Todo mode; this runs a format check to ensure +the item is well-formed.@footnote{Unlike the command @kbd{F e} +(@pxref{File Editing}), @kbd{e m} does not expose you to the risk of +putting the file in an inconsistent state, since it puts only the +current item in Todo Edit mode.} +@end table + +A number of commands are available for interactively editing all or part +of the item header, permitting quick edits and helping avoid formatting +errors. + +The following three commands are for editing any or all of the year, +month and day components of a date header: + +@table @kbd + +@item e d t +Successively prompt for changes to the date's year, month and +day number, and if the option @code{todo-always-add-time-string} is +non-nil, also for editing the time string (see also @kbd{e t} below). + +@item e d a +Change the date to today's date. + +@item e d c +This command pops up the Emacs calendar, and after you type @key{RET} on +a date in the calendar makes that date the item's date. +@end table + +@noindent +You can also use these commands on items whose date header consists of a +weekday name, which then changes to a header with year, month and day +components. + +Each of the following three commands, in contrast to the preceding +three, changes only a single date component and has no effect on a date +header consisting of a weekday name: + +@table @kbd +@item e d y +@itemx e d m +@itemx e d d +Prompt for changing just the year, month or day number, respectively; if +invoked with a positive or negative numeric prefix argument, directly +increment or decrement the date component accordingly and automatically +adjust the other date component if necessary. For example, if the date +string is ``January 1, 2013'', typing @kbd{- 3 e d d} results in +``December 29, 2012''. +@end table + +@table @kbd +@item e d n +Prompt for a weekday name and make it the item's date header. Note that +this replaces an existing date string, it does not add the day name to +the date string. + +@item e t +Edit just the item's time string. A time string can be added both to a +date string and to a weekday name. If you type @key{RET} at the +prompt, this omits a time string from the header, or deletes an existing +time string. + +@item e y y +Change the item's diary inclusion status by adding or removing +@code{todo-nondiary-marker}. + +@item e y k +Change the item's diary marking status by adding or removing +@code{diary-nonmarking-symbol} (this command has an effect only if the +item is not marked for exclusion from the diary). +@end table + +@noindent +Parallel to the latter two item-level commands are the +following category-level commands: + +@table @kbd + +@item C e y +@itemx C e k +Add @code{todo-nondiary-marker} and @code{diary-nonmarking-symbol}, +respectively, to all todo items in the current category; if invoked with +a prefix argument, these markings are removed from all items in the +category. +@end table + +@node Relocating and Removing Items, , Editing Item Headers and Text, Item Editing +@subsection Relocating and Removing Items + +In addition to inserting a new todo item and changing the text or header +of an existing item, you can also move an item to another category +(i.e., recategorize it), change its priority within its category, delete +it from the category and file, or mark it as a ``done'' item, which +removes it from the todo list but does not delete it. + +@menu +* Reprioritizing Items:: +* Moving and Deleting Items:: +* Done Items:: +@end menu + +@node Reprioritizing Items, Moving and Deleting Items, , Relocating and Removing Items +@subsubsection Reprioritizing Items + +There are three ways to change a todo item's priority: + +@table @kbd + +@item r +Raise the current item's priority by one, exchanging its position in the list +with that of the item directly above it (@code{todo-raise-item-priority}). + +@item l +Lower the current item's priority by one, exchanging its position in the list +with that of the item directly below it (@code{todo-lower-item-priority}). + +@item # +Prompt for a number and relocate the item to the corresponding position +in the list (@code{todo-set-item-priority}). For example, entering +@kbd{3} at the prompt makes the item the third in the category, i.e., +gives it third highest priority. You can also pass the desired priority +as a numeric prefix argument, e.g., @kbd{3 #} gives the item third +highest priority without prompting. (Prefix arguments have no effect +with @kbd{r} or @kbd{l}.) +@end table + +@node Moving and Deleting Items, Done Items, Reprioritizing Items, Relocating and Removing Items +@subsubsection Moving and Deleting Items + +You can move an item to another category, thereby recategorizing it: + +@table @kbd + +@item m +Move the item at point to another category (@code{todo-move-item}). +This prompts for a category to move the item to, displays that category, +prompts for the priority of the moved item in the category moved to and +inserts the item accordingly. Minibuffer completion of the name of the +category moved to works as with the navigation command @kbd{j}, and as +with that command, passing a prefix argument prompts for a file and +moves the item to a category in that file; and if the category name you +enter is new, then you are asked whether to add the category to the +file, and if you affirm, the item is moved to the new category. +@end table + +You delete an item, thereby permanently removing it: + +@table @kbd + +@item k +Delete the todo item at point (@code{todo-delete-item}; the binding is +mnenomic for ``kill'', since @kbd{d} is used for marking items as done +(@pxref{Done Items}); but note that @kbd{k} does not put the item into +the kill ring). This command requires confirmation that you want to +delete the item, since you cannot undo the deletion in Todo mode. (You +could use @kbd{F e} to recover the item, but be aware that this would +put the file in an inconsistent state, which you can recover from, but +not without a risk; cf.@: the cautionary note in @ref{Reordering +Categories}.) +@end table + +@quotation Note +Todo commands that require user confirmation, such as @kbd{k}, use a +modified form of @code{y-or-n-p}, which by default only accepts @kbd{y} +or @kbd{Y}, but not @key{SPC}, as an affirmative answer. This is to +diminish the risk of unintentionally executing the command, which is +especially important with commands that do deletion, since there is no +Todo command to undo a deletion. If you want to be able to use SPC for +confirmation, enable the option @code{todo-y-with-space}. +@end quotation + +@node Done Items, , Moving and Deleting Items, Relocating and Removing Items +@subsubsection Done Items + +When the activity or thing that a todo item is about has been done, it +is natural to eliminate the item from the todo list. But instead of +deleting it permanently, you may prefer to keep a record of your +accomplishments by marking the item as done. In Todo mode, this removes +the done item from the todo list, so as not to clutter it up, and stores +it elsewhere. Such stored items form a record or diary of things done. +The Todo package provides two such stores: the ``done items'' section of +a Todo category, described here, and done item archives (@pxref{Todo +Archive Mode}). + +@table @kbd + +@item d +This command (@code{todo-item-done}) removes the todo item at point from +the todo list, appends to the original header a header consisting of +@code{todo-done-string} (by default ``DONE '') and the current date, and +if @code{todo-always-add-time-string} is enabled, also the current time, +and adds the resulting done item to the top of the done items section of +the category. Invoked with a prefix argument, it also prompts you to +enter a comment, which is appended to the end of the done item, prefixed +with @code{todo-comment-string} (by default ``COMMENT: ''). +@end table + +A category's done items section is located below the last todo (i.e., +not done) item in the category. By default this section is hidden from +view. There are two commands for viewing and hiding done items; since +these are toggle commands, for convenience they also have a single key +binding: + +@table @kbd + +@item C v +@itemx v +Make the done items section of the current category visible if it is +hidden, or hide it if it is visible +(@code{todo-toggle-view-done-items}). If you always want to see the +done items section on entering a category, enable the option +@code{todo-show-with-done}; you can still use @kbd{C v} or @kbd{v} to +hide (and unhide) it. + +@item F V +@itemx V +Toggle the standard category display in the current todo file, i.e., +display only the done items section of each category in the file, or if +this is visible, hide it again and display only the todo items section +(@code{todo-toggle-view-done-only}). +@end table + +Three editing commands for done items are available: + +@table @kbd + +@item e c +If you type this command (@code{todo-edit-done-item-comment}) when point is +on a done item that has a comment, you can edit the text of the +comment. If you invoke it with a prefix argument (@kbd{C-u e c}), the +comment is deleted on confirmation. If the done item does not have a +comment, this command allows you to add one. + +@item m +Move the done item at point to the top of the done items section of +another category (@code{todo-move-item}). This is useful in case, after +having relocated an item to its category's done items section, you +create a category that is better suited to the content of the done item +than its current category, so you can recategorize the done item. + +@item u +If you decide the done item at point is not done after all, this command +``undoes'' it, i.e., restores it to the todo list of its category, with +the priority you choose for it (@code{todo-item-undone}). If the done +item has a comment, you are asked whether to delete it from the restored +item. +@end table + +@node Todo Archives, Marked Items, Editing, Top +@chapter Todo Archives + +When the done items section of a category itself starts to become +cluttered, or if you just want to store some accomplished todo items in +a separate file, you can move them to a Todo archive. This is a file +with exactly the same structure as a todo file, i.e., divided into +categories, but differs in that the categories contain only done items. +Todo archives reside, like todo files, in @code{todo-directory} but have +the extension @samp{.toda} instead of @samp{.todo}. + +@menu +* Creating and Visiting Archives:: +* Todo Archive Mode:: +@end menu + +@node Creating and Visiting Archives, Todo Archive Mode, , Todo Archives +@section Creating and Visiting Archives + +Todo mode provides the following command for archiving items: + +@table @kbd + +@item A d +This command (@code{todo-archive-done-item}) archives the done item at point. +Invoked with a prefix argument, it archives all done items in the +current todo category. If an archive for the current todo file +already exists and contains a category with the same name as the +current todo category, then this command moves the done item to the +top of the corresponding archive category. If the archive exists but +it does not have a corresponding category, this command creates the +category in the archive and moves the done item to it. If no archive +for the todo file exists, the command creates both the archive file, +using the same base name as that of the todo file, as well as the +category, and moves the done item to it. +@end table + +Typing @kbd{A d} is also the only way within the Todo mode package to +create an archive file and its categories. Consequently, as a rule each +archive file corresponds to exactly one todo file and has the same base +name as this file, and each category in an archive file corresponds to +and has the same name as a category in the corresponding todo file. +Exceptions can only arise if you delete a todo file but not the +corresponding archive, or if you delete a category in a todo file that +has a corresponding category in an archive. + +You might be inclined to do the latter if you have archived all the +items from a given todo category and you don't plan to add new items to +it. In particular, if you have numerous such empty categories in a todo +file, this can make sequential navigation in the file annoying. You can +avoid this annoyance by deleting these categories, but only at the cost +of putting the todo file out of synch with the archive file. + +You may find it preferable not to delete empty todo categories but to +enable the option @code{todo-skip-archived-categories}. When this is +non-nil, such empty todo categories are skipped over by the sequential +category navigation commands @kbd{f} and @kbd{b}, so they don't distract you +while navigating and you maintain the structural correspondence between +todo and archive files (you can also still jump to empty todo categories +with @kbd{j}). + +If you rename a todo category that has a corresponding category in an +archive, the archive category is also automatically identically renamed. +Likewise, if you move such a todo category to another file; in this +case, if there is no archive file corresponding to the todo file the +category is moved to, then the archive is automatically created and the +archived category is moved to it. + +There are two commands in Todo mode for visiting archive files: + +@table @kbd + +@item A f +Switch to a buffer displaying the archived category corresponding to the +current todo category (@code{todo-find-archive}). If the todo category +has no archived items, the command asks if you want to visit the archive +anyway. If there is no archive for this todo file, it asks if you want +to visit another archive, which you can select via minibuffer +completion. + +@item A c +Choose an archive to visit, whether or not the current todo file has an +archive (@code{todo-choose-archive}). +@end table + +As with todo files, you can also visit a Todo archive by invoking a +standard Emacs file-visiting command; this displays the first (on the +initial invocation) or current category of the archive. + +@node Todo Archive Mode, , Creating and Visiting Archives, Todo Archives +@section Todo Archive Mode + +When you visit a Todo archive, the buffer is in Todo Archive mode. It +displays categories just as in Todo mode, except that they only contain +done items. It provides the same sequential navigation commands as +Todo mode: @kbd{f} and @kbd{b} navigate between the categories of the current +archive, and @kbd{n} and @kbd{p} navigate between the done items of the current +archive category. + +The commands @kbd{t} and @kbd{j} are also available in Todo Archive +mode, and they work the same as in Todo mode, which means they can only +be used to return to Todo mode: @kbd{t} prompt for and switch to a todo +file, and with @kbd{j} you can only jump to a todo category. These +commands exclude archives because an archive file has the same base name +as the corresponding todo file, and category name completion uses only +the base names, so the commands cannot know which type of file you want +to visit. For this reason, there is a special command in Todo Archive +mode for jumping to another archive category or visiting another archive +file: + +@table @kbd + +@item a +This command (@code{todo-jump-to-archive-category}) prompts for a category in the +current archive and jumps to it. Called with a prefix argument, it +prompts for another archive, then for a category in it and jumps to +that category. +@end table + +None of the Todo mode editing commands are available in Todo Archive +mode, since archives are meant to be static records of accomplished todo +items. Should you, however, archive an item by mistake or simply change +your mind about the archival status of an item, you can ``unarchive'' it: + +@table @kbd + +@item u +Restore the done item at point to the top of the done items section of +the corresponding category in the corresponding todo file, i.e., an +unarchived item remains a done item (@code{todo-unarchive-items}). When +the last item in an archive category has been unarchived, the category +is automatically deleted from the archive. If this was the only +category in the archive, the archive file is also automatically deleted. +@end table + +Since it is natural to visit an archive from the corresponding todo +file, it would be convenient to easily return to the todo file when you +have finished browsing the archive. If you type `q' to quit Todo +Archive mode, this switches to the corresponding todo file and shows the +todo category corresponding to the archive category you were just +visiting. + +The command @kbd{F k} (@pxref{File Editing}) is also available in Todo +Archive mode. It deletes the current archive file and prompts you +whether to delete the corresponding todo file. + +@node Marked Items, Todo Categories Mode, Todo Archives, Top +@chapter Marked Items + +For many item editing commands it can make sense and be convenient to +apply them simultaneously to more than one item in the current category. +Todo facilitates this by means of marked items. + +@table @kbd + +@item * +Mark the item at point if it is unmarked, and remove the mark it is +already marked (@code{todo-toggle-mark-item}). The mark is a string +specified by the option @code{todo-item-mark} (by default @samp{*}) +appended in front of the item header (more precisely, in front of the +item's priority number or prefix; @pxref{Todo Display Features} for +details of the latter). After marking the current item, the command +advances point to the next item. It also accepts a numeric prefix +argument, which allows toggling the mark of multiple consecutive items. + +@item C * +Mark all todo items in the current category. + +@item C u +Unmark all todo item in the current category. +@end table + +You can also use the last two commands to mark or unmark all done items in +the category, but only when only the done items section is being +displayed, i.e., after invoking @kbd{C V} or @kbd{V}. + +The following commands operate on marked items: @kbd{k} (deleting), @kbd{m} +(moving to another category), @kbd{d} (moving to the done items section; +note that @kbd{C-u d} adds the same comment to all marked items), @kbd{A d} +(archiving), @kbd{u} (both in Todo mode for undoing a done item and in +Todo Archive mode for unarchiving an item), as well as the commands for +editing the item header (those beginning with the prefix @kbd{e d} as well +as @kbd{e t}, @kbd{e y y} and @kbd{e y k}). The item insertion, textual editing and +priority changing commands do not operate on marked items. + +If you use @kbd{m}, @kbd{d}, @kbd{A d} or @kbd{u} on multiple noncontiguous marked +items, the relocated items retain their relative order but are now +listed consecutively en bloc. + +You can mark both todo and done items, but note that only @kbd{m} can apply +to both; other commands only affect either marked todo or marked done +items, so if both types of items are marked, invoking these commmands +has no effect and informs you of your erroneous attempt. + +@node Todo Categories Mode, Searching for Items, Marked Items, Top +@chapter Todo Categories Mode + +It can be helpful to have a compact overview of the categories in a todo +file and the types of items it contains; Todo provides a tabular view +of this information. + +@table @kbd + +@item F c +Typing this command (@code{todo-show-categories-table}) in Todo mode or Todo +Archive mode switches to a buffer displaying a table that gives an +overview of the categories in the current todo or archive file. This +buffer is in Todo Categories mode. +@end table + +The table consists of a column containing the names of the categories in +the file, followed by columns containing counts of certain types of +items in each category. With todo files there are four count types: all +todo (i.e., not done) items, diary items (i.e., those todo items lacking +the @code{todo-nondiary-marker}, which hence can appear in the Fancy Diary +display), done (but not archived) items, and archived items. With +archive files all items are done, so the table only has a column for +this count. The final row of the table gives total item counts across +all categories in the file. + +Aside from explicitly invoking @kbd{F c} to display the table of +categories, you can also arrange to have it displayed on the first +invocation of @code{todo-show} for a given file (i.e., either using +@code{todo-show} to initiate a Todo session, or calling it in Todo mode +to visit another todo file). To do this customize the option +@code{todo-show-first}. + +@menu +* Table of Item Counts:: +* Reordering Categories:: +@end menu + +@node Table of Item Counts, Reordering Categories, , Todo Categories Mode +@section Table of Item Counts + +Above each column of the table is a labelled button you can press by +clicking with the mouse or by typing @key{RET} on it. Pressing an item +count button sorts the table alternately in ascending or descending +order according to the type of count. Pressing the category button +alternates between the initial numerical order of the categories and +alphabetical order. In numerical order the column of category names is +preceded by a column containing the corresponding category numbers; this +column is not displayed in the alphabetical listing. Instead of +pressing the buttons, you can also sort the table by typing the +following keys: + +@itemize + +@item @kbd{c} +to sort by category numerically or alphabetically; +@item @kbd{t} +to sort by todo item counts; +@item @kbd{y} +to sort by diary item counts; +@item @kbd{d} +to sort by done item counts; +@item @kbd{a} +to sort by archived item counts. +@end itemize + +Each row of the table is also buttonized; pressing one of these exits +the buffer (killing it), returns to the buffer of the file from which +you had invoked `F c', and displays the category that was named in the +row button you pressed (i.e., pressing this button jumps to that +category). However, if the category named in the row is in a todo file +and all of its items have been archived, and you have enabled the option +@code{todo-skip-archived-categories}, then pressing the button jumps to +the archive category instead of the empty todo category. You can +recognize such categories by their items counts in the table---all +columns but the archived one have counts of zero---and in addition, +their lines in the table are also distinguished from the others by a +different face. + +You can navigate around the table: + +@table @kbd + +@item n +@itemx @key{TAB} +Advance point to the next button. + +@item p +@itemx S-@key{TAB} +Put point on the previous button. +@end table + +These commands are cyclic, e.g. when point is on the last button, +pressing @kbd{n} moves it to the first button. + +Typing @kbd{q} exits Todo Categories mode, killing the buffer and returning +to the current category in the Todo mode or Todo Archive mode buffer +from which you had invoked @kbd{F c}. + +@node Reordering Categories, , Table of Item Counts, Todo Categories Mode +@section Reordering Categories + +Todo Categories mode provide commands with which you can change the +numbering of the categories in the current file. This renumbering has +the effect of reordering the categories for sequential navigation by +@kbd{f} and @kbd{b} in Todo mode and Todo Archive mode. These commands +are only operative when the table displays the categories in their +numerical order. They work just like reprioritizing items in Todo mode, +hence have the same key bindings: + +@table @kbd + +@item r +Raise the current line of the table (the one the cursor is on), +decreasing the category's number by one (@code{todo-raise-category}). +This command exchanges lines, and hence the numbers, of the category at +point and the one above it before invoking the command. + +@item l +Lower the current line of the table, increasing the category's number by +one (@code{todo-lower-category}). This command exchanges lines, and +hence the numbers, of the category at point and the one below it before +invoking the command. + +@item # +Prompt for a number between 1 and the number of categories in the file +and reorder the table accordingly (@code{todo-set-category-number}). If +called with a numeric prefix argument within the allowed range, reorder +the table without prompting. +@end table + +The reordering done by these commands remains in effect when you return +to Todo mode or Todo Archive mode and, as long as you save the todo +or archive file after reordering, in subsequent sessions as well. + +@quotation @strong{Caution} +It is important to be aware that renumbering the categories does not +change the textual order of the categories in the file. This is +significant if you should invoke @kbd{F e} to edit the entire file +manually and in so doing alter the number of items in a category: this +will make the item count shown in the table of categories of this file +inconsistent with the actual number. You can repair this inconsistency +by invoking the command @code{todo-repair-categories-sexp} (which lacks +a key binding, since it is meant to be a rarely needed rescue +operation). But this will revert any renumbering of the categories you +have made, so you will have to renumber them again. This is the reason +why you should exercise caution when using @kbd{F e}. +@end quotation + +@node Searching for Items, Todo Filtered Items Mode, Todo Categories Mode, Top +@chapter Searching for Items + +It can be useful to be able to locate and examine all todo items that +fit certain criteria, regardless of which category they belong to. One +way to do this in Todo mode is by sequentially searching in the file: + +@table @kbd + +@item S +This command (@code{todo-search}; the key is capital `S') prompts for a +regular expression, searches from the beginning of the current todo file +and displays the category containing the first match it finds, with the +match highlighted. If there are further matches, a message saying how +many are left is displayed and you are asked if you want to go to the +next match. When you reach the last match, or if you decide not to go +to further matches, you are asked whether the match highlighting should +be removed. + +@item X +This command (@code{todo-clear-matches}) removes any highlighting added by @kbd{S}. +This is so you can leave the matches highlighted at the end of the +search and remove the highlighting later. +@end table + +These commands are also available in Todo Archive mode. + +@node Todo Filtered Items Mode, Todo Display Features, Searching for Items, Top +@chapter Todo Filtered Items Mode + +A more powerful alternative to sequential searching is item filtering, +by which items from different categories that match specified criteria +are gathered and displayed in a new buffer as a kind of virtual +category in a distinct mode, Todo Filtered Items mode. + +@menu +* Filtering Items:: +* Todo Filtered Items Mode Commands:: +* Files of Filtered Items:: +@end menu + +@node Filtering Items, Todo Filtered Items Mode Commands, , Todo Filtered Items Mode +@section Filtering Items + +Todo mode provides three ways to filter items: a general filter for +items matching a user-entered regular expression, as with the search +command; and two specific filters, one for diary-displayable items +(i.e., those lacking @code{todo-nondiary-marker}) and one for top +priority items (more on the latter below). The commands for each +filter come in pairs, one for filtering just the current todo file and +one for filtering a user-specified list of todo files. Thus, there +are six item filtering commands:@footnote{The use of @kbd{F} in the key +sequences of these commands naturally recalls ``filter'', but is also +consistent with the Todo mode mnenomic key binding convention, since the +commands involve one or more whole files.} + +@itemize @bullet + +@item +@kbd{F x x} (@code{todo-filter-regexp-items}) +@item +@kbd{F x m} (@code{todo-filter-regexp-items-multifile}) +@item +@kbd{F y y} (@code{todo-filter-diary-items}) +@item +@kbd{F y m} (@code{todo-filter-diary-items-multifile}) +@item +@kbd{F t t} (@code{todo-filter-top-priorities}) +@item +@kbd{F t m} (@code{todo-filter-top-priorities-multifile}) +@end itemize + +There are two ways to specify which files the multifile filtering +commands apply to. If there are files you want to filter every time you +use these commands, customize the option @code{todo-filter-files}. If you +leave this option empty (the default), invoking a multifile filtering +command pops up a buffer similar to the Customization buffer for +@code{todo-filter-files}, in which you can select files to filter just for +this invocation. + +Diary and top priority items are by definition non-done todo items, but +when filtering by regular expression, you can extend the scope of the +command to done items by enabling the option @code{todo-filter-done-items}. +Then @kbd{F x x} and @kbd{F x m} will gather both matching todo and matching +done items (including done items from any archive files corresponding to +the selected todo files) into the virtual category of filtered items. + +There are several ways to specify how many items in each category count +as top priorities and hence get filtered by @kbd{F t t} and @kbd{F t m}: + +@itemize @bullet + +@item +The option @code{todo-top-priorities} specifies a single default number +for all categories and all todo files; its default value is 1, which +means just the highest priority item in every category is filtered, +unless otherwise specified. +@item +The option @code{todo-top-priorities-overrides} lists file-wide overrides +of @code{todo-top-priorities} as well as category-specific overrides. It +is empty by default. However, using the Custom facility to set this +option would be tedious and error-prone, so instead you should use the +commands @kbd{F t s} and @kbd{C t s}. The former sets (i.e., overrides) the +default number of top priorities for all categories in the current +todo file, and the latter sets the number of top priorities for the +current category. To exclude a category or file from filtering by @kbd{F t t} +and @kbd{F t m}, set the number to @samp{0}. +@item +You can invoke `F t t' and `F t m' with a numeric prefix argument, +which specifies the number of top priorities in each category just for +this invocation, overriding both @code{todo-top-priorities-overrides} and +@code{todo-top-priorities}. +@end itemize + +@node Todo Filtered Items Mode Commands, Files of Filtered Items, Filtering Items, Todo Filtered Items Mode +@section Todo Filtered Items Mode Commands + +The output of the item filtering commands looks similar to a regular +Todo category, but it is not contained in any todo file and does not +have a name on being created, so it is not a ``real'' category but a +``virtual'' category. Another difference is the lack of a done items +section; either there are no done items in the list (when the filtered +items are diary or top priority items), or these are displayed in the +same list as todo items (if you filtered by regular expression and +allowed done items). A further difference is that the items have an +additional header, between the item's date/time header and its text, +specifying which category (and if you invoked a multifile command, also +which file) the item comes from, and if you filtered by regular +expression, also whether the item comes from a Todo archive. + +The sequential item navigation commands @kbd{n} and @kbd{p} work the same in +Todo Filtered Items mode as in Todo mode, as do the file and category +jumping commands @kbd{t} and @kbd{j}; however, the sequential category +navigation commands are unavailable, since virtual categories of +filtered items are not ordered with respect to ``real'' categories. In +addition, Todo Filtered Items mode provides a special navigation +command: + +@table @kbd + +@item g +@itemx @key{RET} +If you type this command (@code{todo-go-to-source-item}) with point on a +filtered item, the buffer switches to the item's source file (in Todo +mode or Todo Archive mode, as the case may be) and displays its +category, with point on the item. +@end table + +Filtered items cannot be textually edited, moved to another category, +marked done or archived like items in a real todo category, since these +would then be out of synch with each other. But there is one type of +editing command that does work in Todo Filtered Items mode: changing an +item's priority: + +@table @kbd + +@item r +@itemx l +@itemx # +These commands raise, lower, or set, respectively, the current item's +priority in the virtual category. +@end table + +@noindent +Using these commands, you can create a cross-category (and even +cross-file) prioritized list of filtered items. However, there is a +restriction on these commands in Todo Filtered Items mode: you cannot +change the relative priorities of items from the same real category, +since that would make the filtered list inconsistent with the source +todo list. + +@node Files of Filtered Items, , Todo Filtered Items Mode Commands, Todo Filtered Items Mode +@section Files of Filtered Items + +Typing @kbd{s} in Todo Filtered Items mode saves the buffer of filtered +items to a file in @code{todo-directory}. Files of items filtered by +regular expression have the extension @samp{.todr}, those with filtered +diary items have the extension @samp{.tody} and those with filtered top +priorities have the extension @samp{.todt}. The extensions are added +automatically the first time you save the buffer to a file. + +With filtered top priority or diary items, the file is automatically +named on first saving it, using as the base name either the same base +name as the single todo file it was generated from, or combining the +base names of the todo files used in multifile filtering commands. +With items filtered by regular expression, it can be useful to save +separate lists generated from the same file(s) using different regular +expressions, so when saving such a list, you are prompted for a short +identifying string to add to the file name. + +When you invoke one of the item filtering commands without a prefix +argument and a corresponding file already exists, the command visits +this file (if, for the current file or chosen files, there are multiple +files of items filtered by regular expression, you are prompted to +choose one). To force generation of a new filtered list, invoke the +command with a prefix argument (in the case of top priority items, +either numeric as described above, or the raw prefix argument @kbd{C-u} to +use the values of @code{todo-top-priorities-overrides} or +@code{todo-top-priorities}). + +Aside from explicitly invoking an item filtering command to display a +saved list of items filtered by a given method from given todo files, +there are two other ways to visit a saved file of filtered items: + +@table @kbd +@item F f +Visit a saved file of filtered items, which you choose via minibuffer +completion (@code{todo-find-filtered-items-file}). +@end table + +@itemize @bullet +@item +As with tables of categories, by customizing @code{todo-show-first} you +can have the first invocation of @code{todo-show} for a given todo file +display the corresponding saved file of filtered items. If there is +no saved filtered items list for the file, @code{todo-show} simply +defaults to visiting the file and displaying its first category, as +usual. +@end itemize + +The command @kbd{F k} (@pxref{File Editing}) is also available in Todo +Filtered Items mode. It deletes the current filtered items file. + +@node Todo Display Features, Printing Todo Buffers, Todo Filtered Items Mode, Top +@chapter Todo Display Features + +You can change the appearance of Todo mode buffers in a variety of ways. + +@menu +* Faces:: +* Item Prefix:: +* Other Display Commands and Options:: +@end menu + +@node Faces, Item Prefix, , Todo Display Features +@section Faces + +Each of the Todo modes uses faces to distinguish various aspects of the +display, both structural and informational. For example, the faces for +the date and time strings of todo item headers by default inherit the +attributes of the corresponding faces used by the Emacs diary; but when +the date and time of a Todo diary item (i.e., an item lacking +@code{todo-nondiary-marker}) is earlier than the current date and time, +they are displayed in a different face. In this way, you can readily +recognize diary items that have ``expired'' and act accordingly (e.g., +by tagging them as done or by updating the deadlines). + +Another example of an informational face is the face used to distinguish +top priority items. A third case is the face used in Todo Categories +mode to mark rows of the table containing categories with only archived +items. + +The @code{todo-faces} customization group contains a complete list of +Todo mode faces and brief descriptions of their use. + + +@node Item Prefix, Other Display Commands and Options, Faces, Todo Display Features +@section Item Prefix + +In the default display of (real or virtual) categories in Todo mode, +Todo Archive mode and Todo Filtered Item mode the items are visually +numbered in ascending order, starting with @samp{1} on the top item, +displayed to the left of its header (date/time string). With todo items +the numbers indicate each item's priority in the list, so when you +reprioritize an item with @kbd{#} or move it with @kbd{m}, these numbers make +it easier to choose the item's new priority. The numbering also lets +you to see at a glance how many items there are in the list. When an +item is inserted, deleted, or moved, the numbering is automatically +updated. In Todo mode, the todo and done items sections in each +category are separately numbered. + +If you prefer not to have item numbering displayed, disable the option +@code{todo-number-prefix}; then the display of each item starts by default +simply with its header. But you can also replace the numbering with a +visually distinctive string of your choice by customizing the option +@code{todo-prefix} (the empty string by default). Another alternative is to +temporarily hide the item numbering: + +@table @kbd + +@item F N +@itemx N +Toggle between displaying item numbering and displaying the +@code{todo-prefix} string in the current Todo file (todo, archive, or +saved virtual category of filtered items. This command also works in +buffers of filtered items that have not yet been written to a file.) +@end table + +In the todo items section of each Todo mode category, the item prefix +(whether a priority number or a fixed string) of the top priority items +(determined as specified in @ref{Filtering Items}) is displayed in a +different face from the prefix of the other items, so you see at a +glance how many items in the category are top priorities. + +@node Other Display Commands and Options, , Item Prefix, Todo Display Features +@section Other Display Commands and Options + +There are two additional toggle commands that affect display in the +current file: + +@table @kbd + +@item F h +@itemx h +Hide the item headers if visible, or show them if they are hidden. +With done items, only the done header (i.e. the done tag and date-time +string inserted when the item was marked done) is hidden, the original +date-time string is not. With filtered items, the category (or +category-file) tag is not hidden. + +@item F H +@itemx H +Highlight the current item if unhighlighted, or remove its highlighting. +When item highlighting is enabled, it follows navigation by @kbd{n} or +@kbd{p}. If you want to have current item highlighting by default, +enable the option @code{todo-highlight-item}. @kbd{F H} or @kbd{H} will +still toggle it. +@end table + +There are two options which affect the display of items whose content is +longer than one screen line: + +@itemize @bullet{} + +@item +@code{todo-indent-to-here} sets the amount of indentation for all lines +after the first in multiline todo items, which is necessary in order +for todo diary items to be fully visible in the Fancy Diary display. +The default indentation is 3 spaces. For a uniform appearance this +option applies to all items, i.e., diary and nondiary todo items and +also done items. + +@item +@code{todo-wrap-lines} allows you to choose, for the purposes of +insertion and editing, between treating multiline todo items as +containing multiple logical lines with hard line breaks or as multiple +visual lines using Visual Line mode; the latter is the default. Since +multiparagraph items also contain hard line breaks in Visual Line mode, +for a uniform appearance this display shows indentation on wrapped lines +by using a wrap-prefix of @code{todo-indent-to-here} spaces. +@end itemize + +The indentation inserted after a hard newline is actually a tab +character, and the Todo modes that display items bind @code{tab-width} to +@code{todo-indent-to-here}, so if you change the default value of the +latter, the next time you visit a Todo file, the indentation will +reflect your change. + +By default, the todo and done items sections of a todo category are +visually separated by a line as wide as the window the buffer is +displayed in. You can change the appearance and width of the separator +by customizing @code{todo-done-separator-string}; you can also change the +face of the separator string. + +There are also several options for changing the appearance in Todo +Categories mode and Todo Filtered Items mode, beyond those mentioned +above in the sections on these modes; see the customization groups +@code{todo-categories} and @code{todo-filtered} for details. + +@node Printing Todo Buffers, Legacy Todo Mode Files, Todo Display Features, Top +@chapter Printing Todo Buffers + +If you print a Todo buffer using one of the standard Emacs printing +commands, it does not look exactly like what you see in the buffer. +This is because some of the display features are non-printable +(specifically, those using overlays, word-wrap and wrap-prefix). Todo +mode provides two print commands that produce output which includes +printable counterparts of such display features: + +@table @kbd + +@item P B +Send the printable buffer output directly to your printer. + +@item P F +Prompt for a file name and write the printable output to that file. +@end table + +By default, Todo uses @code{ps-print-buffer-with-faces} to make the +printable version; you can change this by setting the option +@code{todo-print-function}. + +@node Legacy Todo Mode Files, GNU Free Documentation License, Printing Todo Buffers, Top +@chapter Legacy Todo Mode Files + +Users of the original version of Todo mode will recognize from the +description in this user manual that, although the new version shares +with the original version the same basic user interface and handling of +todo items, there are some incompatible differences between them, such +as the done items sections (there are also other file format +incompatibilities behind the scenes that are normally not visible to +users). + +The most significant incompatibility concerns the item prefix. In the +earlier version of Todo mode the prefix was the initial part of the item +string itself, so in order for the item to be displayable in the Emacs +diary, the prefix had to be a date/time pattern recognizable by the +diary (although the todo item also has its own date/time header). +Moreover, since all items had the same prefix string in the original +version, this means that either only all or no items could appear in the +Fancy Diary display on any given date. This considerably restricts the +practicality of including todo items in the diary. In contrast, the +current version of Todo mode uses overlays for item priority numbering +or prefixes, and item-specific diary-compatible date/time headers and +special marks for todo items to be excluded from the diary, so you can +determine for each item whether and when it appears in the Fancy Diary +display. + +Due to these incompatibilities, files created with the original version +of Todo mode cannot be displayed or edited with the current version. +However, this version provides a function that converts the two main +types of files used by the original version into new-style valid todo +and archive files, respectively, and saves them in +@code{todo-directory}.@footnote{The original version of Todo mode also +allowed saving a file of top priority items, but since you can readily +create such a file with the new version, which is also more flexible, +no conversion is provided for this file.} + +This conversion function is automatically called the first time you +invoke @code{todo-show} (i.e., before you have created a todo file with +the new version), and if it finds the old-style files, it offers to +convert them, making them the first new-style todo and archive files. +If you choose not to convert the old-style files at this time, you can +do so later by invoking the command @code{todo-convert-legacy-files} +(there is no key binding for it, since it shouldn't be necessary to use +it often). (A delicate part of the conversion concerns the customizable +format of item date/time headers in the old-style; see the documentation +string of @code{todo-todo-mode-date-time-regexp} for details.) + +@node GNU Free Documentation License, , Legacy Todo Mode Files, Top +@appendix GNU Free Documentation License +@include doclicense.texi + +@bye + +@c End: diff --git a/info/dir b/info/dir index cecc0d00f47..b6ec2845c3d 100644 --- a/info/dir +++ b/info/dir @@ -36,7 +36,7 @@ Emacs editing modes Java, Pike, AWK, and CORBA IDL code. * IDLWAVE: (idlwave). Major mode and shell for IDL files. * nXML Mode: (nxml-mode). XML editing mode with RELAX NG support. -* Org Mode: (org). Outline-based notes management and organizer +* Org Mode: (org). Outline-based notes management and organizer. Emacs network features * EUDC: (eudc). Emacs client for directory servers (LDAP, PH). @@ -86,6 +86,7 @@ Emacs misc features * Wisent: (wisent). Semantic Wisent parser development. * SES: (ses). Simple Emacs Spreadsheet. * Speedbar: (speedbar). File/Tag summarizing utility. +* Todo Mode: (todo-mode). Make and maintain todo lists. * VIP: (vip). An older VI-emulation for Emacs. * VIPER: (viper). A VI-emulation mode for Emacs. * WoMan: (woman). Browse UN*X Manual Pages "W.O. (without) Man". From d5671a82b8b78b5fd8d83cfc15642d2c0eff6de2 Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Mon, 5 Aug 2013 00:12:18 +0200 Subject: [PATCH 016/449] * lisp/frameset.el: Add new predicate values for frameset-restore args. (frameset-live-filter-alist, frameset-persistent-filter-alist): New variables. (frameset-filter-alist): Use them. Add autoload cookie. (frameset-filter-tty-to-GUI): Move from desktop.el and rename. (frameset--set-id, frameset--reuse-frame): Rename `frame-id' to `frameset--id' (it's supposed to be internal to frameset.el). (frameset--process-minibuffer-frames): Ditto. Doc fix. (frameset--initial-params): New function. (frameset--get-frame): Use it. Doc fix. (frameset--move-onscreen): Accept new PRED value for FORCE-ONSCREEN. Accept :all, not 'all. (frameset-restore): Add new predicate values for FORCE-ONSCREEN and FORCE-DISPLAY. Use :keywords for constant arguments to avoid collision with fbound symbols. Fix frame id matching, and remove matching ids if the frame being restored is deleted. Obey :delete. * lisp/desktop.el (desktop-restore-forces-onscreen) (desktop-restore-reuses-frames): Document :keyword constant values. (desktop-filter-parameters-alist): Remove, now identical to frameset-filter-alist. (desktop--filter-tty*): Remove, moved to frameset.el. (desktop-save-frameset, desktop-restore-frameset): Do not pass :filters argument. --- lisp/ChangeLog | 26 +++++ lisp/desktop.el | 29 +---- lisp/frameset.el | 289 ++++++++++++++++++++++++++++------------------- 3 files changed, 202 insertions(+), 142 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 66bf7422b0d..de1da73bbb1 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,29 @@ +2013-08-04 Juanma Barranquero + + * desktop.el (desktop-restore-forces-onscreen) + (desktop-restore-reuses-frames): Document :keyword constant values. + (desktop-filter-parameters-alist): Remove, now identical to + frameset-filter-alist. + (desktop--filter-tty*): Remove, moved to frameset.el. + (desktop-save-frameset, desktop-restore-frameset): + Do not pass :filters argument. + + * frameset.el (frameset-live-filter-alist) + (frameset-persistent-filter-alist): New variables. + (frameset-filter-alist): Use them. Add autoload cookie. + (frameset-filter-tty-to-GUI): Move from desktop.el and rename. + (frameset--set-id, frameset--reuse-frame): Rename `frame-id' to + `frameset--id' (it's supposed to be internal to frameset.el). + (frameset--process-minibuffer-frames): Ditto. Doc fix. + (frameset--initial-params): New function. + (frameset--get-frame): Use it. Doc fix. + (frameset--move-onscreen): Accept new PRED value for FORCE-ONSCREEN. + Accept :all, not 'all. + (frameset-restore): Add new predicate values for FORCE-ONSCREEN and + FORCE-DISPLAY. Use :keywords for constant arguments to avoid collision + with fbound symbols. Fix frame id matching, and remove matching ids if + the frame being restored is deleted. Obey :delete. + 2013-08-04 Stefan Monnier * subr.el (macrop): New function. diff --git a/lisp/desktop.el b/lisp/desktop.el index 778c37484e1..ab78663c3d0 100644 --- a/lisp/desktop.el +++ b/lisp/desktop.el @@ -390,12 +390,12 @@ If `delete', frames on other displays are deleted instead of restored." (defcustom desktop-restore-forces-onscreen t "If t, offscreen frames are restored onscreen instead. -If `all', frames that are partially offscreen are also forced onscren. +If `:all', frames that are partially offscreen are also forced onscren. NOTE: Checking of frame boundaries is only approximate and can fail to reliably detect frames whose onscreen/offscreen state depends on a few pixels, especially near the right / bottom borders of the screen." :type '(choice (const :tag "Only fully offscreen frames" t) - (const :tag "Also partially offscreen frames" 'all) + (const :tag "Also partially offscreen frames" :all) (const :tag "Do not force frames onscreen" nil)) :group 'desktop :version "24.4") @@ -403,10 +403,10 @@ few pixels, especially near the right / bottom borders of the screen." (defcustom desktop-restore-reuses-frames t "If t, restoring frames reuses existing frames. If nil, existing frames are deleted. -If `keep', existing frames are kept and not reused." +If `:keep', existing frames are kept and not reused." :type '(choice (const :tag "Reuse existing frames" t) (const :tag "Delete existing frames" nil) - (const :tag "Keep existing frames" 'keep)) + (const :tag "Keep existing frames" :keep)) :group 'desktop :version "24.4") @@ -900,25 +900,6 @@ DIRNAME must be the directory in which the desktop file will be saved." ;; ---------------------------------------------------------------------------- -(defvar desktop-filter-parameters-alist - (append '((font-backend . t) - (name . t) - (outer-window-id . t) - (parent-id . t) - (tty . desktop--filter-tty*) - (tty-type . desktop--filter-tty*) - (window-id . t) - (window-system . t)) - frameset-filter-alist) - "Alist of frame parameters and filtering functions. -Its format is identical to `frameset-filter-alist' (which see).") - -(defun desktop--filter-tty* (_current parameters saving) - ;; Remove tty and tty-type parameters when switching - ;; to a GUI frame. - (or saving - (not (frameset-switch-to-gui-p parameters)))) - (defun desktop--check-dont-save (frame) (not (frame-parameter frame 'desktop-dont-save))) @@ -932,7 +913,6 @@ Frames with a non-nil `desktop-dont-save' parameter are not saved." (let ((name (concat user-login-name "@" system-name (format-time-string " %Y-%m-%d %T")))) (frameset-save nil - :filters desktop-filter-parameters-alist :predicate #'desktop--check-dont-save :properties (list :app desktop--app-id :name name)))))) @@ -1049,7 +1029,6 @@ This function depends on the value of `desktop-saved-frameset' being set (usually, by reading it from the desktop)." (when (desktop-restoring-frameset-p) (frameset-restore desktop-saved-frameset - :filters desktop-filter-parameters-alist :reuse-frames desktop-restore-reuses-frames :force-display desktop-restore-in-current-display :force-onscreen desktop-restore-forces-onscreen))) diff --git a/lisp/frameset.el b/lisp/frameset.el index 2a6a0d2dfb8..b24e4ed9362 100644 --- a/lisp/frameset.el +++ b/lisp/frameset.el @@ -46,16 +46,16 @@ ;; user-defined serializable data. Currently defined properties ;; include: ;; :version ID - Identifies the version of the frameset struct; -;; this is the only property always present and -;; must not be modified. +;; this is the only property always present and +;; must not be modified. ;; :app APPINFO - Freeform. Can be used by applications and -;; packages to indicate the intended (but by no -;; means exclusive) use of the frameset. For -;; example, currently desktop.el sets :app to -;; `(desktop . ,desktop-file-version). +;; packages to indicate the intended (but by no +;; means exclusive) use of the frameset. For +;; example, currently desktop.el sets :app to +;; `(desktop . ,desktop-file-version). ;; :name NAME - The name of the frameset instance; a string. ;; :desc TEXT - A description for user consumption (to choose -;; among framesets, etc.); a string. +;; among framesets, etc.); a string. ;; - states: an alist of items (FRAME-PARAMETERS . WINDOW-STATE) in ;; no particular order. Each item represents a frame to be ;; restored. @@ -98,46 +98,66 @@ Properties other than :version can be set with ;; Filtering -(defvar frameset-filter-alist - '((background-color . frameset-filter-sanitize-color) - (buffer-list . t) - (buffer-predicate . t) - (buried-buffer-list . t) - (font . frameset-filter-save-parm) - (foreground-color . frameset-filter-sanitize-color) - (fullscreen . frameset-filter-save-parm) - (GUI:font . frameset-filter-restore-parm) - (GUI:fullscreen . frameset-filter-restore-parm) - (GUI:height . frameset-filter-restore-parm) - (GUI:width . frameset-filter-restore-parm) - (height . frameset-filter-save-parm) - (left . frameset-filter-iconified) - (minibuffer . frameset-filter-minibuffer) - (top . frameset-filter-iconified) - (width . frameset-filter-save-parm)) +;;;###autoload +(defvar frameset-live-filter-alist + '((name . t) + (minibuffer . frameset-filter-minibuffer) + (top . frameset-filter-iconified)) + "Minimum set of parameters to filter for live (on-session) framesets. +See `frameset-filter-alist' for a full description.") + +;;;###autoload +(defvar frameset-persistent-filter-alist + (nconc + '((background-color . frameset-filter-sanitize-color) + (buffer-list . t) + (buffer-predicate . t) + (buried-buffer-list . t) + (font . frameset-filter-save-parm) + (foreground-color . frameset-filter-sanitize-color) + (fullscreen . frameset-filter-save-parm) + (GUI:font . frameset-filter-restore-parm) + (GUI:fullscreen . frameset-filter-restore-parm) + (GUI:height . frameset-filter-restore-parm) + (GUI:width . frameset-filter-restore-parm) + (height . frameset-filter-save-parm) + (left . frameset-filter-iconified) + (outer-window-id . t) + (parent-id . t) + (tty . frameset-filter-tty-to-GUI) + (tty-type . frameset-filter-tty-to-GUI) + (width . frameset-filter-save-parm) + (window-id . t) + (window-system . t)) + frameset-live-filter-alist) + "Recommended set of parameters to filter for persistent framesets. +See `frameset-filter-alist' for a full description.") + +;;;###autoload +(defvar frameset-filter-alist frameset-persistent-filter-alist "Alist of frame parameters and filtering functions. Each element is a cons (PARAM . ACTION), where PARAM is a parameter name (a symbol identifying a frame parameter), and ACTION can be: - t The parameter is always removed from the parameter list. - :save The parameter is removed when saving the frame. + t The parameter is always removed from the parameter list. + :save The parameter is removed when saving the frame. :restore The parameter is removed when restoring the frame. - FILTER A filter function. + FILTER A filter function. FILTER can be a symbol FILTER-FUN, or a list (FILTER-FUN ARGS...). It will be called with four arguments CURRENT, FILTERED, PARAMETERS and SAVING, plus any additional ARGS: CURRENT A cons (PARAM . VALUE), where PARAM is the one being - filtered and VALUE is its current value. + filtered and VALUE is its current value. FILTERED The alist of parameters filtered so far. PARAMETERS The complete alist of parameters being filtered, - SAVING Non-nil if filtering before saving state, nil otherwise. + SAVING Non-nil if filtering before saving state, nil otherwise. The FILTER-FUN function must return: - nil CURRENT is removed from the list. - t CURRENT is left as is. + nil CURRENT is removed from the list. + t CURRENT is left as is. (PARAM' . VALUE') Replace CURRENT with this. Frame parameters not on this list are passed intact.") @@ -156,9 +176,9 @@ Return t if PARAMETERS describes a text-only terminal and the target is a graphic display; otherwise return nil. Only meaningful when called from a filtering function in `frameset-filter-alist'." - (and frameset--target-display ; we're switching - (null (cdr (assq 'display parameters))) ; from a tty - (cdr frameset--target-display))) ; to a GUI display + (and frameset--target-display ; we're switching + (null (cdr (assq 'display parameters))) ; from a tty + (cdr frameset--target-display))) ; to a GUI display (defun frameset-switch-to-tty-p (parameters) "True when switching to a text-only terminal. @@ -167,9 +187,14 @@ the target is a text-only terminal; otherwise return nil. Only meaningful when called from a filtering function in `frameset-filter-alist'." (and frameset--target-display ; we're switching - (cdr (assq 'display parameters)) ; from a GUI display + (cdr (assq 'display parameters)) ; from a GUI display (null (cdr frameset--target-display)))) ; to a tty +(defun frameset-filter-tty-to-GUI (_current _filtered parameters saving) + "Remove CURRENT when switching from tty to a graphic display." + (or saving + (not (frameset-switch-to-gui-p parameters)))) + (defun frameset-filter-sanitize-color (current _filtered parameters saving) "When switching to a GUI frame, remove \"unspecified\" colors. Useful as a filter function for tty-specific parameters." @@ -223,12 +248,6 @@ meaningless in an iconified frame, so the frame is restored in a default position." (not (and saving (eq (cdr (assq 'visibility parameters)) 'icon)))) -(defun frameset-keep-original-display-p (force-display) - "True if saved frames' displays should be honored." - (cond ((daemonp) t) - ((eq system-type 'windows-nt) nil) - (t (null force-display)))) - (defun frameset-filter-params (parameters filter-alist saving) "Filter parameter list PARAMETERS and return a filtered list. FILTER-ALIST is an alist of parameter filters, in the format of @@ -265,18 +284,18 @@ nil while the filtering is done to restore it." ;; Saving framesets (defun frameset--set-id (frame) - "Set FRAME's `frame-id' if not yet set. + "Set FRAME's `frameset--id' if not yet set. Internal use only." - (unless (frame-parameter frame 'frame-id) + (unless (frame-parameter frame 'frameset--id) (set-frame-parameter frame - 'frame-id + 'frameset--id (mapconcat (lambda (n) (format "%04X" n)) (cl-loop repeat 4 collect (random 65536)) "-")))) (defun frameset--process-minibuffer-frames (frame-list) "Process FRAME-LIST and record minibuffer relationships. -FRAME-LIST is a list of frames." +FRAME-LIST is a list of frames. Internal use only." ;; Record frames with their own minibuffer (dolist (frame (minibuffer-frame-list)) (when (memq frame frame-list) @@ -292,12 +311,12 @@ FRAME-LIST is a list of frames." (unless (frame-parameter frame 'frameset--mini) (frameset--set-id frame) (let* ((mb-frame (window-frame (minibuffer-window frame))) - (id (and mb-frame (frame-parameter mb-frame 'frame-id)))) + (id (and mb-frame (frame-parameter mb-frame 'frameset--id)))) (if (null id) (error "Minibuffer frame %S for %S is excluded" mb-frame frame) ;; For minibufferless frames, frameset--mini is a cons - ;; (nil . FRAME-ID), where FRAME-ID is the frame-id of - ;; the frame containing its minibuffer window. + ;; (nil . FRAME-ID), where FRAME-ID is the frameset--id + ;; of the frame containing its minibuffer window. (set-frame-parameter frame 'frameset--mini (cons nil id))))))) @@ -345,26 +364,32 @@ When forced onscreen, frames wider than the monitor's workarea are converted to fullwidth, and frames taller than the workarea are converted to fullheight. NOTE: This only works for non-iconified frames. Internal use only." (pcase-let* ((`(,left ,top ,width ,height) (cl-cdadr (frame-monitor-attributes frame))) - (right (+ left width -1)) - (bottom (+ top height -1)) - (fr-left (frameset--compute-pos (frame-parameter frame 'left) left right)) - (fr-top (frameset--compute-pos (frame-parameter frame 'top) top bottom)) + (right (+ left width -1)) + (bottom (+ top height -1)) + (fr-left (frameset--compute-pos (frame-parameter frame 'left) left right)) + (fr-top (frameset--compute-pos (frame-parameter frame 'top) top bottom)) (ch-width (frame-char-width frame)) (ch-height (frame-char-height frame)) - (fr-width (max (frame-pixel-width frame) (* ch-width (frame-width frame)))) - (fr-height (max (frame-pixel-height frame) (* ch-height (frame-height frame)))) - (fr-right (+ fr-left fr-width -1)) - (fr-bottom (+ fr-top fr-height -1))) + (fr-width (max (frame-pixel-width frame) (* ch-width (frame-width frame)))) + (fr-height (max (frame-pixel-height frame) (* ch-height (frame-height frame)))) + (fr-right (+ fr-left fr-width -1)) + (fr-bottom (+ fr-top fr-height -1))) (when (pcase force-onscreen + ;; A predicate. + ((pred functionp) + (funcall force-onscreen + frame + (list fr-left fr-top fr-width fr-height) + (list left top width height))) ;; Any corner is outside the screen. - (`all (or (< fr-bottom top) (> fr-bottom bottom) + (:all (or (< fr-bottom top) (> fr-bottom bottom) (< fr-left left) (> fr-left right) (< fr-right left) (> fr-right right) - (< fr-top top) (> fr-top bottom))) + (< fr-top top) (> fr-top bottom))) ;; Displaced to the left, right, above or below the screen. - (`t (or (> fr-left right) + (`t (or (> fr-left right) (< fr-right left) - (> fr-top bottom) + (> fr-top bottom) (< fr-bottom top))) ;; Fully inside, no need to do anything. (_ nil)) @@ -430,8 +455,8 @@ is the parameter list of the frame being restored. Internal use only." ;; M-x desktop-read). (setq frame (frameset--find-frame (lambda (f id) - (string= (frame-parameter f 'frame-id) id)) - display (cdr (assq 'frame-id frame-cfg)))) + (string= (frame-parameter f 'frameset--id) id)) + display (cdr (assq 'frameset--id frame-cfg)))) ;; If it has not been loaded, and it is not a minibuffer-only frame, ;; let's look for an existing non-minibuffer-only frame to reuse. (unless (or frame (eq (cdr (assq 'minibuffer frame-cfg)) 'only)) @@ -447,11 +472,11 @@ is the parameter list of the frame being restored. Internal use only." ;; and that they are linked to the right minibuffer frame. (setq frame (frameset--find-frame (lambda (f id mini-id) - (and (string= (frame-parameter f 'frame-id) id) + (and (string= (frame-parameter f 'frameset--id) id) (string= (frame-parameter (window-frame (minibuffer-window f)) - 'frame-id) + 'frameset--id) mini-id))) - display (cdr (assq 'frame-id frame-cfg)) (cdr mini)))) + display (cdr (assq 'frameset--id frame-cfg)) (cdr mini)))) (t ;; Default to just finding a frame in the same display. (setq frame (frameset--find-frame nil display)))) @@ -460,11 +485,21 @@ is the parameter list of the frame being restored. Internal use only." (setq frameset--reuse-list (delq frame frameset--reuse-list))) frame)) +(defun frameset--initial-params (frame-cfg) + "Return parameters from FRAME-CFG that should not be changed later. +Setting position and size parameters as soon as possible helps reducing +flickering; other parameters, like `minibuffer' and `border-width', must +be set when creating the frame because they can not be changed later. +Internal use only." + (cl-loop for param in '(left top with height border-width minibuffer) + collect (assq param frame-cfg))) + (defun frameset--get-frame (frame-cfg window-cfg filters force-onscreen) "Set up and return a frame according to its saved state. That means either reusing an existing frame or creating one anew. FRAME-CFG is the frame's parameter list; WINDOW-CFG is its window state. -For the meaning of FORCE-ONSCREEN, see `frameset-restore'." +For the meaning of FORCE-ONSCREEN, see `frameset-restore'. +Internal use only." (let* ((fullscreen (cdr (assq 'fullscreen frame-cfg))) (lines (assq 'tool-bar-lines frame-cfg)) (filtered-cfg (frameset-filter-params frame-cfg filters nil)) @@ -507,9 +542,7 @@ For the meaning of FORCE-ONSCREEN, see `frameset-restore'." (frameset--reuse-frame display filtered-cfg)) (make-frame-on-display display (cons '(visibility) - (cl-loop - for param in '(left top width height minibuffer) - collect (assq param filtered-cfg)))))) + (frameset--initial-params filtered-cfg))))) (modify-frame-parameters frame (if (eq (frame-parameter frame 'fullscreen) fullscreen) ;; Workaround for bug#14949 @@ -541,6 +574,12 @@ It sorts minibuffer-owning frames before minibufferless ones." ((eq hasmini1 nil) (string< id-def1 id-def2)) (t t)))) +(defun frameset-keep-original-display-p (force-display) + "True if saved frames' displays should be honored." + (cond ((daemonp) t) + ((eq system-type 'windows-nt) nil) + (t (not force-display)))) + (defun frameset-sort-frames-for-deletion (frame1 _frame2) "Predicate to sort live frames for deletion. Minibufferless frames must go first to avoid errors when attempting @@ -548,42 +587,53 @@ to delete a frame whose minibuffer window is used by another frame." (not (frame-parameter frame1 'minibuffer))) ;;;###autoload -(cl-defun frameset-restore (frameset &key filters reuse-frames force-display force-onscreen) +(cl-defun frameset-restore (frameset + &key filters reuse-frames force-display force-onscreen) "Restore a FRAMESET into the current display(s). FILTERS is an alist of parameter filters; defaults to `frameset-filter-alist'. REUSE-FRAMES describes how to reuse existing frames while restoring a frameset: - t Reuse any existing frame if possible; delete leftover frames. - nil Restore frameset in new frames and delete existing frames. - keep Restore frameset in new frames and keep the existing ones. - LIST A list of frames to reuse; only these will be reused, if possible, - and any leftover one will be deleted; other frames not on this - list will be kept. + t Reuse any existing frame if possible; delete leftover frames. + nil Restore frameset in new frames and delete existing frames. + :keep Restore frameset in new frames and keep the existing ones. + LIST A list of frames to reuse; only these will be reused, if possible, + and any leftover one will be deleted; other frames not on this + list will be kept. FORCE-DISPLAY can be: - t Frames will be restored in the current display. - nil Frames will be restored, if possible, in their original displays. - delete Frames in other displays will be deleted instead of restored. + t Frames will be restored in the current display. + nil Frames will be restored, if possible, in their original displays. + :delete Frames in other displays will be deleted instead of restored. + PRED A function which will be called with one argument, the parameter + list, and must return t, nil or `:delete', as above but affecting + only the frame that will be created from that parameter list. FORCE-ONSCREEN can be: - all Force onscreen any frame fully or partially offscreen. - t Force onscreen only those frames that are fully offscreen. - nil Do not force any frame back onscreen. + :all Force onscreen any frame fully or partially offscreen. + t Force onscreen only those frames that are fully offscreen. + nil Do not force any frame back onscreen. + PRED A function which will be called with three arguments, + - the live frame just restored, + - a list (LEFT TOP WIDTH HEIGHT), describing the frame, + - a list (LEFT TOP WIDTH HEIGHT), describing the workarea, + and must return non-nil to force the frame onscreen, nil otherwise. + +Note the timing and scope of the operations described above: REUSE-FRAMES +affects existing frames, FILTERS and FORCE-DISPLAY affect the frame being +restored before that happens, and FORCE-ONSCREEN affects the frame once +it has been restored. All keywords default to nil." (cl-assert (frameset-p frameset)) - (let* ((delete-saved (eq force-display 'delete)) - (forcing (not (frameset-keep-original-display-p force-display))) - (target (and forcing (cons 'display (frame-parameter nil 'display)))) - other-frames) + (let (other-frames) ;; frameset--reuse-list is a list of frames potentially reusable. Later we ;; will decide which ones can be reused, and how to deal with any leftover. (pcase reuse-frames - ((or `nil `keep) + ((or `nil `:keep) (setq frameset--reuse-list nil other-frames (frame-list))) ((pred consp) @@ -604,35 +654,40 @@ All keywords default to nil." ((and d-mini `(,hasmini . ,mb-id)) (cdr (assq 'frameset--mini frame-cfg))) (default (and (booleanp mb-id) mb-id)) + (force-display (if (functionp force-display) + (funcall force-display frame-cfg) + force-display)) (frame nil) (to-tty nil)) ;; Only set target if forcing displays and the target display is different. - (if (or (not forcing) - (equal target (or (assq 'display frame-cfg) '(display . nil)))) - (setq frameset--target-display nil) - (setq frameset--target-display target - to-tty (null (cdr target)))) - ;; If keeping non-reusable frames, and the frame-id of one of them - ;; matches the frame-id of a frame being restored (because, for example, - ;; the frameset has already been read in the same session), remove the - ;; frame-id from the non-reusable frame, which is not useful anymore. - (when (and other-frames - (or (eq reuse-frames 'keep) (consp reuse-frames))) - (let ((dup (cl-find (cdr (assq 'frameset-frame-id frame-cfg)) - other-frames - :key (lambda (frame) - (frame-parameter frame 'frameset-frame-id)) - :test #'string=))) - (when dup - (set-frame-parameter dup 'frameset-frame-id nil)))) + (cond ((frameset-keep-original-display-p force-display) + (setq frameset--target-display nil)) + ((eq (frame-parameter nil 'display) (cdr (assq 'display frame-cfg))) + (setq frameset--target-display nil)) + (t + (setq frameset--target-display (cons 'display + (frame-parameter nil 'display)) + to-tty (null (cdr frameset--target-display))))) ;; Time to restore frames and set up their minibuffers as they were. ;; We only skip a frame (thus deleting it) if either: ;; - we're switching displays, and the user chose the option to delete, or ;; - we're switching to tty, and the frame to restore is minibuffer-only. (unless (and frameset--target-display - (or delete-saved + (or (eq force-display :delete) (and to-tty (eq (cdr (assq 'minibuffer frame-cfg)) 'only)))) - + ;; If keeping non-reusable frames, and the frameset--id of one of them + ;; matches the id of a frame being restored (because, for example, the + ;; frameset has already been read in the same session), remove the + ;; frameset--id from the non-reusable frame, which is not useful anymore. + (when (and other-frames + (or (eq reuse-frames :keep) (consp reuse-frames))) + (let ((dup (cl-find (cdr (assq 'frameset--id frame-cfg)) + other-frames + :key (lambda (frame) + (frame-parameter frame 'frameset--id)) + :test #'string=))) + (when dup + (set-frame-parameter dup 'frameset--id nil)))) ;; Restore minibuffers. Some of this stuff could be done in a filter ;; function, but it would be messy because restoring minibuffers affects ;; global state; it's best to do it here than add a bunch of global @@ -647,7 +702,7 @@ All keywords default to nil." (t ;; Frame depends on other frame's minibuffer window. (let* ((mb-frame (or (cl-find-if (lambda (f) - (string= (frame-parameter f 'frame-id) + (string= (frame-parameter f 'frameset--id) mb-id)) (frame-list)) (error "Minibuffer frame %S not found" mb-id))) @@ -658,14 +713,14 @@ All keywords default to nil." (error "Not a minibuffer window %s" mb-window)) (if mb-param (setcdr mb-param mb-window) - (push (cons 'minibuffer mb-window) frame-cfg)))))) - ;; OK, we're ready at last to create (or reuse) a frame and - ;; restore the window config. - (setq frame (frameset--get-frame frame-cfg window-cfg - (or filters frameset-filter-alist) - force-onscreen)) - ;; Set default-minibuffer if required. - (when default (setq default-minibuffer-frame frame))) + (push (cons 'minibuffer mb-window) frame-cfg))))) + ;; OK, we're ready at last to create (or reuse) a frame and + ;; restore the window config. + (setq frame (frameset--get-frame frame-cfg window-cfg + (or filters frameset-filter-alist) + force-onscreen)) + ;; Set default-minibuffer if required. + (when default (setq default-minibuffer-frame frame)))) (error (delay-warning 'frameset (error-message-string err) :error)))) @@ -674,7 +729,7 @@ All keywords default to nil." (sit-for 0 t) ;; Delete remaining frames, but do not fail if some resist being deleted. - (unless (eq reuse-frames 'keep) + (unless (eq reuse-frames :keep) (dolist (frame (sort (nconc (if (listp reuse-frames) nil other-frames) frameset--reuse-list) #'frameset-sort-frames-for-deletion)) From 3e2cd454fdc04a1afefa23cdfe241c11862eaa8d Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Sun, 4 Aug 2013 18:32:00 -0700 Subject: [PATCH 017/449] Extract truncate-string-to-width tests to a separate file * test/automated/mule-util.el: New file, with tests extracted from lisp/international/mule-util.el. Copyright years based on when the original test-suite comment was added to lisp/international/mule-util.el (in 2002). * lisp/international/mule-util.el: Extract comment test-suite out to separate file. --- lisp/international/mule-util.el | 53 --------------------- test/ChangeLog | 5 ++ test/automated/mule-util.el | 84 +++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 53 deletions(-) create mode 100644 test/automated/mule-util.el diff --git a/lisp/international/mule-util.el b/lisp/international/mule-util.el index 15a7dc10f65..21e09593187 100644 --- a/lisp/international/mule-util.el +++ b/lisp/international/mule-util.el @@ -125,59 +125,6 @@ defaults to \"...\"." (concat head-padding (substring str from-idx idx) tail-padding ellipsis)))) -;;; Test suite for truncate-string-to-width -;; (dolist (test '((("" 0) . "") -;; (("x" 1) . "x") -;; (("xy" 1) . "x") -;; (("xy" 2 1) . "y") -;; (("xy" 0) . "") -;; (("xy" 3) . "xy") -;; (("中" 0) . "") -;; (("中" 1) . "") -;; (("中" 2) . "中") -;; (("中" 1 nil ? ) . " ") -;; (("中文" 3 1 ? ) . " ") -;; (("x中x" 2) . "x") -;; (("x中x" 3) . "x中") -;; (("x中x" 3) . "x中") -;; (("x中x" 4 1) . "中x") -;; (("kor한e글an" 8 1 ? ) . "or한e글") -;; (("kor한e글an" 7 2 ? ) . "r한e ") -;; (("" 0 nil nil "...") . "") -;; (("x" 3 nil nil "...") . "x") -;; (("中" 3 nil nil "...") . "中") -;; (("foo" 3 nil nil "...") . "foo") -;; (("foo" 2 nil nil "...") . "fo") ;; XEmacs failure? -;; (("foobar" 6 0 nil "...") . "foobar") -;; (("foobarbaz" 6 nil nil "...") . "foo...") -;; (("foobarbaz" 7 2 nil "...") . "ob...") -;; (("foobarbaz" 9 3 nil "...") . "barbaz") -;; (("こhんeにlちlはo" 15 1 ? t) . " hんeにlちlはo") -;; (("こhんeにlちlはo" 14 1 ? t) . " hんeにlち...") -;; (("x" 3 nil nil "粵語") . "x") -;; (("中" 2 nil nil "粵語") . "中") -;; (("中" 1 nil ?x "粵語") . "x") ;; XEmacs error -;; (("中文" 3 nil ? "粵語") . "中 ") ;; XEmacs error -;; (("foobarbaz" 4 nil nil "粵語") . "粵語") -;; (("foobarbaz" 5 nil nil "粵語") . "f粵語") -;; (("foobarbaz" 6 nil nil "粵語") . "fo粵語") -;; (("foobarbaz" 8 3 nil "粵語") . "b粵語") -;; (("こhんeにlちlはo" 14 4 ?x "日本語") . "xeに日本語") -;; (("こhんeにlちlはo" 13 4 ?x "日本語") . "xex日本語") -;; )) -;; (let (ret) -;; (condition-case e -;; (setq ret (apply #'truncate-string-to-width (car test))) -;; (error (setq ret e))) -;; (unless (equal ret (cdr test)) -;; (error "%s: expected %s, got %s" -;; (prin1-to-string (cons 'truncate-string-to-width (car test))) -;; (prin1-to-string (cdr test)) -;; (if (consp ret) -;; (format "error: %s: %s" (car ret) -;; (prin1-to-string (cdr ret))) -;; (prin1-to-string ret)))))) - ;;; Nested alist handler. Nested alist is alist whose elements are ;;; also nested alist. diff --git a/test/ChangeLog b/test/ChangeLog index d744a5c788d..2e4d19e7a36 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,8 @@ +2013-08-05 Glenn Morris + + * automated/mule-util.el: New file, with tests extracted from + lisp/international/mule-util.el. + 2013-08-04 Stefan Monnier * automated/advice-tests.el (advice-tests-nadvice): Test removal diff --git a/test/automated/mule-util.el b/test/automated/mule-util.el new file mode 100644 index 00000000000..3e269faad75 --- /dev/null +++ b/test/automated/mule-util.el @@ -0,0 +1,84 @@ +;;; mule-util --- tests for international/mule-util.el -*- coding: utf-8; -*- + +;; Copyright (C) 2002-2013 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;;; Code: + +(require 'ert) +(require 'mule-util) + +(defconst mule-util-test-truncate-data + '((("" 0) . "") + (("x" 1) . "x") + (("xy" 1) . "x") + (("xy" 2 1) . "y") + (("xy" 0) . "") + (("xy" 3) . "xy") + (("中" 0) . "") + (("中" 1) . "") + (("中" 2) . "中") + (("中" 1 nil ? ) . " ") + (("中文" 3 1 ? ) . " ") + (("x中x" 2) . "x") + (("x中x" 3) . "x中") + (("x中x" 3) . "x中") + (("x中x" 4 1) . "中x") + (("kor한e글an" 8 1 ? ) . "or한e글") + (("kor한e글an" 7 2 ? ) . "r한e ") + (("" 0 nil nil "...") . "") + (("x" 3 nil nil "...") . "x") + (("中" 3 nil nil "...") . "中") + (("foo" 3 nil nil "...") . "foo") + (("foo" 2 nil nil "...") . "fo") ;; XEmacs failure? + (("foobar" 6 0 nil "...") . "foobar") + (("foobarbaz" 6 nil nil "...") . "foo...") + (("foobarbaz" 7 2 nil "...") . "ob...") + (("foobarbaz" 9 3 nil "...") . "barbaz") + (("こhんeにlちlはo" 15 1 ? t) . " hんeにlちlはo") + (("こhんeにlちlはo" 14 1 ? t) . " hんeにlち...") + (("x" 3 nil nil "粵語") . "x") + (("中" 2 nil nil "粵語") . "中") + (("中" 1 nil ?x "粵語") . "x") ;; XEmacs error + (("中文" 3 nil ? "粵語") . "中 ") ;; XEmacs error + (("foobarbaz" 4 nil nil "粵語") . "粵語") + (("foobarbaz" 5 nil nil "粵語") . "f粵語") + (("foobarbaz" 6 nil nil "粵語") . "fo粵語") + (("foobarbaz" 8 3 nil "粵語") . "b粵語") + (("こhんeにlちlはo" 14 4 ?x "日本語") . "xeに日本語") + (("こhんeにlちlはo" 13 4 ?x "日本語") . "xex日本語") + ) + "Test data for `truncate-string-to-width'.") + +(defun mule-util-test-truncate-create (n) + "Create a test for element N of the `mule-util-test-truncate-data' constant." + (let ((testname (intern (format "mule-util-test-truncate-%.2d" n))) + (testdoc (format "Test element %d of `mule-util-test-truncate-data'." + n)) + (testdata (nth n mule-util-test-truncate-data))) + (eval + `(ert-deftest ,testname () + ,testdoc + (should (equal (apply 'truncate-string-to-width ',(car testdata)) + ,(cdr testdata))))))) + +(dotimes (i (length mule-util-test-truncate-data)) + (mule-util-test-truncate-create i)) + +;;; mule-util.el ends here From 8f3a2c2659ddee1ae84b4b8bb28f6c388f87fd0f Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Mon, 5 Aug 2013 08:14:43 +0400 Subject: [PATCH 018/449] New macro to iterate over live buffers similar to frames. * buffer.h (FOR_EACH_LIVE_BUFFER): New macro. (Vbuffer_alist, Qpriority, Qbefore_string, Qafter_string): Declare buffer-related variables here to offload lisp.h. * buffer.c (Vbuffer_alist): Adjust comment. (Fget_file_buffer, get_truename_buffer, Fother_buffer) (other_buffer_safely): * data.c (store_symval_forwarding): * dispnew.c (Fframe_or_buffer_changed_p): * fileio.c (Fdo_auto_save): * filelock.c (unlock_all_files): * minibuf.c (read_minibuf): Use FOR_EACH_LIVE_BUFFER. --- src/ChangeLog | 15 +++++++++++++++ src/buffer.c | 38 +++++++++++++------------------------- src/buffer.h | 10 ++++++++++ src/data.c | 11 +++-------- src/dispnew.c | 8 +++----- src/fileio.c | 3 +-- src/filelock.c | 13 ++++++------- src/lisp.h | 3 +-- src/minibuf.c | 23 ++++++++--------------- 9 files changed, 60 insertions(+), 64 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index f8f2fa47089..a0a31f0bf3c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,18 @@ +2013-08-05 Dmitry Antipov + + New macro to iterate over live buffers similar to frames. + * buffer.h (FOR_EACH_LIVE_BUFFER): New macro. + (Vbuffer_alist, Qpriority, Qbefore_string, Qafter_string): + Declare buffer-related variables here to offload lisp.h. + * buffer.c (Vbuffer_alist): Adjust comment. + (Fget_file_buffer, get_truename_buffer, Fother_buffer) + (other_buffer_safely): + * data.c (store_symval_forwarding): + * dispnew.c (Fframe_or_buffer_changed_p): + * fileio.c (Fdo_auto_save): + * filelock.c (unlock_all_files): + * minibuf.c (read_minibuf): Use FOR_EACH_LIVE_BUFFER. + 2013-08-04 Paul Eggert Fix some minor races in hosts lacking mkostemp (Bug#15015). diff --git a/src/buffer.c b/src/buffer.c index dfc6b8bcc02..f9154d42b03 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -108,9 +108,9 @@ static void call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, static void swap_out_buffer_local_variables (struct buffer *b); static void reset_buffer_local_variables (struct buffer *, bool); -/* Alist of all buffer names vs the buffers. */ -/* This used to be a variable, but is no longer, - to prevent lossage due to user rplac'ing this alist or its elements. */ +/* Alist of all buffer names vs the buffers. This used to be + a Lisp-visible variable, but is no longer, to prevent lossage + due to user rplac'ing this alist or its elements. */ Lisp_Object Vbuffer_alist; static Lisp_Object Qkill_buffer_query_functions; @@ -478,8 +478,7 @@ If there is no such live buffer, return nil. See also `find-buffer-visiting'. */) (register Lisp_Object filename) { - register Lisp_Object tail, buf, tem; - Lisp_Object handler; + register Lisp_Object tail, buf, handler; CHECK_STRING (filename); filename = Fexpand_file_name (filename, Qnil); @@ -494,13 +493,10 @@ See also `find-buffer-visiting'. */) return BUFFERP (handled_buf) ? handled_buf : Qnil; } - for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) + FOR_EACH_LIVE_BUFFER (tail, buf) { - buf = Fcdr (XCAR (tail)); - if (!BUFFERP (buf)) continue; if (!STRINGP (BVAR (XBUFFER (buf), filename))) continue; - tem = Fstring_equal (BVAR (XBUFFER (buf), filename), filename); - if (!NILP (tem)) + if (!NILP (Fstring_equal (BVAR (XBUFFER (buf), filename), filename))) return buf; } return Qnil; @@ -509,15 +505,12 @@ See also `find-buffer-visiting'. */) Lisp_Object get_truename_buffer (register Lisp_Object filename) { - register Lisp_Object tail, buf, tem; + register Lisp_Object tail, buf; - for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) + FOR_EACH_LIVE_BUFFER (tail, buf) { - buf = Fcdr (XCAR (tail)); - if (!BUFFERP (buf)) continue; if (!STRINGP (BVAR (XBUFFER (buf), file_truename))) continue; - tem = Fstring_equal (BVAR (XBUFFER (buf), file_truename), filename); - if (!NILP (tem)) + if (!NILP (Fstring_equal (BVAR (XBUFFER (buf), file_truename), filename))) return buf; } return Qnil; @@ -1581,10 +1574,8 @@ exists, return the buffer `*scratch*' (creating it if necessary). */) } /* Consider alist of all buffers next. */ - tail = Vbuffer_alist; - for (; CONSP (tail); tail = XCDR (tail)) + FOR_EACH_LIVE_BUFFER (tail, buf) { - buf = Fcdr (XCAR (tail)); if (candidate_buffer (buf, buffer) /* If the frame has a buffer_predicate, disregard buffers that don't fit the predicate. */ @@ -1621,12 +1612,9 @@ other_buffer_safely (Lisp_Object buffer) { Lisp_Object tail, buf; - for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) - { - buf = Fcdr (XCAR (tail)); - if (candidate_buffer (buf, buffer)) - return buf; - } + FOR_EACH_LIVE_BUFFER (tail, buf) + if (candidate_buffer (buf, buffer)) + return buf; buf = Fget_buffer (build_string ("*scratch*")); if (NILP (buf)) diff --git a/src/buffer.h b/src/buffer.h index 641a561cafc..646f8f72232 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -1120,9 +1120,19 @@ record_unwind_current_buffer (void) } \ } while (0) +extern Lisp_Object Vbuffer_alist; extern Lisp_Object Qbefore_change_functions; extern Lisp_Object Qafter_change_functions; extern Lisp_Object Qfirst_change_hook; +extern Lisp_Object Qpriority, Qbefore_string, Qafter_string; + +/* FOR_EACH_LIVE_BUFFER (LIST_VAR, BUF_VAR) followed by a statement is + a `for' loop which iterates over the buffers from Vbuffer_alist. */ + +#define FOR_EACH_LIVE_BUFFER(list_var, buf_var) \ + for (list_var = Vbuffer_alist; \ + (CONSP (list_var) && (buf_var = XCDR (XCAR (list_var)), 1)); \ + list_var = XCDR (list_var)) /* Get text properties of B. */ diff --git a/src/data.c b/src/data.c index d1e43ac1b5f..ef3a6965779 100644 --- a/src/data.c +++ b/src/data.c @@ -981,19 +981,14 @@ store_symval_forwarding (union Lisp_Fwd *valcontents, register Lisp_Object newva - (char *) &buffer_defaults); int idx = PER_BUFFER_IDX (offset); - Lisp_Object tail; + Lisp_Object tail, buf; if (idx <= 0) break; - for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) + FOR_EACH_LIVE_BUFFER (tail, buf) { - Lisp_Object lbuf; - struct buffer *b; - - lbuf = Fcdr (XCAR (tail)); - if (!BUFFERP (lbuf)) continue; - b = XBUFFER (lbuf); + struct buffer *b = XBUFFER (buf); if (! PER_BUFFER_VALUE_P (b, idx)) set_per_buffer_value (b, offset, newval); diff --git a/src/dispnew.c b/src/dispnew.c index c69f4b3bed5..2708252aa8a 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -5895,9 +5895,8 @@ pass nil for VARIABLE. */) goto changed; } /* Check that the buffer info matches. */ - for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) + FOR_EACH_LIVE_BUFFER (tail, buf) { - buf = XCDR (XCAR (tail)); /* Ignore buffers that aren't included in buffer lists. */ if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ') continue; @@ -5927,7 +5926,7 @@ pass nil for VARIABLE. */) n = 1; FOR_EACH_FRAME (tail, frame) n += 2; - for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) + FOR_EACH_LIVE_BUFFER (tail, buf) n += 3; /* Reallocate the vector if data has grown to need it, or if it has shrunk a lot. */ @@ -5952,9 +5951,8 @@ pass nil for VARIABLE. */) ASET (state, idx, XFRAME (frame)->name); idx++; } - for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) + FOR_EACH_LIVE_BUFFER (tail, buf) { - buf = XCDR (XCAR (tail)); /* Ignore buffers that aren't included in buffer lists. */ if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ') continue; diff --git a/src/fileio.c b/src/fileio.c index 59e84053773..6b24e592bb3 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -5618,9 +5618,8 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */) couldn't handle some ange-ftp'd file. */ for (do_handled_files = 0; do_handled_files < 2; do_handled_files++) - for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) + FOR_EACH_LIVE_BUFFER (tail, buf) { - buf = XCDR (XCAR (tail)); b = XBUFFER (buf); /* Record all the buffers that have auto save mode diff --git a/src/filelock.c b/src/filelock.c index 0f31b7d4deb..cb0bd5c7b96 100644 --- a/src/filelock.c +++ b/src/filelock.c @@ -745,16 +745,15 @@ unlock_file (Lisp_Object fn) void unlock_all_files (void) { - register Lisp_Object tail; + register Lisp_Object tail, buf; register struct buffer *b; - for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) + FOR_EACH_LIVE_BUFFER (tail, buf) { - b = XBUFFER (XCDR (XCAR (tail))); - if (STRINGP (BVAR (b, file_truename)) && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) - { - unlock_file (BVAR (b, file_truename)); - } + b = XBUFFER (buf); + if (STRINGP (BVAR (b, file_truename)) + && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) + unlock_file (BVAR (b, file_truename)); } } diff --git a/src/lisp.h b/src/lisp.h index 5daddb7d335..085acb54348 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -734,6 +734,7 @@ extern Lisp_Object Qarrayp, Qbufferp, Qbuffer_or_string_p, Qchar_table_p; extern Lisp_Object Qconsp, Qfloatp, Qintegerp, Qlambda, Qlistp, Qmarkerp, Qnil; extern Lisp_Object Qnumberp, Qstringp, Qsymbolp, Qvectorp; extern Lisp_Object Qvector_or_char_table_p, Qwholenump; +extern Lisp_Object Qwindow; extern Lisp_Object Ffboundp (Lisp_Object); extern _Noreturn Lisp_Object wrong_type_argument (Lisp_Object, Lisp_Object); @@ -3797,9 +3798,7 @@ extern void fix_start_end_in_overlays (ptrdiff_t, ptrdiff_t); extern void report_overlay_modification (Lisp_Object, Lisp_Object, bool, Lisp_Object, Lisp_Object, Lisp_Object); extern bool overlay_touches_p (ptrdiff_t); -extern Lisp_Object Vbuffer_alist; extern Lisp_Object other_buffer_safely (Lisp_Object); -extern Lisp_Object Qpriority, Qwindow, Qbefore_string, Qafter_string; extern Lisp_Object get_truename_buffer (Lisp_Object); extern void init_buffer_once (void); extern void init_buffer (void); diff --git a/src/minibuf.c b/src/minibuf.c index 2c33b83c11b..b3648b8c1ae 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -568,22 +568,15 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, bset_directory (current_buffer, ambient_dir); else { - Lisp_Object buf_list; + Lisp_Object tail, buf; - for (buf_list = Vbuffer_alist; - CONSP (buf_list); - buf_list = XCDR (buf_list)) - { - Lisp_Object other_buf; - - other_buf = XCDR (XCAR (buf_list)); - if (STRINGP (BVAR (XBUFFER (other_buf), directory))) - { - bset_directory (current_buffer, - BVAR (XBUFFER (other_buf), directory)); - break; - } - } + FOR_EACH_LIVE_BUFFER (tail, buf) + if (STRINGP (BVAR (XBUFFER (buf), directory))) + { + bset_directory (current_buffer, + BVAR (XBUFFER (buf), directory)); + break; + } } if (!EQ (mini_frame, selected_frame)) From 063233c357f823efc7abd61469725a42da90a1a6 Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Mon, 5 Aug 2013 06:45:17 +0200 Subject: [PATCH 019/449] * lisp/frameset.el: Miscellaneous cleanups. (frameset): Add docstring. Move :version property to its own `version' slot. (frameset-copy): Rename from copy-frameset. (frameset-p): Check more thoroughly. (frameset-prop): Do not check for :version, which is no longer a prop. (frameset-live-filter-alist, frameset-persistent-filter-alist): Use new :never value instead of t. (frameset-filter-alist): Expand and clarify docstring. (frameset-filter-tty-to-GUI, frameset-filter-sanitize-color) (frameset-filter-minibuffer, frameset-filter-save-param) (frameset-filter-restore-param, frameset-filter-iconified): Add pointer to docstring of frameset-filter-alist. (frameset-filter-params): Rename filter values to be more meaningful: :never instead of t, and reverse the meanings of :save and :restore. (frameset--process-minibuffer-frames): Clarify error message. (frameset-save): Avoid unnecessary and confusing call to framep. Use new BOA constructor for framesets. (frameset--reuse-list): Doc fix. (frameset--restore-frame): Rename from frameset--get-frame. Doc fix. (frameset--minibufferless-last-p): Rename from frameset--sort-states. (frameset-minibufferless-first-p): Doc fix. Rename from frameset-sort-frames-for-deletion. (frameset-restore): Doc fixes. Use new function names. Most changes suggested by Drew Adams . * lisp/desktop.el (desktop-clear): Use new name of sort predicate. --- lisp/ChangeLog | 29 +++++ lisp/desktop.el | 2 +- lisp/frameset.el | 290 ++++++++++++++++++++++++++++------------------- 3 files changed, 206 insertions(+), 115 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index de1da73bbb1..0c4240c9075 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,32 @@ +2013-08-05 Juanma Barranquero + + * desktop.el (desktop-clear): Use new name of sort predicate. + + * frameset.el (frameset): Add docstring. Move :version property to its + own `version' slot. + (frameset-copy): Rename from copy-frameset. + (frameset-p): Check more thoroughly. + (frameset-prop): Do not check for :version, which is no longer a prop. + (frameset-live-filter-alist, frameset-persistent-filter-alist): + Use new :never value instead of t. + (frameset-filter-alist): Expand and clarify docstring. + (frameset-filter-tty-to-GUI, frameset-filter-sanitize-color) + (frameset-filter-minibuffer, frameset-filter-save-param) + (frameset-filter-restore-param, frameset-filter-iconified): + Add pointer to docstring of frameset-filter-alist. + (frameset-filter-params): Rename filter values to be more meaningful: + :never instead of t, and reverse the meanings of :save and :restore. + (frameset--process-minibuffer-frames): Clarify error message. + (frameset-save): Avoid unnecessary and confusing call to framep. + Use new BOA constructor for framesets. + (frameset--reuse-list): Doc fix. + (frameset--restore-frame): Rename from frameset--get-frame. Doc fix. + (frameset--minibufferless-last-p): Rename from frameset--sort-states. + (frameset-minibufferless-first-p): Doc fix. + Rename from frameset-sort-frames-for-deletion. + (frameset-restore): Doc fixes. Use new function names. + Most changes suggested by Drew Adams . + 2013-08-04 Juanma Barranquero * desktop.el (desktop-restore-forces-onscreen) diff --git a/lisp/desktop.el b/lisp/desktop.el index ab78663c3d0..76aa30e4090 100644 --- a/lisp/desktop.el +++ b/lisp/desktop.el @@ -671,7 +671,7 @@ if different)." (called-interactively-p 'any)) (let* ((this (selected-frame)) (mini (window-frame (minibuffer-window this)))) ; in case they difer - (dolist (frame (sort (frame-list) #'frameset-sort-frames-for-deletion)) + (dolist (frame (sort (frame-list) #'frameset-minibufferless-first-p)) (condition-case err (unless (or (eq frame this) (eq frame mini) diff --git a/lisp/frameset.el b/lisp/frameset.el index b24e4ed9362..c22d71b7d79 100644 --- a/lisp/frameset.el +++ b/lisp/frameset.el @@ -41,48 +41,77 @@ (require 'cl-lib) -;; Framesets have two fields: -;; - properties: a property list to store both frameset-specific and -;; user-defined serializable data. Currently defined properties -;; include: -;; :version ID - Identifies the version of the frameset struct; -;; this is the only property always present and -;; must not be modified. -;; :app APPINFO - Freeform. Can be used by applications and -;; packages to indicate the intended (but by no -;; means exclusive) use of the frameset. For -;; example, currently desktop.el sets :app to -;; `(desktop . ,desktop-file-version). -;; :name NAME - The name of the frameset instance; a string. -;; :desc TEXT - A description for user consumption (to choose -;; among framesets, etc.); a string. -;; - states: an alist of items (FRAME-PARAMETERS . WINDOW-STATE) in -;; no particular order. Each item represents a frame to be -;; restored. - (cl-defstruct (frameset (:type list) :named (:copier nil) - (:predicate nil)) - properties ;; property list - states) ;; list of conses (frame-state . window-state) + (:predicate nil) + ;; A BOA constructor, not the default "keywordy" one. + (:constructor make-frameset (properties states))) -(defun copy-frameset (frameset) + "A frameset encapsulates a serializable view of a set of frames and windows. + +It contains the following slots, which can be accessed with +\(frameset-SLOT fs) and set with (setf (frameset-SLOT fs) VALUE): + + version A non-modifiable version number, identifying the format + of the frameset struct. Currently its value is 1. + properties A property list, to store both frameset-specific and + user-defined serializable data (some suggested properties + are described below). + states An alist of items (FRAME-PARAMETERS . WINDOW-STATE), in no + particular order. Each item represents a frame to be + restored. FRAME-PARAMETERS is a frame's parameter list, + extracted with (frame-parameters FRAME) and filtered through + `frame-parameters-alist' or a similar filter alist. + WINDOW-STATE is the output of `window-state-get', when + applied to the root window of the frame. + +Some suggested properties: + + :app APPINFO Can be used by applications and packages to indicate the + intended (but by no means exclusive) use of the frameset. + Freeform. For example, currently desktop.el framesets set + :app to `(desktop . ,desktop-file-version). + :name NAME The name of the frameset instance; a string. + :desc TEXT A description for user consumption (to show in a menu to + choose among framesets, etc.); a string. + +A frameset is intended to be used through the following simple API: + + - `frameset-save' captures all or a subset of the live frames, and returns + a serializable snapshot of them (a frameset). + - `frameset-restore' takes a frameset, and restores the frames and windows + it describes, as faithfully as possible. + - `frameset-p' is the predicate for the frameset type. It returns nil + for non-frameset objects, and the frameset version number (see below) + for frameset objects. + - `frameset-copy' returns a deep copy of a frameset. + - `frameset-prop' is a `setf'able accessor for the contents of the + `properties' slot. + - The `frameset-SLOT' accessors described above." + + (version 1 :read-only t) + properties states) + +(defun frameset-copy (frameset) "Return a copy of FRAMESET. This is a deep copy done with `copy-tree'." (copy-tree frameset t)) ;;;###autoload (defun frameset-p (frameset) - "If FRAMESET is a frameset, return its :version. + "If FRAMESET is a frameset, return its version number. Else return nil." - (and (eq (car-safe frameset) 'frameset) - (plist-get (cl-second frameset) :version))) + (and (eq (car-safe frameset) 'frameset) ; is a list + (integerp (nth 1 frameset)) ; version is an int + (nth 2 frameset) ; properties is non-null + (nth 3 frameset) ; states is non-null + (nth 1 frameset))) ; return version ;; A setf'able accessor to the frameset's properties (defun frameset-prop (frameset prop) "Return the value of the PROP property of FRAMESET. -Properties other than :version can be set with +Properties can be set with (setf (frameset-prop FRAMESET PROP) NEW-VALUE)" (plist-get (frameset-properties frameset) prop)) @@ -90,7 +119,6 @@ Properties other than :version can be set with (gv-define-setter frameset-prop (val fs prop) (macroexp-let2 nil v val `(progn - (cl-assert (not (eq ,prop :version)) t ":version can not be set") (setf (frameset-properties ,fs) (plist-put (frameset-properties ,fs) ,prop ,v)) ,v))) @@ -100,7 +128,7 @@ Properties other than :version can be set with ;;;###autoload (defvar frameset-live-filter-alist - '((name . t) + '((name . :never) (minibuffer . frameset-filter-minibuffer) (top . frameset-filter-iconified)) "Minimum set of parameters to filter for live (on-session) framesets. @@ -110,25 +138,25 @@ See `frameset-filter-alist' for a full description.") (defvar frameset-persistent-filter-alist (nconc '((background-color . frameset-filter-sanitize-color) - (buffer-list . t) - (buffer-predicate . t) - (buried-buffer-list . t) - (font . frameset-filter-save-parm) + (buffer-list . :never) + (buffer-predicate . :never) + (buried-buffer-list . :never) + (font . frameset-filter-save-param) (foreground-color . frameset-filter-sanitize-color) - (fullscreen . frameset-filter-save-parm) - (GUI:font . frameset-filter-restore-parm) - (GUI:fullscreen . frameset-filter-restore-parm) - (GUI:height . frameset-filter-restore-parm) - (GUI:width . frameset-filter-restore-parm) - (height . frameset-filter-save-parm) + (fullscreen . frameset-filter-save-param) + (GUI:font . frameset-filter-restore-param) + (GUI:fullscreen . frameset-filter-restore-param) + (GUI:height . frameset-filter-restore-param) + (GUI:width . frameset-filter-restore-param) + (height . frameset-filter-save-param) (left . frameset-filter-iconified) - (outer-window-id . t) - (parent-id . t) + (outer-window-id . :never) + (parent-id . :never) (tty . frameset-filter-tty-to-GUI) (tty-type . frameset-filter-tty-to-GUI) - (width . frameset-filter-save-parm) - (window-id . t) - (window-system . t)) + (width . frameset-filter-save-param) + (window-id . :never) + (window-system . :never)) frameset-live-filter-alist) "Recommended set of parameters to filter for persistent framesets. See `frameset-filter-alist' for a full description.") @@ -137,35 +165,48 @@ See `frameset-filter-alist' for a full description.") (defvar frameset-filter-alist frameset-persistent-filter-alist "Alist of frame parameters and filtering functions. -Each element is a cons (PARAM . ACTION), where PARAM is a parameter -name (a symbol identifying a frame parameter), and ACTION can be: +This alist is the default value of the :filters arguments of +`frameset-save' and `frameset-restore' (which see). On saving, +PARAMETERS is the parameter list of each frame processed, and +FILTERED is the parameter list that gets saved to the frameset. +On restoring, PARAMETERS is the parameter list extracted from the +frameset, and FILTERED is the resulting frame parameter list used +to restore the frame. - t The parameter is always removed from the parameter list. - :save The parameter is removed when saving the frame. - :restore The parameter is removed when restoring the frame. +Elements of this alist are conses (PARAM . ACTION), where PARAM +is a parameter name (a symbol identifying a frame parameter), and +ACTION can be: + + nil The parameter is copied to FILTERED. + :never The parameter is never copied to FILTERED. + :save The parameter is copied only when saving the frame. + :restore The parameter is copied only when restoring the frame. FILTER A filter function. FILTER can be a symbol FILTER-FUN, or a list (FILTER-FUN ARGS...). -It will be called with four arguments CURRENT, FILTERED, PARAMETERS -and SAVING, plus any additional ARGS: +FILTER-FUN is called with four arguments CURRENT, FILTERED, PARAMETERS and +SAVING, plus any additional ARGS: CURRENT A cons (PARAM . VALUE), where PARAM is the one being filtered and VALUE is its current value. - FILTERED The alist of parameters filtered so far. + FILTERED The resulting alist (so far). PARAMETERS The complete alist of parameters being filtered, - SAVING Non-nil if filtering before saving state, nil otherwise. + SAVING Non-nil if filtering before saving state, nil if filtering + before restoring it. -The FILTER-FUN function must return: - nil CURRENT is removed from the list. - t CURRENT is left as is. - (PARAM' . VALUE') Replace CURRENT with this. +FILTER-FUN must return: + nil Skip CURRENT (do not add it to FILTERED). + t Add CURRENT to FILTERED as is. + (NEW-PARAM . NEW-VALUE) Add this to FILTERED instead of CURRENT. + +Frame parameters not on this alist are passed intact, as if they were +defined with ACTION = nil.") -Frame parameters not on this list are passed intact.") (defvar frameset--target-display nil ;; Either (minibuffer . VALUE) or nil. ;; This refers to the current frame config being processed inside - ;; `frame--restore-frames' and its auxiliary functions (like filtering). + ;; `frameset-restore' and its auxiliary functions (like filtering). ;; If nil, there is no need to change the display. ;; If non-nil, display parameter to use when creating the frame. "Internal use only.") @@ -191,30 +232,42 @@ Only meaningful when called from a filtering function in (null (cdr frameset--target-display)))) ; to a tty (defun frameset-filter-tty-to-GUI (_current _filtered parameters saving) - "Remove CURRENT when switching from tty to a graphic display." + "Remove CURRENT when switching from tty to a graphic display. + +For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, +see the docstring of `frameset-filter-alist'." (or saving (not (frameset-switch-to-gui-p parameters)))) (defun frameset-filter-sanitize-color (current _filtered parameters saving) "When switching to a GUI frame, remove \"unspecified\" colors. -Useful as a filter function for tty-specific parameters." +Useful as a filter function for tty-specific parameters. + +For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, +see the docstring of `frameset-filter-alist'." (or saving (not (frameset-switch-to-gui-p parameters)) (not (stringp (cdr current))) (not (string-match-p "^unspecified-[fb]g$" (cdr current))))) (defun frameset-filter-minibuffer (current _filtered _parameters saving) - "When saving, convert (minibuffer . #) parameter to (minibuffer . t)." + "When saving, convert (minibuffer . #) parameter to (minibuffer . t). + +For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, +see the docstring of `frameset-filter-alist'." (or (not saving) (if (windowp (cdr current)) '(minibuffer . t) t))) -(defun frameset-filter-save-parm (current _filtered parameters saving - &optional prefix) +(defun frameset-filter-save-param (current _filtered parameters saving + &optional prefix) "When switching to a tty frame, save parameter P as PREFIX:P. -The parameter can be later restored with `frameset-filter-restore-parm'. -PREFIX defaults to `GUI'." +The parameter can be later restored with `frameset-filter-restore-param'. +PREFIX defaults to `GUI'. + +For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, +see the docstring of `frameset-filter-alist'." (unless prefix (setq prefix 'GUI)) (cond (saving t) ((frameset-switch-to-tty-p parameters) @@ -226,9 +279,12 @@ PREFIX defaults to `GUI'." (not (assq (intern (format "%s:%s" prefix (car current))) parameters))) (t t))) -(defun frameset-filter-restore-parm (current filtered parameters saving) +(defun frameset-filter-restore-param (current filtered parameters saving) "When switching to a GUI frame, restore PREFIX:P parameter as P. -CURRENT must be of the form (PREFIX:P . value)." +CURRENT must be of the form (PREFIX:P . value). + +For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, +see the docstring of `frameset-filter-alist'." (or saving (not (frameset-switch-to-gui-p parameters)) (let* ((prefix:p (symbol-name (car current))) @@ -243,9 +299,12 @@ CURRENT must be of the form (PREFIX:P . value)." (defun frameset-filter-iconified (_current _filtered parameters saving) "Remove CURRENT when saving an iconified frame. -This is used for positions parameters `left' and `top', which are +This is used for positional parameters `left' and `top', which are meaningless in an iconified frame, so the frame is restored in a -default position." +default position. + +For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, +see the docstring of `frameset-filter-alist'." (not (and saving (eq (cdr (assq 'visibility parameters)) 'icon)))) (defun frameset-filter-params (parameters filter-alist saving) @@ -259,11 +318,11 @@ nil while the filtering is done to restore it." (pcase (cdr (assq (car current) filter-alist)) (`nil (push current filtered)) - (`t + (:never nil) - (:save - (unless saving (push current filtered))) (:restore + (unless saving (push current filtered))) + (:save (when saving (push current filtered))) ((or `(,fun . ,args) (and fun (pred fboundp))) (let ((this (apply fun current filtered parameters saving args))) @@ -313,7 +372,7 @@ FRAME-LIST is a list of frames. Internal use only." (let* ((mb-frame (window-frame (minibuffer-window frame))) (id (and mb-frame (frame-parameter mb-frame 'frameset--id)))) (if (null id) - (error "Minibuffer frame %S for %S is excluded" mb-frame frame) + (error "Minibuffer frame %S for %S is not being saved" mb-frame frame) ;; For minibufferless frames, frameset--mini is a cons ;; (nil . FRAME-ID), where FRAME-ID is the frameset--id ;; of the frame containing its minibuffer window. @@ -329,27 +388,29 @@ FILTERS is an alist of parameter filters; defaults to `frameset-filter-alist'. PREDICATE is a predicate function, which must return non-nil for frames that should be saved; it defaults to saving all frames from FRAME-LIST. PROPERTIES is a user-defined property list to add to the frameset." - (let ((frames (cl-delete-if-not #'frame-live-p - (cl-delete-if-not (or predicate #'framep) - (or (copy-sequence frame-list) - (frame-list)))))) + (let* ((list (or (copy-sequence frame-list) (frame-list))) + (frames (cl-delete-if-not #'frame-live-p + (if predicate + (cl-delete-if-not predicate list) + list)))) (frameset--process-minibuffer-frames frames) - (make-frameset :properties (append '(:version 1) properties) - :states (mapcar - (lambda (frame) - (cons - (frameset-filter-params (frame-parameters frame) - (or filters - frameset-filter-alist) - t) - (window-state-get (frame-root-window frame) t))) - frames)))) + (make-frameset properties + (mapcar + (lambda (frame) + (cons + (frameset-filter-params (frame-parameters frame) + (or filters frameset-filter-alist) + t) + (window-state-get (frame-root-window frame) t))) + frames)))) ;; Restoring framesets (defvar frameset--reuse-list nil - "Internal use only.") + "The list of frames potentially reusable. +Its value is only meaningful during execution of `frameset-restore'. +Internal use only.") (defun frameset--compute-pos (value left/top right/bottom) (pcase value @@ -494,11 +555,11 @@ Internal use only." (cl-loop for param in '(left top with height border-width minibuffer) collect (assq param frame-cfg))) -(defun frameset--get-frame (frame-cfg window-cfg filters force-onscreen) +(defun frameset--restore-frame (frame-cfg window-cfg filters force-onscreen) "Set up and return a frame according to its saved state. That means either reusing an existing frame or creating one anew. FRAME-CFG is the frame's parameter list; WINDOW-CFG is its window state. -For the meaning of FORCE-ONSCREEN, see `frameset-restore'. +For the meaning of FILTERS and FORCE-ONSCREEN, see `frameset-restore'. Internal use only." (let* ((fullscreen (cdr (assq 'fullscreen frame-cfg))) (lines (assq 'tool-bar-lines frame-cfg)) @@ -563,7 +624,7 @@ Internal use only." (window-state-put window-cfg (frame-root-window frame) 'safe) frame)) -(defun frameset--sort-states (state1 state2) +(defun frameset--minibufferless-last-p (state1 state2) "Predicate to sort frame states in a suitable order to be created. It sorts minibuffer-owning frames before minibufferless ones." (pcase-let ((`(,hasmini1 ,id-def1) (assq 'frameset--mini (car state1))) @@ -580,10 +641,8 @@ It sorts minibuffer-owning frames before minibufferless ones." ((eq system-type 'windows-nt) nil) (t (not force-display)))) -(defun frameset-sort-frames-for-deletion (frame1 _frame2) - "Predicate to sort live frames for deletion. -Minibufferless frames must go first to avoid errors when attempting -to delete a frame whose minibuffer window is used by another frame." +(defun frameset-minibufferless-first-p (frame1 _frame2) + "Predicate to sort minibufferless frames before other frames." (not (frame-parameter frame1 'minibuffer))) ;;;###autoload @@ -593,31 +652,31 @@ to delete a frame whose minibuffer window is used by another frame." FILTERS is an alist of parameter filters; defaults to `frameset-filter-alist'. -REUSE-FRAMES describes how to reuse existing frames while restoring a frameset: +REUSE-FRAMES selects the policy to use to reuse frames when restoring: t Reuse any existing frame if possible; delete leftover frames. nil Restore frameset in new frames and delete existing frames. :keep Restore frameset in new frames and keep the existing ones. - LIST A list of frames to reuse; only these will be reused, if possible, - and any leftover one will be deleted; other frames not on this - list will be kept. + LIST A list of frames to reuse; only these are reused (if possible), + and any leftover ones are deleted; other frames not on this + list are left untouched. FORCE-DISPLAY can be: - t Frames will be restored in the current display. - nil Frames will be restored, if possible, in their original displays. - :delete Frames in other displays will be deleted instead of restored. - PRED A function which will be called with one argument, the parameter - list, and must return t, nil or `:delete', as above but affecting + t Frames are restored in the current display. + nil Frames are restored, if possible, in their original displays. + :delete Frames in other displays are deleted instead of restored. + PRED A function called with one argument, the parameter list; + it must return t, nil or `:delete', as above but affecting only the frame that will be created from that parameter list. FORCE-ONSCREEN can be: - :all Force onscreen any frame fully or partially offscreen. t Force onscreen only those frames that are fully offscreen. nil Do not force any frame back onscreen. - PRED A function which will be called with three arguments, + :all Force onscreen any frame fully or partially offscreen. + PRED A function called with three arguments, - the live frame just restored, - a list (LEFT TOP WIDTH HEIGHT), describing the frame, - - a list (LEFT TOP WIDTH HEIGHT), describing the workarea, - and must return non-nil to force the frame onscreen, nil otherwise. + - a list (LEFT TOP WIDTH HEIGHT), describing the workarea. + It must return non-nil to force the frame onscreen, nil otherwise. Note the timing and scope of the operations described above: REUSE-FRAMES affects existing frames, FILTERS and FORCE-DISPLAY affect the frame being @@ -648,7 +707,7 @@ All keywords default to nil." ;; Sort saved states to guarantee that minibufferless frames will be created ;; after the frames that contain their minibuffer windows. (dolist (state (sort (copy-sequence (frameset-states frameset)) - #'frameset--sort-states)) + #'frameset--minibufferless-last-p)) (condition-case-unless-debug err (pcase-let* ((`(,frame-cfg . ,window-cfg) state) ((and d-mini `(,hasmini . ,mb-id)) @@ -716,9 +775,9 @@ All keywords default to nil." (push (cons 'minibuffer mb-window) frame-cfg))))) ;; OK, we're ready at last to create (or reuse) a frame and ;; restore the window config. - (setq frame (frameset--get-frame frame-cfg window-cfg - (or filters frameset-filter-alist) - force-onscreen)) + (setq frame (frameset--restore-frame frame-cfg window-cfg + (or filters frameset-filter-alist) + force-onscreen)) ;; Set default-minibuffer if required. (when default (setq default-minibuffer-frame frame)))) (error @@ -732,7 +791,10 @@ All keywords default to nil." (unless (eq reuse-frames :keep) (dolist (frame (sort (nconc (if (listp reuse-frames) nil other-frames) frameset--reuse-list) - #'frameset-sort-frames-for-deletion)) + ;; Minibufferless frames must go first to avoid + ;; errors when attempting to delete a frame whose + ;; minibuffer window is used by another frame. + #'frameset-minibufferless-first-p)) (condition-case err (delete-frame frame) (error From 17f25e76c9d133226bddee6a77fe65a2fed5e8fe Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Sun, 4 Aug 2013 23:49:37 -0700 Subject: [PATCH 020/449] * lisp/calendar/calendar.el (calendar-generate-month): Fix for calendar-column-width != 1 + calendar-day-digit-width. --- lisp/ChangeLog | 5 +++++ lisp/calendar/calendar.el | 19 ++++++++++--------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 0c4240c9075..f7dbcfd3a27 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2013-08-05 Glenn Morris + + * calendar/calendar.el (calendar-generate-month): + Fix for calendar-column-width != 1 + calendar-day-digit-width. + 2013-08-05 Juanma Barranquero * desktop.el (desktop-clear): Use new name of sort predicate. diff --git a/lisp/calendar/calendar.el b/lisp/calendar/calendar.el index 20a8684e387..00c6404af7c 100644 --- a/lisp/calendar/calendar.el +++ b/lisp/calendar/calendar.el @@ -1544,15 +1544,16 @@ line." (dotimes (i last) (setq day (1+ i)) ;; TODO should numbers be left-justified, centered...? - (insert (format (format "%%%dd%%s" calendar-day-digit-width) day - (make-string - (- calendar-column-width calendar-day-digit-width) ?\s))) - ;; 'date property prevents intermonth text confusing re-searches. - ;; (Tried intangible, it did not really work.) - (set-text-properties - (- (point) (1+ calendar-day-digit-width)) (1- (point)) - `(mouse-face highlight help-echo ,(eval calendar-date-echo-text) - date t)) + (insert (propertize + (format (format "%%%dd" calendar-day-digit-width) day) + 'mouse-face 'highlight + 'help-echo (eval calendar-date-echo-text) + ;; 'date property prevents intermonth text confusing + ;; re-searches. (Tried intangible, it did not + ;; really work.) + 'date t) + (make-string + (- calendar-column-width calendar-day-digit-width) ?\s)) (when (and (zerop (mod (+ day blank-days) 7)) (/= day last)) (calendar-ensure-newline) From 09e6d5475e16614a178ff90d0ac9f3b3d5197217 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Sun, 4 Aug 2013 23:54:30 -0700 Subject: [PATCH 021/449] * calendar/calendar.el (calendar-generate-month, calendar-font-lock-keywords): Fix for calendar-day-header-width > length of any day name. --- lisp/ChangeLog | 2 ++ lisp/calendar/calendar.el | 20 +++++++++----------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index f7dbcfd3a27..0b766235e04 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -2,6 +2,8 @@ * calendar/calendar.el (calendar-generate-month): Fix for calendar-column-width != 1 + calendar-day-digit-width. + (calendar-generate-month, calendar-font-lock-keywords): + Fix for calendar-day-header-width > length of any day name. 2013-08-05 Juanma Barranquero diff --git a/lisp/calendar/calendar.el b/lisp/calendar/calendar.el index 00c6404af7c..d7e6ea68efa 100644 --- a/lisp/calendar/calendar.el +++ b/lisp/calendar/calendar.el @@ -1532,9 +1532,7 @@ line." (progn (setq string (calendar-day-name (mod (+ calendar-week-start-day i) 7) nil t)) - (if enable-multibyte-characters - (truncate-string-to-width string calendar-day-header-width) - (substring string 0 calendar-day-header-width))) + (truncate-string-to-width string calendar-day-header-width nil ?\s)) (make-string (- calendar-column-width calendar-day-header-width) ?\s))) (calendar-ensure-newline) (calendar-insert-at-column indent calendar-intermonth-text trunc) @@ -1548,9 +1546,8 @@ line." (format (format "%%%dd" calendar-day-digit-width) day) 'mouse-face 'highlight 'help-echo (eval calendar-date-echo-text) - ;; 'date property prevents intermonth text confusing - ;; re-searches. (Tried intangible, it did not - ;; really work.) + ;; 'date property prevents intermonth text confusing re-searches. + ;; (Tried intangible, it did not really work.) 'date t) (make-string (- calendar-column-width calendar-day-digit-width) ?\s)) @@ -2292,14 +2289,15 @@ Negative years are interpreted as years BC; -1 being 1 BC, and so on." " -?[0-9]+") . font-lock-function-name-face) (,(regexp-opt - (list (substring (aref calendar-day-name-array 6) - 0 calendar-day-header-width) - (substring (aref calendar-day-name-array 0) - 0 calendar-day-header-width))) + (list (truncate-string-to-width (aref calendar-day-name-array 6) + calendar-day-header-width) + (truncate-string-to-width (aref calendar-day-name-array 0) + calendar-day-header-width))) ;; Saturdays and Sundays are highlighted differently. . font-lock-comment-face) ;; First two chars of each day are used in the calendar. - (,(regexp-opt (mapcar (lambda (x) (substring x 0 calendar-day-header-width)) + (,(regexp-opt (mapcar (lambda (x) (truncate-string-to-width + x calendar-day-header-width)) calendar-day-name-array)) . font-lock-constant-face)) "Default keywords to highlight in Calendar mode.") From e412eb97cc4e1f9edb1118163f09a77ab9925704 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Mon, 5 Aug 2013 06:17:40 -0400 Subject: [PATCH 022/449] Auto-commit of generated files. --- autogen/Makefile.in | 109 +++++++++++++++-------------- autogen/aclocal.m4 | 3 + autogen/config.in | 16 ++++- autogen/configure | 162 +++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 237 insertions(+), 53 deletions(-) diff --git a/autogen/Makefile.in b/autogen/Makefile.in index d471a9eeb18..f0a6f60d4ae 100644 --- a/autogen/Makefile.in +++ b/autogen/Makefile.in @@ -59,7 +59,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat close-stream crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode fstatat fsync getloadavg getopt-gnu gettime gettimeofday intprops largefile lstat manywarnings memrchr mktime pipe2 pselect pthread_sigmask putenv qacl readlink readlinkat sig2str socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub unsetenv utimens warnings +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open --avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat close-stream crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir filemode fstatat fsync getloadavg getopt-gnu gettime gettimeofday intprops largefile lstat manywarnings memrchr mkostemp mktime pipe2 pselect pthread_sigmask putenv qacl readlink readlinkat sig2str socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub unsetenv utimens warnings VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ @@ -202,14 +202,14 @@ DIST_COMMON = $(srcdir)/../nt/gnulib.mk $(srcdir)/Makefile.am \ @BUILDING_FOR_WINDOWSNT_FALSE@ getopt_int.h gettimeofday.c \ @BUILDING_FOR_WINDOWSNT_FALSE@ group-member.c intprops.h \ @BUILDING_FOR_WINDOWSNT_FALSE@ inttypes.in.h lstat.c memrchr.c \ -@BUILDING_FOR_WINDOWSNT_FALSE@ mktime-internal.h mktime.c \ -@BUILDING_FOR_WINDOWSNT_FALSE@ openat.h pathmax.h pselect.c \ -@BUILDING_FOR_WINDOWSNT_FALSE@ pthread_sigmask.c putenv.c \ -@BUILDING_FOR_WINDOWSNT_FALSE@ acl-internal.h acl.h \ +@BUILDING_FOR_WINDOWSNT_FALSE@ mkostemp.c mktime-internal.h \ +@BUILDING_FOR_WINDOWSNT_FALSE@ mktime.c openat.h pathmax.h \ +@BUILDING_FOR_WINDOWSNT_FALSE@ pselect.c pthread_sigmask.c \ +@BUILDING_FOR_WINDOWSNT_FALSE@ putenv.c acl-internal.h acl.h \ @BUILDING_FOR_WINDOWSNT_FALSE@ acl_entries.c readlink.c \ @BUILDING_FOR_WINDOWSNT_FALSE@ at-func.c readlinkat.c \ -@BUILDING_FOR_WINDOWSNT_FALSE@ root-uid.h sig2str.c sig2str.h \ -@BUILDING_FOR_WINDOWSNT_FALSE@ signal.in.h \ +@BUILDING_FOR_WINDOWSNT_FALSE@ root-uid.h secure_getenv.c \ +@BUILDING_FOR_WINDOWSNT_FALSE@ sig2str.c sig2str.h signal.in.h \ @BUILDING_FOR_WINDOWSNT_FALSE@ $(top_srcdir)/build-aux/snippet/_Noreturn.h \ @BUILDING_FOR_WINDOWSNT_FALSE@ $(top_srcdir)/build-aux/snippet/arg-nonnull.h \ @BUILDING_FOR_WINDOWSNT_FALSE@ $(top_srcdir)/build-aux/snippet/c++defs.h \ @@ -224,12 +224,13 @@ DIST_COMMON = $(srcdir)/../nt/gnulib.mk $(srcdir)/Makefile.am \ @BUILDING_FOR_WINDOWSNT_FALSE@ strtoimax.c strtoumax.c \ @BUILDING_FOR_WINDOWSNT_FALSE@ symlink.c sys_select.in.h \ @BUILDING_FOR_WINDOWSNT_FALSE@ sys_stat.in.h sys_time.in.h \ -@BUILDING_FOR_WINDOWSNT_FALSE@ time.in.h time_r.c timespec.h \ -@BUILDING_FOR_WINDOWSNT_FALSE@ u64.h unistd.in.h unsetenv.c \ -@BUILDING_FOR_WINDOWSNT_FALSE@ utimens.h verify.h \ +@BUILDING_FOR_WINDOWSNT_FALSE@ tempname.h time.in.h time_r.c \ +@BUILDING_FOR_WINDOWSNT_FALSE@ timespec.h u64.h unistd.in.h \ +@BUILDING_FOR_WINDOWSNT_FALSE@ unsetenv.c utimens.h verify.h \ @BUILDING_FOR_WINDOWSNT_FALSE@ xalloc-oversized.h @BUILDING_FOR_WINDOWSNT_FALSE@@gl_GNULIB_ENABLED_be453cec5eecf5731a274f2de7f2db36_TRUE@am__append_10 = gettext.h @BUILDING_FOR_WINDOWSNT_FALSE@am__append_11 = sys sys +@BUILDING_FOR_WINDOWSNT_FALSE@@gl_GNULIB_ENABLED_tempname_TRUE@am__append_12 = tempname.c subdir = lib ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \ @@ -255,33 +256,35 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \ $(top_srcdir)/m4/largefile.m4 $(top_srcdir)/m4/longlong.m4 \ $(top_srcdir)/m4/lstat.m4 $(top_srcdir)/m4/manywarnings.m4 \ $(top_srcdir)/m4/md5.m4 $(top_srcdir)/m4/memrchr.m4 \ - $(top_srcdir)/m4/mktime.m4 $(top_srcdir)/m4/multiarch.m4 \ - $(top_srcdir)/m4/nocrash.m4 $(top_srcdir)/m4/off_t.m4 \ - $(top_srcdir)/m4/pathmax.m4 $(top_srcdir)/m4/pipe2.m4 \ - $(top_srcdir)/m4/pselect.m4 \ + $(top_srcdir)/m4/mkostemp.m4 $(top_srcdir)/m4/mktime.m4 \ + $(top_srcdir)/m4/multiarch.m4 $(top_srcdir)/m4/nocrash.m4 \ + $(top_srcdir)/m4/off_t.m4 $(top_srcdir)/m4/pathmax.m4 \ + $(top_srcdir)/m4/pipe2.m4 $(top_srcdir)/m4/pselect.m4 \ $(top_srcdir)/m4/pthread_sigmask.m4 $(top_srcdir)/m4/putenv.m4 \ $(top_srcdir)/m4/readlink.m4 $(top_srcdir)/m4/readlinkat.m4 \ - $(top_srcdir)/m4/setenv.m4 $(top_srcdir)/m4/sha1.m4 \ - $(top_srcdir)/m4/sha256.m4 $(top_srcdir)/m4/sha512.m4 \ - $(top_srcdir)/m4/sig2str.m4 $(top_srcdir)/m4/signal_h.m4 \ - $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/ssize_t.m4 \ - $(top_srcdir)/m4/st_dm_mode.m4 $(top_srcdir)/m4/stat-time.m4 \ - $(top_srcdir)/m4/stat.m4 $(top_srcdir)/m4/stdalign.m4 \ - $(top_srcdir)/m4/stdarg.m4 $(top_srcdir)/m4/stdbool.m4 \ - $(top_srcdir)/m4/stddef_h.m4 $(top_srcdir)/m4/stdint.m4 \ - $(top_srcdir)/m4/stdio_h.m4 $(top_srcdir)/m4/stdlib_h.m4 \ - $(top_srcdir)/m4/strftime.m4 $(top_srcdir)/m4/string_h.m4 \ - $(top_srcdir)/m4/strtoimax.m4 $(top_srcdir)/m4/strtoll.m4 \ - $(top_srcdir)/m4/strtoull.m4 $(top_srcdir)/m4/strtoumax.m4 \ - $(top_srcdir)/m4/symlink.m4 $(top_srcdir)/m4/sys_select_h.m4 \ + $(top_srcdir)/m4/secure_getenv.m4 $(top_srcdir)/m4/setenv.m4 \ + $(top_srcdir)/m4/sha1.m4 $(top_srcdir)/m4/sha256.m4 \ + $(top_srcdir)/m4/sha512.m4 $(top_srcdir)/m4/sig2str.m4 \ + $(top_srcdir)/m4/signal_h.m4 $(top_srcdir)/m4/socklen.m4 \ + $(top_srcdir)/m4/ssize_t.m4 $(top_srcdir)/m4/st_dm_mode.m4 \ + $(top_srcdir)/m4/stat-time.m4 $(top_srcdir)/m4/stat.m4 \ + $(top_srcdir)/m4/stdalign.m4 $(top_srcdir)/m4/stdarg.m4 \ + $(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/m4/stddef_h.m4 \ + $(top_srcdir)/m4/stdint.m4 $(top_srcdir)/m4/stdio_h.m4 \ + $(top_srcdir)/m4/stdlib_h.m4 $(top_srcdir)/m4/strftime.m4 \ + $(top_srcdir)/m4/string_h.m4 $(top_srcdir)/m4/strtoimax.m4 \ + $(top_srcdir)/m4/strtoll.m4 $(top_srcdir)/m4/strtoull.m4 \ + $(top_srcdir)/m4/strtoumax.m4 $(top_srcdir)/m4/symlink.m4 \ + $(top_srcdir)/m4/sys_select_h.m4 \ $(top_srcdir)/m4/sys_socket_h.m4 \ $(top_srcdir)/m4/sys_stat_h.m4 $(top_srcdir)/m4/sys_time_h.m4 \ - $(top_srcdir)/m4/time_h.m4 $(top_srcdir)/m4/time_r.m4 \ - $(top_srcdir)/m4/timer_time.m4 $(top_srcdir)/m4/timespec.m4 \ - $(top_srcdir)/m4/tm_gmtoff.m4 $(top_srcdir)/m4/unistd_h.m4 \ - $(top_srcdir)/m4/utimbuf.m4 $(top_srcdir)/m4/utimens.m4 \ - $(top_srcdir)/m4/utimes.m4 $(top_srcdir)/m4/warnings.m4 \ - $(top_srcdir)/m4/wchar_t.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/tempname.m4 $(top_srcdir)/m4/time_h.m4 \ + $(top_srcdir)/m4/time_r.m4 $(top_srcdir)/m4/timer_time.m4 \ + $(top_srcdir)/m4/timespec.m4 $(top_srcdir)/m4/tm_gmtoff.m4 \ + $(top_srcdir)/m4/unistd_h.m4 $(top_srcdir)/m4/utimbuf.m4 \ + $(top_srcdir)/m4/utimens.m4 $(top_srcdir)/m4/utimes.m4 \ + $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/m4/wchar_t.m4 \ + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -296,10 +299,11 @@ am__libgnu_a_SOURCES_DIST = allocator.c binary-io.h binary-io.c \ careadlinkat.c close-stream.c md5.c sha1.c sha256.c sha512.c \ dtoastr.c dtotimespec.c filemode.c gettext.h gettime.c pipe2.c \ acl-errno-valid.c file-has-acl.c qcopy-acl.c qset-acl.c \ - stat-time.c strftime.c timespec.c timespec-add.c \ + stat-time.c strftime.c tempname.c timespec.c timespec-add.c \ timespec-sub.c u64.c unistd.c utimens.c openat-die.c \ save-cwd.c am__objects_1 = +@BUILDING_FOR_WINDOWSNT_FALSE@@gl_GNULIB_ENABLED_tempname_TRUE@am__objects_2 = tempname.$(OBJEXT) @BUILDING_FOR_WINDOWSNT_FALSE@am_libgnu_a_OBJECTS = \ @BUILDING_FOR_WINDOWSNT_FALSE@ allocator.$(OBJEXT) \ @BUILDING_FOR_WINDOWSNT_FALSE@ binary-io.$(OBJEXT) \ @@ -323,6 +327,7 @@ am__objects_1 = @BUILDING_FOR_WINDOWSNT_FALSE@ qset-acl.$(OBJEXT) \ @BUILDING_FOR_WINDOWSNT_FALSE@ stat-time.$(OBJEXT) \ @BUILDING_FOR_WINDOWSNT_FALSE@ strftime.$(OBJEXT) \ +@BUILDING_FOR_WINDOWSNT_FALSE@ $(am__objects_2) \ @BUILDING_FOR_WINDOWSNT_FALSE@ timespec.$(OBJEXT) \ @BUILDING_FOR_WINDOWSNT_FALSE@ timespec-add.$(OBJEXT) \ @BUILDING_FOR_WINDOWSNT_FALSE@ timespec-sub.$(OBJEXT) \ @@ -350,15 +355,16 @@ am__objects_1 = @BUILDING_FOR_WINDOWSNT_TRUE@ timespec-add.$(OBJEXT) \ @BUILDING_FOR_WINDOWSNT_TRUE@ timespec-sub.$(OBJEXT) \ @BUILDING_FOR_WINDOWSNT_TRUE@ u64.$(OBJEXT) utimens.$(OBJEXT) \ -@BUILDING_FOR_WINDOWSNT_TRUE@ $(am__objects_1) +@BUILDING_FOR_WINDOWSNT_TRUE@ $(am__objects_1) $(am__objects_2) am__EXTRA_libgnu_a_SOURCES_DIST = openat-proc.c ftoastr.c dup2.c \ euidaccess.c execinfo.c at-func.c faccessat.c fcntl.c \ fdatasync.c fdopendir.c fpending.c fstatat.c fsync.c \ getdtablesize.c getgroups.c getloadavg.c getopt.c getopt1.c \ - gettimeofday.c group-member.c lstat.c memrchr.c mktime.c \ - pselect.c pthread_sigmask.c putenv.c acl_entries.c readlink.c \ - readlinkat.c sig2str.c stat.c strtoimax.c strtol.c strtoll.c \ - strtoul.c strtoull.c strtoumax.c symlink.c time_r.c unsetenv.c + gettimeofday.c group-member.c lstat.c memrchr.c mkostemp.c \ + mktime.c pselect.c pthread_sigmask.c putenv.c acl_entries.c \ + readlink.c readlinkat.c secure_getenv.c sig2str.c stat.c \ + strtoimax.c strtol.c strtoll.c strtoul.c strtoull.c \ + strtoumax.c symlink.c time_r.c unsetenv.c libgnu_a_OBJECTS = $(am_libgnu_a_OBJECTS) depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__depfiles_maybe = depfiles @@ -1248,10 +1254,10 @@ DEFAULT_INCLUDES = -I. -I$(top_srcdir)/lib -I../src -I$(top_srcdir)/src @BUILDING_FOR_WINDOWSNT_FALSE@ acl-errno-valid.c file-has-acl.c \ @BUILDING_FOR_WINDOWSNT_FALSE@ qcopy-acl.c qset-acl.c \ @BUILDING_FOR_WINDOWSNT_FALSE@ stat-time.c strftime.c \ -@BUILDING_FOR_WINDOWSNT_FALSE@ timespec.c timespec-add.c \ -@BUILDING_FOR_WINDOWSNT_FALSE@ timespec-sub.c u64.c unistd.c \ -@BUILDING_FOR_WINDOWSNT_FALSE@ utimens.c openat-die.c \ -@BUILDING_FOR_WINDOWSNT_FALSE@ save-cwd.c +@BUILDING_FOR_WINDOWSNT_FALSE@ $(am__append_12) timespec.c \ +@BUILDING_FOR_WINDOWSNT_FALSE@ timespec-add.c timespec-sub.c \ +@BUILDING_FOR_WINDOWSNT_FALSE@ u64.c unistd.c utimens.c \ +@BUILDING_FOR_WINDOWSNT_FALSE@ openat-die.c save-cwd.c @BUILDING_FOR_WINDOWSNT_TRUE@libgnu_a_SOURCES = c-ctype.h c-ctype.c \ @BUILDING_FOR_WINDOWSNT_TRUE@ c-strcase.h c-strcasecmp.c \ @BUILDING_FOR_WINDOWSNT_TRUE@ c-strncasecmp.c close-stream.c \ @@ -1262,7 +1268,8 @@ DEFAULT_INCLUDES = -I. -I$(top_srcdir)/lib -I../src -I$(top_srcdir)/src @BUILDING_FOR_WINDOWSNT_TRUE@ file-has-acl.c qcopy-acl.c \ @BUILDING_FOR_WINDOWSNT_TRUE@ stat-time.c strftime.c timespec.c \ @BUILDING_FOR_WINDOWSNT_TRUE@ timespec-add.c timespec-sub.c \ -@BUILDING_FOR_WINDOWSNT_TRUE@ u64.c utimens.c $(am__append_10) +@BUILDING_FOR_WINDOWSNT_TRUE@ u64.c utimens.c $(am__append_10) \ +@BUILDING_FOR_WINDOWSNT_TRUE@ $(am__append_12) @BUILDING_FOR_WINDOWSNT_FALSE@libgnu_a_LIBADD = $(gl_LIBOBJS) @BUILDING_FOR_WINDOWSNT_TRUE@libgnu_a_LIBADD = $(gl_LIBOBJS) @BUILDING_FOR_WINDOWSNT_FALSE@libgnu_a_DEPENDENCIES = $(gl_LIBOBJS) @@ -1276,11 +1283,12 @@ DEFAULT_INCLUDES = -I. -I$(top_srcdir)/lib -I../src -I$(top_srcdir)/src @BUILDING_FOR_WINDOWSNT_FALSE@ getgroups.c getloadavg.c \ @BUILDING_FOR_WINDOWSNT_FALSE@ getopt.c getopt1.c \ @BUILDING_FOR_WINDOWSNT_FALSE@ gettimeofday.c group-member.c \ -@BUILDING_FOR_WINDOWSNT_FALSE@ lstat.c memrchr.c mktime.c \ -@BUILDING_FOR_WINDOWSNT_FALSE@ pselect.c pthread_sigmask.c \ -@BUILDING_FOR_WINDOWSNT_FALSE@ putenv.c acl_entries.c \ -@BUILDING_FOR_WINDOWSNT_FALSE@ readlink.c at-func.c \ -@BUILDING_FOR_WINDOWSNT_FALSE@ readlinkat.c sig2str.c stat.c \ +@BUILDING_FOR_WINDOWSNT_FALSE@ lstat.c memrchr.c mkostemp.c \ +@BUILDING_FOR_WINDOWSNT_FALSE@ mktime.c pselect.c \ +@BUILDING_FOR_WINDOWSNT_FALSE@ pthread_sigmask.c putenv.c \ +@BUILDING_FOR_WINDOWSNT_FALSE@ acl_entries.c readlink.c \ +@BUILDING_FOR_WINDOWSNT_FALSE@ at-func.c readlinkat.c \ +@BUILDING_FOR_WINDOWSNT_FALSE@ secure_getenv.c sig2str.c stat.c \ @BUILDING_FOR_WINDOWSNT_FALSE@ strtoimax.c strtol.c strtoll.c \ @BUILDING_FOR_WINDOWSNT_FALSE@ strtol.c strtoul.c strtoull.c \ @BUILDING_FOR_WINDOWSNT_FALSE@ strtoimax.c strtoumax.c \ @@ -1402,6 +1410,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lstat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memrchr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mkostemp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mktime.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openat-die.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openat-proc.Po@am__quote@ @@ -1414,6 +1423,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readlink.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readlinkat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/save-cwd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/secure_getenv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha256.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha512.Po@am__quote@ @@ -1428,6 +1438,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtoull.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtoumax.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symlink.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tempname.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/time_r.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timespec-add.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timespec-sub.Po@am__quote@ diff --git a/autogen/aclocal.m4 b/autogen/aclocal.m4 index c9e796a081f..5beeef676cc 100644 --- a/autogen/aclocal.m4 +++ b/autogen/aclocal.m4 @@ -1024,6 +1024,7 @@ m4_include([m4/lstat.m4]) m4_include([m4/manywarnings.m4]) m4_include([m4/md5.m4]) m4_include([m4/memrchr.m4]) +m4_include([m4/mkostemp.m4]) m4_include([m4/mktime.m4]) m4_include([m4/multiarch.m4]) m4_include([m4/nocrash.m4]) @@ -1035,6 +1036,7 @@ m4_include([m4/pthread_sigmask.m4]) m4_include([m4/putenv.m4]) m4_include([m4/readlink.m4]) m4_include([m4/readlinkat.m4]) +m4_include([m4/secure_getenv.m4]) m4_include([m4/setenv.m4]) m4_include([m4/sha1.m4]) m4_include([m4/sha256.m4]) @@ -1064,6 +1066,7 @@ m4_include([m4/sys_select_h.m4]) m4_include([m4/sys_socket_h.m4]) m4_include([m4/sys_stat_h.m4]) m4_include([m4/sys_time_h.m4]) +m4_include([m4/tempname.m4]) m4_include([m4/time_h.m4]) m4_include([m4/time_r.m4]) m4_include([m4/timer_time.m4]) diff --git a/autogen/config.in b/autogen/config.in index 5c5b2dfdbca..b996a5f071e 100644 --- a/autogen/config.in +++ b/autogen/config.in @@ -192,6 +192,10 @@ along with GNU Emacs. If not, see . */ whether the gnulib module fscanf shall be considered present. */ #undef GNULIB_FSCANF +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module mkostemp shall be considered present. */ +#undef GNULIB_MKOSTEMP + /* enable some gnulib portability checks */ #undef GNULIB_PORTCHECK @@ -625,6 +629,9 @@ along with GNU Emacs. If not, see . */ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H +/* Define to 1 if you have the `issetugid' function. */ +#undef HAVE_ISSETUGID + /* Define to 1 if you have the jpeg library (-ljpeg). */ #undef HAVE_JPEG @@ -753,9 +760,6 @@ along with GNU Emacs. If not, see . */ /* Define to 1 if you have the `mkostemp' function. */ #undef HAVE_MKOSTEMP -/* Define to 1 if you have the `mkstemp' function. */ -#undef HAVE_MKSTEMP - /* Define to 1 if you have a working `mmap' system call. */ #undef HAVE_MMAP @@ -847,6 +851,9 @@ along with GNU Emacs. If not, see . */ /* Define to 1 if using librsvg. */ #undef HAVE_RSVG +/* Define to 1 if you have the `secure_getenv' function. */ +#undef HAVE_SECURE_GETENV + /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT @@ -1201,6 +1208,9 @@ along with GNU Emacs. If not, see . */ /* Define to 1 if you have the `__fpending' function. */ #undef HAVE___FPENDING +/* Define to 1 if you have the `__secure_getenv' function. */ +#undef HAVE___SECURE_GETENV + /* Define to support using a Hesiod database to find the POP server. */ #undef HESIOD diff --git a/autogen/configure b/autogen/configure index 3d207e12537..25466424615 100755 --- a/autogen/configure +++ b/autogen/configure @@ -614,12 +614,16 @@ LIBGNU_LIBDEPS gltests_WITNESS gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec_FALSE gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec_TRUE +gl_GNULIB_ENABLED_tempname_FALSE +gl_GNULIB_ENABLED_tempname_TRUE gl_GNULIB_ENABLED_strtoull_FALSE gl_GNULIB_ENABLED_strtoull_TRUE gl_GNULIB_ENABLED_strtoll_FALSE gl_GNULIB_ENABLED_strtoll_TRUE gl_GNULIB_ENABLED_stat_FALSE gl_GNULIB_ENABLED_stat_TRUE +gl_GNULIB_ENABLED_secure_getenv_FALSE +gl_GNULIB_ENABLED_secure_getenv_TRUE gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c_FALSE gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c_TRUE gl_GNULIB_ENABLED_pathmax_FALSE @@ -3390,6 +3394,7 @@ as_fn_append ac_header_list " wchar.h" as_fn_append ac_header_list " stdint.h" as_fn_append ac_header_list " inttypes.h" as_fn_append ac_func_list " lstat" +as_fn_append ac_func_list " mkostemp" as_fn_append ac_func_list " pipe2" as_fn_append ac_header_list " sys/select.h" as_fn_append ac_func_list " pselect" @@ -3407,6 +3412,7 @@ as_fn_append ac_func_list " futimens" as_fn_append ac_func_list " utimensat" as_fn_append ac_func_list " lutimes" as_fn_append ac_func_list " getdtablesize" +as_fn_append ac_func_list " secure_getenv" # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false @@ -7286,6 +7292,7 @@ esac # Code from module lstat: # Code from module manywarnings: # Code from module memrchr: + # Code from module mkostemp: # Code from module mktime: # Code from module multiarch: # Code from module nocrash: @@ -7299,6 +7306,7 @@ esac # Code from module readlink: # Code from module readlinkat: # Code from module root-uid: + # Code from module secure_getenv: # Code from module sig2str: # Code from module signal-h: # Code from module snippet/_Noreturn: @@ -7329,6 +7337,7 @@ esac # Code from module sys_select: # Code from module sys_stat: # Code from module sys_time: + # Code from module tempname: # Code from module time: # Code from module time_r: # Code from module timer-time: @@ -14692,7 +14701,7 @@ select getpagesize setlocale \ getrlimit setrlimit shutdown getaddrinfo \ strsignal setitimer \ sendto recvfrom getsockname getpeername getifaddrs freeifaddrs \ -gai_strerror mkostemp mkstemp getline getdelim sync \ +gai_strerror getline getdelim sync \ difftime posix_memalign \ getpwent endpwent getgrent endgrent \ touchlock \ @@ -20703,6 +20712,8 @@ cat >>confdefs.h <<_ACEOF _ACEOF + + GNULIB_MKTIME=0; GNULIB_NANOSLEEP=0; GNULIB_STRPTIME=0; @@ -21932,6 +21943,8 @@ _ACEOF + + if false; then GL_COND_LIBTOOL_TRUE= GL_COND_LIBTOOL_FALSE='#' @@ -24090,6 +24103,48 @@ done + if test $ac_cv_func_mkostemp != yes; then + HAVE_MKOSTEMP=0 + fi + + if test $HAVE_MKOSTEMP = 0; then + + + + + + + + + gl_LIBOBJS="$gl_LIBOBJS mkostemp.$ac_objext" + + + + fi + + +cat >>confdefs.h <<_ACEOF +#define GNULIB_MKOSTEMP 1 +_ACEOF + + + + + + + + GNULIB_MKOSTEMP=1 + + + + + + + + + + + if test $APPLE_UNIVERSAL_BUILD = 1; then # A universal build on Apple Mac OS X platforms. # The test result would be 'yes' in 32-bit mode and 'no' in 64-bit mode. @@ -27493,9 +27548,11 @@ $as_echo "#define FUTIMESAT_NULL_BUG 1" >>confdefs.h gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7=false gl_gnulib_enabled_pathmax=false gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=false + gl_gnulib_enabled_secure_getenv=false gl_gnulib_enabled_stat=false gl_gnulib_enabled_strtoll=false gl_gnulib_enabled_strtoull=false + gl_gnulib_enabled_tempname=false gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec=false func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b () { @@ -28096,6 +28153,70 @@ fi gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=true fi } + func_gl_gnulib_m4code_secure_getenv () + { + if ! $gl_gnulib_enabled_secure_getenv; then + + + + + + if test $ac_cv_func_secure_getenv = no; then + HAVE_SECURE_GETENV=0 + fi + + if test $HAVE_SECURE_GETENV = 0; then + + + + + + + + + gl_LIBOBJS="$gl_LIBOBJS secure_getenv.$ac_objext" + + + for ac_func in __secure_getenv +do : + ac_fn_c_check_func "$LINENO" "__secure_getenv" "ac_cv_func___secure_getenv" +if test "x$ac_cv_func___secure_getenv" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE___SECURE_GETENV 1 +_ACEOF + +fi +done + + if test $ac_cv_func___secure_getenv = no; then + for ac_func in issetugid +do : + ac_fn_c_check_func "$LINENO" "issetugid" "ac_cv_func_issetugid" +if test "x$ac_cv_func_issetugid" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_ISSETUGID 1 +_ACEOF + +fi +done + + fi + + fi + + + + + + GNULIB_SECURE_GETENV=1 + + + + + + gl_gnulib_enabled_secure_getenv=true + fi + } func_gl_gnulib_m4code_stat () { if ! $gl_gnulib_enabled_stat; then @@ -28340,6 +28461,18 @@ done gl_gnulib_enabled_strtoull=true fi } + func_gl_gnulib_m4code_tempname () + { + if ! $gl_gnulib_enabled_tempname; then + + + : + + + gl_gnulib_enabled_tempname=true + func_gl_gnulib_m4code_secure_getenv + fi + } func_gl_gnulib_m4code_682e609604ccaac6be382e4ee3a4eaec () { if ! $gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec; then @@ -28382,6 +28515,9 @@ done if test $REPLACE_LSTAT = 1; then func_gl_gnulib_m4code_stat fi + if test $HAVE_MKOSTEMP = 0; then + func_gl_gnulib_m4code_tempname + fi if test $HAVE_READLINK = 0 || test $REPLACE_READLINK = 1; then func_gl_gnulib_m4code_stat fi @@ -28481,6 +28617,14 @@ else gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c_FALSE= fi + if $gl_gnulib_enabled_secure_getenv; then + gl_GNULIB_ENABLED_secure_getenv_TRUE= + gl_GNULIB_ENABLED_secure_getenv_FALSE='#' +else + gl_GNULIB_ENABLED_secure_getenv_TRUE='#' + gl_GNULIB_ENABLED_secure_getenv_FALSE= +fi + if $gl_gnulib_enabled_stat; then gl_GNULIB_ENABLED_stat_TRUE= gl_GNULIB_ENABLED_stat_FALSE='#' @@ -28505,6 +28649,14 @@ else gl_GNULIB_ENABLED_strtoull_FALSE= fi + if $gl_gnulib_enabled_tempname; then + gl_GNULIB_ENABLED_tempname_TRUE= + gl_GNULIB_ENABLED_tempname_FALSE='#' +else + gl_GNULIB_ENABLED_tempname_TRUE='#' + gl_GNULIB_ENABLED_tempname_FALSE= +fi + if $gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec; then gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec_TRUE= gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec_FALSE='#' @@ -28993,6 +29145,10 @@ if test -z "${gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c_TRUE}" && test as_fn_error "conditional \"gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${gl_GNULIB_ENABLED_secure_getenv_TRUE}" && test -z "${gl_GNULIB_ENABLED_secure_getenv_FALSE}"; then + as_fn_error "conditional \"gl_GNULIB_ENABLED_secure_getenv\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${gl_GNULIB_ENABLED_stat_TRUE}" && test -z "${gl_GNULIB_ENABLED_stat_FALSE}"; then as_fn_error "conditional \"gl_GNULIB_ENABLED_stat\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -29005,6 +29161,10 @@ if test -z "${gl_GNULIB_ENABLED_strtoull_TRUE}" && test -z "${gl_GNULIB_ENABLED_ as_fn_error "conditional \"gl_GNULIB_ENABLED_strtoull\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${gl_GNULIB_ENABLED_tempname_TRUE}" && test -z "${gl_GNULIB_ENABLED_tempname_FALSE}"; then + as_fn_error "conditional \"gl_GNULIB_ENABLED_tempname\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec_TRUE}" && test -z "${gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec_FALSE}"; then as_fn_error "conditional \"gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 From 12b4c0ea03a8c7905254be1cefa234bc8d8a8a88 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Mon, 5 Aug 2013 14:35:55 +0400 Subject: [PATCH 023/449] Do not call to `selected-frame' where it is assumed by default. Affected functions are `raise-frame', `redraw-frame', `frame-first-window', `frame-terminal' and `delete-frame'. * lisp/calendar/appt.el (appt-disp-window): * lisp/epg.el (epg-wait-for-completion): * lisp/follow.el (follow-delete-other-windows-and-split) (follow-avoid-tail-recenter): * lisp/international/mule.el (set-terminal-coding-system): * lisp/mail/rmail.el (rmail-mail-return): * lisp/net/newst-plainview.el (newsticker--buffer-set-uptodate): * lisp/progmodes/f90.el (f90-add-imenu-menu): * lisp/progmodes/idlw-toolbar.el (idlwave-toolbar-toggle): * lisp/server.el (server-switch-buffer): * lisp/simple.el (delete-completion-window): * lisp/talk.el (talk): * lisp/term/xterm.el (terminal-init-xterm-modify-other-keys) (xterm-turn-on-modify-other-keys, xterm-remove-modify-other-keys): * lisp/vc/ediff-util.el (ediff-status-info, ediff-show-diff-output): * lisp/vc/ediff.el (ediff-documentation): Related users changed. * lisp/frame.el (selected-terminal): Remove the leftover. --- lisp/ChangeLog | 23 +++++++++++++++++++++++ lisp/calendar/appt.el | 2 +- lisp/epg.el | 2 +- lisp/follow.el | 4 ++-- lisp/frame.el | 3 --- lisp/international/mule.el | 2 +- lisp/mail/rmail.el | 2 +- lisp/net/newst-plainview.el | 2 +- lisp/progmodes/f90.el | 2 +- lisp/progmodes/idlw-toolbar.el | 2 +- lisp/server.el | 2 +- lisp/simple.el | 2 +- lisp/talk.el | 2 +- lisp/term/xterm.el | 6 +++--- lisp/vc/ediff-util.el | 4 ++-- lisp/vc/ediff.el | 2 +- 16 files changed, 41 insertions(+), 21 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 0b766235e04..6ca96741b63 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,26 @@ +2013-08-05 Dmitry Antipov + + Do not call to `selected-frame' where it is assumed by default. + Affected functions are `raise-frame', `redraw-frame', + `frame-first-window', `frame-terminal' and `delete-frame'. + * calendar/appt.el (appt-disp-window): + * epg.el (epg-wait-for-completion): + * follow.el (follow-delete-other-windows-and-split) + (follow-avoid-tail-recenter): + * international/mule.el (set-terminal-coding-system): + * mail/rmail.el (rmail-mail-return): + * net/newst-plainview.el (newsticker--buffer-set-uptodate): + * progmodes/f90.el (f90-add-imenu-menu): + * progmodes/idlw-toolbar.el (idlwave-toolbar-toggle): + * server.el (server-switch-buffer): + * simple.el (delete-completion-window): + * talk.el (talk): + * term/xterm.el (terminal-init-xterm-modify-other-keys) + (xterm-turn-on-modify-other-keys, xterm-remove-modify-other-keys): + * vc/ediff-util.el (ediff-status-info, ediff-show-diff-output): + * vc/ediff.el (ediff-documentation): Related users changed. + * frame.el (selected-terminal): Remove the leftover. + 2013-08-05 Glenn Morris * calendar/calendar.el (calendar-generate-month): diff --git a/lisp/calendar/appt.el b/lisp/calendar/appt.el index ea3a5b2caf2..97b20f6b02b 100644 --- a/lisp/calendar/appt.el +++ b/lisp/calendar/appt.el @@ -472,7 +472,7 @@ separate appointment." (shrink-window-if-larger-than-buffer (get-buffer-window appt-disp-buf t)) (set-buffer-modified-p nil) (setq buffer-read-only t) - (raise-frame (selected-frame)) + (raise-frame) (select-window this-window))) (defun appt-delete-window () diff --git a/lisp/epg.el b/lisp/epg.el index 06d972d6ffa..b832ead4d68 100644 --- a/lisp/epg.el +++ b/lisp/epg.el @@ -1346,7 +1346,7 @@ This function is for internal use only." (> (float-time (or (nth 5 (file-attributes epg-agent-file)) '(0 0 0 0))) (float-time epg-agent-mtime)))) - (redraw-frame (selected-frame))) + (redraw-frame)) (epg-context-set-result-for context 'error (nreverse (epg-context-result-for context 'error)))) diff --git a/lisp/follow.el b/lisp/follow.el index ef26788c0b1..53b32e57031 100644 --- a/lisp/follow.el +++ b/lisp/follow.el @@ -572,7 +572,7 @@ selected if the original window is the first one in the frame." (interactive "P") (let ((other (or (and (null arg) (not (eq (selected-window) - (frame-first-window (selected-frame))))) + (frame-first-window)))) (and arg (< (prefix-numeric-value arg) 0)))) (start (window-start))) @@ -1083,7 +1083,7 @@ should be a member of WINDOWS, starts at position START." This is done by reading and rewriting the start position of non-first windows in Follow mode." (let* ((orig-buffer (current-buffer)) - (top (frame-first-window (selected-frame))) + (top (frame-first-window)) (win top) who) ; list of (buffer . frame) ;; If the only window in the frame is a minibuffer diff --git a/lisp/frame.el b/lisp/frame.el index 22cf484e54a..9d3c839fa35 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -1278,9 +1278,6 @@ keys and their meanings." ;;;; Frame/display capabilities. -(defun selected-terminal () - "Return the terminal that is now selected." - (frame-terminal (selected-frame))) (declare-function msdos-mouse-p "dosfns.c") diff --git a/lisp/international/mule.el b/lisp/international/mule.el index 11c4db5977d..ed98c03fdcc 100644 --- a/lisp/international/mule.el +++ b/lisp/international/mule.el @@ -1346,7 +1346,7 @@ graphical terminals." (if coding-system (setq default-terminal-coding-system coding-system)) (set-terminal-coding-system-internal coding-system terminal) - (redraw-frame (selected-frame))) + (redraw-frame)) (defvar default-keyboard-coding-system nil "Default value of the keyboard coding system. diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el index e29becedb6e..8eeb0991653 100644 --- a/lisp/mail/rmail.el +++ b/lisp/mail/rmail.el @@ -3725,7 +3725,7 @@ to switch to." ;; If the frame was probably made for this buffer, the user ;; probably wants to delete it now. ((display-multi-frame-p) - (delete-frame (selected-frame))) + (delete-frame)) ;; The previous frame is where normally they have the Rmail buffer ;; displayed. (t (other-frame -1)))) diff --git a/lisp/net/newst-plainview.el b/lisp/net/newst-plainview.el index c7a3a107078..2ba4e5c2716 100644 --- a/lisp/net/newst-plainview.el +++ b/lisp/net/newst-plainview.el @@ -1188,7 +1188,7 @@ The mode-line is changed accordingly." "Redraw the newsticker window." (if (fboundp 'force-window-update) (force-window-update (current-buffer)) - (redraw-frame (selected-frame))) + (redraw-frame)) (run-hooks 'newsticker-buffer-change-hook) (sit-for 0)) diff --git a/lisp/progmodes/f90.el b/lisp/progmodes/f90.el index 9bde2900a67..80f663360e4 100644 --- a/lisp/progmodes/f90.el +++ b/lisp/progmodes/f90.el @@ -1026,7 +1026,7 @@ Set subexpression 1 in the match-data to the name of the type." (if (lookup-key (current-local-map) [menu-bar index]) (message "%s" "F90-imenu already exists.") (imenu-add-to-menubar "F90-imenu") - (redraw-frame (selected-frame)))) + (redraw-frame))) ;; Abbrevs have generally two letters, except standard types `c, `i, `r, `t. diff --git a/lisp/progmodes/idlw-toolbar.el b/lisp/progmodes/idlw-toolbar.el index d255b8b1a3f..98f9ee3b530 100644 --- a/lisp/progmodes/idlw-toolbar.el +++ b/lisp/progmodes/idlw-toolbar.el @@ -962,7 +962,7 @@ static char * file[] = { (if (featurep 'xemacs) nil ; no action necessary, toolbar gets updated automatically ;; On Emacs, redraw the frame to make sure the Toolbar is updated. - (redraw-frame (selected-frame)))) + (redraw-frame))) (provide 'idlw-toolbar) (provide 'idlwave-toolbar) diff --git a/lisp/server.el b/lisp/server.el index 8a2a466a315..8208e0b44d8 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -1593,7 +1593,7 @@ be a cons cell (LINENUMBER . COLUMNNUMBER)." (lambda (w) (and (not (window-dedicated-p w)) (equal (frame-terminal (window-frame w)) - (frame-terminal (selected-frame))))) + (frame-terminal)))) 'nomini 'visible (selected-window)))) (condition-case nil (switch-to-buffer next-buffer) diff --git a/lisp/simple.el b/lisp/simple.el index 1fb2fa6014c..6bb05c14a58 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -6630,7 +6630,7 @@ Go to the window from which completion was requested." (let ((buf completion-reference-buffer)) (if (one-window-p t) (if (window-dedicated-p (selected-window)) - (delete-frame (selected-frame))) + (delete-frame)) (delete-window (selected-window)) (if (get-buffer-window buf) (select-window (get-buffer-window buf)))))) diff --git a/lisp/talk.el b/lisp/talk.el index 741571a8d78..8c991c8d995 100644 --- a/lisp/talk.el +++ b/lisp/talk.el @@ -50,7 +50,7 @@ Each element has the form (DISPLAY FRAME BUFFER).") (let ((type (frame-live-p (selected-frame)))) (if (or (eq type t) (eq type 'x)) (talk-add-display - (terminal-name (frame-terminal (selected-frame)))) + (terminal-name (frame-terminal))) (error "Unknown frame type"))) (talk-update-buffers)) diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el index 86f4583b987..af0b0b606e5 100644 --- a/lisp/term/xterm.el +++ b/lisp/term/xterm.el @@ -606,7 +606,7 @@ We run the first FUNCTION whose STRING matches the input events." (add-hook 'delete-terminal-functions 'xterm-remove-modify-other-keys) ;; Add the selected frame to the list of frames that ;; need to deal with modify-other-keys. - (push (frame-terminal (selected-frame)) + (push (frame-terminal) xterm-modify-other-keys-terminal-list) (xterm-turn-on-modify-other-keys)) @@ -728,7 +728,7 @@ versions of xterm." (defun xterm-turn-on-modify-other-keys () "Turn the modifyOtherKeys feature of xterm back on." - (let ((terminal (frame-terminal (selected-frame)))) + (let ((terminal (frame-terminal))) (when (and (terminal-live-p terminal) (memq terminal xterm-modify-other-keys-terminal-list)) (send-string-to-terminal "\e[>4;1m" terminal)))) @@ -742,7 +742,7 @@ versions of xterm." (defun xterm-remove-modify-other-keys (&optional terminal) "Turn off the modifyOtherKeys feature of xterm for good." - (setq terminal (or terminal (frame-terminal (selected-frame)))) + (setq terminal (or terminal (frame-terminal))) (when (and (terminal-live-p terminal) (memq terminal xterm-modify-other-keys-terminal-list)) (setq xterm-modify-other-keys-terminal-list diff --git a/lisp/vc/ediff-util.el b/lisp/vc/ediff-util.el index ec227f44e8f..8f84dfb14ef 100644 --- a/lisp/vc/ediff-util.el +++ b/lisp/vc/ediff-util.el @@ -2818,7 +2818,7 @@ Hit \\[ediff-recenter] to reset the windows afterward." (with-output-to-temp-buffer ediff-msg-buffer (ediff-with-current-buffer standard-output (fundamental-mode)) - (raise-frame (selected-frame)) + (raise-frame) (princ (ediff-version)) (princ "\n\n") (ediff-with-current-buffer ediff-buffer-A @@ -3468,7 +3468,7 @@ Without an argument, it saves customized diff argument, if available (ediff-with-current-buffer buf (goto-char (point-min))) (switch-to-buffer buf) - (raise-frame (selected-frame))))) + (raise-frame)))) (if (frame-live-p ediff-control-frame) (ediff-reset-mouse ediff-control-frame)) (if (window-live-p ediff-control-window) diff --git a/lisp/vc/ediff.el b/lisp/vc/ediff.el index e9a6a97409c..d35c3e53e9a 100644 --- a/lisp/vc/ediff.el +++ b/lisp/vc/ediff.el @@ -1499,7 +1499,7 @@ With optional NODE, goes to that node." (if node (Info-goto-node node) (message "Type `i' to search for a specific topic")) - (raise-frame (selected-frame))) + (raise-frame)) (error (beep 1) (with-output-to-temp-buffer ediff-msg-buffer (ediff-with-current-buffer standard-output From 123ff29791a3d0d24f2ff5706bde56ad145e09d6 Mon Sep 17 00:00:00 2001 From: Xue Fuqiao Date: Mon, 5 Aug 2013 19:37:47 +0800 Subject: [PATCH 024/449] * doc/lispref/windows.texi (Window Start and End): Add an index. --- doc/lispref/ChangeLog | 4 ++++ doc/lispref/windows.texi | 2 ++ 2 files changed, 6 insertions(+) diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index d77ede29da1..82bc279fa5b 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog @@ -1,3 +1,7 @@ +2013-08-05 Xue Fuqiao + + * windows.texi (Window Start and End): Add an index. + 2013-08-02 Xue Fuqiao * display.texi (Face Functions): Add an index. diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi index 51a52218633..13c9ca53222 100644 --- a/doc/lispref/windows.texi +++ b/doc/lispref/windows.texi @@ -2569,6 +2569,7 @@ so @code{window-point} will stay behind text inserted there. @node Window Start and End @section The Window Start and End Positions @cindex window start position +@cindex display-start position Each window maintains a marker used to keep track of a buffer position that specifies where in the buffer display should start. This position @@ -3194,6 +3195,7 @@ The value returned is @var{columns}. Here is how you can determine whether a given position @var{position} is off the screen due to horizontal scrolling: +@c FIXME: Maybe hscroll-on-screen-p is a better name? @example @group (defun hscroll-on-screen (window position) From 38276e01dbc7519f1c79423c909c2703f8415ca8 Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Mon, 5 Aug 2013 15:06:29 +0200 Subject: [PATCH 025/449] lisp/frameset.el: New frame-id functions. (frameset--set-id): Doc fix. (frameset-frame-id, frameset-frame-id-equal-p) (frameset-locate-frame-id): New functions. (frameset--process-minibuffer-frames, frameset--reuse-frame) (frameset-restore): Use them. --- lisp/ChangeLog | 8 +++++++ lisp/frameset.el | 56 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 6ca96741b63..b1ff3080b4d 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,11 @@ +2013-08-05 Juanma Barranquero + + * frameset.el (frameset--set-id): Doc fix. + (frameset-frame-id, frameset-frame-id-equal-p) + (frameset-locate-frame-id): New functions. + (frameset--process-minibuffer-frames, frameset--reuse-frame) + (frameset-restore): Use them. + 2013-08-05 Dmitry Antipov Do not call to `selected-frame' where it is assumed by default. diff --git a/lisp/frameset.el b/lisp/frameset.el index c22d71b7d79..0e98f4655da 100644 --- a/lisp/frameset.el +++ b/lisp/frameset.el @@ -340,10 +340,10 @@ nil while the filtering is done to restore it." filtered)) -;; Saving framesets +;; Frame ids (defun frameset--set-id (frame) - "Set FRAME's `frameset--id' if not yet set. + "Set FRAME's id if not yet set. Internal use only." (unless (frame-parameter frame 'frameset--id) (set-frame-parameter frame @@ -351,6 +351,33 @@ Internal use only." (mapconcat (lambda (n) (format "%04X" n)) (cl-loop repeat 4 collect (random 65536)) "-")))) +;;;###autoload +(defun frameset-frame-id (frame) + "Return the frame id of FRAME, if it has one; else, return nil. +A frame id is a string that uniquely identifies a frame. +It is persistent across `frameset-save' / `frameset-restore' +invocations, and once assigned is never changed unless the same +frame is duplicated (via `frameset-restore'), in which case the +newest frame keeps the id and the old frame's is set to nil." + (frame-parameter frame 'frameset--id)) + +;;;###autoload +(defun frameset-frame-id-equal-p (frame id) + "Return non-nil if FRAME's id matches ID." + (string= (frameset-frame-id frame) id)) + +;;;###autoload +(defun frameset-locate-frame-id (id &optional frame-list) + "Return the live frame with id ID, if exists; else nil. +If FRAME-LIST is a list of frames, check these frames only. +If nil, check all live frames." + (cl-find-if (lambda (f) + (and (frame-live-p f) + (frameset-frame-id-equal-p f id))) + (or frame-list (frame-list)))) + + +;; Saving framesets (defun frameset--process-minibuffer-frames (frame-list) "Process FRAME-LIST and record minibuffer relationships. @@ -370,7 +397,7 @@ FRAME-LIST is a list of frames. Internal use only." (unless (frame-parameter frame 'frameset--mini) (frameset--set-id frame) (let* ((mb-frame (window-frame (minibuffer-window frame))) - (id (and mb-frame (frame-parameter mb-frame 'frameset--id)))) + (id (and mb-frame (frameset-frame-id mb-frame)))) (if (null id) (error "Minibuffer frame %S for %S is not being saved" mb-frame frame) ;; For minibufferless frames, frameset--mini is a cons @@ -516,7 +543,7 @@ is the parameter list of the frame being restored. Internal use only." ;; M-x desktop-read). (setq frame (frameset--find-frame (lambda (f id) - (string= (frame-parameter f 'frameset--id) id)) + (frameset-frame-id-equal-p f id)) display (cdr (assq 'frameset--id frame-cfg)))) ;; If it has not been loaded, and it is not a minibuffer-only frame, ;; let's look for an existing non-minibuffer-only frame to reuse. @@ -533,10 +560,10 @@ is the parameter list of the frame being restored. Internal use only." ;; and that they are linked to the right minibuffer frame. (setq frame (frameset--find-frame (lambda (f id mini-id) - (and (string= (frame-parameter f 'frameset--id) id) - (string= (frame-parameter (window-frame (minibuffer-window f)) - 'frameset--id) - mini-id))) + (and (frameset-frame-id-equal-p f id) + (frameset-frame-id-equal-p (window-frame + (minibuffer-window f)) + mini-id))) display (cdr (assq 'frameset--id frame-cfg)) (cdr mini)))) (t ;; Default to just finding a frame in the same display. @@ -740,11 +767,8 @@ All keywords default to nil." ;; frameset--id from the non-reusable frame, which is not useful anymore. (when (and other-frames (or (eq reuse-frames :keep) (consp reuse-frames))) - (let ((dup (cl-find (cdr (assq 'frameset--id frame-cfg)) - other-frames - :key (lambda (frame) - (frame-parameter frame 'frameset--id)) - :test #'string=))) + (let ((dup (frameset-locate-frame-id (cdr (assq 'frameset--id frame-cfg)) + other-frames))) (when dup (set-frame-parameter dup 'frameset--id nil)))) ;; Restore minibuffers. Some of this stuff could be done in a filter @@ -759,11 +783,7 @@ All keywords default to nil." (setq frame-cfg (append '((tool-bar-lines . 0) (menu-bar-lines . 0)) frame-cfg)))) (t ;; Frame depends on other frame's minibuffer window. - (let* ((mb-frame (or (cl-find-if - (lambda (f) - (string= (frame-parameter f 'frameset--id) - mb-id)) - (frame-list)) + (let* ((mb-frame (or (frameset-locate-frame-id mb-id) (error "Minibuffer frame %S not found" mb-id))) (mb-param (assq 'minibuffer frame-cfg)) (mb-window (minibuffer-window mb-frame))) From 57fedd9fe118489c8dfa3a4d3baee1b9a7a6fad0 Mon Sep 17 00:00:00 2001 From: Xue Fuqiao Date: Mon, 5 Aug 2013 21:28:29 +0800 Subject: [PATCH 026/449] * doc/misc/cl.texi (Blocks and Exits): Add an index. --- doc/misc/ChangeLog | 4 ++++ doc/misc/cl.texi | 1 + 2 files changed, 5 insertions(+) diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog index 979ec83010e..e8a5a7e22b2 100644 --- a/doc/misc/ChangeLog +++ b/doc/misc/ChangeLog @@ -1,3 +1,7 @@ +2013-08-05 Xue Fuqiao + + * cl.texi (Blocks and Exits): Add an index. + 2013-08-04 Stephen Berman * Makefile.in (INFO_TARGETS, DVI_TARGETS, PDF_TARGETS): Add todo-mode. diff --git a/doc/misc/cl.texi b/doc/misc/cl.texi index 90f8a258d23..1b5ea6e78dd 100644 --- a/doc/misc/cl.texi +++ b/doc/misc/cl.texi @@ -1492,6 +1492,7 @@ simply returning @code{nil}. @node Blocks and Exits @section Blocks and Exits +@cindex block @noindent Common Lisp @dfn{blocks} provide a non-local exit mechanism very From b27a1bd53ac62bad378cbafcfb594ac37357bbc6 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Mon, 5 Aug 2013 14:15:37 +0000 Subject: [PATCH 027/449] gnus-int.el (gnus-warp-to-article): Allow warping in all groups so that we can create nndoc groups that excerpt other groups --- lisp/gnus/ChangeLog | 5 +++++ lisp/gnus/gnus-int.el | 22 +++++++++++----------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index 2164fd96b46..2ae70791c16 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog @@ -1,3 +1,8 @@ +2013-08-05 Dave Abrahams + + * gnus-int.el (gnus-warp-to-article): Allow warping in all groups so + that we can create nndoc groups that excerpt other groups. + 2013-08-02 Lars Magne Ingebrigtsen * gnus-delay.el (gnus-delay-article): Fix typo. diff --git a/lisp/gnus/gnus-int.el b/lisp/gnus/gnus-int.el index 6aa874f0347..f0cf0daed01 100644 --- a/lisp/gnus/gnus-int.el +++ b/lisp/gnus/gnus-int.el @@ -582,18 +582,18 @@ This is the string that Gnus uses to identify the group." (gnus-group-method group))) (defun gnus-warp-to-article () - "Jump from an article in a virtual group to the article in its real group. -Does nothing in a real group." + "Look up the current article in the group where it originated. +This command only makes sense for groups shows articles gathered +from other groups -- for instance, search results and the like." (interactive) - (when (gnus-virtual-group-p gnus-newsgroup-name) - (let ((gnus-command-method - (gnus-find-method-for-group gnus-newsgroup-name))) - (or - (when (gnus-check-backend-function - 'warp-to-article (car gnus-command-method)) - (funcall (gnus-get-function gnus-command-method 'warp-to-article))) - (and (bound-and-true-p gnus-registry-enabled) - (gnus-try-warping-via-registry)))))) + (let ((gnus-command-method + (gnus-find-method-for-group gnus-newsgroup-name))) + (or + (when (gnus-check-backend-function + 'warp-to-article (car gnus-command-method)) + (funcall (gnus-get-function gnus-command-method 'warp-to-article))) + (and (bound-and-true-p gnus-registry-enabled) + (gnus-try-warping-via-registry))))) (defun gnus-request-head (article group) "Request the head of ARTICLE in GROUP." From 290d5b5890c5c8d096bd846eb48552d4608d5ed6 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Mon, 5 Aug 2013 18:26:57 +0400 Subject: [PATCH 028/449] Do not call to `selected-window' where it is assumed by default. Affected functions are `window-minibuffer-p', `window-dedicated-p', `window-hscroll', `window-width', `window-height', `window-buffer', `window-frame', `window-start', `window-point', `next-window' and `window-display-table'. * abbrev.el (abbrev--default-expand): * bs.el (bs--show-with-configuration): * buff-menu.el (Buffer-menu-mouse-select): * calc/calc.el (calc): * calendar/calendar.el (calendar-generate-window): * calendar/diary-lib.el (diary-simple-display, diary-show-all-entries) (diary-make-entry): * comint.el (send-invisible, comint-dynamic-complete-filename) (comint-dynamic-simple-complete, comint-dynamic-list-completions): * completion.el (complete): * dabbrev.el (dabbrev-expand, dabbrev--make-friend-buffer-list): * disp-table.el (describe-current-display-table): * doc-view.el (doc-view-insert-image): * ebuff-menu.el (Electric-buffer-menu-mouse-select): * ehelp.el (with-electric-help): * emacs-lisp/easy-mmode.el (easy-mmode-define-navigation): * emacs-lisp/edebug.el (edebug-two-window-p, edebug-pop-to-buffer): * emacs-lisp/helper.el (Helper-help-scroller): * emulation/cua-base.el (cua--post-command-handler-1): * eshell/esh-mode.el (eshell-output-filter): * ffap.el (ffap-gnus-wrapper): * help-macro.el (make-help-screen): * hilit-chg.el (highlight-compare-buffers): * hippie-exp.el (hippie-expand, try-expand-dabbrev-visible): * hl-line.el (global-hl-line-highlight): * icomplete.el (icomplete-simple-completing-p): * isearch.el (isearch-done): * jit-lock.el (jit-lock-stealth-fontify): * mail/rmailsum.el (rmail-summary-scroll-msg-up): * lisp/mouse-drag.el (mouse-drag-should-do-col-scrolling): * mpc.el (mpc-tagbrowser, mpc): * net/rcirc.el (rcirc-any-buffer): * play/gomoku.el (gomoku-max-width, gomoku-max-height): * play/landmark.el (landmark-max-width, landmark-max-height): * play/zone.el (zone): * progmodes/compile.el (compilation-goto-locus): * progmodes/ebrowse.el (ebrowse-view/find-file-and-search-pattern): * progmodes/etags.el (find-tag-other-window): * progmodes/fortran.el (fortran-column-ruler): * progmodes/gdb-mi.el (gdb-mouse-toggle-breakpoint-fringe): * progmodes/verilog-mode.el (verilog-point-text): * reposition.el (reposition-window): * rot13.el (toggle-rot13-mode): * server.el (server-switch-buffer): * shell.el (shell-dynamic-complete-command) (shell-dynamic-complete-environment-variable): * simple.el (insert-buffer, set-selective-display) (delete-completion-window): * speedbar.el (speedbar-timer-fn, speedbar-center-buffer-smartly) (speedbar-recenter): * startup.el (fancy-splash-head): * textmodes/ispell.el (ispell-command-loop): * textmodes/makeinfo.el (makeinfo-compilation-sentinel-region): * tutorial.el (help-with-tutorial): * vc/add-log.el (add-change-log-entry): * vc/compare-w.el (compare-windows): * vc/ediff-help.el (ediff-indent-help-message): * vc/ediff-util.el (ediff-setup-control-buffer, ediff-position-region): * vc/ediff-wind.el (ediff-skip-unsuitable-frames) (ediff-setup-control-frame): * vc/emerge.el (emerge-position-region): * vc/pcvs-util.el (cvs-bury-buffer): * window.el (walk-windows, mouse-autoselect-window-select): * winner.el (winner-set-conf, winner-undo): Related users changed. --- lisp/ChangeLog | 72 ++++++++++++++++++++++++++++++++++ lisp/abbrev.el | 2 +- lisp/bs.el | 2 +- lisp/buff-menu.el | 2 +- lisp/calc/calc.el | 2 +- lisp/calendar/calendar.el | 2 +- lisp/calendar/diary-lib.el | 9 ++--- lisp/comint.el | 8 ++-- lisp/completion.el | 2 +- lisp/dabbrev.el | 4 +- lisp/disp-table.el | 2 +- lisp/doc-view.el | 2 +- lisp/ebuff-menu.el | 2 +- lisp/ehelp.el | 2 +- lisp/emacs-lisp/easy-mmode.el | 2 +- lisp/emacs-lisp/edebug.el | 4 +- lisp/emacs-lisp/helper.el | 2 +- lisp/emulation/cua-base.el | 2 +- lisp/eshell/esh-mode.el | 2 +- lisp/ffap.el | 2 +- lisp/help-macro.el | 4 +- lisp/hilit-chg.el | 2 +- lisp/hippie-exp.el | 6 +-- lisp/hl-line.el | 2 +- lisp/icomplete.el | 2 +- lisp/isearch.el | 2 +- lisp/jit-lock.el | 2 +- lisp/mail/rmail.el | 4 +- lisp/mail/rmailsum.el | 2 +- lisp/mouse-drag.el | 2 +- lisp/mpc.el | 5 +-- lisp/net/rcirc.el | 2 +- lisp/play/gomoku.el | 4 +- lisp/play/landmark.el | 4 +- lisp/play/zone.el | 2 +- lisp/progmodes/compile.el | 2 +- lisp/progmodes/ebrowse.el | 2 +- lisp/progmodes/etags.el | 2 +- lisp/progmodes/fortran.el | 3 +- lisp/progmodes/gdb-mi.el | 2 +- lisp/progmodes/verilog-mode.el | 2 +- lisp/reposition.el | 2 +- lisp/rot13.el | 4 +- lisp/server.el | 8 ++-- lisp/shell.el | 4 +- lisp/simple.el | 9 ++--- lisp/speedbar.el | 16 ++++---- lisp/startup.el | 2 +- lisp/textmodes/ispell.el | 2 +- lisp/textmodes/makeinfo.el | 2 +- lisp/tutorial.el | 2 +- lisp/vc/add-log.el | 6 +-- lisp/vc/compare-w.el | 2 +- lisp/vc/ediff-help.el | 2 +- lisp/vc/ediff-util.el | 4 +- lisp/vc/ediff-wind.el | 6 +-- lisp/vc/emerge.el | 2 +- lisp/vc/pcvs-util.el | 6 +-- lisp/window.el | 6 +-- lisp/winner.el | 5 +-- 60 files changed, 169 insertions(+), 106 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index b1ff3080b4d..8bc39097187 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,75 @@ +2013-08-05 Dmitry Antipov + + Do not call to `selected-window' where it is assumed by default. + Affected functions are `window-minibuffer-p', `window-dedicated-p', + `window-hscroll', `window-width', `window-height', `window-buffer', + `window-frame', `window-start', `window-point', `next-window' + and `window-display-table'. + * abbrev.el (abbrev--default-expand): + * bs.el (bs--show-with-configuration): + * buff-menu.el (Buffer-menu-mouse-select): + * calc/calc.el (calc): + * calendar/calendar.el (calendar-generate-window): + * calendar/diary-lib.el (diary-simple-display, diary-show-all-entries) + (diary-make-entry): + * comint.el (send-invisible, comint-dynamic-complete-filename) + (comint-dynamic-simple-complete, comint-dynamic-list-completions): + * completion.el (complete): + * dabbrev.el (dabbrev-expand, dabbrev--make-friend-buffer-list): + * disp-table.el (describe-current-display-table): + * doc-view.el (doc-view-insert-image): + * ebuff-menu.el (Electric-buffer-menu-mouse-select): + * ehelp.el (with-electric-help): + * emacs-lisp/easy-mmode.el (easy-mmode-define-navigation): + * emacs-lisp/edebug.el (edebug-two-window-p, edebug-pop-to-buffer): + * emacs-lisp/helper.el (Helper-help-scroller): + * emulation/cua-base.el (cua--post-command-handler-1): + * eshell/esh-mode.el (eshell-output-filter): + * ffap.el (ffap-gnus-wrapper): + * help-macro.el (make-help-screen): + * hilit-chg.el (highlight-compare-buffers): + * hippie-exp.el (hippie-expand, try-expand-dabbrev-visible): + * hl-line.el (global-hl-line-highlight): + * icomplete.el (icomplete-simple-completing-p): + * isearch.el (isearch-done): + * jit-lock.el (jit-lock-stealth-fontify): + * mail/rmailsum.el (rmail-summary-scroll-msg-up): + * lisp/mouse-drag.el (mouse-drag-should-do-col-scrolling): + * mpc.el (mpc-tagbrowser, mpc): + * net/rcirc.el (rcirc-any-buffer): + * play/gomoku.el (gomoku-max-width, gomoku-max-height): + * play/landmark.el (landmark-max-width, landmark-max-height): + * play/zone.el (zone): + * progmodes/compile.el (compilation-goto-locus): + * progmodes/ebrowse.el (ebrowse-view/find-file-and-search-pattern): + * progmodes/etags.el (find-tag-other-window): + * progmodes/fortran.el (fortran-column-ruler): + * progmodes/gdb-mi.el (gdb-mouse-toggle-breakpoint-fringe): + * progmodes/verilog-mode.el (verilog-point-text): + * reposition.el (reposition-window): + * rot13.el (toggle-rot13-mode): + * server.el (server-switch-buffer): + * shell.el (shell-dynamic-complete-command) + (shell-dynamic-complete-environment-variable): + * simple.el (insert-buffer, set-selective-display) + (delete-completion-window): + * speedbar.el (speedbar-timer-fn, speedbar-center-buffer-smartly) + (speedbar-recenter): + * startup.el (fancy-splash-head): + * textmodes/ispell.el (ispell-command-loop): + * textmodes/makeinfo.el (makeinfo-compilation-sentinel-region): + * tutorial.el (help-with-tutorial): + * vc/add-log.el (add-change-log-entry): + * vc/compare-w.el (compare-windows): + * vc/ediff-help.el (ediff-indent-help-message): + * vc/ediff-util.el (ediff-setup-control-buffer, ediff-position-region): + * vc/ediff-wind.el (ediff-skip-unsuitable-frames) + (ediff-setup-control-frame): + * vc/emerge.el (emerge-position-region): + * vc/pcvs-util.el (cvs-bury-buffer): + * window.el (walk-windows, mouse-autoselect-window-select): + * winner.el (winner-set-conf, winner-undo): Related users changed. + 2013-08-05 Juanma Barranquero * frameset.el (frameset--set-id): Doc fix. diff --git a/lisp/abbrev.el b/lisp/abbrev.el index 27cd7089a07..d82e2eabd84 100644 --- a/lisp/abbrev.el +++ b/lisp/abbrev.el @@ -856,7 +856,7 @@ return value is that of `abbrev-insert'.)" (endmark (copy-marker wordend t))) (unless (or ;; executing-kbd-macro noninteractive - (window-minibuffer-p (selected-window))) + (window-minibuffer-p)) ;; Add an undo boundary, in case we are doing this for ;; a self-inserting command which has avoided making one so far. (undo-boundary)) diff --git a/lisp/bs.el b/lisp/bs.el index af213333a79..6871a7eeb83 100644 --- a/lisp/bs.el +++ b/lisp/bs.el @@ -1406,7 +1406,7 @@ for buffer selection." (select-window active-window) (bs--restore-window-config) (setq bs--window-config-coming-from (current-window-configuration)) - (when (> (window-height (selected-window)) 7) + (when (> (window-height) 7) ;; Errors would mess with the window configuration (bug#10882). (ignore-errors (select-window (split-window-below))))) (bs-show-in-buffer liste) diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el index 1db9b7229f3..58fde695b39 100644 --- a/lisp/buff-menu.el +++ b/lisp/buff-menu.el @@ -591,7 +591,7 @@ means list those buffers and no others." (select-window (posn-window (event-end event))) (let ((buffer (tabulated-list-get-id (posn-point (event-end event))))) (when (buffer-live-p buffer) - (if (and (window-dedicated-p (selected-window)) + (if (and (window-dedicated-p) (eq (selected-window) (frame-root-window))) (switch-to-buffer-other-frame buffer) (switch-to-buffer buffer))))) diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el index 8a17ad7ce30..e72d0aacd5d 100644 --- a/lisp/calc/calc.el +++ b/lisp/calc/calc.el @@ -1441,7 +1441,7 @@ commands given here will actually operate on the *Calculator* stack." (calc-keypad)))) (when (get-buffer-window "*Calc Keypad*") (calc-keypad) - (set-buffer (window-buffer (selected-window)))) + (set-buffer (window-buffer))) (if (eq major-mode 'calc-mode) (calc-quit) (let ((oldbuf (current-buffer))) diff --git a/lisp/calendar/calendar.el b/lisp/calendar/calendar.el index d7e6ea68efa..40dcb25bc30 100644 --- a/lisp/calendar/calendar.el +++ b/lisp/calendar/calendar.el @@ -1422,7 +1422,7 @@ Optional integers MON and YR are used instead of today's date." (year (calendar-extract-year today)) (today-visible (or (not mon) (<= (abs (calendar-interval mon yr month year)) 1))) - (in-calendar-window (eq (window-buffer (selected-window)) + (in-calendar-window (eq (window-buffer) (get-buffer calendar-buffer)))) (calendar-generate (or mon month) (or yr year)) (calendar-update-mode-line) diff --git a/lisp/calendar/diary-lib.el b/lisp/calendar/diary-lib.el index 7bdb3cd49f6..6b89677554f 100644 --- a/lisp/calendar/diary-lib.el +++ b/lisp/calendar/diary-lib.el @@ -1011,8 +1011,7 @@ Entries that do not apply are made invisible. Holidays are shown in the mode line. This is an option for `diary-display-function'." ;; If selected window is dedicated (to the calendar), need a new one ;; to display the diary. - (let* ((pop-up-frames (or pop-up-frames - (window-dedicated-p (selected-window)))) + (let* ((pop-up-frames (or pop-up-frames (window-dedicated-p))) (dbuff (find-buffer-visiting diary-file)) (empty (diary-display-no-entries))) ;; This may be too wide, but when simple diary is used there is @@ -1216,8 +1215,7 @@ all entries, not just some, are visible. If there is no diary buffer, one is created." (interactive) (let* ((d-file (diary-check-diary-file)) - (pop-up-frames (or pop-up-frames - (window-dedicated-p (selected-window)))) + (pop-up-frames (or pop-up-frames (window-dedicated-p))) (win (selected-window)) (height (window-height))) (with-current-buffer (or (find-buffer-visiting d-file) @@ -2116,8 +2114,7 @@ calendar." "Insert a diary entry STRING which may be NONMARKING in FILE. If omitted, NONMARKING defaults to nil and FILE defaults to `diary-file'." - (let ((pop-up-frames (or pop-up-frames - (window-dedicated-p (selected-window))))) + (let ((pop-up-frames (or pop-up-frames (window-dedicated-p)))) (find-file-other-window (or file diary-file))) (when (eq major-mode (default-value 'major-mode)) (diary-mode)) (widen) diff --git a/lisp/comint.el b/lisp/comint.el index 217bd4e8b6d..c2b69a42a8b 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -2296,7 +2296,7 @@ Security bug: your string can still be temporarily recovered with (interactive "P") ; Defeat snooping via C-x ESC ESC (let ((proc (get-buffer-process (current-buffer))) (prefix - (if (eq (window-buffer (selected-window)) (current-buffer)) + (if (eq (window-buffer) (current-buffer)) "" (format "(In buffer %s) " (current-buffer))))) @@ -3108,7 +3108,7 @@ completions listing is dependent on the value of `comint-completion-autolist'. Returns t if successful." (interactive) (when (comint--match-partial-filename) - (unless (window-minibuffer-p (selected-window)) + (unless (window-minibuffer-p) (message "Completing file name...")) (let ((data (comint--complete-file-name-data))) (completion-in-region (nth 0 data) (nth 1 data) (nth 2 data))))) @@ -3211,7 +3211,7 @@ Return `listed' if a completion listing was shown. See also `comint-dynamic-complete-filename'." (declare (obsolete completion-in-region "24.1")) (let* ((completion-ignore-case (memq system-type '(ms-dos windows-nt cygwin))) - (minibuffer-p (window-minibuffer-p (selected-window))) + (minibuffer-p (window-minibuffer-p)) (suffix (cond ((not comint-completion-addsuffix) "") ((not (consp comint-completion-addsuffix)) " ") (t (cdr comint-completion-addsuffix)))) @@ -3308,7 +3308,7 @@ Typing SPC flushes the completions buffer." (current-window-configuration)) (with-output-to-temp-buffer "*Completions*" (display-completion-list completions common-substring)) - (if (window-minibuffer-p (selected-window)) + (if (window-minibuffer-p) (minibuffer-message "Type space to flush; repeat completion command to scroll") (message "Type space to flush; repeat completion command to scroll"))) diff --git a/lisp/completion.el b/lisp/completion.el index 3fbc3c05fb4..dbddc6f5b87 100644 --- a/lisp/completion.el +++ b/lisp/completion.el @@ -1626,7 +1626,7 @@ Prefix args :: ;; Get the next completion (let* ((print-status-p (and (>= baud-rate completion-prompt-speed-threshold) - (not (window-minibuffer-p (selected-window))))) + (not (window-minibuffer-p)))) (insert-point (point)) (entry (completion-search-next cmpl-current-index)) string) diff --git a/lisp/dabbrev.el b/lisp/dabbrev.el index d1bdd3f52be..e2aeb4ea19b 100644 --- a/lisp/dabbrev.el +++ b/lisp/dabbrev.el @@ -457,7 +457,7 @@ See also `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]." (markerp dabbrev--last-abbrev-location) (marker-position dabbrev--last-abbrev-location) (or (eq last-command this-command) - (and (window-minibuffer-p (selected-window)) + (and (window-minibuffer-p) (= dabbrev--last-abbrev-location (point))))) ;; Find a different expansion for the same abbrev as last time. @@ -793,7 +793,7 @@ of the start of the occurrence." ;; In a minibuffer, search the buffer it was activated from, ;; first after the minibuffer itself. Unless we aren't supposed ;; to search the current buffer either. - (if (and (window-minibuffer-p (selected-window)) + (if (and (window-minibuffer-p) (not dabbrev-search-these-buffers-only)) (setq list (cons (dabbrev--minibuffer-origin) diff --git a/lisp/disp-table.el b/lisp/disp-table.el index 423648f70b5..7c75b38c9d4 100644 --- a/lisp/disp-table.el +++ b/lisp/disp-table.el @@ -119,7 +119,7 @@ Valid symbols are `truncation', `wrap', `escape', `control', (defun describe-current-display-table () "Describe the display table in use in the selected window and buffer." (interactive) - (let ((disptab (or (window-display-table (selected-window)) + (let ((disptab (or (window-display-table) buffer-display-table standard-display-table))) (if disptab diff --git a/lisp/doc-view.el b/lisp/doc-view.el index 10968f7f8dd..589a57b64c2 100644 --- a/lisp/doc-view.el +++ b/lisp/doc-view.el @@ -1262,7 +1262,7 @@ ARGS is a list of image descriptors." (car (image-size image 'pixels))) img-width) img-width)) - (window-width (window-width (selected-window)))) + (window-width (window-width))) (setf (doc-view-current-image) image) (move-overlay ol (point-min) (point-max)) ;; In case the window is wider than the image, center the image diff --git a/lisp/ebuff-menu.el b/lisp/ebuff-menu.el index 10d8e025067..9ac62b68272 100644 --- a/lisp/ebuff-menu.el +++ b/lisp/ebuff-menu.el @@ -227,7 +227,7 @@ Select buffer at point and display buffers marked \">\" in other windows." (defun Electric-buffer-menu-mouse-select (event) (interactive "e") (select-window (posn-window (event-end event))) - (set-buffer (window-buffer (selected-window))) + (set-buffer (window-buffer)) (goto-char (posn-point (event-end event))) (throw 'electric-buffer-menu-select (point))) diff --git a/lisp/ehelp.el b/lisp/ehelp.el index 88fc87b5b7a..b2007909209 100644 --- a/lisp/ehelp.el +++ b/lisp/ehelp.el @@ -146,7 +146,7 @@ BUFFER is put back into its original major mode." (unwind-protect (save-excursion (when one - (goto-char (window-start (selected-window)))) + (goto-char (window-start))) (let ((pop-up-windows t)) (pop-to-buffer buffer)) (with-current-buffer buffer diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index f8fb65be4d3..1301b70bb85 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -604,7 +604,7 @@ BODY is executed after moving to the destination location." (goto-char (or ,(if endfun `(funcall #',endfun)) (point-max))) (user-error "No next %s" ,name)) (goto-char (match-beginning 0)) - (when (and (eq (current-buffer) (window-buffer (selected-window))) + (when (and (eq (current-buffer) (window-buffer)) (called-interactively-p 'interactive)) (let ((endpt (or (save-excursion ,(if endfun `(funcall #',endfun) diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index ac7e5f12a18..928d49f85ba 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -293,7 +293,7 @@ A lambda list keyword is a symbol that starts with `&'." "Return t if there are two windows." (and (not (one-window-p)) (eq (selected-window) - (next-window (next-window (selected-window)))))) + (next-window (next-window))))) (defun edebug-sort-alist (alist function) ;; Return the ALIST sorted with comparison function FUNCTION. @@ -334,7 +334,7 @@ Return the result of the last expression in BODY." ((and (edebug-window-live-p window) (eq (window-buffer window) buffer)) window) - ((eq (window-buffer (selected-window)) buffer) + ((eq (window-buffer) buffer) ;; Selected window already displays BUFFER. (selected-window)) ((get-buffer-window buffer 0)) diff --git a/lisp/emacs-lisp/helper.el b/lisp/emacs-lisp/helper.el index f3b7de521cf..5bef0b06fd4 100644 --- a/lisp/emacs-lisp/helper.el +++ b/lisp/emacs-lisp/helper.el @@ -59,7 +59,7 @@ Helper-return-blurb) "return"))) (save-window-excursion - (goto-char (window-start (selected-window))) + (goto-char (window-start)) (if (get-buffer-window "*Help*") (pop-to-buffer "*Help*") (switch-to-buffer "*Help*")) diff --git a/lisp/emulation/cua-base.el b/lisp/emulation/cua-base.el index 973768b50ef..292fd401a56 100644 --- a/lisp/emulation/cua-base.el +++ b/lisp/emulation/cua-base.el @@ -1298,7 +1298,7 @@ If ARG is the atom `-', scroll upward by nearly full screen." (mark t) (point) cua--explicit-region-start)))) ;; Disable transient-mark-mode if rectangle active in current buffer. - (if (not (window-minibuffer-p (selected-window))) + (if (not (window-minibuffer-p)) (setq transient-mark-mode (and (not cua--rectangle) (if cua-highlight-region-shift-only (not cua--explicit-region-start) diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el index 5346bd16fd2..ed5fecf09ff 100644 --- a/lisp/eshell/esh-mode.el +++ b/lisp/eshell/esh-mode.el @@ -740,7 +740,7 @@ This is done after all necessary filtering has been done." (if (<= (point) oend) (setq oend (+ oend nchars))) (insert-before-markers string) - (if (= (window-start (selected-window)) (point)) + (if (= (window-start) (point)) (set-window-start (selected-window) (- (point) nchars))) (if (= (point) eshell-last-input-end) diff --git a/lisp/ffap.el b/lisp/ffap.el index 70096248e19..ee0b87e8f87 100644 --- a/lisp/ffap.el +++ b/lisp/ffap.el @@ -1736,7 +1736,7 @@ Only intended for interactive use." ;; Preserve selected buffer, but do not do save-window-excursion, ;; since we want to see any window created by the form. Temporarily ;; select the article buffer, so we can see any point movement. - (let ((sb (window-buffer (selected-window)))) + (let ((sb (window-buffer))) (gnus-configure-windows 'article) (pop-to-buffer gnus-article-buffer) (widen) diff --git a/lisp/help-macro.el b/lisp/help-macro.el index 566f1597596..f0fda357705 100644 --- a/lisp/help-macro.el +++ b/lisp/help-macro.el @@ -136,9 +136,9 @@ and then returns." (setq config (current-window-configuration)) (pop-to-buffer " *Metahelp*" nil t) (and (fboundp 'make-frame) - (not (eq (window-frame (selected-window)) + (not (eq (window-frame) prev-frame)) - (setq new-frame (window-frame (selected-window)) + (setq new-frame (window-frame) config nil)) (setq buffer-read-only nil) (let ((inhibit-read-only t)) diff --git a/lisp/hilit-chg.el b/lisp/hilit-chg.el index 17b91245d60..1da3d68e131 100644 --- a/lisp/hilit-chg.el +++ b/lisp/hilit-chg.el @@ -860,7 +860,7 @@ changes are made, so \\[highlight-changes-next-change] and (get-buffer (read-buffer "buffer-a " (current-buffer) t)) (get-buffer (read-buffer "buffer-b " - (window-buffer (next-window (selected-window))) t)))) + (window-buffer (next-window)) t)))) (let ((file-a (buffer-file-name buf-a)) (file-b (buffer-file-name buf-b))) (highlight-markup-buffers buf-a file-a buf-b file-b) diff --git a/lisp/hippie-exp.el b/lisp/hippie-exp.el index 7d14d780e2e..ad233b2a507 100644 --- a/lisp/hippie-exp.el +++ b/lisp/hippie-exp.el @@ -296,7 +296,7 @@ undoes the expansion." (message "No further expansions found")) (ding)) (if (and hippie-expand-verbose - (not (window-minibuffer-p (selected-window)))) + (not (window-minibuffer-p))) (message "Using %s" (nth he-num hippie-expand-try-functions-list))))) (if (and (>= he-num 0) @@ -305,7 +305,7 @@ undoes the expansion." (setq he-num -1) (he-reset-string) (if (and hippie-expand-verbose - (not (window-minibuffer-p (selected-window)))) + (not (window-minibuffer-p))) (message "Undoing expansions")))))) ;; Initializes the region to expand (to between BEG and END). @@ -978,7 +978,7 @@ The argument OLD has to be nil the first call of this function, and t for subsequent calls (for further possible expansions of the same string). It returns t if a new expansion is found, nil otherwise." (let ((expansion ()) - (flag (if (frame-visible-p (window-frame (selected-window))) + (flag (if (frame-visible-p (window-frame)) 'visible t))) (unless old (he-init-string (he-dabbrev-beg) (point)) diff --git a/lisp/hl-line.el b/lisp/hl-line.el index 1ed17b4cd8e..e2171a27f5c 100644 --- a/lisp/hl-line.el +++ b/lisp/hl-line.el @@ -198,7 +198,7 @@ Global-Hl-Line mode uses the functions `global-hl-line-unhighlight' and (defun global-hl-line-highlight () "Highlight the current line in the current window." (when global-hl-line-mode ; Might be changed outside the mode function. - (unless (window-minibuffer-p (selected-window)) + (unless (window-minibuffer-p) (unless global-hl-line-overlay (setq global-hl-line-overlay (make-overlay 1 1)) ; to be moved (overlay-put global-hl-line-overlay 'face hl-line-face)) diff --git a/lisp/icomplete.el b/lisp/icomplete.el index 73049df097d..104e3363831 100644 --- a/lisp/icomplete.el +++ b/lisp/icomplete.el @@ -221,7 +221,7 @@ Conditions are: indicate some non-standard, non-simple completion mechanism, like file-name and other custom-func completions)." - (and (window-minibuffer-p (selected-window)) + (and (window-minibuffer-p) (not executing-kbd-macro) minibuffer-completion-table (or (not (functionp minibuffer-completion-table)) diff --git a/lisp/isearch.el b/lisp/isearch.el index ec4f32aecca..a591f8b4291 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -1015,7 +1015,7 @@ NOPUSH is t and EDIT is t." (setq minibuffer-message-timeout isearch-original-minibuffer-message-timeout) (isearch-dehighlight) (lazy-highlight-cleanup lazy-highlight-cleanup) - (let ((found-start (window-start (selected-window))) + (let ((found-start (window-start)) (found-point (point))) (when isearch-window-configuration (set-window-configuration isearch-window-configuration) diff --git a/lisp/jit-lock.el b/lisp/jit-lock.el index 9d700a5ed82..d0e88309daf 100644 --- a/lisp/jit-lock.el +++ b/lisp/jit-lock.el @@ -482,7 +482,7 @@ non-nil in a repeated invocation of this function." (cancel-timer jit-lock-stealth-repeat-timer)) (unless (or executing-kbd-macro memory-full - (window-minibuffer-p (selected-window)) + (window-minibuffer-p) ;; For first invocation set up `jit-lock-stealth-buffers'. ;; In repeated invocations it's already been set up. (null (if repeat diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el index 8eeb0991653..aa244ddae81 100644 --- a/lisp/mail/rmail.el +++ b/lisp/mail/rmail.el @@ -4768,9 +4768,7 @@ If prefix argument REVERSE is non-nil, sorts in reverse order. ;;;*** -;;;### (autoloads (rmail-summary-by-senders rmail-summary-by-topic -;;;;;; rmail-summary-by-regexp rmail-summary-by-recipients rmail-summary-by-labels -;;;;;; rmail-summary) "rmailsum" "rmailsum.el" "61e7ad0931be1e07034dd57825ff326a") +;;;### (autoloads nil "rmailsum" "rmailsum.el" "a9b3bbd9b82dd566524a1209b5cdb7dd") ;;; Generated autoloads from rmailsum.el (autoload 'rmail-summary "rmailsum" "\ diff --git a/lisp/mail/rmailsum.el b/lisp/mail/rmailsum.el index 8dd4120d179..3a0a7824ad8 100644 --- a/lisp/mail/rmailsum.el +++ b/lisp/mail/rmailsum.el @@ -1288,7 +1288,7 @@ advance to the next message." (prog1 ;; Is EOB visible in the buffer? (save-excursion - (let ((ht (window-height (selected-window)))) + (let ((ht (window-height))) (move-to-window-line (- ht 2)) (end-of-line) (eobp))) diff --git a/lisp/mouse-drag.el b/lisp/mouse-drag.el index 3a29e05c8b1..009cc2efe1a 100644 --- a/lisp/mouse-drag.el +++ b/lisp/mouse-drag.el @@ -156,7 +156,7 @@ Keep the cursor on the screen as needed." "Determine if it's wise to enable col-scrolling for the current window. Basically, we check for existing horizontal scrolling." (or truncate-lines - (> (window-hscroll (selected-window)) 0) + (> (window-hscroll) 0) (not (window-full-width-p)) (and mouse-drag-electric-col-scrolling diff --git a/lisp/mpc.el b/lisp/mpc.el index ad7381bb4b7..0800af1bd36 100644 --- a/lisp/mpc.el +++ b/lisp/mpc.el @@ -1513,7 +1513,7 @@ when constructing the set of constraints." (let* ((newbuf (mpc-tagbrowser-buf tag)) (win (get-buffer-window newbuf 0))) (if win (select-window win) - (if (with-current-buffer (window-buffer (selected-window)) + (if (with-current-buffer (window-buffer) (derived-mode-p 'mpc-tagbrowser-mode)) (setq win (selected-window)) ;; Find a tagbrowser-mode buffer. @@ -2618,8 +2618,7 @@ This is used so that they can be compared with `eq', which is needed for (song-win (get-buffer-window song-buf 0))) (if song-win (select-window song-win) - (if (or (window-dedicated-p (selected-window)) - (window-minibuffer-p)) + (if (or (window-dedicated-p) (window-minibuffer-p)) (ignore-errors (select-frame (make-frame mpc-frame-alist))) (with-current-buffer song-buf (setq-local mpc-previous-window-config diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el index 7c70ded3eaa..2d8da415295 100644 --- a/lisp/net/rcirc.el +++ b/lisp/net/rcirc.el @@ -1331,7 +1331,7 @@ if ARG is omitted or nil." "Return a buffer for PROCESS, either the one selected or the process buffer." (if rcirc-always-use-server-buffer-flag (process-buffer process) - (let ((buffer (window-buffer (selected-window)))) + (let ((buffer (window-buffer))) (if (and buffer (with-current-buffer buffer (and (eq major-mode 'rcirc-mode) diff --git a/lisp/play/gomoku.el b/lisp/play/gomoku.el index f2abc00e3f5..609585c9522 100644 --- a/lisp/play/gomoku.el +++ b/lisp/play/gomoku.el @@ -948,13 +948,13 @@ If the game is finished, this command requests for another game." (defun gomoku-max-width () "Largest possible board width for the current window." - (1+ (/ (- (window-width (selected-window)) + (1+ (/ (- (window-width) gomoku-x-offset gomoku-x-offset 1) gomoku-square-width))) (defun gomoku-max-height () "Largest possible board height for the current window." - (1+ (/ (- (window-height (selected-window)) + (1+ (/ (- (window-height) gomoku-y-offset gomoku-y-offset 2) ;; 2 instead of 1 because WINDOW-HEIGHT includes the mode line ! gomoku-square-height))) diff --git a/lisp/play/landmark.el b/lisp/play/landmark.el index 0845ea2c300..cf86d7a9de5 100644 --- a/lisp/play/landmark.el +++ b/lisp/play/landmark.el @@ -843,13 +843,13 @@ If the game is finished, this command requests for another game." (defun landmark-max-width () "Largest possible board width for the current window." - (1+ (/ (- (window-width (selected-window)) + (1+ (/ (- (window-width) landmark-x-offset landmark-x-offset 1) landmark-square-width))) (defun landmark-max-height () "Largest possible board height for the current window." - (1+ (/ (- (window-height (selected-window)) + (1+ (/ (- (window-height) landmark-y-offset landmark-y-offset 2) ;; 2 instead of 1 because WINDOW-HEIGHT includes the mode line ! landmark-square-height))) diff --git a/lisp/play/zone.el b/lisp/play/zone.el index 1724ebdf198..0f333392b9a 100644 --- a/lisp/play/zone.el +++ b/lisp/play/zone.el @@ -110,7 +110,7 @@ If the element is a function or a list of a function and a number, (let ((f (selected-frame)) (outbuf (get-buffer-create "*zone*")) (text (buffer-substring (window-start) (window-end))) - (wp (1+ (- (window-point (selected-window)) + (wp (1+ (- (window-point) (window-start))))) (put 'zone 'orig-buffer (current-buffer)) (switch-to-buffer outbuf) diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el index d9c482330cc..e909f1a5e5b 100644 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el @@ -2492,7 +2492,7 @@ displays at the top of the window; there is no arrow." All arguments are markers. If END-MK is non-nil, mark is set there and overlay is highlighted between MK and END-MK." ;; Show compilation buffer in other window, scrolled to this error. - (let* ((from-compilation-buffer (eq (window-buffer (selected-window)) + (let* ((from-compilation-buffer (eq (window-buffer) (marker-buffer msg))) ;; Use an existing window if it is in a visible frame. (pre-existing (get-buffer-window (marker-buffer msg) 0)) diff --git a/lisp/progmodes/ebrowse.el b/lisp/progmodes/ebrowse.el index 6a71ab330a8..865211d109c 100644 --- a/lisp/progmodes/ebrowse.el +++ b/lisp/progmodes/ebrowse.el @@ -1605,7 +1605,7 @@ specifies where to find/view the result." ;; Get the source file to view or find. (setf file (ebrowse-find-source-file file tags-file)) ;; If current window is dedicated, use another frame. - (when (window-dedicated-p (selected-window)) + (when (window-dedicated-p) (setf where 'other-window)) (cond (view (setf ebrowse-temp-position-to-view struc diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el index ff6321d74c3..a7b7e630bb9 100644 --- a/lisp/progmodes/etags.el +++ b/lisp/progmodes/etags.el @@ -982,7 +982,7 @@ See documentation of variable `tags-file-name'." ;; selected window's buffer; without the hair, point is moved in both ;; windows. To prevent this, we save the selected window's point before ;; doing find-tag-noselect, and restore it after. - (let* ((window-point (window-point (selected-window))) + (let* ((window-point (window-point)) (tagbuf (find-tag-noselect tagname next-p regexp-p)) (tagpoint (progn (set-buffer tagbuf) (point)))) (set-window-point (prog1 diff --git a/lisp/progmodes/fortran.el b/lisp/progmodes/fortran.el index ff667f80f9d..0fc805aae81 100644 --- a/lisp/progmodes/fortran.el +++ b/lisp/progmodes/fortran.el @@ -1080,8 +1080,7 @@ The next key typed is executed unless it is SPC." fortran-column-ruler-fixed) (save-excursion (beginning-of-line) - (if (eq (window-start (selected-window)) - (window-point (selected-window))) + (if (eq (window-start) (window-point)) (line-beginning-position 2) (point))) nil "Type SPC or any command to erase ruler.")) diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index 4b51a5e7835..2017636435c 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el @@ -2951,7 +2951,7 @@ If not in a source or disassembly buffer just set point." obj) (when (numberp pos) (with-selected-window (posn-window posn) - (with-current-buffer (window-buffer (selected-window)) + (with-current-buffer (window-buffer) (goto-char pos) (dolist (overlay (overlays-in pos pos)) (when (overlay-get overlay 'put-break) diff --git a/lisp/progmodes/verilog-mode.el b/lisp/progmodes/verilog-mode.el index ed911fcbba2..03364bddd9f 100644 --- a/lisp/progmodes/verilog-mode.el +++ b/lisp/progmodes/verilog-mode.el @@ -3256,7 +3256,7 @@ inserted using a single call to `verilog-insert'." (defun verilog-point-text (&optional pointnum) "Return text describing where POINTNUM or current point is (for errors). Use filename, if current buffer being edited shorten to just buffer name." - (concat (or (and (equal (window-buffer (selected-window)) (current-buffer)) + (concat (or (and (equal (window-buffer) (current-buffer)) (buffer-name)) buffer-file-name (buffer-name)) diff --git a/lisp/reposition.el b/lisp/reposition.el index 0bd27654065..c67200f9550 100644 --- a/lisp/reposition.el +++ b/lisp/reposition.el @@ -61,7 +61,7 @@ first comment line visible (if point is in a comment)." (here (point)) ;; change this name once I've gotten rid of references to ht. ;; this is actually the number of the last screen line - (ht (- (window-height (selected-window)) 2)) + (ht (- (window-height) 2)) (line (repos-count-screen-lines (window-start) (point))) (comment-height ;; The call to max deals with the case of cursor between defuns. diff --git a/lisp/rot13.el b/lisp/rot13.el index 03beed3a85b..1b61855f2dc 100644 --- a/lisp/rot13.el +++ b/lisp/rot13.el @@ -101,9 +101,9 @@ See also `toggle-rot13-mode'." (defun toggle-rot13-mode () "Toggle the use of ROT13 encoding for the current window." (interactive) - (if (eq (window-display-table (selected-window)) rot13-display-table) + (if (eq (window-display-table) rot13-display-table) (set-window-display-table (selected-window) nil) - (if (null (window-display-table (selected-window))) + (if (null (window-display-table)) (set-window-display-table (selected-window) rot13-display-table)))) (provide 'rot13) diff --git a/lisp/server.el b/lisp/server.el index 8208e0b44d8..a76b2d4ce5f 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -1557,7 +1557,7 @@ be a cons cell (LINENUMBER . COLUMNNUMBER)." (setq next-buffer (car (process-get proc 'buffers)))) (setq rest (cdr rest))))) (and next-buffer (server-switch-buffer next-buffer killed-one)) - (unless (or next-buffer killed-one (window-dedicated-p (selected-window))) + (unless (or next-buffer killed-one (window-dedicated-p)) ;; (switch-to-buffer (other-buffer)) (message "No server buffers remain to edit"))) (if (not (buffer-live-p next-buffer)) @@ -1584,10 +1584,10 @@ be a cons cell (LINENUMBER . COLUMNNUMBER)." (unless (frame-live-p server-window) (setq server-window (make-frame))) (select-window (frame-selected-window server-window)))) - (when (window-minibuffer-p (selected-window)) + (when (window-minibuffer-p) (select-window (next-window nil 'nomini 0))) ;; Move to a non-dedicated window, if we have one. - (when (window-dedicated-p (selected-window)) + (when (window-dedicated-p) (select-window (get-window-with-predicate (lambda (w) @@ -1601,7 +1601,7 @@ be a cons cell (LINENUMBER . COLUMNNUMBER)." ;; a minibuffer/dedicated-window (if there's no other). (error (pop-to-buffer next-buffer))))))) (when server-raise-frame - (select-frame-set-input-focus (window-frame (selected-window)))))) + (select-frame-set-input-focus (window-frame))))) ;;;###autoload (defun server-save-buffers-kill-terminal (arg) diff --git a/lisp/shell.el b/lisp/shell.el index a78ab7f81ab..3ca2564b65c 100644 --- a/lisp/shell.el +++ b/lisp/shell.el @@ -1122,7 +1122,7 @@ Returns t if successful." (interactive) (let ((data (shell-command-completion))) (if data - (prog2 (unless (window-minibuffer-p (selected-window)) + (prog2 (unless (window-minibuffer-p) (message "Completing command name...")) (apply #'completion-in-region data))))) @@ -1232,7 +1232,7 @@ Returns non-nil if successful." (interactive) (let ((data (shell-environment-variable-completion))) (if data - (prog2 (unless (window-minibuffer-p (selected-window)) + (prog2 (unless (window-minibuffer-p) (message "Completing variable name...")) (apply #'completion-in-region data))))) diff --git a/lisp/simple.el b/lisp/simple.el index 6bb05c14a58..d64c0c9ac74 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -4098,9 +4098,9 @@ Don't call it from programs: use `insert-buffer-substring' instead!" (progn (barf-if-buffer-read-only) (read-buffer "Insert buffer: " - (if (eq (selected-window) (next-window (selected-window))) + (if (eq (selected-window) (next-window)) (other-buffer (current-buffer)) - (window-buffer (next-window (selected-window)))) + (window-buffer (next-window))) t)))) (push-mark (save-excursion @@ -5965,7 +5965,7 @@ The variable `selective-display' has a separate value for each buffer." (setq selective-display (and arg (prefix-numeric-value arg))) (recenter current-vpos)) - (set-window-start (selected-window) (window-start (selected-window))) + (set-window-start (selected-window) (window-start)) (princ "selective-display set to " t) (prin1 selective-display t) (princ "." t)) @@ -6629,8 +6629,7 @@ Go to the window from which completion was requested." (interactive) (let ((buf completion-reference-buffer)) (if (one-window-p t) - (if (window-dedicated-p (selected-window)) - (delete-frame)) + (if (window-dedicated-p) (delete-frame)) (delete-window (selected-window)) (if (get-buffer-window buf) (select-window (get-buffer-window buf)))))) diff --git a/lisp/speedbar.el b/lisp/speedbar.el index 2f995219193..d9f59b3a665 100644 --- a/lisp/speedbar.el +++ b/lisp/speedbar.el @@ -2648,7 +2648,7 @@ Also resets scanner functions." (dframe-select-attached-frame speedbar-frame) ;; make sure we at least choose a window to ;; get a good directory from - (if (window-minibuffer-p (selected-window)) + (if (window-minibuffer-p) nil ;; Check for special modes (speedbar-maybe-add-localized-support (current-buffer)) @@ -3512,7 +3512,7 @@ interested in." (set-buffer speedbar-buffer) (if (<= (count-lines (point-min) (point-max)) - (1- (window-height (selected-window)))) + (1- (window-height))) ;; whole buffer fits (let ((cp (point))) @@ -3545,7 +3545,7 @@ interested in." (setq end (point-max))))) ;; Now work out the details of centering (let ((nl (count-lines start end)) - (wl (1- (window-height (selected-window)))) + (wl (1- (window-height))) (cp (point))) (if (> nl wl) ;; We can't fit it all, so just center on cursor @@ -3558,12 +3558,12 @@ interested in." nil ;; we need to do something... (goto-char start) - (let ((newcent (/ (- (window-height (selected-window)) nl) 2)) + (let ((newcent (/ (- (window-height) nl) 2)) (lte (count-lines start (point-max)))) - (if (and (< (+ newcent lte) (window-height (selected-window))) - (> (- (window-height (selected-window)) lte 1) + (if (and (< (+ newcent lte) (window-height)) + (> (- (window-height) lte 1) newcent)) - (setq newcent (- (window-height (selected-window)) + (setq newcent (- (window-height) lte 1))) (recenter newcent)))) (goto-char cp)))))) @@ -3997,7 +3997,7 @@ TEXT is the buffer's name, TOKEN and INDENT are unused." (defun speedbar-recenter () "Recenter the current buffer so point is in the center of the window." - (recenter (/ (window-height (selected-window)) 2))) + (recenter (/ (window-height) 2))) ;;; Color loading section. diff --git a/lisp/startup.el b/lisp/startup.el index 44eea7745f7..ec7d73306a2 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -1541,7 +1541,7 @@ a face or button specification." (t "splash.pbm"))) (img (create-image image-file)) (image-width (and img (car (image-size img)))) - (window-width (window-width (selected-window)))) + (window-width (window-width))) (when img (when (> window-width image-width) ;; Center the image in the window. diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el index 94b184d09a1..3998fafa5cc 100644 --- a/lisp/textmodes/ispell.el +++ b/lisp/textmodes/ispell.el @@ -2218,7 +2218,7 @@ Global `ispell-quit' set to start location to continue spell session." (window-min-height (min window-min-height ispell-choices-win-default-height)) (command-characters '( ? ?i ?a ?A ?r ?R ?? ?x ?X ?q ?l ?u ?m )) - (dedicated (window-dedicated-p (selected-window))) + (dedicated (window-dedicated-p)) (skipped 0) char num result textwin dedicated-win) diff --git a/lisp/textmodes/makeinfo.el b/lisp/textmodes/makeinfo.el index 35c6e607569..4b57e0b9746 100644 --- a/lisp/textmodes/makeinfo.el +++ b/lisp/textmodes/makeinfo.el @@ -211,7 +211,7 @@ nonsensical results." (with-current-buffer buffer (revert-buffer t t)) (setq buffer (find-file-noselect makeinfo-output-file-name))) - (if (window-dedicated-p (selected-window)) + (if (window-dedicated-p) (switch-to-buffer-other-window buffer) (switch-to-buffer buffer))) (goto-char (point-min)))) diff --git a/lisp/tutorial.el b/lisp/tutorial.el index 39eb9e8b9aa..6fb8d05f438 100644 --- a/lisp/tutorial.el +++ b/lisp/tutorial.el @@ -896,7 +896,7 @@ Run the Viper tutorial? ")) ;; inserted at the start of the buffer, the "type C-v to ;; move to the next screen" might not be visible on the ;; first screen (n < 0). How will the novice know what to do? - (let ((n (- (window-height (selected-window)) + (let ((n (- (window-height) (count-lines (point-min) (point)) 6))) (if (< n 8) diff --git a/lisp/vc/add-log.el b/lisp/vc/add-log.el index f0ea9c68464..f926a164797 100644 --- a/lisp/vc/add-log.el +++ b/lisp/vc/add-log.el @@ -813,12 +813,12 @@ non-nil, otherwise in local time." (unless (equal file-name buffer-file-name) (cond - ((equal file-name (buffer-file-name (window-buffer (selected-window)))) + ((equal file-name (buffer-file-name (window-buffer))) ;; If the selected window already shows the desired buffer don't show ;; it again (particularly important if other-window is true). ;; This is important for diff-add-change-log-entries-other-window. - (set-buffer (window-buffer (selected-window)))) - ((or other-window (window-dedicated-p (selected-window))) + (set-buffer (window-buffer))) + ((or other-window (window-dedicated-p)) (find-file-other-window file-name)) (t (find-file file-name)))) (or (derived-mode-p 'change-log-mode) diff --git a/lisp/vc/compare-w.el b/lisp/vc/compare-w.el index ae4fcc99a25..235ebe5a072 100644 --- a/lisp/vc/compare-w.el +++ b/lisp/vc/compare-w.el @@ -179,7 +179,7 @@ on third call it again advances points to the next difference and so on." 'compare-windows-sync-regexp compare-windows-sync))) (setq p1 (point) b1 (current-buffer)) - (setq w2 (next-window (selected-window))) + (setq w2 (next-window)) (if (eq w2 (selected-window)) (setq w2 (next-window (selected-window) nil 'visible))) (if (eq w2 (selected-window)) diff --git a/lisp/vc/ediff-help.el b/lisp/vc/ediff-help.el index 833e84b6cea..78d1a6abfd1 100644 --- a/lisp/vc/ediff-help.el +++ b/lisp/vc/ediff-help.el @@ -253,7 +253,7 @@ the value of this variable and the variables `ediff-help-message-*' in (defun ediff-indent-help-message () - (let* ((shift (/ (max 0 (- (window-width (selected-window)) + (let* ((shift (/ (max 0 (- (window-width) (ediff-help-message-line-length))) 2)) (str (make-string shift ?\ ))) diff --git a/lisp/vc/ediff-util.el b/lisp/vc/ediff-util.el index 8f84dfb14ef..2f2c71a71e6 100644 --- a/lisp/vc/ediff-util.el +++ b/lisp/vc/ediff-util.el @@ -537,7 +537,7 @@ to invocation.") ;; to reside. (defun ediff-setup-control-buffer (ctl-buf) "Set up window for control buffer." - (if (window-dedicated-p (selected-window)) + (if (window-dedicated-p) (set-buffer ctl-buf) ; we are in control frame but just in case (switch-to-buffer ctl-buf)) (let ((window-min-height 2)) @@ -1629,7 +1629,7 @@ the width of the A/B/C windows." (setq lines (1+ lines))) ;; And position the beginning on the right line (goto-char beg) - (recenter (/ (1+ (max (- (1- (window-height (selected-window))) + (recenter (/ (1+ (max (- (1- (window-height)) lines) 1) ) diff --git a/lisp/vc/ediff-wind.el b/lisp/vc/ediff-wind.el index 124bdbd26df..5a14c193344 100644 --- a/lisp/vc/ediff-wind.el +++ b/lisp/vc/ediff-wind.el @@ -861,7 +861,7 @@ into icons, regardless of the window manager." ;; create a new splittable frame if none is found (defun ediff-skip-unsuitable-frames (&optional ok-unsplittable) (if (ediff-window-display-p) - (let ((wind-frame (window-frame (selected-window))) + (let ((wind-frame (window-frame)) seen-windows) (while (and (not (memq (selected-window) seen-windows)) (or @@ -877,7 +877,7 @@ into icons, regardless of the window manager." (setq seen-windows (cons (selected-window) seen-windows)) ;; try new window (other-window 1 t) - (setq wind-frame (window-frame (selected-window))) + (setq wind-frame (window-frame)) ) (if (memq (selected-window) seen-windows) ;; fed up, no appropriate frames @@ -939,7 +939,7 @@ into icons, regardless of the window manager." (setq ctl-frame-iconified-p (ediff-frame-iconified-p ctl-frame)) (select-frame ctl-frame) - (if (window-dedicated-p (selected-window)) + (if (window-dedicated-p) () (delete-other-windows) (switch-to-buffer ctl-buffer)) diff --git a/lisp/vc/emerge.el b/lisp/vc/emerge.el index 0a1bd044125..8d0e8efc75c 100644 --- a/lisp/vc/emerge.el +++ b/lisp/vc/emerge.el @@ -1770,7 +1770,7 @@ to the left margin, if they are in windows." (setq lines (1+ lines))) ;; And position the beginning on the right line (goto-char beg) - (recenter (/ (1+ (- (1- (window-height (selected-window))) + (recenter (/ (1+ (- (1- (window-height)) lines)) 2)))))) (goto-char pos)) diff --git a/lisp/vc/pcvs-util.el b/lisp/vc/pcvs-util.el index 28ae4ed3de3..2868bb98b29 100644 --- a/lisp/vc/pcvs-util.el +++ b/lisp/vc/pcvs-util.el @@ -97,7 +97,7 @@ try to split a new window instead." BUF is assumed to be a temporary buffer used from the buffer MAINBUF." (interactive (list (current-buffer))) (save-current-buffer - (let ((win (if (eq buf (window-buffer (selected-window))) (selected-window) + (let ((win (if (eq buf (window-buffer)) (selected-window) (get-buffer-window buf t)))) (when win (if (window-dedicated-p win) @@ -111,8 +111,8 @@ BUF is assumed to be a temporary buffer used from the buffer MAINBUF." ;;; ) ))) (with-current-buffer buf - (bury-buffer (unless (and (eq buf (window-buffer (selected-window))) - (not (window-dedicated-p (selected-window)))) + (bury-buffer (unless (and (eq buf (window-buffer)) + (not (window-dedicated-p))) buf))) (when mainbuf (let ((mainwin (or (get-buffer-window mainbuf) diff --git a/lisp/window.el b/lisp/window.el index 86d93c0a9f6..c36244f8f4e 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -1486,7 +1486,7 @@ This function changes neither the order of recently selected windows nor the buffer list." ;; If we start from the minibuffer window, don't fail to come ;; back to it. - (when (window-minibuffer-p (selected-window)) + (when (window-minibuffer-p) (setq minibuf t)) ;; Make sure to not mess up the order of recently selected ;; windows. Use `save-selected-window' and `select-window' @@ -6676,7 +6676,7 @@ is active. This function is run by `mouse-autoselect-window-timer'." ;; minibuffer. Use `unread-command-events' in order to execute pre- ;; and post-command hooks and trigger idle timers. To avoid delaying ;; autoselection again, set `mouse-autoselect-window-state'." - (unless (window-minibuffer-p (selected-window)) + (unless (window-minibuffer-p) (setq mouse-autoselect-window-state 'select) (setq unread-command-events (cons (list 'select-window (list window)) @@ -6702,7 +6702,7 @@ is active. This function is run by `mouse-autoselect-window-timer'." ;; minibuffer gets unselected unexpectedly, and where ;; you then have to move your mouse all the way down to ;; the minibuffer to select it. - (window-minibuffer-p (selected-window)) + (window-minibuffer-p) ;; Don't switch to minibuffer window unless it's active. (and (window-minibuffer-p window) (not (minibuffer-window-active-p window))) diff --git a/lisp/winner.el b/lisp/winner.el index e7e7d0614b4..e81052f8499 100644 --- a/lisp/winner.el +++ b/lisp/winner.el @@ -227,8 +227,7 @@ You may want to include buffer names such as *Help*, *Apropos*, (set-window-configuration winconf)) (cond ((window-live-p chosen) (select-window chosen)) - ((window-minibuffer-p (selected-window)) - (other-window 1))) + ((window-minibuffer-p) (other-window 1))) (when (/= minisize (window-height miniwin)) (with-selected-window miniwin (setf (window-height) minisize))))) @@ -381,7 +380,7 @@ In other words, \"undo\" changes in window configuration." (setq winner-undone-data (list (winner-win-data)))) (cl-incf winner-undo-counter) ; starting at 1 (when (and (winner-undo-this) - (not (window-minibuffer-p (selected-window)))) + (not (window-minibuffer-p))) (message "Winner undo (%d / %d)" winner-undo-counter (1- (ring-length winner-pending-undo-ring))))))) From 184e2342878976819f7175fd31d3be31f279027e Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Mon, 5 Aug 2013 09:18:57 -0700 Subject: [PATCH 029/449] admin/make-tarball.txt: mention platform-testers mailing list --- admin/make-tarball.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/admin/make-tarball.txt b/admin/make-tarball.txt index 005c6694228..3172854ede7 100644 --- a/admin/make-tarball.txt +++ b/admin/make-tarball.txt @@ -144,6 +144,8 @@ General steps (for each step, check for possible errors): Download them and check the signatures. Check they build. 12. For a pretest, announce it on emacs-devel and info-gnu-emacs@gnu.org. + Probably should also include the platform-testers list: + https://lists.gnu.org/mailman/listinfo/platform-testers For a release, also announce it on info-gnu@gnu.org. (Probably bcc the info- addresses to make it less likely that people will followup on those lists.) From 5c0e57feb7429f367ed402dbe4a0572a6528d0b5 Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Mon, 5 Aug 2013 18:29:09 +0200 Subject: [PATCH 030/449] etc/tutorials/TUTORIAL.es: Fix typo (bug#15027). --- etc/ChangeLog | 4 ++++ etc/tutorials/TUTORIAL.es | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/etc/ChangeLog b/etc/ChangeLog index 4c0535d07a0..2d204f326b2 100644 --- a/etc/ChangeLog +++ b/etc/ChangeLog @@ -1,3 +1,7 @@ +2013-08-05 Juanma Barranquero + + * tutorials/TUTORIAL.es: Fix typo (bug#15027). + 2013-08-03 Juanma Barranquero * NEWS: Document new package frameset.el. diff --git a/etc/tutorials/TUTORIAL.es b/etc/tutorials/TUTORIAL.es index 15b0a4e26bf..f2ae8ab0354 100644 --- a/etc/tutorials/TUTORIAL.es +++ b/etc/tutorials/TUTORIAL.es @@ -974,7 +974,7 @@ diferentes: >> Teclee C-x 4 C-f seguido del nombre de uno de sus archivos. Finalice con . Vea que el archivo especificado aparece en - la ventana inferior. El cursor vá allá también. + la ventana inferior. El cursor va allá también. >> Teclee C-x o para regresar a la ventana superior, y C-x 1 para borrar la ventana inferior. From 98a428c15ad48f8579b00b68aae6a89b34238b12 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 5 Aug 2013 20:09:28 +0300 Subject: [PATCH 031/449] Fix bugs in update-game-score, on MS-Windows and elsewhere. lib-src/update-game-score.c (read_score): Try reading a character before probing the stream for EOF. Initialize score->score to zero, before reading and accumulating the score. (read_scores): Fix logic that determines which value to return. Close the input stream when finished reading the scores (avoids failures in overwriting the file with a new one on MS-Windows, since a file that is open cannot be deleted). lib-src/ntlib.h (rename): Don't undefine. lib-src/ntlib.c (sys_rename): New function, needed for update-game-score. --- lib-src/ChangeLog | 15 +++++++++++++ lib-src/ntlib.c | 28 +++++++++++++++++------ lib-src/ntlib.h | 1 - lib-src/update-game-score.c | 44 ++++++++++++++++++++----------------- 4 files changed, 60 insertions(+), 28 deletions(-) diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index ace62d9d8f7..0336eae0981 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog @@ -1,3 +1,18 @@ +2013-08-05 Eli Zaretskii + + * update-game-score.c (read_score): Try reading a character before + probing the stream for EOF. Initialize score->score to zero, + before reading and accumulating the score. + (read_scores): Fix logic that determines which value to return. + Close the input stream when finished reading the scores (avoids + failures in overwriting the file with a new one on MS-Windows, + since a file that is open cannot be deleted). + + * ntlib.h (rename): Don't undefine. + + * ntlib.c (sys_rename): New function, needed for + update-game-score. + 2013-08-04 Eli Zaretskii * ntlib.h: Include fcntl.h. diff --git a/lib-src/ntlib.c b/lib-src/ntlib.c index 0d0642d1bf2..ab7d8b590df 100644 --- a/lib-src/ntlib.c +++ b/lib-src/ntlib.c @@ -424,14 +424,14 @@ lstat (const char * path, struct stat * buf) } /* Implementation of mkostemp for MS-Windows, to avoid race conditions - when using mktemp. + when using mktemp. Copied from w32.c. - Standard algorithm for generating a temporary file name seems to be - use pid or tid with a letter on the front (in place of the 6 X's) - and cycle through the letters to find a unique name. We extend - that to allow any reasonable character as the first of the 6 X's, - so that the number of simultaneously used temporary files will be - greater. */ + This is used only in update-game-score.c. It is overkill for that + use case, since update-game-score renames the temporary file into + the game score file, which isn't atomic on MS-Windows anyway, when + the game score already existed before running the program, which it + almost always does. But using a simpler implementation just to + make a point is uneconomical... */ int mkostemp (char * template, int flags) @@ -477,3 +477,17 @@ mkostemp (char * template, int flags) /* Template is badly formed or else we can't generate a unique name. */ return -1; } + +/* On Windows, you cannot rename into an existing file. */ +int +sys_rename (const char *from, const char *to) +{ + int retval = rename (from, to); + + if (retval < 0 && errno == EEXIST) + { + if (unlink (to) == 0) + retval = rename (from, to); + } + return retval; +} diff --git a/lib-src/ntlib.h b/lib-src/ntlib.h index c30958365ca..ab5f5ea3b89 100644 --- a/lib-src/ntlib.h +++ b/lib-src/ntlib.h @@ -69,7 +69,6 @@ int mkostemp (char * template, int flags); #define pipe _pipe #undef read #define read _read -#undef rename #undef rmdir #define rmdir _rmdir #undef unlink diff --git a/lib-src/update-game-score.c b/lib-src/update-game-score.c index 1699e305c8d..92c1663f658 100644 --- a/lib-src/update-game-score.c +++ b/lib-src/update-game-score.c @@ -228,10 +228,11 @@ static int read_score (FILE *f, struct score_entry *score) { int c; + if ((c = getc (f)) != EOF) + ungetc (c, f); if (feof (f)) return 1; - while ((c = getc (f)) != EOF - && isdigit (c)) + for (score->score = 0; (c = getc (f)) != EOF && isdigit (c); ) { score->score *= 10; score->score += (c-48); @@ -311,34 +312,38 @@ read_score (FILE *f, struct score_entry *score) static int read_scores (const char *filename, struct score_entry **scores, int *count) { - int readval, scorecount, cursize; + int readval = -1, scorecount, cursize; struct score_entry *ret; FILE *f = fopen (filename, "r"); + int retval = -1; if (!f) return -1; scorecount = 0; cursize = 16; ret = (struct score_entry *) malloc (sizeof (struct score_entry) * cursize); - if (!ret) - return -1; - while ((readval = read_score (f, &ret[scorecount])) == 0) + if (ret) { - /* We encountered an error. */ - if (readval < 0) - return -1; - scorecount++; - if (scorecount >= cursize) + while ((readval = read_score (f, &ret[scorecount])) == 0) { - cursize *= 2; - ret = (struct score_entry *) - realloc (ret, (sizeof (struct score_entry) * cursize)); - if (!ret) - return -1; + scorecount++; + if (scorecount >= cursize) + { + cursize *= 2; + ret = (struct score_entry *) + realloc (ret, (sizeof (struct score_entry) * cursize)); + if (!ret) + break; + } } } - *count = scorecount; - *scores = ret; - return 0; + if (readval > 0) + { + *count = scorecount; + *scores = ret; + retval = 0; + } + fclose (f); + return retval; } static int @@ -461,5 +466,4 @@ unlock_file (const char *filename, void *state) return ret; } - /* update-game-score.c ends here */ From dc6c0edad789a8aab129ae12b8f064d0e912cca7 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Mon, 5 Aug 2013 14:05:46 -0400 Subject: [PATCH 032/449] Revert introduction of isearch-filter-predicates. Rely on add-function instead. * lisp/loadup.el: Preload nadvice. * lisp/isearch.el (isearch-filter-predicates): Rename it back to isearch-filter-predicate. (isearch-message-prefix): Use advice-function-mapc and advice properties to get the isearch-message-prefix. (isearch-search, isearch-lazy-highlight-search): Revert to funcall instead of run-hook-with-args-until-failure. (isearch-filter-visible): Not obsolete any more. * lisp/replace.el (perform-replace): Revert to funcall instead of run-hook-with-args-until-failure. * lisp/wdired.el (wdired-change-to-wdired-mode): Use add-function. * lisp/dired-aux.el (dired-isearch-filenames-mode): Rename from dired-isearch-filenames-toggle; make it into a proper minor mode. Use add/remove-function. (dired-isearch-filenames-setup, dired-isearch-filenames-end): Call the minor-mode rather than add/remove-hook. (dired-isearch-filter-filenames): Remove isearch-message-prefix property. * lisp/info.el (Info--search-loop): New function, extracted from Info-search. Funcall isearch-filter-predicate instead of run-hook-with-args-until-failure isearch-filter-predicates. (Info-search): Use it. (Info-mode): Use isearch-filter-predicate instead of isearch-filter-predicates. * src/lisp.mk (lisp): Add nadvice.elc. * lib-src/makefile.w32-in (lisp2): Add nadvice.elc. Fixes: debbugs:14714 --- lib-src/ChangeLog | 4 ++ lib-src/makefile.w32-in | 1 + lisp/ChangeLog | 29 ++++++++++ lisp/dired-aux.el | 28 +++++----- lisp/dired.el | 17 +----- lisp/info.el | 121 +++++++++++++++++----------------------- lisp/isearch.el | 57 +++++++------------ lisp/loadup.el | 1 + lisp/replace.el | 15 +++-- lisp/wdired.el | 3 +- src/ChangeLog | 4 ++ src/frame.c | 2 +- src/lisp.mk | 1 + 13 files changed, 137 insertions(+), 146 deletions(-) diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index 0336eae0981..da97246ef64 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog @@ -1,3 +1,7 @@ +2013-08-05 Stefan Monnier + + * makefile.w32-in (lisp2): Add nadvice.elc. + 2013-08-05 Eli Zaretskii * update-game-score.c (read_score): Try reading a character before diff --git a/lib-src/makefile.w32-in b/lib-src/makefile.w32-in index 9656a3badec..dee80c4b560 100644 --- a/lib-src/makefile.w32-in +++ b/lib-src/makefile.w32-in @@ -251,6 +251,7 @@ lisp2 = \ $(lispsource)register.elc \ $(lispsource)replace.elc \ $(lispsource)simple.elc \ + $(lispsource)emacs-lisp/nadvice.elc \ $(lispsource)minibuffer.elc \ $(lispsource)startup.elc \ $(lispsource)subr.elc \ diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 8bc39097187..ad7d82c30d7 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,32 @@ +2013-08-05 Stefan Monnier + + Revert introduction of isearch-filter-predicates (bug#14714). + Rely on add-function instead. + * isearch.el (isearch-filter-predicates): Rename it back to + isearch-filter-predicate. + (isearch-message-prefix): Use advice-function-mapc and advice + properties to get the isearch-message-prefix. + (isearch-search, isearch-lazy-highlight-search): Revert to funcall + instead of run-hook-with-args-until-failure. + (isearch-filter-visible): Not obsolete any more. + * loadup.el: Preload nadvice. + * replace.el (perform-replace): Revert to funcall + instead of run-hook-with-args-until-failure. + * wdired.el (wdired-change-to-wdired-mode): Use add-function. + * dired-aux.el (dired-isearch-filenames-mode): Rename from + dired-isearch-filenames-toggle; make it into a proper minor mode. + Use add/remove-function. + (dired-isearch-filenames-setup, dired-isearch-filenames-end): + Call the minor-mode rather than add/remove-hook. + (dired-isearch-filter-filenames): + Remove isearch-message-prefix property. + * info.el (Info--search-loop): New function, extracted from Info-search. + Funcall isearch-filter-predicate instead of + run-hook-with-args-until-failure isearch-filter-predicates. + (Info-search): Use it. + (Info-mode): Use isearch-filter-predicate instead of + isearch-filter-predicates. + 2013-08-05 Dmitry Antipov Do not call to `selected-window' where it is assumed by default. diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 7cb63f6b012..c12ac068689 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -2491,18 +2491,21 @@ a file name. Otherwise, it searches the whole buffer without restrictions." :group 'dired :version "23.1") -(defun dired-isearch-filenames-toggle () +(define-minor-mode dired-isearch-filenames-mode "Toggle file names searching on or off. When on, Isearch skips matches outside file names using the predicate `dired-isearch-filter-filenames' that matches only at file names. When off, it uses the original predicate." - (interactive) - (setq isearch-filter-predicates - (if (memq 'dired-isearch-filter-filenames isearch-filter-predicates) - (delq 'dired-isearch-filter-filenames isearch-filter-predicates) - (cons 'dired-isearch-filter-filenames isearch-filter-predicates))) - (setq isearch-success t isearch-adjusted t) - (isearch-update)) + nil nil nil + (if dired-isearch-filenames-mode + (add-function :before-while (local 'isearch-filter-predicate) + #'dired-isearch-filter-filenames + '((isearch-message-prefix . "filename "))) + (remove-function (local 'isearch-filter-predicate) + #'dired-isearch-filter-filenames)) + (when isearch-mode + (setq isearch-success t isearch-adjusted t) + (isearch-update))) ;;;###autoload (defun dired-isearch-filenames-setup () @@ -2511,15 +2514,14 @@ Intended to be added to `isearch-mode-hook'." (when (or (eq dired-isearch-filenames t) (and (eq dired-isearch-filenames 'dwim) (get-text-property (point) 'dired-filename))) - (define-key isearch-mode-map "\M-sff" 'dired-isearch-filenames-toggle) - (add-hook 'isearch-filter-predicates 'dired-isearch-filter-filenames nil t) + (define-key isearch-mode-map "\M-sff" 'dired-isearch-filenames-mode) + (dired-isearch-filenames-mode 1) (add-hook 'isearch-mode-end-hook 'dired-isearch-filenames-end nil t))) (defun dired-isearch-filenames-end () "Clean up the Dired file name search after terminating isearch." - (setq isearch-message-prefix-add nil) (define-key isearch-mode-map "\M-sff" nil) - (remove-hook 'isearch-filter-predicates 'dired-isearch-filter-filenames t) + (dired-isearch-filenames-mode -1) (remove-hook 'isearch-mode-end-hook 'dired-isearch-filenames-end t)) (defun dired-isearch-filter-filenames (beg end) @@ -2531,8 +2533,6 @@ name (has the text property `dired-filename')." 'dired-filename nil) t)) -(put 'dired-isearch-filter-filenames 'isearch-message-prefix "filename ") - ;;;###autoload (defun dired-isearch-filenames () "Search for a string using Isearch only in file names in the Dired buffer." diff --git a/lisp/dired.el b/lisp/dired.el index c871761bb3c..c44cf574889 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -3849,22 +3849,7 @@ Ask means pop up a menu for the user to select one of copy, move or link." ;;; Start of automatically extracted autoloads. -;;;### (autoloads (dired-show-file-type dired-do-query-replace-regexp -;;;;;; dired-do-search dired-do-isearch-regexp dired-do-isearch -;;;;;; dired-isearch-filenames-regexp dired-isearch-filenames dired-isearch-filenames-setup -;;;;;; dired-hide-all dired-hide-subdir dired-tree-down dired-tree-up -;;;;;; dired-kill-subdir dired-mark-subdir-files dired-goto-subdir -;;;;;; dired-prev-subdir dired-insert-subdir dired-maybe-insert-subdir -;;;;;; dired-downcase dired-upcase dired-do-symlink-regexp dired-do-hardlink-regexp -;;;;;; dired-do-copy-regexp dired-do-rename-regexp dired-do-rename -;;;;;; dired-do-hardlink dired-do-symlink dired-do-copy dired-create-directory -;;;;;; dired-rename-file dired-copy-file dired-relist-file dired-remove-file -;;;;;; dired-add-file dired-do-redisplay dired-do-load dired-do-byte-compile -;;;;;; dired-do-compress dired-query dired-compress-file dired-do-kill-lines -;;;;;; dired-run-shell-command dired-do-shell-command dired-do-async-shell-command -;;;;;; dired-clean-directory dired-do-print dired-do-touch dired-do-chown -;;;;;; dired-do-chgrp dired-do-chmod dired-compare-directories dired-backup-diff -;;;;;; dired-diff) "dired-aux" "dired-aux.el" "8f5af3aa4eee1b3448525896fa6f39a3") +;;;### (autoloads nil "dired-aux" "dired-aux.el" "555c067fcab27f5a377536db407803ab") ;;; Generated autoloads from dired-aux.el (autoload 'dired-diff "dired-aux" "\ diff --git a/lisp/info.el b/lisp/info.el index 0e0a11753ba..182ad8563aa 100644 --- a/lisp/info.el +++ b/lisp/info.el @@ -1905,6 +1905,30 @@ the Top node in FILENAME." (defvar Info-search-case-fold nil "The value of `case-fold-search' from previous `Info-search' command.") +(defun Info--search-loop (regexp bound backward) + (when backward + ;; Hide Info file header for backward search. + (narrow-to-region (save-excursion + (goto-char (point-min)) + (search-forward "\n\^_") + (1- (point))) + (point-max))) + (let ((give-up nil) + (found nil) + (beg-found nil)) + (while (not (or give-up + (and found + (funcall isearch-filter-predicate + beg-found found)))) + (let ((search-spaces-regexp Info-search-whitespace-regexp)) + (if (funcall + (if backward #'re-search-backward #'re-search-forward) + regexp bound t) + (setq found (point) beg-found (if backward (match-end 0) + (match-beginning 0))) + (setq give-up t found nil)))) + found)) + (defun Info-search (regexp &optional bound _noerror _count direction) "Search for REGEXP, starting from point, and select node it's found in. If DIRECTION is `backward', search in the reverse direction." @@ -1920,55 +1944,35 @@ If DIRECTION is `backward', search in the reverse direction." (when (equal regexp "") (setq regexp (car Info-search-history))) (when regexp - (let (found beg-found give-up - (backward (eq direction 'backward)) - (onode Info-current-node) - (ofile Info-current-file) - (opoint (point)) - (opoint-min (point-min)) - (opoint-max (point-max)) - (ostart (window-start)) - (osubfile Info-current-subfile)) - (setq Info-search-case-fold case-fold-search) - (save-excursion - (save-restriction - (widen) - (when backward - ;; Hide Info file header for backward search - (narrow-to-region (save-excursion - (goto-char (point-min)) - (search-forward "\n\^_") - (1- (point))) - (point-max))) - (while (and (not give-up) - (or (null found) - (not (run-hook-with-args-until-failure - 'isearch-filter-predicates beg-found found)))) - (let ((search-spaces-regexp Info-search-whitespace-regexp)) - (if (if backward - (re-search-backward regexp bound t) - (re-search-forward regexp bound t)) - (setq found (point) beg-found (if backward (match-end 0) - (match-beginning 0))) - (setq give-up t)))))) + (setq Info-search-case-fold case-fold-search) + (let* ((backward (eq direction 'backward)) + (onode Info-current-node) + (ofile Info-current-file) + (opoint (point)) + (opoint-min (point-min)) + (opoint-max (point-max)) + (ostart (window-start)) + (osubfile Info-current-subfile) + (found + (save-excursion + (save-restriction + (widen) + (Info--search-loop regexp bound backward))))) - (when (and isearch-mode Info-isearch-search - (not Info-isearch-initial-node) - (not bound) - (or give-up (and found (not (and (> found opoint-min) - (< found opoint-max)))))) + (unless (or (not isearch-mode) (not Info-isearch-search) + Info-isearch-initial-node + bound + (and found (> found opoint-min) (< found opoint-max))) (signal 'search-failed (list regexp "end of node"))) ;; If no subfiles, give error now. - (if give-up - (if (null Info-current-subfile) - (if isearch-mode - (signal 'search-failed (list regexp "end of manual")) - (let ((search-spaces-regexp Info-search-whitespace-regexp)) - (if backward - (re-search-backward regexp) - (re-search-forward regexp)))) - (setq found nil))) + (unless (or found Info-current-subfile) + (if isearch-mode + (signal 'search-failed (list regexp "end of manual")) + (let ((search-spaces-regexp Info-search-whitespace-regexp)) + (if backward + (re-search-backward regexp) + (re-search-forward regexp))))) (if (and bound (not found)) (signal 'search-failed (list regexp))) @@ -2009,29 +2013,9 @@ If DIRECTION is `backward', search in the reverse direction." (while list (message "Searching subfile %s..." (cdr (car list))) (Info-read-subfile (car (car list))) - (when backward - ;; Hide Info file header for backward search - (narrow-to-region (save-excursion - (goto-char (point-min)) - (search-forward "\n\^_") - (1- (point))) - (point-max)) - (goto-char (point-max))) + (when backward (goto-char (point-max))) (setq list (cdr list)) - (setq give-up nil found nil) - (while (and (not give-up) - (or (null found) - (not (run-hook-with-args-until-failure - 'isearch-filter-predicates beg-found found)))) - (let ((search-spaces-regexp Info-search-whitespace-regexp)) - (if (if backward - (re-search-backward regexp nil t) - (re-search-forward regexp nil t)) - (setq found (point) beg-found (if backward (match-end 0) - (match-beginning 0))) - (setq give-up t)))) - (if give-up - (setq found nil)) + (setq found (Info--search-loop regexp nil backward)) (if found (setq list nil))) (if found @@ -4288,8 +4272,7 @@ Advanced commands: 'Info-isearch-wrap) (set (make-local-variable 'isearch-push-state-function) 'Info-isearch-push-state) - (set (make-local-variable 'isearch-filter-predicates) - '(Info-isearch-filter)) + (set (make-local-variable 'isearch-filter-predicate) #'Info-isearch-filter) (set (make-local-variable 'revert-buffer-function) 'Info-revert-buffer-function) (Info-set-mode-line) diff --git a/lisp/isearch.el b/lisp/isearch.el index a591f8b4291..072ccc26772 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -187,21 +187,15 @@ or to the end of the buffer for a backward search.") "Function to save a function restoring the mode-specific Isearch state to the search status stack.") -(defvar isearch-filter-predicates nil - "Predicates that filter the search hits that would normally be available. -Search hits that dissatisfy the list of predicates are skipped. -Each function in this list has two arguments: the positions of -start and end of text matched by the search. -The search loop uses `run-hook-with-args-until-failure' to call -each predicate in order, and when one of the predicates returns nil, -skips this match and continues searching for the next match. -When the list of predicates is empty, `run-hook-with-args-until-failure' -returns non-nil that means that the found match is accepted. -The property `isearch-message-prefix' put on the predicate's symbol -specifies the prefix string displayed in the search message.") -(define-obsolete-variable-alias 'isearch-filter-predicate - 'isearch-filter-predicates - "24.4") +(defvar isearch-filter-predicate #'isearch-filter-visible + "Predicate that filter the search hits that would normally be available. +Search hits that dissatisfy the predicate are skipped. The function +has two arguments: the positions of start and end of text matched by +the search. If this function returns nil, continue searching without +stopping at this match. +If you use `add-function' to modify this variable, you can use the +`isearch-message-prefix' advice property to specify the prefix string +displayed in the search message.") ;; Search ring. @@ -2614,13 +2608,13 @@ If there is no completion possible, say so and continue searching." (< (point) isearch-opoint))) "over") (if isearch-wrapped "wrapped ") - (mapconcat (lambda (s) - (and (symbolp s) - (get s 'isearch-message-prefix))) - (if (consp isearch-filter-predicates) - isearch-filter-predicates - (list isearch-filter-predicates)) - "") + (let ((prefix "")) + (advice-function-mapc + (lambda (_ props) + (let ((np (cdr (assq 'isearch-message-prefix props)))) + (if np (setq prefix (concat np prefix))))) + isearch-filter-predicate) + prefix) (if isearch-word (or (and (symbolp isearch-word) (get isearch-word 'isearch-message-prefix)) @@ -2766,15 +2760,8 @@ update the match data, and return point." (if (or (not isearch-success) (bobp) (eobp) (= (match-beginning 0) (match-end 0)) - ;; When one of filter predicates returns nil, - ;; retry the search. Otherwise, act according - ;; to search-invisible (open overlays, etc.) - (and (run-hook-with-args-until-failure - 'isearch-filter-predicates - (match-beginning 0) (match-end 0)) - (or (eq search-invisible t) - (not (isearch-range-invisible - (match-beginning 0) (match-end 0)))))) + (funcall isearch-filter-predicate + (match-beginning 0) (match-end 0))) (setq retry nil))) (setq isearch-just-started nil) (if isearch-success @@ -2951,7 +2938,6 @@ determined by `isearch-range-invisible' unless invisible text can be searched too when `search-invisible' is t." (or (eq search-invisible t) (not (isearch-range-invisible beg end)))) -(make-obsolete 'isearch-filter-visible 'isearch-invisible "24.4") ;; General utilities @@ -3177,11 +3163,8 @@ Attempt to do the search exactly the way the pending Isearch would." (if (or (not success) (= (point) bound) ; like (bobp) (eobp) in `isearch-search'. (= (match-beginning 0) (match-end 0)) - (and (run-hook-with-args-until-failure - 'isearch-filter-predicates - (match-beginning 0) (match-end 0)) - (not (isearch-range-invisible - (match-beginning 0) (match-end 0))))) + (funcall isearch-filter-predicate + (match-beginning 0) (match-end 0))) (setq retry nil))) success) (error nil))) diff --git a/lisp/loadup.el b/lisp/loadup.el index 7fb9526b360..c32bd00463e 100644 --- a/lisp/loadup.el +++ b/lisp/loadup.el @@ -139,6 +139,7 @@ ;; In case loaddefs hasn't been generated yet. (file-error (load "ldefs-boot.el"))) +(load "emacs-lisp/nadvice") (load "minibuffer") (load "abbrev") ;lisp-mode.el and simple.el use define-abbrev-table. (load "simple") diff --git a/lisp/replace.el b/lisp/replace.el index be0ecda20fa..5e44677b0f8 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -252,7 +252,7 @@ or capitalized.) Ignore read-only matches if `query-replace-skip-read-only' is non-nil, ignore hidden matches if `search-invisible' is nil, and ignore more -matches using a non-nil `isearch-filter-predicates'. +matches using `isearch-filter-predicate'. If `replace-lax-whitespace' is non-nil, a space or spaces in the string to be replaced will match a sequence of whitespace chars defined by the @@ -306,7 +306,7 @@ capitalized.) Ignore read-only matches if `query-replace-skip-read-only' is non-nil, ignore hidden matches if `search-invisible' is nil, and ignore more -matches using a non-nil `isearch-filter-predicates'. +matches using `isearch-filter-predicate'. If `replace-regexp-lax-whitespace' is non-nil, a space or spaces in the regexp to be replaced will match a sequence of whitespace chars defined by the @@ -390,7 +390,7 @@ are non-nil and REGEXP has no uppercase letters. Ignore read-only matches if `query-replace-skip-read-only' is non-nil, ignore hidden matches if `search-invisible' is nil, and ignore more -matches using a non-nil `isearch-filter-predicates'. +matches using `isearch-filter-predicate'. If `replace-regexp-lax-whitespace' is non-nil, a space or spaces in the regexp to be replaced will match a sequence of whitespace chars defined by the @@ -484,7 +484,7 @@ then its replacement is upcased or capitalized.) Ignore read-only matches if `query-replace-skip-read-only' is non-nil, ignore hidden matches if `search-invisible' is nil, and ignore more -matches using a non-nil `isearch-filter-predicates'. +matches using `isearch-filter-predicate'. If `replace-lax-whitespace' is non-nil, a space or spaces in the string to be replaced will match a sequence of whitespace chars defined by the @@ -530,7 +530,7 @@ are non-nil and REGEXP has no uppercase letters. Ignore read-only matches if `query-replace-skip-read-only' is non-nil, ignore hidden matches if `search-invisible' is nil, and ignore more -matches using a non-nil `isearch-filter-predicates'. +matches using `isearch-filter-predicate'. If `replace-regexp-lax-whitespace' is non-nil, a space or spaces in the regexp to be replaced will match a sequence of whitespace chars defined by the @@ -2087,9 +2087,8 @@ make, or the user didn't cancel the call." 'read-only nil)))) (setq skip-read-only-count (1+ skip-read-only-count))) ;; Optionally filter out matches. - ((not (run-hook-with-args-until-failure - 'isearch-filter-predicates - (nth 0 real-match-data) (nth 1 real-match-data))) + ((not (funcall isearch-filter-predicate + (nth 0 real-match-data) (nth 1 real-match-data))) (setq skip-filtered-count (1+ skip-filtered-count))) ;; Optionally ignore invisible matches. ((not (or (eq search-invisible t) diff --git a/lisp/wdired.el b/lisp/wdired.el index 55665fbb6a0..6c2c9777a47 100644 --- a/lisp/wdired.el +++ b/lisp/wdired.el @@ -239,7 +239,8 @@ See `wdired-mode'." (dired-remember-marks (point-min) (point-max))) (set (make-local-variable 'wdired-old-point) (point)) (set (make-local-variable 'query-replace-skip-read-only) t) - (add-hook 'isearch-filter-predicates 'wdired-isearch-filter-read-only nil t) + (add-function :after-while (local 'isearch-filter-predicate) + #'wdired-isearch-filter-read-only) (use-local-map wdired-mode-map) (force-mode-line-update) (setq buffer-read-only nil) diff --git a/src/ChangeLog b/src/ChangeLog index a0a31f0bf3c..35b5c1cfe5c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2013-08-05 Stefan Monnier + + * lisp.mk (lisp): Add nadvice.elc. + 2013-08-05 Dmitry Antipov New macro to iterate over live buffers similar to frames. diff --git a/src/frame.c b/src/frame.c index 14fc15c4717..813c97ffe3e 100644 --- a/src/frame.c +++ b/src/frame.c @@ -710,7 +710,7 @@ affects all frames on the same terminal device. */) type[SBYTES (tty_type)] = 0; } - t = init_tty (name, type, 0); /* Errors are not fatal. */ + t = init_tty (name, type, 0); /* Errors are not fatal. */ } f = make_terminal_frame (t); diff --git a/src/lisp.mk b/src/lisp.mk index edd81bcf493..a9a661ea3a8 100644 --- a/src/lisp.mk +++ b/src/lisp.mk @@ -71,6 +71,7 @@ lisp = \ $(lispsource)/faces.elc \ $(lispsource)/button.elc \ $(lispsource)/startup.elc \ + $(lispsource)/emacs-lisp/nadvice.elc \ $(lispsource)/minibuffer.elc \ $(lispsource)/abbrev.elc \ $(lispsource)/simple.elc \ From 1d237bbae7fe9bb69708760abc9ae435513a0465 Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Tue, 6 Aug 2013 03:03:08 +0200 Subject: [PATCH 033/449] lisp/dired.el (dired-insert-directory): Revert change in 2013-06-21T12:24:37Z!lekktu@gmail.com. Fixes: debbugs:15028 --- lisp/ChangeLog | 5 +++++ lisp/dired.el | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index ad7d82c30d7..c3f908b83ae 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2013-08-06 Juanma Barranquero + + * dired.el (dired-insert-directory): Revert change in 2013-06-21T12:24:37Z!lekktu@gmail.com + to use looking-at-p instead of looking-at. (Bug#15028) + 2013-08-05 Stefan Monnier Revert introduction of isearch-filter-predicates (bug#14714). diff --git a/lisp/dired.el b/lisp/dired.el index c44cf574889..48f1b463f4a 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -1225,7 +1225,7 @@ see `dired-use-ls-dired' for more details.") (save-excursion (goto-char opoint) (when (and (or hdr wildcard) - (not (and (looking-at-p "^ \\(.*\\):$") + (not (and (looking-at "^ \\(.*\\):$") (file-name-absolute-p (match-string 1))))) ;; Note that dired-build-subdir-alist will replace the name ;; by its expansion, so it does not matter whether what we insert From 307764cc3a2afd363cae0a36a6d18dfa68788cb4 Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Tue, 6 Aug 2013 03:26:29 +0200 Subject: [PATCH 034/449] lisp/frameset.el: Various fixes. (frameset-p): Don't check non-nullness of the `properties' slot , which can indeed be nil. (frameset-live-filter-alist, frameset-persistent-filter-alist): Move entry for `left' from persistent to live filter alist. (frameset-filter-alist, frameset--minibufferless-last-p, frameset-save): Doc fixes. (frameset-filter-params): When restoring a frame, copy items added to `filtered', to avoid unwittingly modifying the original parameters. (frameset-move-onscreen): Rename from frameset--move-onscreen. Doc fix. (frameset--restore-frame): Fix reference to frameset-move-onscreen. --- lisp/ChangeLog | 11 +++++++++++ lisp/frameset.el | 34 ++++++++++++++++++++-------------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index c3f908b83ae..61254731938 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,16 @@ 2013-08-06 Juanma Barranquero + * frameset.el (frameset-p): Don't check non-nullness of the `properties' + slot , which can indeed be nil. + (frameset-live-filter-alist, frameset-persistent-filter-alist): + Move entry for `left' from persistent to live filter alist. + (frameset-filter-alist, frameset--minibufferless-last-p, frameset-save): + Doc fixes. + (frameset-filter-params): When restoring a frame, copy items added to + `filtered', to avoid unwittingly modifying the original parameters. + (frameset-move-onscreen): Rename from frameset--move-onscreen. Doc fix. + (frameset--restore-frame): Fix reference to frameset-move-onscreen. + * dired.el (dired-insert-directory): Revert change in 2013-06-21T12:24:37Z!lekktu@gmail.com to use looking-at-p instead of looking-at. (Bug#15028) diff --git a/lisp/frameset.el b/lisp/frameset.el index 0e98f4655da..71c26112917 100644 --- a/lisp/frameset.el +++ b/lisp/frameset.el @@ -103,7 +103,6 @@ This is a deep copy done with `copy-tree'." Else return nil." (and (eq (car-safe frameset) 'frameset) ; is a list (integerp (nth 1 frameset)) ; version is an int - (nth 2 frameset) ; properties is non-null (nth 3 frameset) ; states is non-null (nth 1 frameset))) ; return version @@ -129,6 +128,7 @@ Properties can be set with ;;;###autoload (defvar frameset-live-filter-alist '((name . :never) + (left . frameset-filter-iconified) (minibuffer . frameset-filter-minibuffer) (top . frameset-filter-iconified)) "Minimum set of parameters to filter for live (on-session) framesets. @@ -149,7 +149,6 @@ See `frameset-filter-alist' for a full description.") (GUI:height . frameset-filter-restore-param) (GUI:width . frameset-filter-restore-param) (height . frameset-filter-save-param) - (left . frameset-filter-iconified) (outer-window-id . :never) (parent-id . :never) (tty . frameset-filter-tty-to-GUI) @@ -194,7 +193,8 @@ SAVING, plus any additional ARGS: SAVING Non-nil if filtering before saving state, nil if filtering before restoring it. -FILTER-FUN must return: +FILTER-FUN is allowed to modify items in FILTERED, but no other arguments. +It must return: nil Skip CURRENT (do not add it to FILTERED). t Add CURRENT to FILTERED as is. (NEW-PARAM . NEW-VALUE) Add this to FILTERED instead of CURRENT. @@ -315,19 +315,24 @@ SAVING is non-nil while filtering parameters to save a frameset, nil while the filtering is done to restore it." (let ((filtered nil)) (dolist (current parameters) + ;; When saving, the parameter list is temporary, so modifying it + ;; is not a problem. When restoring, the parameter list is part + ;; of a frameset, so we must copy parameters to avoid inadvertent + ;; modifications. (pcase (cdr (assq (car current) filter-alist)) (`nil - (push current filtered)) + (push (if saving current (copy-tree current)) filtered)) (:never nil) (:restore - (unless saving (push current filtered))) + (unless saving (push (copy-tree current) filtered))) (:save (when saving (push current filtered))) ((or `(,fun . ,args) (and fun (pred fboundp))) - (let ((this (apply fun current filtered parameters saving args))) - (when this - (push (if (eq this t) current this) filtered)))) + (let* ((this (apply fun current filtered parameters saving args)) + (val (if (eq this t) current this))) + (when val + (push (if saving val (copy-tree val)) filtered)))) (other (delay-warning 'frameset (format "Unknown filter %S" other) :error)))) ;; Set the display parameter after filtering, so that filter functions @@ -410,7 +415,8 @@ FRAME-LIST is a list of frames. Internal use only." ;;;###autoload (cl-defun frameset-save (frame-list &key filters predicate properties) "Return the frameset of FRAME-LIST, a list of frames. -If nil, FRAME-LIST defaults to all live frames. +Dead frames and non-frame objects are silently removed from the list. +If nil, FRAME-LIST defaults to the output of `frame-list' (all live frames). FILTERS is an alist of parameter filters; defaults to `frameset-filter-alist'. PREDICATE is a predicate function, which must return non-nil for frames that should be saved; it defaults to saving all frames from FRAME-LIST. @@ -445,12 +451,12 @@ Internal use only.") (`(- ,val) (+ right/bottom val)) (val val))) -(defun frameset--move-onscreen (frame force-onscreen) +(defun frameset-move-onscreen (frame force-onscreen) "If FRAME is offscreen, move it back onscreen and, if necessary, resize it. For the description of FORCE-ONSCREEN, see `frameset-restore'. When forced onscreen, frames wider than the monitor's workarea are converted to fullwidth, and frames taller than the workarea are converted to fullheight. -NOTE: This only works for non-iconified frames. Internal use only." +NOTE: This only works for non-iconified frames." (pcase-let* ((`(,left ,top ,width ,height) (cl-cdadr (frame-monitor-attributes frame))) (right (+ left width -1)) (bottom (+ top height -1)) @@ -642,7 +648,7 @@ Internal use only." ;; FIXME: iconified frames should be checked too, ;; but it is impossible without deiconifying them. (not (eq (frame-parameter frame 'visibility) 'icon))) - (frameset--move-onscreen frame force-onscreen)) + (frameset-move-onscreen frame force-onscreen)) ;; Let's give the finishing touches (visibility, tool-bar, maximization). (when lines (push lines alt-cfg)) @@ -652,7 +658,7 @@ Internal use only." frame)) (defun frameset--minibufferless-last-p (state1 state2) - "Predicate to sort frame states in a suitable order to be created. + "Predicate to sort frame states in an order suitable for creating frames. It sorts minibuffer-owning frames before minibufferless ones." (pcase-let ((`(,hasmini1 ,id-def1) (assq 'frameset--mini (car state1))) (`(,hasmini2 ,id-def2) (assq 'frameset--mini (car state2)))) @@ -665,7 +671,7 @@ It sorts minibuffer-owning frames before minibufferless ones." (defun frameset-keep-original-display-p (force-display) "True if saved frames' displays should be honored." (cond ((daemonp) t) - ((eq system-type 'windows-nt) nil) + ((eq system-type 'windows-nt) nil) ;; Does ns support more than one display? (t (not force-display)))) (defun frameset-minibufferless-first-p (frame1 _frame2) From 00012b86257f33dd4e08e79b814f4a7ad6010713 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Tue, 6 Aug 2013 09:30:18 +0400 Subject: [PATCH 035/449] Invalidate region caches only if buffer text is going to be changed. * lisp.h (modify_region_1): Remove 3rd arg and rename to... (modify_text): ...new prototype. (prepare_to_modify_buffer_1): New prototype. * textprop.c (modify_region): Rename to... (modify_text_properties): ...new function. (add_text_properties_1, set_text_properties, Fremove_text_properties) (Fremove_list_of_text_properties): Adjust users. * insdel.c (modify_region_1): Remove 3rd arg and reimplement as... (modify_text): ...new function. (prepare_to_modify_buffer): Reimplement mostly as a wrapper for... (prepare_to_modify_buffer_1): ...new function. * casefiddle.c (casify_region): * editfns.c (Fsubst_char_in_region, Ftranslate_region_internal) (Ftranspose_regions): Use modify_text. --- src/ChangeLog | 18 ++++++++++++++++++ src/casefiddle.c | 2 +- src/editfns.c | 14 +++++++------- src/insdel.c | 32 ++++++++++++++++++-------------- src/lisp.h | 3 ++- src/textprop.c | 41 ++++++++++++++++++++++++++--------------- 6 files changed, 72 insertions(+), 38 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 35b5c1cfe5c..7b7d9b56cb5 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,21 @@ +2013-08-06 Dmitry Antipov + + Invalidate region caches only if buffer text is going to be changed. + * lisp.h (modify_region_1): Remove 3rd arg and rename to... + (modify_text): ...new prototype. + (prepare_to_modify_buffer_1): New prototype. + * textprop.c (modify_region): Rename to... + (modify_text_properties): ...new function. + (add_text_properties_1, set_text_properties, Fremove_text_properties) + (Fremove_list_of_text_properties): Adjust users. + * insdel.c (modify_region_1): Remove 3rd arg and reimplement as... + (modify_text): ...new function. + (prepare_to_modify_buffer): Reimplement mostly as a wrapper for... + (prepare_to_modify_buffer_1): ...new function. + * casefiddle.c (casify_region): + * editfns.c (Fsubst_char_in_region, Ftranslate_region_internal) + (Ftranspose_regions): Use modify_text. + 2013-08-05 Stefan Monnier * lisp.mk (lisp): Add nadvice.elc. diff --git a/src/casefiddle.c b/src/casefiddle.c index 7f5b99752fa..5a40790f87f 100644 --- a/src/casefiddle.c +++ b/src/casefiddle.c @@ -214,7 +214,7 @@ casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e) validate_region (&b, &e); start = XFASTINT (b); end = XFASTINT (e); - modify_region_1 (start, end, false); + modify_text (start, end); record_change (start, end - start); start_byte = CHAR_TO_BYTE (start); diff --git a/src/editfns.c b/src/editfns.c index 50bde90788d..90346a88eb2 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -2928,7 +2928,7 @@ Both characters must have the same length of multi-byte form. */) else if (!changed) { changed = -1; - modify_region_1 (pos, XINT (end), false); + modify_text (pos, XINT (end)); if (! NILP (noundo)) { @@ -3104,7 +3104,7 @@ It returns the number of characters changed. */) pos = XINT (start); pos_byte = CHAR_TO_BYTE (pos); end_pos = XINT (end); - modify_region_1 (pos, end_pos, false); + modify_text (pos, end_pos); cnt = 0; for (; pos < end_pos; ) @@ -4615,7 +4615,7 @@ Transposing beyond buffer boundaries is an error. */) if (end1 == start2) /* adjacent regions */ { - modify_region_1 (start1, end2, false); + modify_text (start1, end2); record_change (start1, len1 + len2); tmp_interval1 = copy_intervals (cur_intv, start1, len1); @@ -4674,8 +4674,8 @@ Transposing beyond buffer boundaries is an error. */) { USE_SAFE_ALLOCA; - modify_region_1 (start1, end1, false); - modify_region_1 (start2, end2, false); + modify_text (start1, end1); + modify_text (start2, end2); record_change (start1, len1); record_change (start2, len2); tmp_interval1 = copy_intervals (cur_intv, start1, len1); @@ -4708,7 +4708,7 @@ Transposing beyond buffer boundaries is an error. */) { USE_SAFE_ALLOCA; - modify_region_1 (start1, end2, false); + modify_text (start1, end2); record_change (start1, (end2 - start1)); tmp_interval1 = copy_intervals (cur_intv, start1, len1); tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); @@ -4741,7 +4741,7 @@ Transposing beyond buffer boundaries is an error. */) USE_SAFE_ALLOCA; record_change (start1, (end2 - start1)); - modify_region_1 (start1, end2, false); + modify_text (start1, end2); tmp_interval1 = copy_intervals (cur_intv, start1, len1); tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); diff --git a/src/insdel.c b/src/insdel.c index 58c3e15c233..ac64299a997 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -1756,27 +1756,22 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte, return deletion; } -/* Call this if you're about to change the region of current buffer +/* Call this if you're about to change the text of current buffer from character positions START to END. This checks the read-only properties of the region, calls the necessary modification hooks, and warns the next redisplay that it should pay attention to that - area. - - If PRESERVE_CHARS_MODIFF, do not update CHARS_MODIFF. - Otherwise set CHARS_MODIFF to the new value of MODIFF. */ + area. */ void -modify_region_1 (ptrdiff_t start, ptrdiff_t end, bool preserve_chars_modiff) +modify_text (ptrdiff_t start, ptrdiff_t end) { prepare_to_modify_buffer (start, end, NULL); BUF_COMPUTE_UNCHANGED (current_buffer, start - 1, end); - if (MODIFF <= SAVE_MODIFF) record_first_change (); MODIFF++; - if (! preserve_chars_modiff) - CHARS_MODIFF = MODIFF; + CHARS_MODIFF = MODIFF; bset_point_before_scroll (current_buffer, Qnil); } @@ -1792,8 +1787,8 @@ modify_region_1 (ptrdiff_t start, ptrdiff_t end, bool preserve_chars_modiff) by holding its value temporarily in a marker. */ void -prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, - ptrdiff_t *preserve_ptr) +prepare_to_modify_buffer_1 (ptrdiff_t start, ptrdiff_t end, + ptrdiff_t *preserve_ptr) { struct buffer *base_buffer; @@ -1864,6 +1859,17 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, } signal_before_change (start, end, preserve_ptr); + Vdeactivate_mark = Qt; +} + +/* Like above, but called when we know that the buffer text + will be modified and region caches should be invalidated. */ + +void +prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, + ptrdiff_t *preserve_ptr) +{ + prepare_to_modify_buffer_1 (start, end, preserve_ptr); if (current_buffer->newline_cache) invalidate_region_cache (current_buffer, @@ -1873,10 +1879,8 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, invalidate_region_cache (current_buffer, current_buffer->width_run_cache, start - BEG, Z - end); - - Vdeactivate_mark = Qt; } - + /* These macros work with an argument named `preserve_ptr' and a local variable named `preserve_marker'. */ diff --git a/src/lisp.h b/src/lisp.h index 085acb54348..8ca6d05a821 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3370,8 +3370,9 @@ extern void del_range_byte (ptrdiff_t, ptrdiff_t, bool); extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool); extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool); -extern void modify_region_1 (ptrdiff_t, ptrdiff_t, bool); +extern void modify_text (ptrdiff_t, ptrdiff_t); extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *); +extern void prepare_to_modify_buffer_1 (ptrdiff_t, ptrdiff_t, ptrdiff_t *); extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t); extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t); diff --git a/src/textprop.c b/src/textprop.c index 282ae11d4ac..b804f345047 100644 --- a/src/textprop.c +++ b/src/textprop.c @@ -93,15 +93,25 @@ text_read_only (Lisp_Object propval) xsignal0 (Qtext_read_only); } -/* Prepare to modify the region of BUFFER from START to END. */ +/* Prepare to modify the text properties of BUFFER from START to END. */ static void -modify_region (Lisp_Object buffer, Lisp_Object start, Lisp_Object end) +modify_text_properties (Lisp_Object buffer, Lisp_Object start, Lisp_Object end) { + ptrdiff_t b = XINT (start), e = XINT (end); struct buffer *buf = XBUFFER (buffer), *old = current_buffer; set_buffer_internal (buf); - modify_region_1 (XINT (start), XINT (end), true); + + prepare_to_modify_buffer_1 (b, e, NULL); + + BUF_COMPUTE_UNCHANGED (buf, b - 1, e); + if (MODIFF <= SAVE_MODIFF) + record_first_change (); + MODIFF++; + + bset_point_before_scroll (current_buffer, Qnil); + set_buffer_internal (old); } @@ -1213,9 +1223,9 @@ add_text_properties_1 (Lisp_Object start, Lisp_Object end, ptrdiff_t prev_total_length = TOTAL_LENGTH (i); ptrdiff_t prev_pos = i->position; - modify_region (object, start, end); + modify_text_properties (object, start, end); /* If someone called us recursively as a side effect of - modify_region, and changed the intervals behind our back + modify_text_properties, and changed the intervals behind our back (could happen if lock_file, called by prepare_to_modify_buffer, triggers redisplay, and that calls add-text-properties again in the same buffer), we cannot continue with I, because its @@ -1357,7 +1367,8 @@ into it. */) otherwise. */ Lisp_Object -set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, Lisp_Object object, Lisp_Object coherent_change_p) +set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, + Lisp_Object object, Lisp_Object coherent_change_p) { register INTERVAL i; Lisp_Object ostart, oend; @@ -1403,7 +1414,7 @@ set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, } if (BUFFERP (object) && !NILP (coherent_change_p)) - modify_region (object, start, end); + modify_text_properties (object, start, end); set_text_properties_1 (start, end, properties, object, i); @@ -1558,9 +1569,9 @@ Use `set-text-properties' if you want to remove all text properties. */) ptrdiff_t prev_total_length = TOTAL_LENGTH (i); ptrdiff_t prev_pos = i->position; - modify_region (object, start, end); + modify_text_properties (object, start, end); /* If someone called us recursively as a side effect of - modify_region, and changed the intervals behind our back + modify_text_properties, and changed the intervals behind our back (could happen if lock_file, called by prepare_to_modify_buffer, triggers redisplay, and that calls add-text-properties again in the same buffer), we cannot continue with I, because its @@ -1667,9 +1678,9 @@ Return t if any property was actually removed, nil otherwise. */) /* We are at the beginning of an interval, with len to scan. The flag `modified' records if changes have been made. - When object is a buffer, we must call modify_region before changes are - made and signal_after_change when we are done. - We call modify_region before calling remove_properties if modified == 0, + When object is a buffer, we must call modify_text_properties + before changes are made and signal_after_change when we are done. + We call modify_text_properties before calling remove_properties if modified == 0, and we call signal_after_change before returning if modified != 0. */ for (;;) { @@ -1693,7 +1704,7 @@ Return t if any property was actually removed, nil otherwise. */) else if (LENGTH (i) == len) { if (!modified && BUFFERP (object)) - modify_region (object, start, end); + modify_text_properties (object, start, end); remove_properties (Qnil, properties, i, object); if (BUFFERP (object)) signal_after_change (XINT (start), XINT (end) - XINT (start), @@ -1706,7 +1717,7 @@ Return t if any property was actually removed, nil otherwise. */) i = split_interval_left (i, len); copy_properties (unchanged, i); if (!modified && BUFFERP (object)) - modify_region (object, start, end); + modify_text_properties (object, start, end); remove_properties (Qnil, properties, i, object); if (BUFFERP (object)) signal_after_change (XINT (start), XINT (end) - XINT (start), @@ -1717,7 +1728,7 @@ Return t if any property was actually removed, nil otherwise. */) if (interval_has_some_properties_list (properties, i)) { if (!modified && BUFFERP (object)) - modify_region (object, start, end); + modify_text_properties (object, start, end); remove_properties (Qnil, properties, i, object); modified = 1; } From e30b79c1c52a4428189ca148c73e7ecc993c6f6a Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Tue, 6 Aug 2013 10:53:09 +0400 Subject: [PATCH 036/449] Use region cache to speedup bidi_find_paragraph_start. * src/buffer.h (struct buffer): New member bidi_paragraph_cache. Rename cache_long_line_scans to cache_long_scans. * src/buffer.c (bset_cache_long_line_scans): Rename to bset_cache_long_scans. (Fget_buffer_create, Fmake_indirect_buffer, Fkill_buffer) (Fbuffer_swap_text, init_buffer_once): Take bidi_paragraph_cache into account. (syms_of_buffer): Rename cache-long-line-scans to cache-long-scans. Adjust docstring. * src/search.c (newline_cache_on_off): * src/indent.c (width_run_cache_on_off): Adjust users. * src/bidi.c (bidi_paragraph_cache_on_off): New function. (bidi_find_paragraph_start): Use bidi_paragraph_cache if needed. * src/insdel.c (prepare_to_modify_buffer): Invalidate bidi_paragraph_cache if enabled. * doc/lispref/positions.texi (Motion by Screen Lines): * doc/lispref/display.texi (Truncation): Rename `cache-long-line-scans' to `cache-long-scans'. --- doc/lispref/ChangeLog | 6 ++++++ doc/lispref/display.texi | 4 ++-- doc/lispref/positions.texi | 2 +- src/ChangeLog | 19 +++++++++++++++++++ src/bidi.c | 39 +++++++++++++++++++++++++++++++++++--- src/buffer.c | 30 +++++++++++++++++++++-------- src/buffer.h | 11 +++++++---- src/indent.c | 6 +++--- src/insdel.c | 4 ++++ src/search.c | 4 ++-- 10 files changed, 102 insertions(+), 23 deletions(-) diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index 82bc279fa5b..0aac5235a29 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog @@ -1,3 +1,9 @@ +2013-08-06 Dmitry Antipov + + * positions.texi (Motion by Screen Lines): + * display.texi (Truncation): Rename `cache-long-line-scans' + to `cache-long-scans'. + 2013-08-05 Xue Fuqiao * windows.texi (Window Start and End): Add an index. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index c5068425c66..59a6f5ce340 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -217,9 +217,9 @@ over the @code{line-prefix} variable. @xref{Special Properties}. continuation to display them, computing the continuation lines can make redisplay slow. The column computation and indentation functions also become slow. Then you might find it advisable to set -@code{cache-long-line-scans} to @code{t}. +@code{cache-long-scans} to @code{t}. -@defvar cache-long-line-scans +@defvar cache-long-scans If this variable is non-@code{nil}, various indentation and motion functions, and Emacs redisplay, cache the results of scanning the buffer, and consult the cache to avoid rescanning regions of the buffer diff --git a/doc/lispref/positions.texi b/doc/lispref/positions.texi index e8b6166f63c..119ad98a53d 100644 --- a/doc/lispref/positions.texi +++ b/doc/lispref/positions.texi @@ -483,7 +483,7 @@ Display}. These functions scan text to determine where screen lines break, and thus take time proportional to the distance scanned. If you intend to use them heavily, Emacs provides caches which may improve the -performance of your code. @xref{Truncation, cache-long-line-scans}. +performance of your code. @xref{Truncation, cache-long-scans}. @defun vertical-motion count &optional window This function moves point to the start of the screen line @var{count} diff --git a/src/ChangeLog b/src/ChangeLog index 7b7d9b56cb5..e8c09b3b4f3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,22 @@ +2013-08-06 Dmitry Antipov + + Use region cache to speedup bidi_find_paragraph_start. + * buffer.h (struct buffer): New member bidi_paragraph_cache. + Rename cache_long_line_scans to cache_long_scans. + * buffer.c (bset_cache_long_line_scans): Rename to + bset_cache_long_scans. + (Fget_buffer_create, Fmake_indirect_buffer, Fkill_buffer) + (Fbuffer_swap_text, init_buffer_once): Take bidi_paragraph_cache + into account. + (syms_of_buffer): Rename cache-long-line-scans to + cache-long-scans. Adjust docstring. + * search.c (newline_cache_on_off): + * indent.c (width_run_cache_on_off): Adjust users. + * bidi.c (bidi_paragraph_cache_on_off): New function. + (bidi_find_paragraph_start): Use bidi_paragraph_cache if needed. + * insdel.c (prepare_to_modify_buffer): Invalidate + bidi_paragraph_cache if enabled. + 2013-08-06 Dmitry Antipov Invalidate region caches only if buffer text is going to be changed. diff --git a/src/bidi.c b/src/bidi.c index c31d208ecbc..7d082a94997 100644 --- a/src/bidi.c +++ b/src/bidi.c @@ -61,6 +61,7 @@ along with GNU Emacs. If not, see . */ #include "character.h" #include "buffer.h" #include "dispextern.h" +#include "region-cache.h" static bool bidi_initialized = 0; @@ -1085,6 +1086,29 @@ bidi_at_paragraph_end (ptrdiff_t charpos, ptrdiff_t bytepos) return val; } +/* If the user has requested the long scans caching, make sure that + BIDI cache is enabled. Otherwise, make sure it's disabled. */ + +static struct region_cache * +bidi_paragraph_cache_on_off (void) +{ + if (NILP (BVAR (current_buffer, cache_long_scans))) + { + if (current_buffer->bidi_paragraph_cache) + { + free_region_cache (current_buffer->bidi_paragraph_cache); + current_buffer->bidi_paragraph_cache = 0; + } + return NULL; + } + else + { + if (!current_buffer->bidi_paragraph_cache) + current_buffer->bidi_paragraph_cache = new_region_cache (); + return current_buffer->bidi_paragraph_cache; + } +} + /* On my 2005-vintage machine, searching back for paragraph start takes ~1 ms per line. And bidi_paragraph_init is called 4 times when user types C-p. The number below limits each call to @@ -1100,7 +1124,8 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte) { Lisp_Object re = paragraph_start_re; ptrdiff_t limit = ZV, limit_byte = ZV_BYTE; - ptrdiff_t n = 0; + struct region_cache *bpc = bidi_paragraph_cache_on_off (); + ptrdiff_t n = 0, oldpos = pos, next; while (pos_byte > BEGV_BYTE && n++ < MAX_PARAGRAPH_SEARCH @@ -1111,10 +1136,18 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte) of the text over which we scan back includes paragraph_start_re? */ DEC_BOTH (pos, pos_byte); - pos = find_newline_no_quit (pos, pos_byte, -1, &pos_byte); + if (bpc && region_cache_backward (current_buffer, bpc, pos, &next)) + { + pos = next, pos_byte = CHAR_TO_BYTE (pos); + break; + } + else + pos = find_newline_no_quit (pos, pos_byte, -1, &pos_byte); } if (n >= MAX_PARAGRAPH_SEARCH) - pos_byte = BEGV_BYTE; + pos = BEGV, pos_byte = BEGV_BYTE; + if (bpc) + know_region_cache (current_buffer, bpc, pos, oldpos); return pos_byte; } diff --git a/src/buffer.c b/src/buffer.c index f9154d42b03..339175d9078 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -203,9 +203,9 @@ bset_buffer_file_coding_system (struct buffer *b, Lisp_Object val) b->INTERNAL_FIELD (buffer_file_coding_system) = val; } static void -bset_cache_long_line_scans (struct buffer *b, Lisp_Object val) +bset_cache_long_scans (struct buffer *b, Lisp_Object val) { - b->INTERNAL_FIELD (cache_long_line_scans) = val; + b->INTERNAL_FIELD (cache_long_scans) = val; } static void bset_case_fold_search (struct buffer *b, Lisp_Object val) @@ -583,6 +583,7 @@ even if it is dead. The return value is never nil. */) b->newline_cache = 0; b->width_run_cache = 0; + b->bidi_paragraph_cache = 0; bset_width_table (b, Qnil); b->prevent_redisplay_optimizations_p = 1; @@ -806,6 +807,7 @@ CLONE nil means the indirect buffer's state is reset to default values. */) b->newline_cache = 0; b->width_run_cache = 0; + b->bidi_paragraph_cache = 0; bset_width_table (b, Qnil); name = Fcopy_sequence (name); @@ -1945,6 +1947,11 @@ cleaning up all windows currently displaying the buffer to be killed. */) free_region_cache (b->width_run_cache); b->width_run_cache = 0; } + if (b->bidi_paragraph_cache) + { + free_region_cache (b->bidi_paragraph_cache); + b->bidi_paragraph_cache = 0; + } bset_width_table (b, Qnil); unblock_input (); bset_undo_list (b, Qnil); @@ -2355,6 +2362,7 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, current_buffer->clip_changed = 1; other_buffer->clip_changed = 1; swapfield (newline_cache, struct region_cache *); swapfield (width_run_cache, struct region_cache *); + swapfield (bidi_paragraph_cache, struct region_cache *); current_buffer->prevent_redisplay_optimizations_p = 1; other_buffer->prevent_redisplay_optimizations_p = 1; swapfield (overlays_before, struct Lisp_Overlay *); @@ -5169,7 +5177,7 @@ init_buffer_once (void) bset_buffer_file_coding_system (&buffer_defaults, Qnil); XSETFASTINT (BVAR (&buffer_defaults, fill_column), 70); XSETFASTINT (BVAR (&buffer_defaults, left_margin), 0); - bset_cache_long_line_scans (&buffer_defaults, Qnil); + bset_cache_long_scans (&buffer_defaults, Qnil); bset_file_truename (&buffer_defaults, Qnil); XSETFASTINT (BVAR (&buffer_defaults, display_count), 0); XSETFASTINT (BVAR (&buffer_defaults, left_margin_cols), 0); @@ -5233,7 +5241,7 @@ init_buffer_once (void) XSETFASTINT (BVAR (&buffer_local_flags, abbrev_table), idx); ++idx; XSETFASTINT (BVAR (&buffer_local_flags, display_table), idx); ++idx; XSETFASTINT (BVAR (&buffer_local_flags, syntax_table), idx); ++idx; - XSETFASTINT (BVAR (&buffer_local_flags, cache_long_line_scans), idx); ++idx; + XSETFASTINT (BVAR (&buffer_local_flags, cache_long_scans), idx); ++idx; XSETFASTINT (BVAR (&buffer_local_flags, category_table), idx); ++idx; XSETFASTINT (BVAR (&buffer_local_flags, bidi_display_reordering), idx); ++idx; XSETFASTINT (BVAR (&buffer_local_flags, bidi_paragraph_direction), idx); ++idx; @@ -6120,8 +6128,8 @@ If the value of the variable is t, undo information is not recorded. */); DEFVAR_PER_BUFFER ("mark-active", &BVAR (current_buffer, mark_active), Qnil, doc: /* Non-nil means the mark and region are currently active in this buffer. */); - DEFVAR_PER_BUFFER ("cache-long-line-scans", &BVAR (current_buffer, cache_long_line_scans), Qnil, - doc: /* Non-nil means that Emacs should use caches to handle long lines more quickly. + DEFVAR_PER_BUFFER ("cache-long-scans", &BVAR (current_buffer, cache_long_scans), Qnil, + doc: /* Non-nil means that Emacs should use caches in attempt to speedup buffer scans. Normally, the line-motion functions work by scanning the buffer for newlines. Columnar operations (like `move-to-column' and @@ -6131,18 +6139,24 @@ buffer's lines are very long (say, more than 500 characters), these motion functions will take longer to execute. Emacs may also take longer to update the display. -If `cache-long-line-scans' is non-nil, these motion functions cache the +If `cache-long-scans' is non-nil, these motion functions cache the results of their scans, and consult the cache to avoid rescanning regions of the buffer until the text is modified. The caches are most beneficial when they prevent the most searching---that is, when the buffer contains long lines and large regions of characters with the same, fixed screen width. -When `cache-long-line-scans' is non-nil, processing short lines will +When `cache-long-scans' is non-nil, processing short lines will become slightly slower (because of the overhead of consulting the cache), and the caches will use memory roughly proportional to the number of newlines and characters whose screen width varies. +Bidirectional editing also requires buffer scans to find paragraph +separators. If you have large paragraphs or no paragraph separators +at all, these scans may be slow. If `cache-long-scans' is non-nil, +results of these scans are cached. This doesn't help too much if +paragraphs are of the reasonable (few thousands of characters) size. + The caches require no explicit maintenance; their accuracy is maintained internally by the Emacs primitives. Enabling or disabling the cache should not affect the behavior of any of the motion diff --git a/src/buffer.h b/src/buffer.h index 646f8f72232..221db39329a 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -632,9 +632,9 @@ struct buffer /* List of symbols naming the file format used for auto-save file. */ Lisp_Object INTERNAL_FIELD (auto_save_file_format); - /* True if the newline position cache and width run cache are - enabled. See search.c and indent.c. */ - Lisp_Object INTERNAL_FIELD (cache_long_line_scans); + /* True if the newline position cache, width run cache and BIDI paragraph + cache are enabled. See search.c, indent.c and bidi.c for details. */ + Lisp_Object INTERNAL_FIELD (cache_long_scans); /* If the width run cache is enabled, this table contains the character widths width_run_cache (see above) assumes. When we @@ -839,9 +839,12 @@ struct buffer the character's width; if it maps a character to zero, we don't know what its width is. This allows compute_motion to process such regions very quickly, using algebra instead of inspecting - each character. See also width_table, below. */ + each character. See also width_table, below. + + The latter cache is used to speedup bidi_find_paragraph_start. */ struct region_cache *newline_cache; struct region_cache *width_run_cache; + struct region_cache *bidi_paragraph_cache; /* Non-zero means don't use redisplay optimizations for displaying this buffer. */ diff --git a/src/indent.c b/src/indent.c index 47358e17db8..6aaf86579d7 100644 --- a/src/indent.c +++ b/src/indent.c @@ -141,13 +141,13 @@ recompute_width_table (struct buffer *buf, struct Lisp_Char_Table *disptab) XSETFASTINT (widthtab->contents[i], character_width (i, disptab)); } -/* Allocate or free the width run cache, as requested by the current - state of current_buffer's cache_long_line_scans variable. */ +/* Allocate or free the width run cache, as requested by the + current state of current_buffer's cache_long_scans variable. */ static void width_run_cache_on_off (void) { - if (NILP (BVAR (current_buffer, cache_long_line_scans)) + if (NILP (BVAR (current_buffer, cache_long_scans)) /* And, for the moment, this feature doesn't work on multibyte characters. */ || !NILP (BVAR (current_buffer, enable_multibyte_characters))) diff --git a/src/insdel.c b/src/insdel.c index ac64299a997..f746fd34330 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -1879,6 +1879,10 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, invalidate_region_cache (current_buffer, current_buffer->width_run_cache, start - BEG, Z - end); + if (current_buffer->bidi_paragraph_cache) + invalidate_region_cache (current_buffer, + current_buffer->bidi_paragraph_cache, + start - BEG, Z - end); } /* These macros work with an argument named `preserve_ptr' diff --git a/src/search.c b/src/search.c index 0f4d41586a3..761c12a364a 100644 --- a/src/search.c +++ b/src/search.c @@ -598,14 +598,14 @@ fast_looking_at (Lisp_Object regexp, ptrdiff_t pos, ptrdiff_t pos_byte, /* The newline cache: remembering which sections of text have no newlines. */ -/* If the user has requested newline caching, make sure it's on. +/* If the user has requested the long scans caching, make sure it's on. Otherwise, make sure it's off. This is our cheezy way of associating an action with the change of state of a buffer-local variable. */ static void newline_cache_on_off (struct buffer *buf) { - if (NILP (BVAR (buf, cache_long_line_scans))) + if (NILP (BVAR (buf, cache_long_scans))) { /* It should be off. */ if (buf->newline_cache) From 8951efefa167119b567b9d1aab0eb5dd05d362b8 Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Tue, 6 Aug 2013 11:38:41 +0200 Subject: [PATCH 037/449] lisp/vc/vc.el: Silence byte-compiler warning. --- lisp/ChangeLog | 3 +++ lisp/vc/vc.el | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 61254731938..c7a5d6ae070 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,8 @@ 2013-08-06 Juanma Barranquero + * vc/vc.el (vc-default-ignore-completion-table): + Silence byte-compiler warning. + * frameset.el (frameset-p): Don't check non-nullness of the `properties' slot , which can indeed be nil. (frameset-live-filter-alist, frameset-persistent-filter-alist): diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index 9757d4a43be..35e91e7e059 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -486,7 +486,7 @@ ;; default implementation always returns nil. ;; ;; - root (file) -;; +;; ;; Return the root of the VC controlled hierarchy for file. ;; ;; - repository-hostname (dirname) @@ -502,13 +502,13 @@ ;; Ignore FILE under the current VCS. When called interactively and ;; with a prefix argument, remove an ignored file. When called from ;; Lisp code, if REMOVE is non-nil, remove FILE from ignored files." -;; +;; ;; - ignore-completion-table -;; +;; ;; Return the completion table for files ignored by the current ;; version control system, e.g., the entries in `.gitignore' and ;; `.bzrignore'. -;; +;; ;; - previous-revision (file rev) ;; ;; Return the revision number that precedes REV for FILE, or nil if no such @@ -1365,7 +1365,7 @@ non-nil, remove FILE from ignored files." (setq backend (vc-backend directory)) (vc-call-backend backend 'ignore file default-directory remove)))) -(defun vc-default-ignore-completion-table (file) +(defun vc-default-ignore-completion-table (_file) "Return the list of ignored files." ;; Unused lexical argument `file' nil) From c8c2aca8d0b231bfb960e2e4d4af268cceeada7c Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Tue, 6 Aug 2013 14:59:39 +0400 Subject: [PATCH 038/449] * frame.el (get-other-frame): Tiny cleanup. --- lisp/ChangeLog | 4 ++++ lisp/frame.el | 5 +---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index c7a5d6ae070..b9d97d4e140 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,7 @@ +2013-08-06 Dmitry Antipov + + * frame.el (get-other-frame): Tiny cleanup. + 2013-08-06 Juanma Barranquero * vc/vc.el (vc-default-ignore-completion-table): diff --git a/lisp/frame.el b/lisp/frame.el index 9d3c839fa35..31a9123503d 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -500,10 +500,7 @@ See help of `modify-frame-parameters' for more information." "Return some frame other than the current frame. Create one if necessary. Note that the minibuffer frame, if separate, is not considered (see `next-frame')." - (let ((s (if (equal (next-frame (selected-frame)) (selected-frame)) - (make-frame) - (next-frame (selected-frame))))) - s)) + (if (equal (next-frame) (selected-frame)) (make-frame) (next-frame))) (defun next-multiframe-window () "Select the next window, regardless of which frame it is on." From 64e22afeb39dd568082929d945148060d2ac7fa7 Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Tue, 6 Aug 2013 14:12:33 +0200 Subject: [PATCH 039/449] lisp/find-lisp.el: Fix typos in docstrings. --- lisp/ChangeLog | 5 +++++ lisp/find-lisp.el | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index b9d97d4e140..31c5414cae0 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2013-08-06 Juanma Barranquero + + * find-lisp.el (find-lisp-line-indent, find-lisp-find-dired-filter): + Fix typos in docstrings. + 2013-08-06 Dmitry Antipov * frame.el (get-other-frame): Tiny cleanup. diff --git a/lisp/find-lisp.el b/lisp/find-lisp.el index cac09bb11a8..0eea918dc48 100644 --- a/lisp/find-lisp.el +++ b/lisp/find-lisp.el @@ -53,7 +53,7 @@ "Internal variable.") (defconst find-lisp-line-indent " " - "Indentation for dired file lines.") + "Indentation for Dired file lines.") (defvar find-lisp-file-predicate nil "Predicate for choosing to include files.") @@ -280,7 +280,7 @@ It is a function which takes two arguments, the directory and its parent." ;;;###autoload (defun find-lisp-find-dired-filter (regexp) - "Change the filter on a find-lisp-find-dired buffer to REGEXP." + "Change the filter on a `find-lisp-find-dired' buffer to REGEXP." (interactive "sSet filter to regexp: ") (setq find-lisp-regexp regexp) (revert-buffer)) From 024b38fc4d3e1e09871109f428d80d37166ae032 Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Tue, 6 Aug 2013 14:18:43 +0200 Subject: [PATCH 040/449] lisp/frameset.el: Doc fixes. (frameset, frameset-filter-alist, frameset-filter-params, frameset-save) (frameset--reuse-frame, frameset--minibufferless-last-p, frameset-restore): Doc fixes. (frameset-compute-pos): Rename from frameset--compute-pos, and add docstring. (frameset-move-onscreen): Use frameset-compute-pos. Most changes suggested by Drew Adams . --- lisp/ChangeLog | 8 +++++ lisp/frameset.el | 76 ++++++++++++++++++++++++++++++------------------ 2 files changed, 56 insertions(+), 28 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 31c5414cae0..0843ca2398a 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,13 @@ 2013-08-06 Juanma Barranquero + * frameset.el (frameset, frameset-filter-alist) + (frameset-filter-params, frameset-save, frameset--reuse-frame) + (frameset--minibufferless-last-p, frameset-restore): Doc fixes. + (frameset-compute-pos): Rename from frameset--compute-pos, + and add docstring. + (frameset-move-onscreen): Use frameset-compute-pos. + Most changes suggested by Drew Adams . + * find-lisp.el (find-lisp-line-indent, find-lisp-find-dired-filter): Fix typos in docstrings. diff --git a/lisp/frameset.el b/lisp/frameset.el index 71c26112917..45cf86eb3cc 100644 --- a/lisp/frameset.el +++ b/lisp/frameset.el @@ -42,9 +42,12 @@ (cl-defstruct (frameset (:type list) :named + ;; Copier and predicate functions are defined below. (:copier nil) (:predicate nil) ;; A BOA constructor, not the default "keywordy" one. + ;; This is for internal use; to create a frameset, + ;; the "right" way to do it is with frameset-save. (:constructor make-frameset (properties states))) "A frameset encapsulates a serializable view of a set of frames and windows. @@ -55,11 +58,10 @@ It contains the following slots, which can be accessed with version A non-modifiable version number, identifying the format of the frameset struct. Currently its value is 1. properties A property list, to store both frameset-specific and - user-defined serializable data (some suggested properties - are described below). + user-defined serializable data (see suggestions below). states An alist of items (FRAME-PARAMETERS . WINDOW-STATE), in no particular order. Each item represents a frame to be - restored. FRAME-PARAMETERS is a frame's parameter list, + restored. FRAME-PARAMETERS is a frame's parameter alist, extracted with (frame-parameters FRAME) and filtered through `frame-parameters-alist' or a similar filter alist. WINDOW-STATE is the output of `window-state-get', when @@ -75,10 +77,14 @@ Some suggested properties: :desc TEXT A description for user consumption (to show in a menu to choose among framesets, etc.); a string. +To avoid collisions, it is recommended that applications wanting to add +private serializable data to `properties' either store all info under a +single, distinctive name, or use property names with a well-chosen prefix. + A frameset is intended to be used through the following simple API: - - `frameset-save' captures all or a subset of the live frames, and returns - a serializable snapshot of them (a frameset). + - `frameset-save', the type's constructor, captures all or a subset of the + live frames, and returns a serializable snapshot of them (a frameset). - `frameset-restore' takes a frameset, and restores the frames and windows it describes, as faithfully as possible. - `frameset-p' is the predicate for the frameset type. It returns nil @@ -166,15 +172,15 @@ See `frameset-filter-alist' for a full description.") This alist is the default value of the :filters arguments of `frameset-save' and `frameset-restore' (which see). On saving, -PARAMETERS is the parameter list of each frame processed, and -FILTERED is the parameter list that gets saved to the frameset. -On restoring, PARAMETERS is the parameter list extracted from the -frameset, and FILTERED is the resulting frame parameter list used +PARAMETERS is the parameter alist of each frame processed, and +FILTERED is the parameter alist that gets saved to the frameset. +On restoring, PARAMETERS is the parameter alist extracted from the +frameset, and FILTERED is the resulting frame parameter alist used to restore the frame. -Elements of this alist are conses (PARAM . ACTION), where PARAM -is a parameter name (a symbol identifying a frame parameter), and -ACTION can be: +Elements of `frameset-filter-alist' are conses (PARAM . ACTION), +where PARAM is a parameter name (a symbol identifying a frame +parameter), and ACTION can be: nil The parameter is copied to FILTERED. :never The parameter is never copied to FILTERED. @@ -183,8 +189,11 @@ ACTION can be: FILTER A filter function. FILTER can be a symbol FILTER-FUN, or a list (FILTER-FUN ARGS...). -FILTER-FUN is called with four arguments CURRENT, FILTERED, PARAMETERS and -SAVING, plus any additional ARGS: +FILTER-FUN is invoked with + + (apply FILTER-FUN CURRENT FILTERED PARAMETERS SAVING ARGS) + +where CURRENT A cons (PARAM . VALUE), where PARAM is the one being filtered and VALUE is its current value. @@ -192,6 +201,7 @@ SAVING, plus any additional ARGS: PARAMETERS The complete alist of parameters being filtered, SAVING Non-nil if filtering before saving state, nil if filtering before restoring it. + ARGS Any additional arguments specified in the ACTION. FILTER-FUN is allowed to modify items in FILTERED, but no other arguments. It must return: @@ -308,15 +318,15 @@ see the docstring of `frameset-filter-alist'." (not (and saving (eq (cdr (assq 'visibility parameters)) 'icon)))) (defun frameset-filter-params (parameters filter-alist saving) - "Filter parameter list PARAMETERS and return a filtered list. + "Filter parameter alist PARAMETERS and return a filtered alist. FILTER-ALIST is an alist of parameter filters, in the format of `frameset-filter-alist' (which see). SAVING is non-nil while filtering parameters to save a frameset, nil while the filtering is done to restore it." (let ((filtered nil)) (dolist (current parameters) - ;; When saving, the parameter list is temporary, so modifying it - ;; is not a problem. When restoring, the parameter list is part + ;; When saving, the parameter alist is temporary, so modifying it + ;; is not a problem. When restoring, the parameter alist is part ;; of a frameset, so we must copy parameters to avoid inadvertent ;; modifications. (pcase (cdr (assq (car current) filter-alist)) @@ -417,9 +427,9 @@ FRAME-LIST is a list of frames. Internal use only." "Return the frameset of FRAME-LIST, a list of frames. Dead frames and non-frame objects are silently removed from the list. If nil, FRAME-LIST defaults to the output of `frame-list' (all live frames). -FILTERS is an alist of parameter filters; defaults to `frameset-filter-alist'. +FILTERS is an alist of parameter filters, or `frameset-filter-alist' if nil. PREDICATE is a predicate function, which must return non-nil for frames that -should be saved; it defaults to saving all frames from FRAME-LIST. +should be saved; if PREDICATE is nil, all frames from FRAME-LIST are saved. PROPERTIES is a user-defined property list to add to the frameset." (let* ((list (or (copy-sequence frame-list) (frame-list))) (frames (cl-delete-if-not #'frame-live-p @@ -445,7 +455,16 @@ PROPERTIES is a user-defined property list to add to the frameset." Its value is only meaningful during execution of `frameset-restore'. Internal use only.") -(defun frameset--compute-pos (value left/top right/bottom) +(defun frameset-compute-pos (value left/top right/bottom) + "Return an absolute positioning value for a frame. +VALUE is the value of a positional frame parameter (`left' or `top'). +If VALUE is relative to the screen edges (like (+ -35) or (-200), it is +converted to absolute by adding it to the corresponding edge; if it is +an absolute position, it is returned unmodified. +LEFT/TOP and RIGHT/BOTTOM indicate the dimensions of the screen in +pixels along the relevant direction: either the position of the left +and right edges for a `left' positional parameter, or the position of +the top and bottom edges for a `top' parameter." (pcase value (`(+ ,val) (+ left/top val)) (`(- ,val) (+ right/bottom val)) @@ -460,8 +479,8 @@ NOTE: This only works for non-iconified frames." (pcase-let* ((`(,left ,top ,width ,height) (cl-cdadr (frame-monitor-attributes frame))) (right (+ left width -1)) (bottom (+ top height -1)) - (fr-left (frameset--compute-pos (frame-parameter frame 'left) left right)) - (fr-top (frameset--compute-pos (frame-parameter frame 'top) top bottom)) + (fr-left (frameset-compute-pos (frame-parameter frame 'left) left right)) + (fr-top (frameset-compute-pos (frame-parameter frame 'top) top bottom)) (ch-width (frame-char-width frame)) (ch-height (frame-char-height frame)) (fr-width (max (frame-pixel-width frame) (* ch-width (frame-width frame)))) @@ -529,7 +548,7 @@ If PREDICATE is nil, it is always satisfied. Internal use only." (defun frameset--reuse-frame (display frame-cfg) "Look for an existing frame to reuse. DISPLAY is the display where the frame will be shown, and FRAME-CFG -is the parameter list of the frame being restored. Internal use only." +is the parameter alist of the frame being restored. Internal use only." (let ((frame nil) mini) ;; There are no fancy heuristics there. We could implement some @@ -591,7 +610,7 @@ Internal use only." (defun frameset--restore-frame (frame-cfg window-cfg filters force-onscreen) "Set up and return a frame according to its saved state. That means either reusing an existing frame or creating one anew. -FRAME-CFG is the frame's parameter list; WINDOW-CFG is its window state. +FRAME-CFG is the frame's parameter alist; WINDOW-CFG is its window state. For the meaning of FILTERS and FORCE-ONSCREEN, see `frameset-restore'. Internal use only." (let* ((fullscreen (cdr (assq 'fullscreen frame-cfg))) @@ -631,7 +650,7 @@ Internal use only." ;; If a frame needs to be created and it falls partially or fully offscreen, ;; sometimes it gets "pushed back" onscreen; however, moving it afterwards is ;; allowed. So we create the frame as invisible and then reapply the full - ;; parameter list (including position and size parameters). + ;; parameter alist (including position and size parameters). (setq frame (or (and frameset--reuse-list (frameset--reuse-frame display filtered-cfg)) (make-frame-on-display display @@ -659,7 +678,8 @@ Internal use only." (defun frameset--minibufferless-last-p (state1 state2) "Predicate to sort frame states in an order suitable for creating frames. -It sorts minibuffer-owning frames before minibufferless ones." +It sorts minibuffer-owning frames before minibufferless ones. +Internal use only." (pcase-let ((`(,hasmini1 ,id-def1) (assq 'frameset--mini (car state1))) (`(,hasmini2 ,id-def2) (assq 'frameset--mini (car state2)))) (cond ((eq id-def1 t) t) @@ -697,9 +717,9 @@ FORCE-DISPLAY can be: t Frames are restored in the current display. nil Frames are restored, if possible, in their original displays. :delete Frames in other displays are deleted instead of restored. - PRED A function called with one argument, the parameter list; + PRED A function called with one argument, the parameter alist; it must return t, nil or `:delete', as above but affecting - only the frame that will be created from that parameter list. + only the frame that will be created from that parameter alist. FORCE-ONSCREEN can be: t Force onscreen only those frames that are fully offscreen. From a6933dccd7ac7f5dcae6fe590b3fea68bad7f767 Mon Sep 17 00:00:00 2001 From: Katsumi Yamaoka Date: Tue, 6 Aug 2013 13:52:59 +0000 Subject: [PATCH 041/449] lisp/gnus/mm-decode.el (mm-display-external): Work for xdg-open --- lisp/gnus/ChangeLog | 7 +++++++ lisp/gnus/mm-decode.el | 15 ++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index 2ae70791c16..238017e25fc 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog @@ -1,3 +1,10 @@ +2013-08-06 Katsumi Yamaoka + + * mm-decode.el (mm-display-external): Bind process-connection-type to + nil; don't delete a temp file immediately even if a viewer finishes, + since it may be a shell script, like xdg-open, that launches a real + viewer program belatedly. + 2013-08-05 Dave Abrahams * gnus-int.el (gnus-warp-to-article): Allow warping in all groups so diff --git a/lisp/gnus/mm-decode.el b/lisp/gnus/mm-decode.el index 7274708f014..98d854340ee 100644 --- a/lisp/gnus/mm-decode.el +++ b/lisp/gnus/mm-decode.el @@ -962,7 +962,7 @@ external if displayed external." (let ((command (mm-mailcap-command method file (mm-handle-type handle)))) (unwind-protect - (progn + (let ((process-connection-type nil)) (start-process "*display*" (setq buffer (generate-new-buffer " *mm*")) @@ -984,12 +984,13 @@ external if displayed external." (delete-directory (file-name-directory file))))) (lambda (process state) (when (eq (process-status process) 'exit) - (condition-case nil - (delete-file file) - (error)) - (condition-case nil - (delete-directory (file-name-directory file)) - (error)) + (run-at-time + 10.0 nil + (lambda () + (ignore-errors + (delete-file file)) + (ignore-errors + (delete-directory (file-name-directory file))))) (when (buffer-live-p outbuf) (with-current-buffer outbuf (let ((buffer-read-only nil) From 2878ba7ef3225a7946c72ef6346467f35c453347 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 6 Aug 2013 07:17:25 -0700 Subject: [PATCH 042/449] * process.c: Fix minor off-by-one issues in descriptor counts. This shouldn't fix any real bugs, but it cleans up the code a bit. (max_process_desc, max_input_desc): -1, not 0, means none. All uses changed. (delete_input_desc): New function. (delete_write_fd, delete_keyboard_wait_descriptor): Use it. (deactivate_process): Scan backwards when recomuting max_process_desc; that should be faster. (init_process_emacs): Initialize max_input_desc. --- src/ChangeLog | 12 ++++++++++++ src/process.c | 54 +++++++++++++++++++++++++-------------------------- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index e8c09b3b4f3..03420788a64 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,15 @@ +2013-08-06 Paul Eggert + + * process.c: Fix minor off-by-one issues in descriptor counts. + This shouldn't fix any real bugs, but it cleans up the code a bit. + (max_process_desc, max_input_desc): -1, not 0, means none. + All uses changed. + (delete_input_desc): New function. + (delete_write_fd, delete_keyboard_wait_descriptor): Use it. + (deactivate_process): Scan backwards when recomuting max_process_desc; + that should be faster. + (init_process_emacs): Initialize max_input_desc. + 2013-08-06 Dmitry Antipov Use region cache to speedup bidi_find_paragraph_start. diff --git a/src/process.c b/src/process.c index d87a1803fe2..85d07028c59 100644 --- a/src/process.c +++ b/src/process.c @@ -323,10 +323,10 @@ static SELECT_TYPE connect_wait_mask; static int num_pending_connects; #endif /* NON_BLOCKING_CONNECT */ -/* The largest descriptor currently in use for a process object. */ +/* The largest descriptor currently in use for a process object; -1 if none. */ static int max_process_desc; -/* The largest descriptor currently in use for input. */ +/* The largest descriptor currently in use for input; -1 if none. */ static int max_input_desc; /* Indexed by descriptor, gives the process (if any) for that descriptor */ @@ -500,13 +500,27 @@ add_write_fd (int fd, fd_callback func, void *data) fd_callback_info[fd].condition |= FOR_WRITE; } +/* FD is no longer an input descriptor; update max_input_desc accordingly. */ + +static void +delete_input_desc (int fd) +{ + if (fd == max_input_desc) + { + do + fd--; + while (0 <= fd && ! (FD_ISSET (fd, &input_wait_mask) + || FD_ISSET (fd, &write_mask))); + + max_input_desc = fd; + } +} + /* Stop monitoring file descriptor FD for when write is possible. */ void delete_write_fd (int fd) { - int lim = max_input_desc; - eassert (fd < MAXDESC); FD_CLR (fd, &write_mask); fd_callback_info[fd].condition &= ~FOR_WRITE; @@ -514,15 +528,7 @@ delete_write_fd (int fd) { fd_callback_info[fd].func = 0; fd_callback_info[fd].data = 0; - - if (fd == max_input_desc) - for (fd = lim; fd >= 0; fd--) - if (FD_ISSET (fd, &input_wait_mask) || FD_ISSET (fd, &write_mask)) - { - max_input_desc = fd; - break; - } - + delete_input_desc (fd); } } @@ -3831,13 +3837,14 @@ deactivate_process (Lisp_Object proc) #endif if (inchannel == max_process_desc) { - int i; /* We just closed the highest-numbered process input descriptor, so recompute the highest-numbered one now. */ - max_process_desc = 0; - for (i = 0; i < MAXDESC; i++) - if (!NILP (chan_process[i])) - max_process_desc = i; + int i = inchannel; + do + i--; + while (0 <= i && NILP (chan_process[i])); + + max_process_desc = i; } } } @@ -6763,16 +6770,9 @@ void delete_keyboard_wait_descriptor (int desc) { #ifdef subprocesses - int fd; - int lim = max_input_desc; - FD_CLR (desc, &input_wait_mask); FD_CLR (desc, &non_process_wait_mask); - - if (desc == max_input_desc) - for (fd = 0; fd < lim; fd++) - if (FD_ISSET (fd, &input_wait_mask) || FD_ISSET (fd, &write_mask)) - max_input_desc = fd; + delete_input_desc (desc); #endif } @@ -7037,7 +7037,7 @@ init_process_emacs (void) FD_ZERO (&non_keyboard_wait_mask); FD_ZERO (&non_process_wait_mask); FD_ZERO (&write_mask); - max_process_desc = 0; + max_process_desc = max_input_desc = -1; memset (fd_callback_info, 0, sizeof (fd_callback_info)); #ifdef NON_BLOCKING_CONNECT From ed4fd9c52765d5f0aa411eecd563143c38d547ba Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Tue, 6 Aug 2013 20:33:14 +0400 Subject: [PATCH 043/449] * lisp/files.el (cache-long-line-scans): Make obsolete alias to `cache-long-scans'. * etc/NEWS: Mention `cache-long-scans'. --- etc/ChangeLog | 4 ++++ etc/NEWS | 4 ++++ lisp/ChangeLog | 5 +++++ lisp/files.el | 4 +++- 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/etc/ChangeLog b/etc/ChangeLog index 2d204f326b2..85a04f87f57 100644 --- a/etc/ChangeLog +++ b/etc/ChangeLog @@ -1,3 +1,7 @@ +2013-08-06 Dmitry Antipov + + * NEWS: Mention `cache-long-scans'. + 2013-08-05 Juanma Barranquero * tutorials/TUTORIAL.es: Fix typo (bug#15027). diff --git a/etc/NEWS b/etc/NEWS index 507cd04aa10..3682b6fc08b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -53,6 +53,10 @@ pkg-config is required to find ImageMagick libraries. ** Key ? also describes prefix bindings like C-h. ++++ +** `cache-long-line-scans' has been renamed to `cache-long-scans' +because it affects caching of paragraph scanning results as well. + +++ ** `apropos-variable' is now `apropos-user-option' `apropos-user-option' shows all user options while `apropos-variable' diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 0843ca2398a..5f243b82e04 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2013-08-06 Dmitry Antipov + + * files.el (cache-long-line-scans): Make + obsolete alias to `cache-long-scans'. + 2013-08-06 Juanma Barranquero * frameset.el (frameset, frameset-filter-alist) diff --git a/lisp/files.el b/lisp/files.el index 526c535450b..efd89605b1b 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -6690,7 +6690,9 @@ based on existing mode bits, as in \"og+rX-w\"." (string-to-number value 8) (file-modes-symbolic-to-number value modes))))) - +(define-obsolete-variable-alias 'cache-long-line-scans + 'cache-long-scans "24.4") + ;; Trashcan handling. (defcustom trash-directory nil "Directory for `move-file-to-trash' to move files and directories to. From 56b5d5b1a191ed6f50d3358e464ffa4c40ae4fe9 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Tue, 6 Aug 2013 20:51:41 +0400 Subject: [PATCH 044/449] * window.c (window_scroll, window_scroll_pixel_based) (window_scroll_line_based): Use bool for booleans. --- src/ChangeLog | 5 +++++ src/window.c | 14 +++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 03420788a64..034926f1fae 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2013-08-06 Dmitry Antipov + + * window.c (window_scroll, window_scroll_pixel_based) + (window_scroll_line_based): Use bool for booleans. + 2013-08-06 Paul Eggert * process.c: Fix minor off-by-one issues in descriptor counts. diff --git a/src/window.c b/src/window.c index 1b288368884..33d7dab7ec0 100644 --- a/src/window.c +++ b/src/window.c @@ -66,9 +66,9 @@ static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of; static int displayed_window_lines (struct window *); static int count_windows (struct window *); static int get_leaf_windows (struct window *, struct window **, int); -static void window_scroll (Lisp_Object, EMACS_INT, int, int); -static void window_scroll_pixel_based (Lisp_Object, int, int, int); -static void window_scroll_line_based (Lisp_Object, int, int, int); +static void window_scroll (Lisp_Object, EMACS_INT, bool, int); +static void window_scroll_pixel_based (Lisp_Object, int, bool, int); +static void window_scroll_line_based (Lisp_Object, int, bool, int); static int freeze_window_start (struct window *, void *); static Lisp_Object window_list (void); static int add_window_to_list (struct window *, void *); @@ -4336,7 +4336,7 @@ window_internal_height (struct window *w) respectively. */ static void -window_scroll (Lisp_Object window, EMACS_INT n, int whole, int noerror) +window_scroll (Lisp_Object window, EMACS_INT n, bool whole, int noerror) { immediate_quit = 1; n = clip_to_bounds (INT_MIN, n, INT_MAX); @@ -4357,7 +4357,7 @@ window_scroll (Lisp_Object window, EMACS_INT n, int whole, int noerror) descriptions. */ static void -window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) +window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror) { struct it it; struct window *w = XWINDOW (window); @@ -4725,7 +4725,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) See the comment of window_scroll for parameter descriptions. */ static void -window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror) +window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror) { register struct window *w = XWINDOW (window); /* Fvertical_motion enters redisplay, which can trigger @@ -4737,7 +4737,7 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror) register ptrdiff_t pos, pos_byte; register int ht = window_internal_height (w); register Lisp_Object tem; - int lose; + bool lose; Lisp_Object bolp; ptrdiff_t startpos = marker_position (w->start); ptrdiff_t startbyte = marker_byte_position (w->start); From 8bcced1f1217adc8058bc5ff6b00c640b668d94d Mon Sep 17 00:00:00 2001 From: Stephen Berman Date: Tue, 6 Aug 2013 22:28:23 +0200 Subject: [PATCH 045/449] * NEWS: Mention Todo mode user manual. --- etc/NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/etc/NEWS b/etc/NEWS index 3682b6fc08b..6c0c81dc0ae 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -432,6 +432,7 @@ New features include: archive files, undoing or unarchiving done items; - reprioritizing items by inputting a numerical priority; - extensive customizability of operation and display, including numerous faces. +The Todo mode user manual describes all commands and most user options. To support some of these features, a new file format is used, which is incompatible with the old format; however, you can convert old todo and done item files to the new format on initializing the first new todo file, or at any From ec6a2d7a5a0d308fc7f7c2cd20435766472ad394 Mon Sep 17 00:00:00 2001 From: Lars Magne Ingebrigtsen Date: Tue, 6 Aug 2013 23:28:38 +0200 Subject: [PATCH 046/449] shr table rendering touch-ups * net/shr.el (shr-render-td): Remove debugging. (shr-render-td): Make width computation consistent by defaulting all zero-width columns to 10 characters. This may not be optimal, but it's at least consistent. --- lisp/ChangeLog | 7 +++++++ lisp/net/shr.el | 9 ++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 5f243b82e04..381ded5e697 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,10 @@ +2013-08-06 Lars Magne Ingebrigtsen + + * net/shr.el (shr-render-td): Remove debugging. + (shr-render-td): Make width computation consistent by defaulting + all zero-width columns to 10 characters. This may not be optimal, + but it's at least consistent. + 2013-08-06 Dmitry Antipov * files.el (cache-long-line-scans): Make diff --git a/lisp/net/shr.el b/lisp/net/shr.el index 89791511e09..281ad3630a4 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el @@ -1496,11 +1496,11 @@ ones, in case fg and bg are nil." shr-table-separator-length (aref widths (+ i 1 j)))))) (setq width-column (+ width-column (1- colspan)))) + ;; Sanity check for degenerate tables. + (when (zerop width) + (setq width 10)) (when (or column (not fill)) - ;; Sanity check for degenerate tables. - (when (zerop width) - (setq width 10)) (push (shr-render-td (cdr column) width fill) tds)) (setq i (1+ i) @@ -1509,7 +1509,6 @@ ones, in case fg and bg are nil." (nreverse trs))) (defun shr-render-td (cont width fill) - (when (= width 0) (debug)) (with-temp-buffer (let ((bgcolor (cdr (assq :bgcolor cont))) (fgcolor (cdr (assq :fgcolor cont))) @@ -1577,7 +1576,7 @@ ones, in case fg and bg are nil." (split-string (buffer-string) "\n") nil (car actual-colors)) - max))))) + (max max 10)))))) (defun shr-buffer-width () (goto-char (point-min)) From 2122cb6dd2e1323963ebb2340078fc9f22e245e7 Mon Sep 17 00:00:00 2001 From: Lars Magne Ingebrigtsen Date: Wed, 7 Aug 2013 00:05:33 +0200 Subject: [PATCH 047/449] Further shr width computation fixes (shr-make-table-1): Redo last change to fix the real problem in colspan handling. --- lisp/ChangeLog | 2 ++ lisp/net/shr.el | 11 ++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 381ded5e697..666fab55bf4 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -4,6 +4,8 @@ (shr-render-td): Make width computation consistent by defaulting all zero-width columns to 10 characters. This may not be optimal, but it's at least consistent. + (shr-make-table-1): Redo last change to fix the real problem in + colspan handling. 2013-08-06 Dmitry Antipov diff --git a/lisp/net/shr.el b/lisp/net/shr.el index 281ad3630a4..7eda2554e06 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el @@ -1488,7 +1488,11 @@ ones, in case fg and bg are nil." 10)) (when (and fill (setq colspan (cdr (assq :colspan (cdr column))))) - (setq colspan (string-to-number colspan)) + (setq colspan (min (string-to-number colspan) + ;; The colspan may be wrong, so + ;; truncate it to the length of the + ;; remaining columns. + (- (length widths) i))) (dotimes (j (1- colspan)) (if (> (+ i 1 j) (1- (length widths))) (setq width (aref widths (1- (length widths)))) @@ -1496,9 +1500,6 @@ ones, in case fg and bg are nil." shr-table-separator-length (aref widths (+ i 1 j)))))) (setq width-column (+ width-column (1- colspan)))) - ;; Sanity check for degenerate tables. - (when (zerop width) - (setq width 10)) (when (or column (not fill)) (push (shr-render-td (cdr column) width fill) @@ -1576,7 +1577,7 @@ ones, in case fg and bg are nil." (split-string (buffer-string) "\n") nil (car actual-colors)) - (max max 10)))))) + max))))) (defun shr-buffer-width () (goto-char (point-min)) From ec9564383ba1599be3e253d0b6643d392938de41 Mon Sep 17 00:00:00 2001 From: Jan Tatarik Date: Tue, 6 Aug 2013 22:09:27 +0000 Subject: [PATCH 048/449] gnus-icalendar.el (gnus-icalendar-event-from-ical): Replace pcase with cond for backwards compatability --- lisp/gnus/ChangeLog | 5 +++++ lisp/gnus/gnus-icalendar.el | 30 ++++++++++++++++-------------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index 238017e25fc..96187c48844 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog @@ -1,3 +1,8 @@ +2013-08-06 Jan Tatarik + + * gnus-icalendar.el (gnus-icalendar-event-from-ical): Replace pcase + with cond for backwards compatability. + 2013-08-06 Katsumi Yamaoka * mm-decode.el (mm-display-external): Bind process-connection-type to diff --git a/lisp/gnus/gnus-icalendar.el b/lisp/gnus/gnus-icalendar.el index 0286fd5dd89..3a9e743e8ed 100644 --- a/lisp/gnus/gnus-icalendar.el +++ b/lisp/gnus/gnus-icalendar.el @@ -183,11 +183,11 @@ :end (gnus-icalendar-event--decode-datefield event 'DTEND zone-map) :rsvp (string= (plist-get (cadr attendee) 'RSVP) "TRUE"))) - (event-class (pcase method - ("REQUEST" 'gnus-icalendar-event-request) - ("CANCEL" 'gnus-icalendar-event-cancel) - ("REPLY" 'gnus-icalendar-event-reply) - (_ 'gnus-icalendar-event)))) + (event-class (cond + ((string= method "REQUEST") 'gnus-icalendar-event-request) + ((string= method "CANCEL") 'gnus-icalendar-event-cancel) + ((string= method "REPLY") 'gnus-icalendar-event-reply) + (t 'gnus-icalendar-event)))) (labels ((map-property (prop) (let ((value (icalendar--get-event-property event prop))) @@ -252,14 +252,15 @@ status will be retrieved from the first matching attendee record." ;; NOTE: not all of the below fields are mandatory, ;; but they are often present in other clients' ;; replies. Can be helpful for debugging, too. - (new-line (pcase key - ("ATTENDEE" (update-attendee-status line)) - ("SUMMARY" (update-summary line)) - ("DTSTAMP" (update-dtstamp)) - ((or "ORGANIZER" "DTSTART" "DTEND" - "LOCATION" "DURATION" "SEQUENCE" - "RECURRENCE-ID" "UID") line) - (_ nil)))) + (new-line + (cond + ((string= key "ATTENDEE") (update-attendee-status line)) + ((string= key "SUMMARY") (update-summary line)) + ((string= key "DTSTAMP") (update-dtstamp)) + ((find key '("ORGANIZER" "DTSTART" "DTEND" + "LOCATION" "DURATION" "SEQUENCE" + "RECURRENCE-ID" "UID")) line) + (t nil)))) (when new-line (push new-line reply-event-lines)))))) @@ -405,7 +406,8 @@ Return nil for non-recurring EVENT." (defun gnus-icalendar--deactivate-org-timestamp (ts) (replace-regexp-in-string "[<>]" - (lambda (m) (pcase m ("<" "[") (">" "]"))) + (lambda (m) (cond ((string= m "<") "[") + ((string= m ">") "]"))) ts)) (defun gnus-icalendar-find-org-event-file (event &optional org-file) From 3b5c03d32b5917f1d14aabeb2bf082a0451ae3da Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Tue, 6 Aug 2013 19:53:49 -0400 Subject: [PATCH 049/449] calendar.el: Add new faces, and day-header-array * lisp/calendar/calendar.el (calendar-weekday-header) (calendar-weekend-header, calendar-month-header): New faces. (calendar-day-header-construct): New function. (calendar-day-header-width): Also :set calendar-day-header-array. (calendar-american-month-header, calendar-european-month-header) (calendar-iso-month-header): Use calendar- faces. (calendar-generate-month): Use calendar-day-header-array for day headers; apply faces to them. (calendar-mode): Check calendar-font-lock-keywords non-nil. (calendar-abbrev-construct): Add optional maxlen argument. (calendar-day-name-array): Doc fix. (calendar-day-name-array, calendar-abbrev-length) (calendar-day-abbrev-array): Also :set calendar-day-header-array, and maybe redraw. (calendar-day-header-array): New option. (calendar-font-lock-keywords): Use calendar-day-header-array, and calendar- faces. Make obsolete. (calendar-day-name): Add option to use header array. * etc/NEWS: Mention this. Fixes: debbugs:15007 --- etc/NEWS | 7 ++ lisp/ChangeLog | 22 +++++ lisp/calendar/calendar.el | 167 +++++++++++++++++++++++++++++--------- 3 files changed, 156 insertions(+), 40 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 6c0c81dc0ae..4758a4da31f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -233,6 +233,13 @@ The default separator is changed to allow surrounding spaces around the comma. ** Calendar and Diary +*** New faces: `calendar-weekday-header', `calendar-weekend-header', +`calendar-month-header'. + +*** New option `calendar-day-header-array'. + +*** The variable `calendar-font-lock-keywords' is obsolete. + +++ *** New variable `diary-from-outlook-function', used by the command `diary-from-outlook'. diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 666fab55bf4..ff9b68e1987 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,25 @@ +2013-08-06 Glenn Morris + + * calendar/calendar.el: Add new faces, and day-header-array. + (calendar-weekday-header, calendar-weekend-header) + (calendar-month-header): New faces. + (calendar-day-header-construct): New function. + (calendar-day-header-width): Also :set calendar-day-header-array. + (calendar-american-month-header, calendar-european-month-header) + (calendar-iso-month-header): Use calendar- faces. + (calendar-generate-month): + Use calendar-day-header-array for day headers; apply faces to them. + (calendar-mode): Check calendar-font-lock-keywords non-nil. + (calendar-abbrev-construct): Add optional maxlen argument. + (calendar-day-name-array): Doc fix. + (calendar-day-name-array, calendar-abbrev-length) + (calendar-day-abbrev-array): + Also :set calendar-day-header-array, and maybe redraw. + (calendar-day-header-array): New option. (Bug#15007) + (calendar-font-lock-keywords): Use calendar-day-header-array, + and calendar- faces. Make obsolete. + (calendar-day-name): Add option to use header array. + 2013-08-06 Lars Magne Ingebrigtsen * net/shr.el (shr-render-td): Remove debugging. diff --git a/lisp/calendar/calendar.el b/lisp/calendar/calendar.el index 40dcb25bc30..b5d06aba135 100644 --- a/lisp/calendar/calendar.el +++ b/lisp/calendar/calendar.el @@ -259,6 +259,23 @@ See `calendar-holiday-marker'." (define-obsolete-face-alias 'holiday-face 'holiday "22.1") +(defface calendar-weekday-header '((t :inherit font-lock-constant-face)) + "Face used for weekday column headers in the calendar. +See also the face `calendar-weekend-header'." + :version "24.4" + :group 'calendar-faces) + +(defface calendar-weekend-header '((t :inherit font-lock-comment-face)) + "Face used for weekend column headers in the calendar. +See also the face `calendar-weekday-header'." + :version "24.4" + :group 'calendar-faces) + +(defface calendar-month-header '((t :inherit font-lock-function-name-face)) + "Face used for month headers in the calendar." + :version "24.4" + :group 'calendar-faces) + ;; These briefly checked font-lock-mode, but that is broken, since it ;; is a buffer-local variable, and which buffer happens to be current ;; when this file is loaded shouldn't make a difference. One could @@ -447,7 +464,6 @@ rightmost column." (push (cons i (calendar-month-edges i)) calendar-month-edges)) (setq calendar-month-edges (reverse calendar-month-edges))) -;; FIXME add font-lock-keywords. (defun calendar-set-layout-variable (symbol value &optional minmax) "Set SYMBOL's value to VALUE, an integer. A positive/negative MINMAX enforces a minimum/maximum value. @@ -491,12 +507,25 @@ Then redraw the calendar, if necessary." :type 'integer :version "23.1") +(defun calendar-day-header-construct (&optional width) + "Return the default value for `calendar-day-header-array'. +WIDTH defaults to `calendar-day-header-width'." + (or width (setq width calendar-day-header-width)) + (calendar-abbrev-construct (if (<= width calendar-abbrev-length) + calendar-day-abbrev-array + calendar-day-name-array) + width)) + +;; FIXME better to use a format spec? (defcustom calendar-day-header-width 2 "Width of the day column headers in the calendar. Must be at least one less than `calendar-column-width'." :group 'calendar :initialize 'custom-initialize-default :set (lambda (sym val) + (or (calendar-customized-p 'calendar-day-header-array) + (setq calendar-day-header-array + (calendar-day-header-construct val))) (calendar-set-layout-variable sym val (- 1 calendar-column-width))) :type 'integer :version "23.1") @@ -924,33 +953,33 @@ styles." (defcustom calendar-american-month-header '(propertize (format "%s %d" (calendar-month-name month) year) - 'font-lock-face 'font-lock-function-name-face) + 'font-lock-face 'calendar-month-header) "Default format for calendar month headings with the American date style. Normally you should not customize this, but `calender-month-header'." :group 'calendar :risky t :type 'sexp - :version "24.3") + :version "24.4") ; font-lock-function-name-face -> calendar-month-header (defcustom calendar-european-month-header '(propertize (format "%s %d" (calendar-month-name month) year) - 'font-lock-face 'font-lock-function-name-face) + 'font-lock-face 'calendar-month-header) "Default format for calendar month headings with the European date style. Normally you should not customize this, but `calender-month-header'." :group 'calendar :risky t :type 'sexp - :version "24.3") + :version "24.4") ; font-lock-function-name-face -> calendar-month-header (defcustom calendar-iso-month-header '(propertize (format "%d %s" year (calendar-month-name month)) - 'font-lock-face 'font-lock-function-name-face) + 'font-lock-face 'calendar-month-header) "Default format for calendar month headings with the ISO date style. Normally you should not customize this, but `calender-month-header'." :group 'calendar :risky t :type 'sexp - :version "24.3") + :version "24.4") ; font-lock-function-name-face -> calendar-month-header (defcustom calendar-month-header (cond ((eq calendar-date-style 'iso) @@ -1517,8 +1546,7 @@ line." (last (calendar-last-day-of-month month year)) (trunc (min calendar-intermonth-spacing (1- calendar-left-margin))) - (day 1) - string) + (day 1)) (goto-char (point-min)) (calendar-move-to-column indent) (insert @@ -1526,13 +1554,16 @@ line." ?\s calendar-month-digit-width)) (calendar-ensure-newline) (calendar-insert-at-column indent calendar-intermonth-header trunc) - ;; Use the first two characters of each day to head the columns. + ;; Use the first N characters of each day to head the columns. (dotimes (i 7) (insert - (progn - (setq string - (calendar-day-name (mod (+ calendar-week-start-day i) 7) nil t)) - (truncate-string-to-width string calendar-day-header-width nil ?\s)) + (truncate-string-to-width + (propertize (calendar-day-name (mod (+ calendar-week-start-day i) 7) + 'header t) + 'font-lock-face (if (memq i '(0 6)) + 'calendar-weekend-header + 'calendar-weekday-header)) + calendar-day-header-width nil ?\s) (make-string (- calendar-column-width calendar-day-header-width) ?\s))) (calendar-ensure-newline) (calendar-insert-at-column indent calendar-intermonth-text trunc) @@ -1808,8 +1839,9 @@ For a complete description, see the info node `Calendar/Diary'. ;; soon in calendar-generate, but better safe than sorry. (unless (boundp 'displayed-month) (setq displayed-month 1)) (unless (boundp 'displayed-year) (setq displayed-year 2001)) - (set (make-local-variable 'font-lock-defaults) - '(calendar-font-lock-keywords t))) + (if (bound-and-true-p calendar-font-lock-keywords) + (set (make-local-variable 'font-lock-defaults) + '(calendar-font-lock-keywords t)))) (defun calendar-string-spread (strings char length) "Concatenate list of STRINGS separated with copies of CHAR to fill LENGTH. @@ -2079,33 +2111,41 @@ is a string to insert in the minibuffer before reading." (and standard (not (equal (eval (car standard)) (default-value symbol))))))) -(defun calendar-abbrev-construct (full) +(defun calendar-abbrev-construct (full &optional maxlen) "From sequence FULL, return a vector of abbreviations. -Each abbreviation is no longer than `calendar-abbrev-length' characters." +Each abbreviation is no longer than MAXLEN (default `calendar-abbrev-length') +characters." + (or maxlen (setq maxlen calendar-abbrev-length)) (apply 'vector (mapcar (lambda (f) - (substring f 0 (min calendar-abbrev-length (length f)))) + ;; TODO? truncate-string-to-width? + (substring f 0 (min maxlen (length f)))) full))) (defcustom calendar-day-name-array ["Sunday" "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday"] "Array of capitalized strings giving, in order from Sunday, the day names. -The first two characters of each string will be used to head the -day columns in the calendar. If you change this without using customize after the calendar has loaded, -then you may also want to change `calendar-day-abbrev-array'." +then you may also want to change `calendar-day-abbrev-array' +and `calendar-day-header-array'." :group 'calendar :initialize 'custom-initialize-default :set (lambda (symbol value) (let ((dcustomized (calendar-customized-p 'calendar-day-abbrev-array)) - (hcustomized (calendar-customized-p 'cal-html-day-abbrev-array))) + (hcustomized (calendar-customized-p 'cal-html-day-abbrev-array)) + (ccustomized (calendar-customized-p 'calendar-day-header-array))) (set symbol value) (or dcustomized (setq calendar-day-abbrev-array (calendar-abbrev-construct calendar-day-name-array))) (and (not hcustomized) (boundp 'cal-html-day-abbrev-array) - (setq cal-html-day-abbrev-array calendar-day-abbrev-array)))) + (setq cal-html-day-abbrev-array calendar-day-abbrev-array)) + (or ccustomized + (equal calendar-day-header-array + (setq calendar-day-header-array + (calendar-day-header-construct))) + (calendar-redraw)))) :type '(vector (string :tag "Sunday") (string :tag "Monday") (string :tag "Tuesday") @@ -2125,7 +2165,8 @@ then you may also want to change `calendar-day-abbrev-array' and (let ((dcustomized (calendar-customized-p 'calendar-day-abbrev-array)) (mcustomized (calendar-customized-p 'calendar-month-abbrev-array)) - (hcustomized (calendar-customized-p 'cal-html-day-abbrev-array))) + (hcustomized (calendar-customized-p 'cal-html-day-abbrev-array)) + (ccustomized (calendar-customized-p 'calendar-day-header-array))) (set symbol value) (or dcustomized (setq calendar-day-abbrev-array @@ -2135,7 +2176,12 @@ then you may also want to change `calendar-day-abbrev-array' and (calendar-abbrev-construct calendar-month-name-array))) (and (not hcustomized) (boundp 'cal-html-day-abbrev-array) - (setq cal-html-day-abbrev-array calendar-day-abbrev-array)))) + (setq cal-html-day-abbrev-array calendar-day-abbrev-array)) + (or ccustomized + (equal calendar-day-header-array + (setq calendar-day-header-array + (calendar-day-header-construct))) + (calendar-redraw)))) :type 'integer) (defcustom calendar-day-abbrev-array @@ -2152,11 +2198,17 @@ full name." :initialize 'custom-initialize-default :set-after '(calendar-abbrev-length calendar-day-name-array) :set (lambda (symbol value) - (let ((hcustomized (calendar-customized-p 'cal-html-day-abbrev-array))) + (let ((hcustomized (calendar-customized-p 'cal-html-day-abbrev-array)) + (ccustomized (calendar-customized-p 'calendar-day-header-array))) (set symbol value) (and (not hcustomized) (boundp 'cal-html-day-abbrev-array) - (setq cal-html-day-abbrev-array calendar-day-abbrev-array)))) + (setq cal-html-day-abbrev-array calendar-day-abbrev-array)) + (or ccustomized + (equal calendar-day-header-array + (setq calendar-day-header-array + (calendar-day-header-construct))) + (calendar-redraw)))) :type '(vector (string :tag "Sun") (string :tag "Mon") (string :tag "Tue") @@ -2167,6 +2219,33 @@ full name." ;; Made defcustom, changed defaults from nil nil... :version "24.1") +(defcustom calendar-day-header-array (calendar-day-header-construct) + "Array of strings to use for the headers of the calendar's day columns. +The order should be the same as in `calendar-day-name-array'. +In use, the calendar truncates elements to no more than +`calendar-day-header-width' columns wide. +Emacs constructs the default from either `calendar-day-name-array' +\(if `calendar-day-header-width' is more than `calendar-abbrev-length'), +or from `calendar-day-abbrev-array' (assuming that the abbreviated +name are more likely to be unique when truncated)." + :group 'calendar + :initialize 'custom-initialize-default + :set-after '(calendar-day-header-width + calendar-abbrev-length calendar-day-name-array + calendar-day-abbrev-array) + :set (lambda (symbol value) + (or (equal calendar-day-header-array + (set symbol value)) + (calendar-redraw))) + :type '(vector (string :tag "Su") + (string :tag "Mo") + (string :tag "Tu") + (string :tag "We") + (string :tag "Th") + (string :tag "Fr") + (string :tag "Sa")) + :version "24.4") + (defcustom calendar-month-name-array ["January" "February" "March" "April" "May" "June" "July" "August" "September" "October" "November" "December"] @@ -2287,30 +2366,38 @@ Negative years are interpreted as years BC; -1 being 1 BC, and so on." ;; of that variable. `((,(concat (regexp-opt (mapcar 'identity calendar-month-name-array) t) " -?[0-9]+") - . font-lock-function-name-face) + . 'calendar-month-header) + ;; Day headers. + ;; Also not needed now that calendar-generate-month uses propertize. (,(regexp-opt - (list (truncate-string-to-width (aref calendar-day-name-array 6) + (list (truncate-string-to-width (aref calendar-day-header-array 6) calendar-day-header-width) - (truncate-string-to-width (aref calendar-day-name-array 0) + (truncate-string-to-width (aref calendar-day-header-array 0) calendar-day-header-width))) ;; Saturdays and Sundays are highlighted differently. - . font-lock-comment-face) - ;; First two chars of each day are used in the calendar. - (,(regexp-opt (mapcar (lambda (x) (truncate-string-to-width - x calendar-day-header-width)) - calendar-day-name-array)) - . font-lock-constant-face)) + . 'calendar-weekend-header) + (,(regexp-opt (mapcar (lambda (x) (truncate-string-to-width + x calendar-day-header-width)) + calendar-day-header-array)) + . 'calendar-day-header)) "Default keywords to highlight in Calendar mode.") +(make-obsolete-variable 'calendar-font-lock-keywords + "set font-lock keywords in `calendar-mode-hook', \ +or customize calendar faces." "24.4") + (defun calendar-day-name (date &optional abbrev absolute) "Return a string with the name of the day of the week of DATE. DATE should be a list in the format (MONTH DAY YEAR), unless the optional argument ABSOLUTE is non-nil, in which case DATE should be an integer in the range 0 to 6 corresponding to the day of the week. Day names are taken from the variable `calendar-day-name-array', -unless the optional argument ABBREV is non-nil, in which case -the variable `calendar-day-abbrev-array' is used." - (aref (if abbrev calendar-day-abbrev-array calendar-day-name-array) +unless the optional argument ABBREV is non-nil: +`header' means to use `calendar-day-header-array'; +t to use `calendar-day-abbrev-array'." + (aref (cond ((eq abbrev 'header) calendar-day-header-array) + (abbrev calendar-day-abbrev-array) + (t calendar-day-name-array)) (if absolute date (calendar-day-of-week date)))) (defun calendar-month-name (month &optional abbrev) From 8a806f0430cf2c42e08768920a714cc497ce6f77 Mon Sep 17 00:00:00 2001 From: Glenn Morris Date: Tue, 6 Aug 2013 20:06:43 -0400 Subject: [PATCH 050/449] * lisp/calendar/calendar.el (calendar-font-lock-keywords): Set to nil --- lisp/ChangeLog | 3 +-- lisp/calendar/calendar.el | 21 +-------------------- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index ff9b68e1987..09e0349e7f1 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -16,8 +16,7 @@ (calendar-day-abbrev-array): Also :set calendar-day-header-array, and maybe redraw. (calendar-day-header-array): New option. (Bug#15007) - (calendar-font-lock-keywords): Use calendar-day-header-array, - and calendar- faces. Make obsolete. + (calendar-font-lock-keywords): Set to nil and make obsolete. (calendar-day-name): Add option to use header array. 2013-08-06 Lars Magne Ingebrigtsen diff --git a/lisp/calendar/calendar.el b/lisp/calendar/calendar.el index b5d06aba135..e1f85832dc4 100644 --- a/lisp/calendar/calendar.el +++ b/lisp/calendar/calendar.el @@ -2360,26 +2360,7 @@ Negative years are interpreted as years BC; -1 being 1 BC, and so on." (+ (* 12 (- yr2 yr1)) (- mon2 mon1))) -(defvar calendar-font-lock-keywords - ;; Month and year. Not really needed now that calendar-month-header - ;; contains propertize, and not correct for non-american forms - ;; of that variable. - `((,(concat (regexp-opt (mapcar 'identity calendar-month-name-array) t) - " -?[0-9]+") - . 'calendar-month-header) - ;; Day headers. - ;; Also not needed now that calendar-generate-month uses propertize. - (,(regexp-opt - (list (truncate-string-to-width (aref calendar-day-header-array 6) - calendar-day-header-width) - (truncate-string-to-width (aref calendar-day-header-array 0) - calendar-day-header-width))) - ;; Saturdays and Sundays are highlighted differently. - . 'calendar-weekend-header) - (,(regexp-opt (mapcar (lambda (x) (truncate-string-to-width - x calendar-day-header-width)) - calendar-day-header-array)) - . 'calendar-day-header)) +(defvar calendar-font-lock-keywords nil "Default keywords to highlight in Calendar mode.") (make-obsolete-variable 'calendar-font-lock-keywords From c85989f5c5d6d53a017f56ea13b1b2d47ea8f83a Mon Sep 17 00:00:00 2001 From: Xue Fuqiao Date: Wed, 7 Aug 2013 10:25:52 +0800 Subject: [PATCH 051/449] doc/misc/cl.texi: Add indexes. * doc/misc/cl.texi (Argument Lists): (For Clauses): Add indexes. --- doc/lispref/display.texi | 1 + doc/misc/ChangeLog | 5 +++++ doc/misc/cl.texi | 2 ++ 3 files changed, 8 insertions(+) diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 59a6f5ce340..6b8d24179e7 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -1243,6 +1243,7 @@ Type RET when done reading @node Overlays @section Overlays @cindex overlays +@c FIXME: mention intervals in this section? You can use @dfn{overlays} to alter the appearance of a buffer's text on the screen, for the sake of presentation features. An overlay is an diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog index e8a5a7e22b2..f3f26ad1fc4 100644 --- a/doc/misc/ChangeLog +++ b/doc/misc/ChangeLog @@ -1,3 +1,8 @@ +2013-08-07 Xue Fuqiao + + * cl.texi (Argument Lists): + (For Clauses): Add indexes. + 2013-08-05 Xue Fuqiao * cl.texi (Blocks and Exits): Add an index. diff --git a/doc/misc/cl.texi b/doc/misc/cl.texi index 1b5ea6e78dd..429d8a8b33f 100644 --- a/doc/misc/cl.texi +++ b/doc/misc/cl.texi @@ -461,6 +461,7 @@ matter of stylistic taste: @var{body})) @end example +@cindex destructuring, in argument list Argument lists support @dfn{destructuring}. In Common Lisp, destructuring is only allowed with @code{defmacro}; this package allows it with @code{cl-defun} and other argument lists as well. @@ -2140,6 +2141,7 @@ that was just set by the previous clause; in the second loop, based on the value of @code{x} left over from the previous time through the loop. +@cindex destructuring, in cl-loop Another feature of the @code{cl-loop} macro is @emph{destructuring}, similar in concept to the destructuring provided by @code{defmacro} (@pxref{Argument Lists}). From 20940c206593a8e7bd4809348ff95a6f971c5528 Mon Sep 17 00:00:00 2001 From: Xue Fuqiao Date: Wed, 7 Aug 2013 15:01:54 +0800 Subject: [PATCH 052/449] doc/misc/cl.texi: Add index for compiler macro. --- doc/misc/ChangeLog | 3 ++- doc/misc/cl.texi | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog index f3f26ad1fc4..922930efc93 100644 --- a/doc/misc/ChangeLog +++ b/doc/misc/ChangeLog @@ -1,7 +1,8 @@ 2013-08-07 Xue Fuqiao * cl.texi (Argument Lists): - (For Clauses): Add indexes. + (For Clauses): + (Macros): Add indexes. 2013-08-05 Xue Fuqiao diff --git a/doc/misc/cl.texi b/doc/misc/cl.texi index 429d8a8b33f..6dfc41d83f3 100644 --- a/doc/misc/cl.texi +++ b/doc/misc/cl.texi @@ -2506,6 +2506,8 @@ if @var{expr} returns a list of the wrong number of arguments or with incorrect keyword arguments. @end defmac +@cindex compiler macros +@cindex define compiler macros This package also includes the Common Lisp @code{define-compiler-macro} facility, which allows you to define compile-time expansions and optimizations for your functions. From 170da1ec691127471ecd118dccd79eec7c9f3699 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Wed, 7 Aug 2013 14:32:08 +0400 Subject: [PATCH 053/449] Be more careful if selected window shows the buffer other than current, use window_outdated only if this is not so. This change should also address some weird issues discussed in Bug#13012. * window.h (window_outdated): New prototype. * window.c (window_outdated): Now here. Convert from static and always assume window's buffer. (Fwindow_end, Fwindow_line_height): Use it. * xdisp.c (reconsider_clip_changes): Remove prototype, drop 2nd arg and always assume window's buffer. (redisplay_window): Adjust user. (redisplay_internal): Call to reconsider_clip_change once and check whether mode line should be updated only if selected window shows current buffer. (run_window_scroll_functions): Use eassert for debugging check. (Fmove_point_visually, note_mouse_highlight): Use window_outdated. --- src/ChangeLog | 18 +++++++++ src/window.c | 17 +++++++-- src/window.h | 1 + src/xdisp.c | 104 ++++++++++++++++++++------------------------------ 4 files changed, 73 insertions(+), 67 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 034926f1fae..a090e02e74a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,21 @@ +2013-08-07 Dmitry Antipov + + Be more careful if selected window shows the buffer other than current, + use window_outdated only if this is not so. This change should also + address some weird issues discussed in Bug#13012. + * window.h (window_outdated): New prototype. + * window.c (window_outdated): Now here. Convert from static and + always assume window's buffer. + (Fwindow_end, Fwindow_line_height): Use it. + * xdisp.c (reconsider_clip_changes): Remove prototype, drop 2nd arg + and always assume window's buffer. + (redisplay_window): Adjust user. + (redisplay_internal): Call to reconsider_clip_change once and + check whether mode line should be updated only if selected window + shows current buffer. + (run_window_scroll_functions): Use eassert for debugging check. + (Fmove_point_visually, note_mouse_highlight): Use window_outdated. + 2013-08-06 Dmitry Antipov * window.c (window_scroll, window_scroll_pixel_based) diff --git a/src/window.c b/src/window.c index 33d7dab7ec0..dff449072f5 100644 --- a/src/window.c +++ b/src/window.c @@ -239,6 +239,17 @@ wset_combination (struct window *w, bool horflag, Lisp_Object val) w->horizontal = horflag; } +/* Nonzero if leaf window W doesn't reflect the actual state + of displayed buffer due to its text or overlays change. */ + +bool +window_outdated (struct window *w) +{ + struct buffer *b = XBUFFER (w->contents); + return (w->last_modified < BUF_MODIFF (b) + || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b)); +} + struct window * decode_live_window (register Lisp_Object window) { @@ -1506,8 +1517,7 @@ if it isn't already recorded. */) || !w->window_end_valid || b->clip_changed || b->prevent_redisplay_optimizations_p - || w->last_modified < BUF_MODIFF (b) - || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b)) + || window_outdated (w)) && !noninteractive) { struct text_pos startp; @@ -1720,8 +1730,7 @@ Return nil if window display is not up-to-date. In that case, use || windows_or_buffers_changed || b->clip_changed || b->prevent_redisplay_optimizations_p - || w->last_modified < BUF_MODIFF (b) - || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b)) + || window_outdated (w)) return Qnil; if (NILP (line)) diff --git a/src/window.h b/src/window.h index 5da6165c48d..24949e1e287 100644 --- a/src/window.h +++ b/src/window.h @@ -973,6 +973,7 @@ extern void replace_buffer_in_windows (Lisp_Object); extern void replace_buffer_in_windows_safely (Lisp_Object); /* This looks like a setter, but it is a bit special. */ extern void wset_buffer (struct window *, Lisp_Object); +extern bool window_outdated (struct window *); extern void init_window_once (void); extern void init_window (void); extern void syms_of_window (void); diff --git a/src/xdisp.c b/src/xdisp.c index 7a1f03ce244..5e6311ed98d 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -804,7 +804,6 @@ static void pint2str (char *, int, ptrdiff_t); static void pint2hrstr (char *, int, ptrdiff_t); static struct text_pos run_window_scroll_functions (Lisp_Object, struct text_pos); -static void reconsider_clip_changes (struct window *, struct buffer *); static int text_outside_line_unchanged_p (struct window *, ptrdiff_t, ptrdiff_t); static void store_mode_line_noprop_char (char); @@ -10850,17 +10849,6 @@ buffer_shared_and_changed (void) && UNCHANGED_MODIFIED < MODIFF); } -/* Nonzero if W doesn't reflect the actual state of current buffer due - to its text or overlays change. FIXME: this may be called when - XBUFFER (w->contents) != current_buffer, which looks suspicious. */ - -static int -window_outdated (struct window *w) -{ - return (w->last_modified < MODIFF - || w->last_overlay_modified < OVERLAY_MODIFF); -} - /* Nonzero if W's buffer was changed but not saved or Transient Mark mode is enabled and mark of W's buffer was changed since last W's update. */ @@ -12866,13 +12854,13 @@ check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt, && start < pt && end > pt); } - -/* Reconsider the setting of B->clip_changed which is displayed - in window W. */ +/* Reconsider the clip changes of buffer which is displayed in W. */ static void -reconsider_clip_changes (struct window *w, struct buffer *b) +reconsider_clip_changes (struct window *w) { + struct buffer *b = XBUFFER (w->contents); + if (b->clip_changed && w->window_end_valid && w->current_matrix->buffer == b @@ -12885,24 +12873,17 @@ reconsider_clip_changes (struct window *w, struct buffer *b) we set b->clip_changed to 1 to force updating the screen. If b->clip_changed has already been set to 1, we can skip this check. */ - if (!b->clip_changed && BUFFERP (w->contents) && w->window_end_valid) + if (!b->clip_changed && w->window_end_valid) { - ptrdiff_t pt; + ptrdiff_t pt = (w == XWINDOW (selected_window) + ? PT : marker_position (w->pointm)); - if (w == XWINDOW (selected_window)) - pt = PT; - else - pt = marker_position (w->pointm); - - if ((w->current_matrix->buffer != XBUFFER (w->contents) - || pt != w->last_point) + if ((w->current_matrix->buffer != b || pt != w->last_point) && check_point_in_composition (w->current_matrix->buffer, - w->last_point, - XBUFFER (w->contents), pt)) + w->last_point, b, pt)) b->clip_changed = 1; } } - #define STOP_POLLING \ do { if (! polling_stopped_here) stop_polling (); \ @@ -12923,10 +12904,10 @@ redisplay_internal (void) struct window *sw; struct frame *fr; int pending; - int must_finish = 0; + bool must_finish = 0, match_p; struct text_pos tlbufpos, tlendpos; int number_of_visible_frames; - ptrdiff_t count, count1; + ptrdiff_t count; struct frame *sf; int polling_stopped_here = 0; Lisp_Object tail, frame; @@ -12983,7 +12964,6 @@ redisplay_internal (void) sw = w; pending = 0; - reconsider_clip_changes (w, current_buffer); last_escape_glyph_frame = NULL; last_escape_glyph_face_id = (1 << FACE_ID_BITS); last_glyphless_glyph_frame = NULL; @@ -13038,10 +13018,7 @@ redisplay_internal (void) /* do_pending_window_change could change the selected_window due to frame resizing which makes the selected window too small. */ if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw) - { - sw = w; - reconsider_clip_changes (w, current_buffer); - } + sw = w; /* Clear frames marked as garbaged. */ clear_garbaged_frames (); @@ -13053,23 +13030,32 @@ redisplay_internal (void) if (windows_or_buffers_changed) update_mode_lines++; - /* Detect case that we need to write or remove a star in the mode line. */ - if ((SAVE_MODIFF < MODIFF) != w->last_had_star) + reconsider_clip_changes (w); + + /* In most cases selected window displays current buffer. */ + match_p = XBUFFER (w->contents) == current_buffer; + if (match_p) { - w->update_mode_line = 1; - if (buffer_shared_and_changed ()) - update_mode_lines++; + ptrdiff_t count1; + + /* Detect case that we need to write or remove a star in the mode line. */ + if ((SAVE_MODIFF < MODIFF) != w->last_had_star) + { + w->update_mode_line = 1; + if (buffer_shared_and_changed ()) + update_mode_lines++; + } + + /* Avoid invocation of point motion hooks by `current_column' below. */ + count1 = SPECPDL_INDEX (); + specbind (Qinhibit_point_motion_hooks, Qt); + + if (mode_line_update_needed (w)) + w->update_mode_line = 1; + + unbind_to (count1, Qnil); } - /* Avoid invocation of point motion hooks by `current_column' below. */ - count1 = SPECPDL_INDEX (); - specbind (Qinhibit_point_motion_hooks, Qt); - - if (mode_line_update_needed (w)) - w->update_mode_line = 1; - - unbind_to (count1, Qnil); - consider_all_windows_p = (update_mode_lines || buffer_shared_and_changed () || cursor_type_changed); @@ -13167,7 +13153,7 @@ redisplay_internal (void) && !FRAME_OBSCURED_P (XFRAME (w->frame)) /* Make sure recorded data applies to current buffer, etc. */ && this_line_buffer == current_buffer - && current_buffer == XBUFFER (w->contents) + && match_p && !w->force_start && !w->optional_new_start /* Point must be on the line that we have info recorded about. */ @@ -14458,8 +14444,7 @@ run_window_scroll_functions (Lisp_Object window, struct text_pos startp) struct window *w = XWINDOW (window); SET_MARKER_FROM_TEXT_POS (w->start, startp); - if (current_buffer != XBUFFER (w->contents)) - emacs_abort (); + eassert (current_buffer == XBUFFER (w->contents)); if (!NILP (Vwindow_scroll_functions)) { @@ -15360,7 +15345,7 @@ redisplay_window (Lisp_Object window, int just_this_one_p) eassert (XMARKER (w->pointm)->buffer == buffer); restart: - reconsider_clip_changes (w, buffer); + reconsider_clip_changes (w); frame_line_height = default_line_pixel_height (w); /* Has the mode line to be updated? */ @@ -20115,7 +20100,7 @@ Value is the new character position of point. */) (Lisp_Object direction) { struct window *w = XWINDOW (selected_window); - struct buffer *b = NULL; + struct buffer *b = XBUFFER (w->contents); struct glyph_row *row; int dir; Lisp_Object paragraph_dir; @@ -20135,9 +20120,6 @@ Value is the new character position of point. */) else dir = -1; - if (BUFFERP (w->contents)) - b = XBUFFER (w->contents); - /* If current matrix is up-to-date, we can use the information recorded in the glyphs, at least as long as the goal is on the screen. */ @@ -20146,8 +20128,7 @@ Value is the new character position of point. */) && b && !b->clip_changed && !b->prevent_redisplay_optimizations_p - && w->last_modified >= BUF_MODIFF (b) - && w->last_overlay_modified >= BUF_OVERLAY_MODIFF (b) + && !window_outdated (w) && w->cursor.vpos >= 0 && w->cursor.vpos < w->current_matrix->nrows && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p) @@ -28142,10 +28123,7 @@ note_mouse_highlight (struct frame *f, int x, int y) /* Are we in a window whose display is up to date? And verify the buffer's text has not changed. */ b = XBUFFER (w->contents); - if (part == ON_TEXT - && w->window_end_valid - && w->last_modified == BUF_MODIFF (b) - && w->last_overlay_modified == BUF_OVERLAY_MODIFF (b)) + if (part == ON_TEXT && w->window_end_valid && !window_outdated (w)) { int hpos, vpos, dx, dy, area = LAST_AREA; ptrdiff_t pos; From 98374c9aebd118332e3cb0d7f0a27cc585390c7d Mon Sep 17 00:00:00 2001 From: Xue Fuqiao Date: Wed, 7 Aug 2013 20:44:16 +0800 Subject: [PATCH 054/449] * doc/misc/newsticker.texi (Usage): Use @key for RET. --- doc/misc/ChangeLog | 2 ++ doc/misc/newsticker.texi | 6 +++--- etc/TODO | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog index 922930efc93..84147698029 100644 --- a/doc/misc/ChangeLog +++ b/doc/misc/ChangeLog @@ -1,5 +1,7 @@ 2013-08-07 Xue Fuqiao + * newsticker.texi (Usage): Use @key for RET. + * cl.texi (Argument Lists): (For Clauses): (Macros): Add indexes. diff --git a/doc/misc/newsticker.texi b/doc/misc/newsticker.texi index ab3bffc2ce9..afb44a6a396 100644 --- a/doc/misc/newsticker.texi +++ b/doc/misc/newsticker.texi @@ -169,9 +169,9 @@ single buffer, called @samp{*newsticker*}. The modeline in the @samp{*newsticker*} buffer informs you whenever new headlines have arrived. @end itemize -In both views clicking mouse-button 2 or pressing RET on a headline -will call @code{browse-url} to load the corresponding news story in -your favorite web browser. +In both views clicking mouse-button 2 or pressing @key{RET} on a +headline will call @code{browse-url} to load the corresponding news +story in your favorite web browser. @findex newsticker-start-ticker @findex newsticker-stop-ticker diff --git a/etc/TODO b/etc/TODO index 305722dfe7b..3bdb82aa4d4 100644 --- a/etc/TODO +++ b/etc/TODO @@ -76,7 +76,8 @@ to use it. ** Convert all defvars with leading `*' in the doc-strings into defcustoms of appropriate :type and :group. -** Remove any leading `*'s from defcustom doc-strings. [done?] +** Remove any leading `*'s from defcustom doc-strings. +[done?] [A lot of them are in CC Mode.] ** Remove unnecessary autoload cookies from defcustoms. This needs a bit of care, since often people have become used to From 998ad848a4f1fd347fdbb1cf181035a0e174eddc Mon Sep 17 00:00:00 2001 From: Xue Fuqiao Date: Wed, 7 Aug 2013 21:19:48 +0800 Subject: [PATCH 055/449] Index and whitespace fixes for doc/misc/sc.texi. * sc.texi (Introduction): Fix indexes. (Usage Overview): (Citations, Citation Elements, Recognizing Citations) (Information Keys and the Info Alist, Reference Headers) (The Built-in Header Rewrite Functions) (Electric References, Reply Buffer Initialization) (Filling Cited Text, Selecting an Attribution) (Attribution Preferences) (Anonymous Attributions, Author Names) (Using Regi, Post-yank Formatting Commands) (Citing Commands, Insertion Commands) (Mail Field Commands) (Hints to MUA Authors, Thanks and History): Change from one space between sentences to two. --- doc/misc/ChangeLog | 17 +++- doc/misc/sc.texi | 192 +++++++++++++++++++++++---------------------- 2 files changed, 114 insertions(+), 95 deletions(-) diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog index 84147698029..5721626f4e3 100644 --- a/doc/misc/ChangeLog +++ b/doc/misc/ChangeLog @@ -1,5 +1,20 @@ 2013-08-07 Xue Fuqiao + * sc.texi (Introduction): Fix index. + (Usage Overview): + (Citations, Citation Elements, Recognizing Citations) + (Information Keys and the Info Alist, Reference Headers) + (The Built-in Header Rewrite Functions) + (Electric References, Reply Buffer Initialization) + (Filling Cited Text, Selecting an Attribution) + (Attribution Preferences) + (Anonymous Attributions, Author Names) + (Using Regi, Post-yank Formatting Commands) + (Citing Commands, Insertion Commands) + (Mail Field Commands) + (Hints to MUA Authors, Thanks and History): Change from one space + between sentences to two. + * newsticker.texi (Usage): Use @key for RET. * cl.texi (Argument Lists): @@ -205,7 +220,7 @@ 2013-05-25 Xue Fuqiao - * flymake.texi: Changing from one space between sentences to two. + * flymake.texi: Change from one space between sentences to two. 2013-05-04 Stefan Monnier diff --git a/doc/misc/sc.texi b/doc/misc/sc.texi index cfd040f0e82..7d7ef07ed61 100644 --- a/doc/misc/sc.texi +++ b/doc/misc/sc.texi @@ -84,12 +84,15 @@ into the following chapters. @node Introduction @chapter Introduction -Supercite is a GNU Emacs package written entirely in Emacs Lisp. It +@cindex MUA +@cindex NUA +Supercite is a GNU Emacs package written entirely in Emacs Lisp. It interfaces to most of the commonly used Emacs mail user agents (@dfn{MUAs}) and news user agents (@dfn{NUAs}), and provides sophisticated facilities for the citing and attributing of message -replies. Supercite has a very specific and limited role in the process -of composing replies to both USENET network news and electronic mail. +replies. Supercite has a very specific and limited role in the +process of composing replies to both USENET network news and +electronic mail. The preferred way to spell Supercite is with a capital @samp{S}, lowercase @samp{upercite}. @@ -100,8 +103,7 @@ lowercase @samp{upercite}. * What Supercite Does:: @end menu -@cindex MUA -@cindex NUA +@c FIXME: move it above the menu? --xfq Supercite is only useful in conjunction with MUAs and NUAs such as VM, Gnus, RMAIL, MH-E, etc. Supercite is typically called by the MUA after a reply buffer has been setup. Thereafter, Supercite's many commands and @@ -118,21 +120,22 @@ sent. Supercite is re-initialized in each new reply buffer. @cindex cite, citing @cindex attribute, attributing -Typical usage is as follows. You want to reply or followup to a message -in your MUA@. You will probably hit @kbd{r} (i.e., ``reply'') or @kbd{f} -(i.e., ``forward'') to begin composing the reply. In response, the MUA -will create a reply buffer and initialize the outgoing mail headers -appropriately. The body of the reply will usually be empty at this -point. You now decide that you would like to include part of the -original message in your reply. To do this, you @dfn{yank} the original -message into the reply buffer, typically with a key stroke such as -@kbd{C-c C-y}. This sequence will invoke an MUA-specific function which -fills the body of the reply with the original message and then -@dfn{attributes} this text to its author. This is called @dfn{citing} -and its effect is to prefix every line from the original message with a -special text tag. Most MUAs provide some default style of citing; by -using Supercite you gain a wider flexibility in the look and style of -citations. Supercite's only job is to cite the original message. +Typical usage is as follows. You want to reply or followup to a +message in your MUA@. You will probably hit @kbd{r} (i.e., ``reply'') +or @kbd{f} (i.e., ``forward'') to begin composing the reply. In +response, the MUA will create a reply buffer and initialize the +outgoing mail headers appropriately. The body of the reply will +usually be empty at this point. You now decide that you would like to +include part of the original message in your reply. To do this, you +@dfn{yank} the original message into the reply buffer, typically with +a key stroke such as @kbd{C-c C-y}. This sequence will invoke an +MUA-specific function which fills the body of the reply with the +original message and then @dfn{attributes} this text to its author. +This is called @dfn{citing} and its effect is to prefix every line +from the original message with a special text tag. Most MUAs provide +some default style of citing; by using Supercite you gain a wider +flexibility in the look and style of citations. Supercite's only job +is to cite the original message. @node What Supercite Does Not Do @section What Supercite Doesn't Do @@ -253,10 +256,10 @@ make the message very difficult for the eye to scan. @cindex non-nested citations In @dfn{non-nested citations}, each cited line begins with an -informative string attributing that line to the original author. Only -the first level of attribution will be shown; subsequent citations don't -nest the citation strings. The above dialog might look like this when -non-nested citations are used: +informative string attributing that line to the original author. Only +the first level of attribution will be shown; subsequent citations +don't nest the citation strings. The above dialog might look like +this when non-nested citations are used: @example John> John originally wrote this @@ -272,19 +275,20 @@ message did not result in a line cited with @samp{Jane>John>}. @vindex sc-nested-citation-p @vindex nested-citation-p (sc-) Supercite supports both styles of citation, and the variable -@code{sc-nested-citation-p} controls which style it will use when citing -previously uncited text. When this variable is @code{nil} (the default), -non-nested citations are used. When non-@code{nil}, nested citations -are used. +@code{sc-nested-citation-p} controls which style it will use when +citing previously uncited text. When this variable is @code{nil} (the +default), non-nested citations are used. When non-@code{nil}, nested +citations are used. @node Citation Elements @section Citation Elements @cindex citation string -@dfn{Citation strings} are composed of one or more elements. Non-nested -citations are composed of four elements, three of which are directly -user definable. The elements are concatenated together, in this order: +@dfn{Citation strings} are composed of one or more elements. +Non-nested citations are composed of four elements, three of which are +directly user definable. The elements are concatenated together, in +this order: @cindex citation leader @vindex citation-leader (sc-) @@ -337,10 +341,10 @@ multi-level nested citations. @section Recognizing Citations Supercite also recognizes citations in the original article, and can -transform these already cited lines in a number of ways. This is how +transform these already cited lines in a number of ways. This is how Supercite suppresses the multiple citing of non-nested citations. -Recognition of cited lines is controlled by variables analogous to those -that make up the citation string as mentioned previously. +Recognition of cited lines is controlled by variables analogous to +those that make up the citation string as mentioned previously. @vindex sc-citation-leader-regexp @vindex citation-leader-regexp (sc-) @@ -387,16 +391,16 @@ change @code{sc-citation-root-regexp} you should always also change @dfn{Mail header information keys} are nuggets of information that Supercite extracts from the various mail headers of the original -message, placed in the reply buffer by the MUA@. Information is kept in -the @dfn{Info Alist} as key-value pairs, and can be retrieved for use in -various places within Supercite, such as in header rewrite functions and -attribution selection. Other bits of data, composed and created by -Supercite, are also kept as key-value pairs in this alist. In the case -of mail fields, the key is the name of the field, omitting the trailing -colon. Info keys are always case insensitive (as are mail headers), and -the value for a corresponding key can be retrieved from the alist with -the @code{sc-mail-field} function. Thus, if the following fields were -present in the original article:@refill +message, placed in the reply buffer by the MUA@. Information is kept +in the @dfn{Info Alist} as key-value pairs, and can be retrieved for +use in various places within Supercite, such as in header rewrite +functions and attribution selection. Other bits of data, composed and +created by Supercite, are also kept as key-value pairs in this alist. +In the case of mail fields, the key is the name of the field, omitting +the trailing colon. Info keys are always case insensitive (as are +mail headers), and the value for a corresponding key can be retrieved +from the alist with the @code{sc-mail-field} function. Thus, if the +following fields were present in the original article:@refill @example Date:@: 08 April 1991, 17:32:09 EST @@ -419,7 +423,7 @@ then, the following lisp constructs return: Since the argument to @code{sc-mail-field} can be any string, it is possible that the mail field will not be present on the info alist (possibly because the mail header was not present in the original -message). In this case, @code{sc-mail-field} will return the value of +message). In this case, @code{sc-mail-field} will return the value of the variable @code{sc-mumble}. Supercite always places all mail fields found in the yanked original @@ -510,8 +514,8 @@ header. @vindex sc-rewrite-header-list @vindex rewrite-header-list (sc-) There are a number of built-in @dfn{header rewrite functions} supplied -by Supercite, but you can write your own custom header rewrite functions -(perhaps using the built-in ones as examples). The variable +by Supercite, but you can write your own custom header rewrite +functions (perhaps using the built-in ones as examples). The variable @code{sc-rewrite-header-list} contains the list of such header rewrite functions. This list is consulted both when inserting the initial reference header, and when displaying @dfn{electric references}. @@ -521,7 +525,7 @@ reference header, and when displaying @dfn{electric references}. @vindex preferred-header-style (sc-) When Supercite is initially run on a reply buffer (via @code{sc-cite-original}), it will automatically call one of these -functions. The one it uses is defined in the variable +functions. The one it uses is defined in the variable @code{sc-preferred-header-style}. The value of this variable is an integer which is an index into the @code{sc-rewrite-header-list}, beginning at zero. @@ -556,9 +560,9 @@ problem either in your MUA or in Supercite's installation). @findex sc-no-header @findex no-header (sc-) @item sc-no-header -This function produces no header. It should be used instead of -@code{nil} to produce a blank header. This header can possibly contain -a blank line after the @code{mail-header-separator} line. +This function produces no header. It should be used instead of +@code{nil} to produce a blank header. This header can possibly +contain a blank line after the @code{mail-header-separator} line. @item sc-no-blank-line-or-header @findex sc-no-blank-line-or-header @@ -612,11 +616,11 @@ line after the @code{mail-header-separator} line will be removed. By default, when Supercite cites the original message for the first time, it just goes ahead and inserts the reference header indexed by @code{sc-preferred-header-style}. However, you may want to select -different reference headers based on the type of reply or forwarding you -are doing. You may also want to preview the reference header before -deciding whether to insert it into the reply buffer or not. Supercite -provides an optional @dfn{electric reference} mode which you can drop -into to give you this functionality. +different reference headers based on the type of reply or forwarding +you are doing. You may also want to preview the reference header +before deciding whether to insert it into the reply buffer or +not. Supercite provides an optional @dfn{electric reference} mode +which you can drop into to give you this functionality. @vindex sc-electric-references-p @vindex electric-references-p (sc-) @@ -629,7 +633,7 @@ through all the reference header rewrite functions in your @code{sc-rewrite-header-list}. You can also set a new preferred header style, jump to any header, or -jump to the preferred header. The header will be shown in the electric +jump to the preferred header. The header will be shown in the electric reference buffer and the header index and function name will appear in the echo area. @@ -643,7 +647,7 @@ The following commands are available while in electric reference mode @kindex n @vindex sc-electric-circular-p @vindex electric-circular-p (sc-) -Displays the next reference header in the electric reference buffer. If +Displays the next reference header in the electric reference buffer. If the variable @code{sc-electric-circular-p} is non-@code{nil}, invoking @code{sc-eref-next} while viewing the last reference header in the list will wrap around to the first header.@refill @@ -854,7 +858,7 @@ affect alternative citing styles. @vindex mail-warn-if-non-rfc822-p (sc-) All previously retrieved info key-value pairs are deleted from the info alist, then the mail headers in the body of the yanked message are -scanned. Info key-value pairs are created for each header found. Also, +scanned. Info key-value pairs are created for each header found. Also, such useful information as the author's name and email address are extracted. If the variable @code{sc-mail-warn-if-non-rfc822-p} is non-@code{nil}, then Supercite will warn you if it finds a mail header @@ -931,7 +935,7 @@ in the original message should be cited or not. If this variable is non-@code{nil}, blank lines will be cited just like non-blank lines. Otherwise, blank lines will be treated as paragraph separators. -Citing of the original message is highly configurable. Supercite's +Citing of the original message is highly configurable. Supercite's default setup does a pretty good job of citing many common forms of previously cited messages. But there are as many citation styles out there as people on the net, or just about! It would be impossible for @@ -945,8 +949,8 @@ recognize those styles you see often. @vindex sc-post-hook @vindex post-hook (sc-) This variable is very similar to @code{sc-pre-hook}, except that it runs -after @code{sc-cite-original} is finished. This hook is provided mostly -for completeness and backward compatibility. Perhaps it could be used to +after @code{sc-cite-original} is finished. This hook is provided mostly +for completeness and backward compatibility. Perhaps it could be used to reset certain variables set in @code{sc-pre-hook}.@refill @end enumerate @@ -1012,7 +1016,7 @@ both of these variables is provided on the key binding @pxref{Post-yank Formatting Commands}).@refill You will noticed that the minor mode string will -show the state of these variables as qualifier characters. When both +show the state of these variables as qualifier characters. When both variables are @code{nil}, the Supercite minor mode string will display @samp{SC}. When just @code{sc-auto-fill-region-p} is non-@code{nil}, the string will display @samp{SC:f}, and when just @@ -1036,11 +1040,11 @@ fill cited text. @vindex preferred-attribution-list (sc-) As you know, the attribution string is the part of the author's name -that will be used to composed a non-nested citation string. Supercite +that will be used to composed a non-nested citation string. Supercite scans the various mail headers present in the original article and uses a number of heuristics to extract strings which it puts into the -@dfn{attribution association list} or @dfn{attribution alist}. This is -analogous, but different than, the info alist previously mentioned. Each +@dfn{attribution association list} or @dfn{attribution alist}. This is +analogous, but different than, the info alist previously mentioned. Each element in the attribution alist is a key-value pair containing such information as the author's first name, middle names, and last name, the author's initials, and the author's email terminus. @@ -1083,7 +1087,7 @@ the author's last name. the author's first middle name. @item "sc-lastchoice" -the last attribution string you have selected. This is useful when you +the last attribution string you have selected. This is useful when you recite paragraphs in the reply.@refill @item "sc-consult" @@ -1094,7 +1098,7 @@ be used to select special attributions based on the value of any info key. See below for details. @item "x-attribution" -the original author's suggestion for attribution string choice. See below +the original author's suggestion for attribution string choice. See below for details.@refill @end table @@ -1141,7 +1145,7 @@ Each element in this list contains lists of the following form: @findex sc-mail-field @findex mail-field (sc-) where @var{infokey} is a key for @code{sc-mail-field} and @var{regexp} -is a regular expression to match against the @var{infokey}'s value. If +is a regular expression to match against the @var{infokey}'s value. If @var{regexp} matches the @var{infokey}'s value, the @var{attribution} is used as the attribution string. Actually, @var{attribution} can be a string or a list; if it is a list, it is @code{eval}uated and the return @@ -1166,7 +1170,7 @@ The fallback author name is contained in the variable @code{sc-default-author-name} and the fallback attribution string is contained in the variable @code{sc-default-attribution}. Default values for these variables are @code{"Anonymous"} and @code{"Anon"}, -respectively. Note that in most circumstances, getting the default +respectively. Note that in most circumstances, getting the default author name or attribution is a sign that something is set up incorrectly. @@ -1174,7 +1178,7 @@ incorrectly. @vindex use-only-preference-p (sc-) Also, if the preferred attribution, which you specified in your @code{sc-preferred-attribution-list} variable cannot be found, a -secondary method can be employed to find a valid attribution string. The +secondary method can be employed to find a valid attribution string. The variable @code{sc-use-only-preference-p} controls what happens in this case. If the variable's value is non-@code{nil}, then @code{sc-default-author-name} and @code{sc-default-attribution} are @@ -1209,11 +1213,11 @@ attribution alist. @vindex sc-confirm-always-p @vindex confirm-always-p (sc-) Once the attribution string has been automatically selected, a number of -things can happen. If the variable @code{sc-confirm-always-p} is +things can happen. If the variable @code{sc-confirm-always-p} is non-@code{nil}, you are queried for confirmation of the chosen -attribution string. The possible values for completion are those strings +attribution string. The possible values for completion are those strings in the attribution alist, however you are not limited to these choices. -You can type any arbitrary string at the confirmation prompt. The string +You can type any arbitrary string at the confirmation prompt. The string you enter becomes the value associated with the @code{"sc-lastchoice"} key in the attribution alist. @@ -1279,7 +1283,7 @@ author's name proper. Examples include the titles ``Dr.'', ``Mr.'', Also, some companies prepend or append the name of the division, organization, or project on the author's name. All of these titles are noise which should be ignored. The variable @code{sc-name-filter-alist} -is used for this purpose. As implied by its name, this variable is an +is used for this purpose. As implied by its name, this variable is an association list, where each element is a cons cell of the form: @example @@ -1290,7 +1294,7 @@ association list, where each element is a cons cell of the form: where @var{regexp} is a regular expression that is matched (using @code{string-match}) against each element of the @samp{From:@:} field's author name. @var{position} is a position indicator, starting at zero. -Thus to strip out all titles of ``Dr.'', ``Mr.'', etc. from the name, +Thus to strip out all titles of ``Dr.'', ``Mr.'', etc. from the name, @code{sc-name-filter-alist} would have an entry such as: @example @@ -1380,10 +1384,10 @@ The four special symbol values for @var{pred} are recognized: @item t Always produces a true outcome. @item begin -Always executed before the frame is interpreted. This can be used to +Always executed before the frame is interpreted. This can be used to initialize some global variables for example. @item end -Always executed after frame interpreting is completed. This can be used +Always executed after frame interpreting is completed. This can be used to perform any necessary post-processing. @item every Executes whenever the frame is reset, usually after the entire frame has @@ -1406,12 +1410,12 @@ of the following elements:@refill @table @asis @item the symbol @code{continue} This tells Regi to continue processing entries after a match, instead of -resetting the frame and moving @samp{point}. In this way, lines of text +resetting the frame and moving @samp{point}. In this way, lines of text can have multiple matches, but you have to be careful to avoid entering infinite loops. @item the symbol @code{abort} -This tells Regi to terminate frame processing. However, any @code{end} +This tells Regi to terminate frame processing. However, any @code{end} entry is still processed. @item the list @code{(frame . @var{newframe})} @@ -1422,7 +1426,7 @@ can be the frame in-lined.@refill @item the list @code{(step . @var{step})} Tells Regi to move @var{step} number of lines forward as it continues -processing. By default, Regi moves forward one line. @var{step} can be +processing. By default, Regi moves forward one line. @var{step} can be zero or negative of course, but watch out for infinite loops.@refill @end table @@ -1510,12 +1514,12 @@ is not found from the alist, then the appropriate default frame is used. Once the original message has been yanked into the reply buffer, and @code{sc-cite-original} has had a chance to do its thing, a number of -useful Supercite commands will be available to you. Since there is wide +useful Supercite commands will be available to you. Since there is wide variety in the keymaps that MUAs set up in their reply buffers, it is next to impossible for Supercite to properly sprinkle its commands into the existing keymap. For this reason Supercite places its commands on a separate keymap, putting this keymap onto a prefix key in the reply -buffer. You can customize the prefix key Supercite uses by changing the +buffer. You can customize the prefix key Supercite uses by changing the variable @code{sc-mode-map-prefix}. By default, the @code{sc-mode-map-prefix} is @kbd{C-c C-p}; granted, not a great choice, but unfortunately the best general solution so far. In the rest of this @@ -1536,7 +1540,7 @@ prefix.@refill Probably the three most common post-yank formatting operations that you will perform will be the manual citing, reciting, and unciting of -regions of text in the reply buffer. Often you may want to recite a +regions of text in the reply buffer. Often you may want to recite a paragraph to use a nickname, or manually cite a message when setting @code{sc-cite-region-limit} to @code{nil}. The following commands perform these functions on the region of text between @samp{point} and @@ -1582,7 +1586,7 @@ cited line in the region by interpreting the selected frame from @item @code{sc-recite-region} (@kbd{C-c C-p r}) This command recites each line the region by interpreting the selected frame from @code{sc-recite-frame-alist}, or the default reciting frame -@code{sc-default-recite-frame}. It runs the hook +@code{sc-default-recite-frame}. It runs the hook @code{sc-pre-recite-hook} before interpreting the frame. @xref{Configuring the Citation Engine}.@refill @@ -1606,7 +1610,7 @@ These two functions insert various strings into the reply buffer. @vindex preferred-header-style (sc-) Inserts a reference header into the reply buffer at @samp{point}. With no arguments, the header indexed by @code{sc-preferred-header-style} is -inserted. An optional numeric argument is the index into +inserted. An optional numeric argument is the index into @code{sc-rewrite-header-list} indicating which reference header to write.@refill @@ -1719,7 +1723,7 @@ Allows you to interactively view, modify, add, and delete info alist key-value pairs. With no argument, you are prompted (with completion) for a info key. The value associated with that key is displayed in the minibuffer. With an argument, this command will first ask if you want -to view, modify, add, or delete an info key. Viewing is identical to +to view, modify, add, or delete an info key. Viewing is identical to running the command with no arguments. If you want to modify the value of a key, Supercite will first prompt @@ -1770,7 +1774,7 @@ an optional numeric argument inserts that many new lines.@refill @chapter Hints to MUA Authors In June of 1989, some discussion was held between the various MUA -authors, the Supercite author, and other Supercite users. These +authors, the Supercite author, and other Supercite users. These discussions centered around the need for a standard interface between MUAs and Supercite (or any future Supercite-like packages). This interface was formally proposed by Martin Neitzel on Fri, 23 Jun 89, in @@ -1810,14 +1814,14 @@ some default citing when that is the case.@refill If you are writing a new MUA package, or maintaining an existing MUA package, you should make it conform to this interface so that your users -will be able to link Supercite easily and seamlessly. To do this, when +will be able to link Supercite easily and seamlessly. To do this, when setting up a reply or forward buffer, your MUA should follow these steps: @enumerate @item Insert the original message, including the mail headers into the reply -buffer. At this point you should not modify the raw text in any way +buffer. At this point you should not modify the raw text in any way (except for any necessary decoding, e.g., of quoted-printable text), and you should place all the original headers into the body of the reply. This means that many of the mail headers will be duplicated, one copy @@ -1826,7 +1830,7 @@ there will probably be more headers below this line.@refill @item Set @samp{point} to the beginning of the line containing the first mail -header in the body of the reply. Set @samp{mark} at the end of the +header in the body of the reply. Set @samp{mark} at the end of the message text. It is very important that the region be set around the text Supercite is to modify and that the mail headers are within this region. Supercite will not venture outside the region for any reason, @@ -1834,7 +1838,7 @@ and anything within the region is fair game, so don't put anything that @strong{must} remain unchanged inside the region.@refill @item -Run the hook @code{mail-citation-hook}. You will probably want to +Run the hook @code{mail-citation-hook}. You will probably want to provide some kind of default citation functions in cases where the user does not have Supercite installed. By default, your MUA should @code{defvar} @code{mail-citation-hook} to @code{nil}, and in your @@ -1853,9 +1857,9 @@ this interface ``out of the box.'' The Supercite package was derived from its predecessor Superyank 1.11 which was inspired by various bits of code and ideas from Martin Neitzel -and Ashwin Ram. They were the folks who came up with the idea of +and Ashwin Ram. They were the folks who came up with the idea of non-nested citations and implemented some rough code to provide this -style. Superyank and Supercite version 2 evolved to the point where much +style. Superyank and Supercite version 2 evolved to the point where much of the attribution selection mechanism was automatic, and features have been continuously added through the comments and suggestions of the Supercite mailing list participants. From d2a95ffb4eeed87b00c9ac1c8eec7d39b06226e5 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Wed, 7 Aug 2013 17:21:59 +0400 Subject: [PATCH 056/449] Prefer selected_window to Fselected_window, likewise for frames. * buffer.c (Fbuffer_swap_text): * data.c (Fvariable_binding_locus): * window.c (run_window_configuration_change_hook): Adjust users. * w16select.c (Fw16_set_clipboard_data, Fw16_get_clipboard_data): Use decode_live_frame. --- src/ChangeLog | 9 +++++++++ src/buffer.c | 2 +- src/data.c | 2 +- src/w16select.c | 12 ++---------- src/window.c | 4 ++-- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index a090e02e74a..4f7646ea835 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2013-08-07 Dmitry Antipov + + Prefer selected_window to Fselected_window, likewise for frames. + * buffer.c (Fbuffer_swap_text): + * data.c (Fvariable_binding_locus): + * window.c (run_window_configuration_change_hook): Adjust users. + * w16select.c (Fw16_set_clipboard_data, Fw16_get_clipboard_data): + Use decode_live_frame. + 2013-08-07 Dmitry Antipov Be more careful if selected window shows the buffer other than current, diff --git a/src/buffer.c b/src/buffer.c index 339175d9078..ce4b44c87c3 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -2409,7 +2409,7 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, live window points to that window's buffer. So since we just swapped the markers between the two buffers, we need to undo the effect of this swap for window markers. */ - Lisp_Object w = Fselected_window (), ws = Qnil; + Lisp_Object w = selected_window, ws = Qnil; Lisp_Object buf1, buf2; XSETBUFFER (buf1, current_buffer); XSETBUFFER (buf2, other_buffer); diff --git a/src/data.c b/src/data.c index ef3a6965779..9f4bd1f1c02 100644 --- a/src/data.c +++ b/src/data.c @@ -1975,7 +1975,7 @@ If the current binding is global (the default), the value is nil. */) { union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); if (KBOARD_OBJFWDP (valcontents)) - return Fframe_terminal (Fselected_frame ()); + return Fframe_terminal (selected_frame); else if (!BUFFER_OBJFWDP (valcontents)) return Qnil; } diff --git a/src/w16select.c b/src/w16select.c index 3bcc663e565..864757b3e61 100644 --- a/src/w16select.c +++ b/src/w16select.c @@ -452,11 +452,7 @@ DEFUN ("w16-set-clipboard-data", Fw16_set_clipboard_data, Sw16_set_clipboard_dat CHECK_STRING (string); - if (NILP (frame)) - frame = Fselected_frame (); - - CHECK_LIVE_FRAME (frame); - if ( !FRAME_MSDOS_P (XFRAME (frame))) + if (!FRAME_MSDOS_P (decode_live_frame (frame))) goto done; block_input (); @@ -558,11 +554,7 @@ DEFUN ("w16-get-clipboard-data", Fw16_get_clipboard_data, Sw16_get_clipboard_dat Lisp_Object ret = Qnil; int require_decoding = 0; - if (NILP (frame)) - frame = Fselected_frame (); - - CHECK_LIVE_FRAME (frame); - if ( !FRAME_MSDOS_P (XFRAME (frame))) + if (!FRAME_MSDOS_P (decode_live_frame (frame))) goto done; block_input (); diff --git a/src/window.c b/src/window.c index dff449072f5..118c5852275 100644 --- a/src/window.c +++ b/src/window.c @@ -3128,7 +3128,7 @@ run_window_configuration_change_hook (struct frame *f) if (SELECTED_FRAME () != f) { - record_unwind_protect (select_frame_norecord, Fselected_frame ()); + record_unwind_protect (select_frame_norecord, selected_frame); select_frame_norecord (frame); } @@ -3143,7 +3143,7 @@ run_window_configuration_change_hook (struct frame *f) buffer))) { ptrdiff_t inner_count = SPECPDL_INDEX (); - record_unwind_protect (select_window_norecord, Fselected_window ()); + record_unwind_protect (select_window_norecord, selected_window); select_window_norecord (window); run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook, buffer)); From 16ddd1a690a4810bf7a4d77e4fafb0554415da03 Mon Sep 17 00:00:00 2001 From: Martin Rudalics Date: Wed, 7 Aug 2013 15:34:17 +0200 Subject: [PATCH 057/449] In w32fullscreen_hook really maximize frame when asked for (Bug#14841). * w32term.c (w32fullscreen_hook): Really maximize frame when asked for (Bug#14841). --- src/ChangeLog | 5 +++++ src/w32term.c | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ChangeLog b/src/ChangeLog index 4f7646ea835..f759584fb79 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2013-08-07 Martin Rudalics + + * w32term.c (w32fullscreen_hook): Really maximize frame when + asked for (Bug#14841). + 2013-08-07 Dmitry Antipov Prefer selected_window to Fselected_window, likewise for frames. diff --git a/src/w32term.c b/src/w32term.c index 59cfdee86b0..56793660d90 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -5717,7 +5717,9 @@ w32fullscreen_hook (struct frame *f) w32_fullscreen_rect (hwnd, f->want_fullscreen, FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect); FRAME_PREV_FSMODE (f) = f->want_fullscreen; - if (f->want_fullscreen == FULLSCREEN_BOTH) + if (f->want_fullscreen == FULLSCREEN_MAXIMIZED) + PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, 0xf030, 0); + else if (f->want_fullscreen == FULLSCREEN_BOTH) { SetWindowLong (hwnd, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW); SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, From 0ee18172b3dabfbddc81993cbba766cc925281be Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 7 Aug 2013 16:49:47 +0300 Subject: [PATCH 058/449] Fix bug #14616 with unnecessary redrawing of TTY frames. src/xdisp.c (prepare_menu_bars): Don't call x_consider_frame_title for TTY frames that are not the top frame on their console. --- src/ChangeLog | 6 ++++++ src/xdisp.c | 13 ++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/ChangeLog b/src/ChangeLog index f759584fb79..a0363732164 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2013-08-07 Eli Zaretskii + + * xdisp.c (prepare_menu_bars): Don't call x_consider_frame_title + for TTY frames that are not the top frame on their console. + (Bug#14616) + 2013-08-07 Martin Rudalics * w32term.c (w32fullscreen_hook): Really maximize frame when diff --git a/src/xdisp.c b/src/xdisp.c index 5e6311ed98d..fc19b5ce6d7 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -11169,7 +11169,18 @@ prepare_menu_bars (void) { f = XFRAME (frame); if (!EQ (frame, tooltip_frame) - && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f))) + && (FRAME_ICONIFIED_P (f) + || FRAME_VISIBLE_P (f) == 1 + /* Exclude TTY frames that are obscured because they + are not the top frame on their console. This is + because x_consider_frame_title actually swit6ches + to the frame, which for TTY frames means it is + marked as garbaged, and will be completely + redrawn on the next redisplay cycle. This causes + TTY frames to be completely redrawn, when there + are more than one of them, even though nothing + should be changed on display. */ + || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f)))) x_consider_frame_title (frame); } } From f2243267a9eec37e687891e833930f101db2354d Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 7 Aug 2013 16:58:41 +0300 Subject: [PATCH 059/449] Fix bug #15038 with incorrect Texinfo in Emacs Lisp Intro manual. doc/lispintro/emacs-lisp-intro.texi (Beginning init File): Rename from "Beginning a .emacs File", since a node name cannot include a period. (Top, Emacs Initialization, Change a defun): All references changed. --- doc/lispintro/ChangeLog | 8 ++++++++ doc/lispintro/emacs-lisp-intro.texi | 8 ++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/doc/lispintro/ChangeLog b/doc/lispintro/ChangeLog index 481eb0c9db8..7f1f9ab18c0 100644 --- a/doc/lispintro/ChangeLog +++ b/doc/lispintro/ChangeLog @@ -1,3 +1,11 @@ +2013-08-07 Eli Zaretskii + + * emacs-lisp-intro.texi (Beginning init File): Rename from + "Beginning a .emacs File", since a node name cannot include a + period. + (Top, Emacs Initialization, Change a defun): All references + changed. (Bug#15038) + 2013-08-02 Xue Fuqiao * emacs-lisp-intro.texi (zap-to-char): Remove obsolete stuff. diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi index f0d9ab63935..2160d7ba5a9 100644 --- a/doc/lispintro/emacs-lisp-intro.texi +++ b/doc/lispintro/emacs-lisp-intro.texi @@ -648,7 +648,7 @@ Your @file{.emacs} File * Default Configuration:: * Site-wide Init:: You can write site-wide init files. * defcustom:: Emacs will write code for you. -* Beginning a .emacs File:: How to write a @code{.emacs file}. +* Beginning init File:: How to write a @file{.emacs} init file. * Text and Auto-fill:: Automatically wrap lines. * Mail Aliases:: Use abbreviations for email addresses. * Indent Tabs Mode:: Don't use tabs with @TeX{} @@ -3260,7 +3260,7 @@ line that follows a semicolon is a comment. The end of the line is the end of the comment. To stretch a comment over two or more lines, begin each line with a semicolon. -@xref{Beginning a .emacs File, , Beginning a @file{.emacs} +@xref{Beginning init File, , Beginning a @file{.emacs} File}, and @ref{Comments, , Comments, elisp, The GNU Emacs Lisp Reference Manual}, for more about comments. @@ -16706,7 +16706,7 @@ expressions in Emacs Lisp you can change or extend Emacs. * Default Configuration:: * Site-wide Init:: You can write site-wide init files. * defcustom:: Emacs will write code for you. -* Beginning a .emacs File:: How to write a @code{.emacs file}. +* Beginning init File:: How to write a @file{.emacs} init file. * Text and Auto-fill:: Automatically wrap lines. * Mail Aliases:: Use abbreviations for email addresses. * Indent Tabs Mode:: Don't use tabs with @TeX{} @@ -16977,7 +16977,7 @@ intent is that neither programs nor users should ever change a value set by @code{defconst}. (You can change it; the value set is a variable; but please do not.) -@node Beginning a .emacs File +@node Beginning init File @section Beginning a @file{.emacs} File @cindex @file{.emacs} file, beginning of From 2a024334540b2f75b34ed16a425f37bab33fef4e Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 7 Aug 2013 17:15:23 +0300 Subject: [PATCH 060/449] Minor fixes in the ToDo Mode manual. doc/misc/todo-mode.texi: Update @dircategory. (Overview, Todo Items as Diary Entries, Todo Mode Entry Points) (File Editing, Marked Items, Item Prefix): Fix usage of @xref and @ref. --- doc/misc/ChangeLog | 7 +++++++ doc/misc/todo-mode.texi | 24 ++++++++++++------------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog index 5721626f4e3..4ced6e2e97b 100644 --- a/doc/misc/ChangeLog +++ b/doc/misc/ChangeLog @@ -1,3 +1,10 @@ +2013-08-07 Eli Zaretskii + + * todo-mode.texi: Update @dircategory. + (Overview, Todo Items as Diary Entries, Todo Mode Entry Points) + (File Editing, Marked Items, Item Prefix): Fix usage of @xref and + @ref. + 2013-08-07 Xue Fuqiao * sc.texi (Introduction): Fix index. diff --git a/doc/misc/todo-mode.texi b/doc/misc/todo-mode.texi index a14802e9181..27ec68cdf05 100644 --- a/doc/misc/todo-mode.texi +++ b/doc/misc/todo-mode.texi @@ -23,7 +23,7 @@ modify this GNU manual.'' @end quotation @end copying -@dircategory Emacs +@dircategory Emacs misc features @direntry * Todo Mode: (todo-mode). Make and maintain todo lists. @end direntry @@ -138,7 +138,7 @@ are subsidiary to and accessible from Todo mode. This version of Todo mode greatly expands on, and in significant ways differs from, the original version; for details and consequences of the -most important differences, @xref{Legacy Todo Mode Files}. +most important differences, @ref{Legacy Todo Mode Files}. @menu * Levels of Organization:: @@ -192,8 +192,8 @@ file in the Emacs diary file (@pxref{Fancy Diary Display,,, emacs}), the Fancy Diary display will show those todo items that are not marked with @code{todo-nondiary-marker}. This effectively augments the Emacs diary with categorized diary entries. For the various options available for -making a todo item a diary entry, @ref{Inserting New Items} and -@xref{Editing Item Headers and Text}. +making a todo item a diary entry, see @ref{Inserting New Items} and +@ref{Editing Item Headers and Text}. To ensure the proper display of todo items in the Fancy Diary display, they must have the format of diary entries, i.e., they have to begin @@ -244,9 +244,9 @@ default todo file. If you want to enter Todo mode and go directly to a specific category instead the first or current category in the current or default todo -file, use the command @code{todo-jump-to-category}; @ref{Navigation} for +file, use the command @code{todo-jump-to-category}; @ref{Navigation}, for details. You can also enter Todo mode by invoking a todo item insertion -command; @ref{Inserting New Items} for details. +command; @ref{Inserting New Items}, for details. The most convenient way to use these commands to enter Todo mode is to define global key bindings for them in your init file. Good choices are @@ -421,7 +421,7 @@ name and creates the file in @code{todo-directory}, adding the @samp{.todo} extension (so you should not include the extension in the name you enter). The command also prompts for the file's first category and, if option @code{todo-add-item-if-new-category} is enabled (the default), -for that category's first item. +for that category's first item. @item F r Rename the current todo file (@code{todo-rename-file}). If called with @@ -461,7 +461,7 @@ Using @kbd{C-x C-q} to quit Todo Edit mode provides a measure of safety, since it runs a file format check, signaling an error if the format has become invalid. However, this check cannot tell if the number of items changed, which could result in the file containing inconsistent -information (see the cautionary note in @ref{Reordering Categories} for +information (see the cautionary note in @ref{Reordering Categories}, for more details). For this reason @kbd{F e} should be used with caution. @end table @@ -1139,7 +1139,7 @@ Mark the item at point if it is unmarked, and remove the mark it is already marked (@code{todo-toggle-mark-item}). The mark is a string specified by the option @code{todo-item-mark} (by default @samp{*}) appended in front of the item header (more precisely, in front of the -item's priority number or prefix; @pxref{Todo Display Features} for +item's priority number or prefix; see @ref{Todo Display Features}, for details of the latter). After marking the current item, the command advances point to the next item. It also accepts a numeric prefix argument, which allows toggling the mark of multiple consecutive items. @@ -1332,7 +1332,7 @@ way to do this in Todo mode is by sequentially searching in the file: @table @kbd @item S -This command (@code{todo-search}; the key is capital `S') prompts for a +This command (@code{todo-search}; the key is capital @kbd{S}) prompts for a regular expression, searches from the beginning of the current todo file and displays the category containing the first match it finds, with the match highlighted. If there are further matches, a message saying how @@ -1355,7 +1355,7 @@ These commands are also available in Todo Archive mode. A more powerful alternative to sequential searching is item filtering, by which items from different categories that match specified criteria are gathered and displayed in a new buffer as a kind of virtual -category in a distinct mode, Todo Filtered Items mode. +category in a distinct mode, Todo Filtered Items mode. @menu * Filtering Items:: @@ -1612,7 +1612,7 @@ buffers of filtered items that have not yet been written to a file.) In the todo items section of each Todo mode category, the item prefix (whether a priority number or a fixed string) of the top priority items -(determined as specified in @ref{Filtering Items}) is displayed in a +(determined as specified in @pxref{Filtering Items}) is displayed in a different face from the prefix of the other items, so you see at a glance how many items in the category are top priorities. From 03eb60c17ad3abb221aaa71623ce837906836d49 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 7 Aug 2013 18:14:23 +0300 Subject: [PATCH 061/449] xdisp.c: Fix a typo in a comment for the last commit. --- src/xdisp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xdisp.c b/src/xdisp.c index fc19b5ce6d7..102eafbba49 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -11173,7 +11173,7 @@ prepare_menu_bars (void) || FRAME_VISIBLE_P (f) == 1 /* Exclude TTY frames that are obscured because they are not the top frame on their console. This is - because x_consider_frame_title actually swit6ches + because x_consider_frame_title actually switches to the frame, which for TTY frames means it is marked as garbaged, and will be completely redrawn on the next redisplay cycle. This causes From 400a3178cb749fe9cdbad59871aa0786babd434e Mon Sep 17 00:00:00 2001 From: Arni Magnusson Date: Wed, 7 Aug 2013 11:43:57 -0400 Subject: [PATCH 062/449] * lisp/progmodes/dos.el: New file. * lisp/generic-x.el (bat-generic-mode): Redefine as an obsolete alias to dos-mode. --- lisp/ChangeLog | 6 ++ lisp/generic-x.el | 125 +---------------------------- lisp/progmodes/dos.el | 183 ++++++++++++++++++++++++++++++++++++++++++ lisp/subr.el | 2 +- 4 files changed, 191 insertions(+), 125 deletions(-) create mode 100644 lisp/progmodes/dos.el diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 09e0349e7f1..de2b79577e1 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,9 @@ +2013-08-07 Arni Magnusson + + * progmodes/dos.el: New file. + * generic-x.el (bat-generic-mode): Redefine as an obsolete alias to + dos-mode. + 2013-08-06 Glenn Morris * calendar/calendar.el: Add new faces, and day-header-array. diff --git a/lisp/generic-x.el b/lisp/generic-x.el index 1867759b549..698819d73a1 100644 --- a/lisp/generic-x.el +++ b/lisp/generic-x.el @@ -460,130 +460,7 @@ like an INI file. You can add this hook to `find-file-hook'." ;;; DOS/Windows BAT files (when (memq 'bat-generic-mode generic-extras-enable-list) - -(define-generic-mode bat-generic-mode - nil - nil - (eval-when-compile - (list - ;; Make this one first in the list, otherwise comments will - ;; be over-written by other variables - '("^[@ \t]*\\([rR][eE][mM][^\n\r]*\\)" 1 font-lock-comment-face t) - '("^[ \t]*\\(::.*\\)" 1 font-lock-comment-face t) - '("^[@ \t]*\\([bB][rR][eE][aA][kK]\\|[vV][eE][rR][iI][fF][yY]\\)[ \t]+\\([oO]\\([nN]\\|[fF][fF]\\)\\)" - (1 font-lock-builtin-face) - (2 font-lock-constant-face t t)) - ;; Any text (except ON/OFF) following ECHO is a string. - '("^[@ \t]*\\([eE][cC][hH][oO]\\)[ \t]+\\(\\([oO]\\([nN]\\|[fF][fF]\\)\\)\\|\\([^>|\r\n]+\\)\\)" - (1 font-lock-builtin-face) - (3 font-lock-constant-face t t) - (5 font-lock-string-face t t)) - ;; These keywords appear as the first word on a line. (Actually, they - ;; can also appear after "if ..." or "for ..." clause, but since they - ;; are frequently used in simple text, we punt.) - ;; In `generic-bat-mode-setup-function' we make the keywords - ;; case-insensitive - '("^[@ \t]*\\_<\\(for\\|if\\)\\_>" 1 font-lock-keyword-face) - ;; These keywords can be anywhere on a line - ;; In `generic-bat-mode-setup-function' we make the keywords - ;; case-insensitive - (list (regexp-opt '("do" "exist" "errorlevel" "goto" "not") 'symbols) - 1 font-lock-keyword-face) - ;; These are built-in commands. Only frequently-used ones are listed. - (list (concat "[ \t|\n]" - (regexp-opt '("CALL" "call" "Call" - "CD" "cd" "Cd" - "CLS" "cls" "Cls" - "COPY" "copy" "Copy" - "DEL" "del" "Del" - "ECHO" "echo" "Echo" - "MD" "md" "Md" - "PATH" "path" "Path" - "PAUSE" "pause" "Pause" - "PROMPT" "prompt" "Prompt" - "RD" "rd" "Rd" - "REN" "ren" "Ren" - "SET" "set" "Set" - "START" "start" "Start" - "SHIFT" "shift" "Shift") 'symbols)) - 1 font-lock-builtin-face) - '("^[ \t]*\\(:\\sw+\\)" 1 font-lock-function-name-face t) - '("\\(%\\sw+%\\)" 1 font-lock-variable-name-face t) - '("\\(%[0-9]\\)" 1 font-lock-variable-name-face t) - '("[\t ]+\\([+-/][^\t\n\" ]+\\)" 1 font-lock-type-face) - '("[ \t\n|]\\<\\([gG][oO][tT][oO]\\)\\>[ \t]*\\(\\sw+\\)?" - (1 font-lock-keyword-face) - (2 font-lock-function-name-face nil t)) - '("[ \t\n|]\\<\\([sS][eE][tT]\\)\\>[ \t]*\\(\\sw+\\)?[ \t]*=?" - (1 font-lock-builtin-face) - (2 font-lock-variable-name-face t t)))) - '("\\.[bB][aA][tT]\\'" - "\\.[cC][mM][dD]\\'" - "\\`[cC][oO][nN][fF][iI][gG]\\." - "\\`[aA][uU][tT][oO][eE][xX][eE][cC]\\.") - '(generic-bat-mode-setup-function) - "Generic mode for MS-Windows batch files.") - -(defvar bat-generic-mode-syntax-table nil - "Syntax table in use in `bat-generic-mode' buffers.") - -(defvar bat-generic-mode-keymap (make-sparse-keymap) - "Keymap for `bat-generic-mode'.") - -(defun bat-generic-mode-compile () - "Run the current BAT file in a compilation buffer." - (interactive) - (let ((compilation-buffer-name-function - (function - (lambda (_ign) - (concat "*" (buffer-file-name) "*"))))) - (compile - (concat (w32-shell-name) " -c " (buffer-file-name))))) - -(declare-function comint-mode "comint" ()) -(declare-function comint-exec "comint" (buffer name command startfile switches)) - -(defun bat-generic-mode-run-as-comint () - "Run the current BAT file in a comint buffer." - (interactive) - (require 'comint) - (let* ((file (buffer-file-name)) - (buf-name (concat "*" file "*"))) - (with-current-buffer (get-buffer-create buf-name) - (erase-buffer) - (comint-mode) - (comint-exec - buf-name - file - (w32-shell-name) - nil - (list "-c" file)) - (display-buffer buf-name)))) - -(define-key bat-generic-mode-keymap "\C-c\C-c" 'bat-generic-mode-compile) - -;; Make underscores count as words -(unless bat-generic-mode-syntax-table - (setq bat-generic-mode-syntax-table (make-syntax-table)) - (modify-syntax-entry ?_ "w" bat-generic-mode-syntax-table)) - -;; bat-generic-mode doesn't use the comment functionality of -;; define-generic-mode because it has a three-letter comment-string, -;; so we do it here manually instead -(defun generic-bat-mode-setup-function () - (make-local-variable 'parse-sexp-ignore-comments) - (make-local-variable 'comment-start) - (make-local-variable 'comment-start-skip) - (make-local-variable 'comment-end) - (setq imenu-generic-expression '((nil "^:\\(\\sw+\\)" 1)) - parse-sexp-ignore-comments t - comment-end "" - comment-start "REM " - comment-start-skip "[Rr][Ee][Mm] *") - (set-syntax-table bat-generic-mode-syntax-table) - ;; Make keywords case-insensitive - (setq font-lock-defaults '(generic-font-lock-keywords nil t)) - (use-local-map bat-generic-mode-keymap))) + (define-obsolete-function-alias 'bat-generic-mode 'dos-mode "24.4")) ;;; Mailagent ;; Mailagent is a Unix mail filtering program. Anyone wanna do a diff --git a/lisp/progmodes/dos.el b/lisp/progmodes/dos.el new file mode 100644 index 00000000000..57b137f97fb --- /dev/null +++ b/lisp/progmodes/dos.el @@ -0,0 +1,183 @@ +;;; dos.el --- Major mode for editing Dos scripts + +;; Copyright (C) 2003, 2008-2013 Free Software Foundation, Inc. + +;; Author: Arni Magnusson +;; Keywords: languages + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: +;; +;; Major mode for editing Dos scripts (batch files). Provides syntax +;; highlighting, a basic template, access to Dos help pages, imenu/outline +;; navigation, and the ability to run scripts from within Emacs. The syntax +;; groups for highlighting are: +;; +;; Face Example +;; dos-label-face :LABEL +;; font-lock-comment-face rem +;; font-lock-builtin-face copy +;; font-lock-keyword-face goto +;; font-lock-warning-face cp +;; font-lock-constant-face [call] prog +;; font-lock-variable-name-face %var% +;; font-lock-type-face -option +;; +;; Usage: +;; +;; See documentation of function `dos-mode'. +;; +;; Separate package `dos-indent' (Matthew Fidler) provides rudimentary +;; indentation, see http://www.emacswiki.org/emacs/dos-indent.el. +;; +;; Acknowledgements: +;; +;; Inspired by `batch-mode' (Agnar Renolen) and `cmd-mode' (Tadamegu Furukawa). + +;;; Code: + +;; 1 Preamble + +(defgroup dos nil + "Major mode for editing Dos scripts." + :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) + :group 'languages) + +;; 2 User variables + +(defface dos-label-face '((t :weight bold)) + "Font Lock mode face used to highlight Dos labels." + :group 'dos) + +;; 3 Internal variables + +(defvar dos-font-lock-keywords + (eval-when-compile + (let ((COMMANDS + '("assoc" "at" "attrib" "cd" "cls" "color" "copy" "date" "del" "dir" + "doskey" "echo" "endlocal" "erase" "fc" "find" "findstr" "format" + "ftype" "label" "md" "mkdir" "more" "move" "net" "path" "pause" + "popd" "prompt" "pushd" "rd" "ren" "rename" "replace" "rmdir" "set" + "setlocal" "shift" "sort" "subst" "time" "title" "tree" "type" + "ver" "vol" "xcopy")) + (CONTROLFLOW + '("call" "cmd" "defined" "do" "else" "equ" "exist" "exit" "for" "geq" + "goto" "gtr" "if" "in" "leq" "lss" "neq" "not" "start")) + (LINUX + '("cat" "cp" "ls" "mv" "rm"))) + (list + '("\\<\\(call\\|goto\\)\\>[ \t]+%?\\([A-Za-z0-9-_\\:.]+\\)%?" + (2 font-lock-constant-face t)) + '("^[ \t]*\\(@?rem\\>\\|::\\).*" + (0 font-lock-comment-face t)) + '("^:[^:].*" + . 'dos-label-face) + '("\\<\\(defined\\|set\\)\\>[ \t]*\\(\\w+\\)" + (2 font-lock-variable-name-face)) + '("%\\(\\w+\\)%?" + (1 font-lock-variable-name-face)) + '("!\\(\\w+\\)!?" ; delayed-expansion !variable! + (1 font-lock-variable-name-face)) + '("[ =][-/]+\\(\\w+\\)" + (1 font-lock-type-face append)) + (cons (regexp-opt COMMANDS 'words) font-lock-builtin-face) + (cons (regexp-opt CONTROLFLOW 'words) font-lock-keyword-face) + (cons (regexp-opt LINUX 'words) font-lock-warning-face))))) + +(defvar dos-menu + '("Dos" + ["Run" dos-run :help "Run script"] + ["Run with Args" dos-run-args :help "Run script with args"] + "--" + ["Imenu" imenu :help "Navigate with imenu"] + "--" + ["Template" dos-template :help "Insert template"] + "--" + ["Help (Command)" dos-cmd-help :help "Show help page for Dos command"] + ["Help (Mode)" dos-mode-help :help "Show help page for Emacs Dos Mode"])) + +(defvar dos-mode-map + (let ((map (make-sparse-keymap))) + (easy-menu-define nil map nil dos-menu) + (define-key map [?\C-c ?\C-.] 'dos-mode-help) + (define-key map [?\C-c ?\C-/] 'dos-cmd-help) + (define-key map [?\C-c ?\C-a] 'dos-run-args) + (define-key map [?\C-c ?\C-c] 'dos-run) + (define-key map [?\C-c ?\C-t] 'dos-template) + (define-key map [?\C-c ?\C-v] 'dos-run) + map)) + +(defvar dos-mode-syntax-table + (let ((table (make-syntax-table))) + (modify-syntax-entry ?~ "w" table) + (modify-syntax-entry ?% "." table) + (modify-syntax-entry ?- "w" table) + (modify-syntax-entry ?_ "w" table) + (modify-syntax-entry ?{ "w" table) + (modify-syntax-entry ?} "w" table) + (modify-syntax-entry ?\\ "." table) + table)) + +;; 4 User functions + +(defun dos-cmd-help (cmd) + "Show help for Dos command." + (interactive "sHelp: ") + (if (string-equal cmd "net") + (shell-command "net /?") (shell-command (concat "help " cmd)))) + +(defun dos-mode-help () + "Show help page for `dos-mode'." + (interactive) + (describe-function 'dos-mode) + (switch-to-buffer "*Help*") (delete-other-windows) (message nil)) + +(defun dos-run () + "Run Dos script." + (interactive) + (save-buffer) (shell-command buffer-file-name)) + +(defun dos-run-args (args) + "Run Dos script with ARGS." + (interactive "sArgs: ") + (shell-command (concat buffer-file-name " " args))) + +(defun dos-template () + "Insert minimal Dos template." + (interactive) + (goto-char (point-min)) (insert "@echo off\nsetlocal\n\n")) + +;; 5 Main function + +;;;###autoload +(define-derived-mode dos-mode prog-mode "Dos" + "Major mode for editing Dos scripts.\n +The `dos-mode-help' command shows this page.\n +Start a new script from `dos-template'. Read help pages for Dos commands with +`dos-cmd-help'. Navigate between sections using `imenu'. Run script using +`dos-run' and `dos-run-args'.\n +\\{dos-mode-map}" + (set (make-local-variable 'comment-start) "rem") + (set (make-local-variable 'font-lock-defaults) + '(dos-font-lock-keywords nil t)) ; case-insensitive keywords + (set (make-local-variable 'imenu-generic-expression) '((nil "^:[^:].*" 0))) + (set (make-local-variable 'outline-regexp) ":[^:]") + (set-syntax-table dos-mode-syntax-table)) + +(provide 'dos) + +;;; dos.el ends here diff --git a/lisp/subr.el b/lisp/subr.el index bdeee677471..43a9fc015b1 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2755,7 +2755,7 @@ Otherwise, return nil." (let ((def (indirect-function object t))) (when (consp def) (or (eq 'macro (car def)) - (and (eq 'autoload (car def)) (memq (nth 4 def) '(macro t))))))) + (and (autoloadp def) (memq (nth 4 def) '(macro t))))))) (defun field-at-pos (pos) "Return the field at position POS, taking stickiness etc into account." From 312b1740c24f3a26b93fb6ea3a8d53f15e3edd91 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Wed, 7 Aug 2013 11:50:16 -0400 Subject: [PATCH 063/449] * lisp/progmodes/dos.el (auto-mode-alist): Add entries for dos-mode. (dos-mode): Use setq-local. Add space after "rem". (dos-mode-syntax-table): Don't use "w" for symbol chars. (dos-font-lock-keywords): Try to adjust font-lock rules accordingly. --- lisp/ChangeLog | 7 ++++++ lisp/progmodes/dos.el | 58 ++++++++++++++++++++++++------------------- 2 files changed, 40 insertions(+), 25 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index de2b79577e1..6ccb8d61836 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,10 @@ +2013-08-07 Stefan Monnier + + * progmodes/dos.el (auto-mode-alist): Add entries for dos-mode. + (dos-mode): Use setq-local. Add space after "rem". + (dos-mode-syntax-table): Don't use "w" for symbol chars. + (dos-font-lock-keywords): Try to adjust font-lock rules accordingly. + 2013-08-07 Arni Magnusson * progmodes/dos.el: New file. diff --git a/lisp/progmodes/dos.el b/lisp/progmodes/dos.el index 57b137f97fb..adc94f201a6 100644 --- a/lisp/progmodes/dos.el +++ b/lisp/progmodes/dos.el @@ -22,9 +22,9 @@ ;;; Commentary: ;; -;; Major mode for editing Dos scripts (batch files). Provides syntax +;; Major mode for editing Dos scripts (batch files). Provides syntax ;; highlighting, a basic template, access to Dos help pages, imenu/outline -;; navigation, and the ability to run scripts from within Emacs. The syntax +;; navigation, and the ability to run scripts from within Emacs. The syntax ;; groups for highlighting are: ;; ;; Face Example @@ -79,24 +79,25 @@ "goto" "gtr" "if" "in" "leq" "lss" "neq" "not" "start")) (LINUX '("cat" "cp" "ls" "mv" "rm"))) - (list - '("\\<\\(call\\|goto\\)\\>[ \t]+%?\\([A-Za-z0-9-_\\:.]+\\)%?" + `(("\\<_\\(call\\|goto\\)\\_>[ \t]+%?\\([A-Za-z0-9-_\\:.]+\\)%?" (2 font-lock-constant-face t)) - '("^[ \t]*\\(@?rem\\>\\|::\\).*" + ("^[ \t]*\\(@?rem\\_>\\|::\\).*" (0 font-lock-comment-face t)) - '("^:[^:].*" + ("^:[^:].*" . 'dos-label-face) - '("\\<\\(defined\\|set\\)\\>[ \t]*\\(\\w+\\)" + ("\\<_\\(defined\\|set\\)\\_>[ \t]*\\(\\w+\\)" (2 font-lock-variable-name-face)) - '("%\\(\\w+\\)%?" + ("%\\(\\w+\\)%?" (1 font-lock-variable-name-face)) - '("!\\(\\w+\\)!?" ; delayed-expansion !variable! + ("!\\(\\w+\\)!?" ; delayed-expansion !variable! (1 font-lock-variable-name-face)) - '("[ =][-/]+\\(\\w+\\)" + ("[ =][-/]+\\(\\w+\\)" (1 font-lock-type-face append)) - (cons (regexp-opt COMMANDS 'words) font-lock-builtin-face) - (cons (regexp-opt CONTROLFLOW 'words) font-lock-keyword-face) - (cons (regexp-opt LINUX 'words) font-lock-warning-face))))) + (,(concat "\\_<" (regexp-opt COMMANDS) "\\_>") . font-lock-builtin-face) + (,(concat "\\_<" (regexp-opt CONTROLFLOW) "\\_>") + . font-lock-keyword-face) + (,(concat "\\_<" (regexp-opt LINUX) "\\_>") + . font-lock-warning-face))))) (defvar dos-menu '("Dos" @@ -114,7 +115,7 @@ (let ((map (make-sparse-keymap))) (easy-menu-define nil map nil dos-menu) (define-key map [?\C-c ?\C-.] 'dos-mode-help) - (define-key map [?\C-c ?\C-/] 'dos-cmd-help) + (define-key map [?\C-c ?\C-/] 'dos-cmd-help) ;FIXME: Why not C-c C-? ? (define-key map [?\C-c ?\C-a] 'dos-run-args) (define-key map [?\C-c ?\C-c] 'dos-run) (define-key map [?\C-c ?\C-t] 'dos-template) @@ -123,21 +124,24 @@ (defvar dos-mode-syntax-table (let ((table (make-syntax-table))) - (modify-syntax-entry ?~ "w" table) + ;; Beware: `w' should not be used for non-alphabetic chars. + (modify-syntax-entry ?~ "_" table) (modify-syntax-entry ?% "." table) - (modify-syntax-entry ?- "w" table) - (modify-syntax-entry ?_ "w" table) - (modify-syntax-entry ?{ "w" table) - (modify-syntax-entry ?} "w" table) + (modify-syntax-entry ?- "_" table) + (modify-syntax-entry ?_ "_" table) + ;; FIXME: { and } can appear in identifiers? Really? + (modify-syntax-entry ?{ "_" table) + (modify-syntax-entry ?} "_" table) (modify-syntax-entry ?\\ "." table) table)) ;; 4 User functions (defun dos-cmd-help (cmd) - "Show help for Dos command." + "Show help for Dos command CMD." (interactive "sHelp: ") (if (string-equal cmd "net") + ;; FIXME: liable to quoting nightmare. Use call-process? (shell-command "net /?") (shell-command (concat "help " cmd)))) (defun dos-mode-help () @@ -149,11 +153,13 @@ (defun dos-run () "Run Dos script." (interactive) + ;; FIXME: liable to quoting nightmare. Use call/start-process? (save-buffer) (shell-command buffer-file-name)) (defun dos-run-args (args) "Run Dos script with ARGS." (interactive "sArgs: ") + ;; FIXME: Use `compile'? (shell-command (concat buffer-file-name " " args))) (defun dos-template () @@ -161,6 +167,9 @@ (interactive) (goto-char (point-min)) (insert "@echo off\nsetlocal\n\n")) +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.\\(bat\\|cmd\\)\\'" . dos-mode)) + ;; 5 Main function ;;;###autoload @@ -171,12 +180,11 @@ Start a new script from `dos-template'. Read help pages for Dos commands with `dos-cmd-help'. Navigate between sections using `imenu'. Run script using `dos-run' and `dos-run-args'.\n \\{dos-mode-map}" - (set (make-local-variable 'comment-start) "rem") - (set (make-local-variable 'font-lock-defaults) + (setq-local comment-start "rem ") + (setq-local font-lock-defaults '(dos-font-lock-keywords nil t)) ; case-insensitive keywords - (set (make-local-variable 'imenu-generic-expression) '((nil "^:[^:].*" 0))) - (set (make-local-variable 'outline-regexp) ":[^:]") - (set-syntax-table dos-mode-syntax-table)) + (setq-local imenu-generic-expression '((nil "^:[^:].*" 0))) + (setq-local outline-regexp ":[^:]")) (provide 'dos) From cdc1ebb9413fb4db15aa5a3175bcb6db3ce02609 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 7 Aug 2013 19:37:04 +0300 Subject: [PATCH 064/449] Minor fixes in lisp/progmodes/dos.el. lisp/progmodes/dos.el (dos-font-lock-keywords): Rename LINUX to UNIX and add a few popular commands found in batch files. (dos, dos-label-face, dos-cmd-help, dos-run, dos-run-args) (dos-mode): Doc fixes. --- lisp/ChangeLog | 7 +++++++ lisp/progmodes/dos.el | 26 +++++++++++++------------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 6ccb8d61836..4b670eb2f8b 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,10 @@ +2013-08-07 Eli Zaretskii + + * progmodes/dos.el (dos-font-lock-keywords): Rename LINUX to UNIX + and add a few popular commands found in batch files. + (dos, dos-label-face, dos-cmd-help, dos-run, dos-run-args) + (dos-mode): Doc fixes. + 2013-08-07 Stefan Monnier * progmodes/dos.el (auto-mode-alist): Add entries for dos-mode. diff --git a/lisp/progmodes/dos.el b/lisp/progmodes/dos.el index adc94f201a6..593b5e9fc92 100644 --- a/lisp/progmodes/dos.el +++ b/lisp/progmodes/dos.el @@ -53,14 +53,14 @@ ;; 1 Preamble (defgroup dos nil - "Major mode for editing Dos scripts." + "Major mode for editing DOS/Windows batch files." :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) :group 'languages) ;; 2 User variables (defface dos-label-face '((t :weight bold)) - "Font Lock mode face used to highlight Dos labels." + "Font Lock mode face used to highlight labels in batch files." :group 'dos) ;; 3 Internal variables @@ -77,8 +77,8 @@ (CONTROLFLOW '("call" "cmd" "defined" "do" "else" "equ" "exist" "exit" "for" "geq" "goto" "gtr" "if" "in" "leq" "lss" "neq" "not" "start")) - (LINUX - '("cat" "cp" "ls" "mv" "rm"))) + (UNIX + '("bash" "cat" "cp" "fgrep" "grep" "ls" "sed" "sh" "mv" "rm"))) `(("\\<_\\(call\\|goto\\)\\_>[ \t]+%?\\([A-Za-z0-9-_\\:.]+\\)%?" (2 font-lock-constant-face t)) ("^[ \t]*\\(@?rem\\_>\\|::\\).*" @@ -96,7 +96,7 @@ (,(concat "\\_<" (regexp-opt COMMANDS) "\\_>") . font-lock-builtin-face) (,(concat "\\_<" (regexp-opt CONTROLFLOW) "\\_>") . font-lock-keyword-face) - (,(concat "\\_<" (regexp-opt LINUX) "\\_>") + (,(concat "\\_<" (regexp-opt UNIX) "\\_>") . font-lock-warning-face))))) (defvar dos-menu @@ -138,7 +138,7 @@ ;; 4 User functions (defun dos-cmd-help (cmd) - "Show help for Dos command CMD." + "Show help for batch file command CMD." (interactive "sHelp: ") (if (string-equal cmd "net") ;; FIXME: liable to quoting nightmare. Use call-process? @@ -151,19 +151,19 @@ (switch-to-buffer "*Help*") (delete-other-windows) (message nil)) (defun dos-run () - "Run Dos script." + "Run a batch file." (interactive) ;; FIXME: liable to quoting nightmare. Use call/start-process? (save-buffer) (shell-command buffer-file-name)) (defun dos-run-args (args) - "Run Dos script with ARGS." + "Run a batch file with ARGS." (interactive "sArgs: ") ;; FIXME: Use `compile'? (shell-command (concat buffer-file-name " " args))) (defun dos-template () - "Insert minimal Dos template." + "Insert minimal batch file template." (interactive) (goto-char (point-min)) (insert "@echo off\nsetlocal\n\n")) @@ -174,11 +174,11 @@ ;;;###autoload (define-derived-mode dos-mode prog-mode "Dos" - "Major mode for editing Dos scripts.\n + "Major mode for editing DOS/Windows batch files.\n The `dos-mode-help' command shows this page.\n -Start a new script from `dos-template'. Read help pages for Dos commands with -`dos-cmd-help'. Navigate between sections using `imenu'. Run script using -`dos-run' and `dos-run-args'.\n +Start a new script from `dos-template'. Read help pages for Dos commands +with `dos-cmd-help'. Navigate between sections using `imenu'. +Run script using `dos-run' and `dos-run-args'.\n \\{dos-mode-map}" (setq-local comment-start "rem ") (setq-local font-lock-defaults From 8fd9c92e1fc88dc04f3bb2c9a370982e980b941e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Dj=C3=A4rv?= Date: Wed, 7 Aug 2013 18:59:23 +0200 Subject: [PATCH 065/449] * xselect.c (x_send_client_event): Set send_event and serial, memset data.l as it might be bigger than data.b. Use 24 bit mask to XSendEvent. Fixes: debbugs:15034 --- src/ChangeLog | 6 ++++++ src/xselect.c | 10 ++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index a0363732164..55f9a5c641b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2013-08-07 Jan Djärv + + * xselect.c (x_send_client_event): Set send_event and serial, memset + data.l as it might be bigger than data.b. Use 24 bit mask to + XSendEvent (Bug#15034). + 2013-08-07 Eli Zaretskii * xdisp.c (prepare_menu_bars): Don't call x_consider_frame_title diff --git a/src/xselect.c b/src/xselect.c index 3a16d7d3496..e5f2e214fba 100644 --- a/src/xselect.c +++ b/src/xselect.c @@ -2628,6 +2628,8 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from, block_input (); + event.xclient.send_event = True; + event.xclient.serial = 0; event.xclient.message_type = message_type; event.xclient.display = dpyinfo->display; @@ -2635,19 +2637,19 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from, when sending to the root window. */ event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest; - - memset (event.xclient.data.b, 0, sizeof (event.xclient.data.b)); + memset (event.xclient.data.l, 0, sizeof (event.xclient.data.l)); x_fill_property_data (dpyinfo->display, values, event.xclient.data.b, event.xclient.format); /* If event mask is 0 the event is sent to the client that created the destination window. But if we are sending to the root window, - there is no such client. Then we set the event mask to 0xffff. The + there is no such client. Then we set the event mask to 0xffffff. The event then goes to clients selecting for events on the root window. */ x_catch_errors (dpyinfo->display); { int propagate = to_root ? False : True; - unsigned mask = to_root ? 0xffff : 0; + long mask = to_root ? 0xffffff : 0; + XSendEvent (dpyinfo->display, wdest, propagate, mask, &event); XFlush (dpyinfo->display); } From e5eefe9b9648e8dd3095e2cbb3b9b91f18206e54 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Wed, 7 Aug 2013 21:03:46 +0400 Subject: [PATCH 066/449] Fix typo in ChangeLog entry. --- src/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ChangeLog b/src/ChangeLog index 55f9a5c641b..ead50fa0517 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -36,7 +36,7 @@ * xdisp.c (reconsider_clip_changes): Remove prototype, drop 2nd arg and always assume window's buffer. (redisplay_window): Adjust user. - (redisplay_internal): Call to reconsider_clip_change once and + (redisplay_internal): Call to reconsider_clip_changes once and check whether mode line should be updated only if selected window shows current buffer. (run_window_scroll_functions): Use eassert for debugging check. From bb41480a689afe5444d8e76bea259f4e61cf1216 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Wed, 7 Aug 2013 13:33:30 -0400 Subject: [PATCH 067/449] * lisp/emacs-lisp/bytecomp.el: Check existence of f in #'f. (byte-compile-callargs-warn): Use `push'. (byte-compile-arglist-warn): Ignore higher-order "calls". (byte-compile-file-form-autoload): Use `pcase'. (byte-compile-function-form): If quoting a symbol, check that it exists. --- lisp/ChangeLog | 8 ++++ lisp/emacs-lisp/byte-run.el | 1 - lisp/emacs-lisp/bytecomp.el | 94 ++++++++++++++++++++++--------------- 3 files changed, 64 insertions(+), 39 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 4b670eb2f8b..70e10615dd7 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,11 @@ +2013-08-07 Stefan Monnier + + * emacs-lisp/bytecomp.el: Check existence of f in #'f. + (byte-compile-callargs-warn): Use `push'. + (byte-compile-arglist-warn): Ignore higher-order "calls". + (byte-compile-file-form-autoload): Use `pcase'. + (byte-compile-function-form): If quoting a symbol, check that it exists. + 2013-08-07 Eli Zaretskii * progmodes/dos.el (dos-font-lock-keywords): Rename LINUX to UNIX diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el index 8f0999b2f80..0bb04950dfd 100644 --- a/lisp/emacs-lisp/byte-run.el +++ b/lisp/emacs-lisp/byte-run.el @@ -83,7 +83,6 @@ The return value of this function is not used." (list 'quote f) (list 'quote new-name) (list 'quote when)))) (list 'compiler-macro #'(lambda (f args compiler-function) - ;; FIXME: Make it possible to just reuse `args'. `(eval-and-compile (put ',f 'compiler-macro ,(if (eq (car-safe compiler-function) 'lambda) diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index f4e79dc4886..ce377dc5caf 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -1273,7 +1273,7 @@ Each function's symbol gets added to `byte-compile-noruntime-functions'." (n (length (cdr form)))) (if cons (or (memq n (cdr cons)) - (setcdr cons (cons n (cdr cons)))) + (push n (cdr cons))) (push (list (car form) n) byte-compile-unresolved-functions)))))) @@ -1364,7 +1364,10 @@ extra args." ;; This is the first definition. See if previous calls are compatible. (let ((calls (assq name byte-compile-unresolved-functions)) nums sig min max) - (when calls + (setq byte-compile-unresolved-functions + (delq calls byte-compile-unresolved-functions)) + (setq calls (delq t calls)) ;Ignore higher-order uses of the function. + (when (cdr calls) (when (and (symbolp name) (eq (function-get name 'byte-optimizer) 'byte-compile-inline-expand)) @@ -1382,10 +1385,7 @@ extra args." name (byte-compile-arglist-signature-string sig) (if (equal sig '(1 . 1)) " arg" " args") - (byte-compile-arglist-signature-string (cons min max)))) - - (setq byte-compile-unresolved-functions - (delq calls byte-compile-unresolved-functions))))))) + (byte-compile-arglist-signature-string (cons min max))))))))) (defvar byte-compile-cl-functions nil "List of functions defined in CL.") @@ -2214,37 +2214,33 @@ list that represents a doc string reference. (defun byte-compile-file-form-autoload (form) (and (let ((form form)) (while (if (setq form (cdr form)) (macroexp-const-p (car form)))) - (null form)) ;Constants only + (null form)) ;Constants only (memq (eval (nth 5 form)) '(t macro)) ;Macro - (eval form)) ;Define the autoload. + (eval form)) ;Define the autoload. ;; Avoid undefined function warnings for the autoload. - (when (and (consp (nth 1 form)) - (eq (car (nth 1 form)) 'quote) - (consp (cdr (nth 1 form))) - (symbolp (nth 1 (nth 1 form)))) - ;; Don't add it if it's already defined. Otherwise, it might - ;; hide the actual definition. However, do remove any entry from - ;; byte-compile-noruntime-functions, in case we have an autoload - ;; of foo-func following an (eval-when-compile (require 'foo)). - (unless (fboundp (nth 1 (nth 1 form))) - (push (cons (nth 1 (nth 1 form)) - (cons 'autoload (cdr (cdr form)))) - byte-compile-function-environment)) - ;; If an autoload occurs _before_ the first call to a function, - ;; byte-compile-callargs-warn does not add an entry to - ;; byte-compile-unresolved-functions. Here we mimic the logic - ;; of byte-compile-callargs-warn so as not to warn if the - ;; autoload comes _after_ the function call. - ;; Alternatively, similar logic could go in - ;; byte-compile-warn-about-unresolved-functions. - (if (memq (nth 1 (nth 1 form)) byte-compile-noruntime-functions) - (setq byte-compile-noruntime-functions - (delq (nth 1 (nth 1 form)) byte-compile-noruntime-functions) - byte-compile-noruntime-functions) - (setq byte-compile-unresolved-functions - (delq (assq (nth 1 (nth 1 form)) - byte-compile-unresolved-functions) - byte-compile-unresolved-functions)))) + (pcase (nth 1 form) + (`',(and (pred symbolp) funsym) + ;; Don't add it if it's already defined. Otherwise, it might + ;; hide the actual definition. However, do remove any entry from + ;; byte-compile-noruntime-functions, in case we have an autoload + ;; of foo-func following an (eval-when-compile (require 'foo)). + (unless (fboundp funsym) + (push (cons funsym (cons 'autoload (cdr (cdr form)))) + byte-compile-function-environment)) + ;; If an autoload occurs _before_ the first call to a function, + ;; byte-compile-callargs-warn does not add an entry to + ;; byte-compile-unresolved-functions. Here we mimic the logic + ;; of byte-compile-callargs-warn so as not to warn if the + ;; autoload comes _after_ the function call. + ;; Alternatively, similar logic could go in + ;; byte-compile-warn-about-unresolved-functions. + (if (memq funsym byte-compile-noruntime-functions) + (setq byte-compile-noruntime-functions + (delq funsym byte-compile-noruntime-functions) + byte-compile-noruntime-functions) + (setq byte-compile-unresolved-functions + (delq (assq funsym byte-compile-unresolved-functions) + byte-compile-unresolved-functions))))) (if (stringp (nth 3 form)) form ;; No doc string, so we can compile this as a normal form. @@ -3574,10 +3570,32 @@ discarding." ;; and (funcall (function foo)) will lose with autoloads. (defun byte-compile-function-form (form) - (byte-compile-constant (if (eq 'lambda (car-safe (nth 1 form))) - (byte-compile-lambda (nth 1 form)) - (nth 1 form)))) + (let ((f (nth 1 form))) + (when (and (symbolp f) + (byte-compile-warning-enabled-p 'callargs)) + (when (get f 'byte-obsolete-info) + (byte-compile-warn-obsolete (car form))) + ;; Check to see if the function will be available at runtime + ;; and/or remember its arity if it's unknown. + (or (and (or (fboundp f) ; Might be a subr or autoload. + (byte-compile-fdefinition (car form) nil)) + (not (memq f byte-compile-noruntime-functions))) + (eq f byte-compile-current-form) ; ## This doesn't work + ; with recursion. + ;; It's a currently-undefined function. + ;; Remember number of args in call. + (let ((cons (assq f byte-compile-unresolved-functions))) + (if cons + (or (memq t (cdr cons)) + (push t (cdr cons))) + (push (list f t) + byte-compile-unresolved-functions))))) + + (byte-compile-constant (if (eq 'lambda (car-safe f)) + (byte-compile-lambda f) + f)))) + (defun byte-compile-indent-to (form) (let ((len (length form))) (cond ((= len 2) From 7679edb1e0afb258cc80657a15eebcafcbdb7f81 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Wed, 7 Aug 2013 18:42:44 -0400 Subject: [PATCH 068/449] * lisp/progmodes/bat-mode.el: Rename from dos.el. Use "bat-" prefix. (dos-mode-help): Remove. Use describe-mode (C-h m) instead. --- lisp/ChangeLog | 3 + lisp/generic-x.el | 2 +- lisp/progmodes/{dos.el => bat-mode.el} | 84 ++++++++++++-------------- 3 files changed, 41 insertions(+), 48 deletions(-) rename lisp/progmodes/{dos.el => bat-mode.el} (72%) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 70e10615dd7..e1d366f0510 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,8 @@ 2013-08-07 Stefan Monnier + * progmodes/bat-mode.el: Rename from dos.el. Use "bat-" prefix. + (dos-mode-help): Remove. Use describe-mode (C-h m) instead. + * emacs-lisp/bytecomp.el: Check existence of f in #'f. (byte-compile-callargs-warn): Use `push'. (byte-compile-arglist-warn): Ignore higher-order "calls". diff --git a/lisp/generic-x.el b/lisp/generic-x.el index 698819d73a1..c964b53952e 100644 --- a/lisp/generic-x.el +++ b/lisp/generic-x.el @@ -460,7 +460,7 @@ like an INI file. You can add this hook to `find-file-hook'." ;;; DOS/Windows BAT files (when (memq 'bat-generic-mode generic-extras-enable-list) - (define-obsolete-function-alias 'bat-generic-mode 'dos-mode "24.4")) + (define-obsolete-function-alias 'bat-generic-mode 'bat-mode "24.4")) ;;; Mailagent ;; Mailagent is a Unix mail filtering program. Anyone wanna do a diff --git a/lisp/progmodes/dos.el b/lisp/progmodes/bat-mode.el similarity index 72% rename from lisp/progmodes/dos.el rename to lisp/progmodes/bat-mode.el index 593b5e9fc92..45c350e9847 100644 --- a/lisp/progmodes/dos.el +++ b/lisp/progmodes/bat-mode.el @@ -1,4 +1,4 @@ -;;; dos.el --- Major mode for editing Dos scripts +;;; bat-mode.el --- Major mode for editing DOS/Windows scripts ;; Copyright (C) 2003, 2008-2013 Free Software Foundation, Inc. @@ -22,13 +22,13 @@ ;;; Commentary: ;; -;; Major mode for editing Dos scripts (batch files). Provides syntax -;; highlighting, a basic template, access to Dos help pages, imenu/outline +;; Major mode for editing DOS/Windows scripts (batch files). Provides syntax +;; highlighting, a basic template, access to DOS help pages, imenu/outline ;; navigation, and the ability to run scripts from within Emacs. The syntax ;; groups for highlighting are: ;; ;; Face Example -;; dos-label-face :LABEL +;; bat-label-face :LABEL ;; font-lock-comment-face rem ;; font-lock-builtin-face copy ;; font-lock-keyword-face goto @@ -39,7 +39,7 @@ ;; ;; Usage: ;; -;; See documentation of function `dos-mode'. +;; See documentation of function `bat-mode'. ;; ;; Separate package `dos-indent' (Matthew Fidler) provides rudimentary ;; indentation, see http://www.emacswiki.org/emacs/dos-indent.el. @@ -52,20 +52,19 @@ ;; 1 Preamble -(defgroup dos nil +(defgroup bat-mode nil "Major mode for editing DOS/Windows batch files." :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) :group 'languages) ;; 2 User variables -(defface dos-label-face '((t :weight bold)) - "Font Lock mode face used to highlight labels in batch files." - :group 'dos) +(defface bat-label-face '((t :weight bold)) + "Font Lock mode face used to highlight labels in batch files.") ;; 3 Internal variables -(defvar dos-font-lock-keywords +(defvar bat-font-lock-keywords (eval-when-compile (let ((COMMANDS '("assoc" "at" "attrib" "cd" "cls" "color" "copy" "date" "del" "dir" @@ -84,7 +83,7 @@ ("^[ \t]*\\(@?rem\\_>\\|::\\).*" (0 font-lock-comment-face t)) ("^:[^:].*" - . 'dos-label-face) + . 'bat-label-face) ("\\<_\\(defined\\|set\\)\\_>[ \t]*\\(\\w+\\)" (2 font-lock-variable-name-face)) ("%\\(\\w+\\)%?" @@ -99,30 +98,28 @@ (,(concat "\\_<" (regexp-opt UNIX) "\\_>") . font-lock-warning-face))))) -(defvar dos-menu - '("Dos" - ["Run" dos-run :help "Run script"] - ["Run with Args" dos-run-args :help "Run script with args"] +(defvar bat-menu + '("Bat" + ["Run" bat-run :help "Run script"] + ["Run with Args" bat-run-args :help "Run script with args"] "--" ["Imenu" imenu :help "Navigate with imenu"] "--" - ["Template" dos-template :help "Insert template"] + ["Template" bat-template :help "Insert template"] "--" - ["Help (Command)" dos-cmd-help :help "Show help page for Dos command"] - ["Help (Mode)" dos-mode-help :help "Show help page for Emacs Dos Mode"])) + ["Help (Command)" bat-cmd-help :help "Show help page for DOS command"])) -(defvar dos-mode-map +(defvar bat-mode-map (let ((map (make-sparse-keymap))) - (easy-menu-define nil map nil dos-menu) - (define-key map [?\C-c ?\C-.] 'dos-mode-help) - (define-key map [?\C-c ?\C-/] 'dos-cmd-help) ;FIXME: Why not C-c C-? ? - (define-key map [?\C-c ?\C-a] 'dos-run-args) - (define-key map [?\C-c ?\C-c] 'dos-run) - (define-key map [?\C-c ?\C-t] 'dos-template) - (define-key map [?\C-c ?\C-v] 'dos-run) + (easy-menu-define nil map nil bat-menu) + (define-key map [?\C-c ?\C-/] 'bat-cmd-help) ;FIXME: Why not C-c C-? ? + (define-key map [?\C-c ?\C-a] 'bat-run-args) + (define-key map [?\C-c ?\C-c] 'bat-run) + (define-key map [?\C-c ?\C-t] 'bat-template) + (define-key map [?\C-c ?\C-v] 'bat-run) map)) -(defvar dos-mode-syntax-table +(defvar bat-mode-syntax-table (let ((table (make-syntax-table))) ;; Beware: `w' should not be used for non-alphabetic chars. (modify-syntax-entry ?~ "_" table) @@ -137,55 +134,48 @@ ;; 4 User functions -(defun dos-cmd-help (cmd) +(defun bat-cmd-help (cmd) "Show help for batch file command CMD." (interactive "sHelp: ") (if (string-equal cmd "net") ;; FIXME: liable to quoting nightmare. Use call-process? (shell-command "net /?") (shell-command (concat "help " cmd)))) -(defun dos-mode-help () - "Show help page for `dos-mode'." - (interactive) - (describe-function 'dos-mode) - (switch-to-buffer "*Help*") (delete-other-windows) (message nil)) - -(defun dos-run () +(defun bat-run () "Run a batch file." (interactive) ;; FIXME: liable to quoting nightmare. Use call/start-process? (save-buffer) (shell-command buffer-file-name)) -(defun dos-run-args (args) +(defun bat-run-args (args) "Run a batch file with ARGS." (interactive "sArgs: ") ;; FIXME: Use `compile'? (shell-command (concat buffer-file-name " " args))) -(defun dos-template () +(defun bat-template () "Insert minimal batch file template." (interactive) (goto-char (point-min)) (insert "@echo off\nsetlocal\n\n")) ;;;###autoload -(add-to-list 'auto-mode-alist '("\\.\\(bat\\|cmd\\)\\'" . dos-mode)) +(add-to-list 'auto-mode-alist '("\\.\\(bat\\|cmd\\)\\'" . bat-mode)) ;; 5 Main function ;;;###autoload -(define-derived-mode dos-mode prog-mode "Dos" +(define-derived-mode bat-mode prog-mode "Bat" "Major mode for editing DOS/Windows batch files.\n -The `dos-mode-help' command shows this page.\n -Start a new script from `dos-template'. Read help pages for Dos commands -with `dos-cmd-help'. Navigate between sections using `imenu'. -Run script using `dos-run' and `dos-run-args'.\n -\\{dos-mode-map}" +Start a new script from `bat-template'. Read help pages for DOS commands +with `bat-cmd-help'. Navigate between sections using `imenu'. +Run script using `bat-run' and `bat-run-args'.\n +\\{bat-mode-map}" (setq-local comment-start "rem ") (setq-local font-lock-defaults - '(dos-font-lock-keywords nil t)) ; case-insensitive keywords + '(bat-font-lock-keywords nil t)) ; case-insensitive keywords (setq-local imenu-generic-expression '((nil "^:[^:].*" 0))) (setq-local outline-regexp ":[^:]")) -(provide 'dos) +(provide 'bat-mode) -;;; dos.el ends here +;;; bat-mode.el ends here From f001e98ec5cc0d145a324f2d4062adbe44c16060 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Wed, 7 Aug 2013 18:53:18 -0400 Subject: [PATCH 069/449] * lisp/progmodes/bat-mode.el (bat--syntax-propertize): New var. (bat-mode): Use it. (bat-mode-syntax-table): Mark \n as end-of-comment. (bat-font-lock-keywords): Remove comment rule. --- lisp/ChangeLog | 5 +++++ lisp/progmodes/bat-mode.el | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index e1d366f0510..20c20097532 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,10 @@ 2013-08-07 Stefan Monnier + * progmodes/bat-mode.el (bat--syntax-propertize): New var. + (bat-mode): Use it. + (bat-mode-syntax-table): Mark \n as end-of-comment. + (bat-font-lock-keywords): Remove comment rule. + * progmodes/bat-mode.el: Rename from dos.el. Use "bat-" prefix. (dos-mode-help): Remove. Use describe-mode (C-h m) instead. diff --git a/lisp/progmodes/bat-mode.el b/lisp/progmodes/bat-mode.el index 45c350e9847..2b6f9d3434d 100644 --- a/lisp/progmodes/bat-mode.el +++ b/lisp/progmodes/bat-mode.el @@ -80,8 +80,6 @@ '("bash" "cat" "cp" "fgrep" "grep" "ls" "sed" "sh" "mv" "rm"))) `(("\\<_\\(call\\|goto\\)\\_>[ \t]+%?\\([A-Za-z0-9-_\\:.]+\\)%?" (2 font-lock-constant-face t)) - ("^[ \t]*\\(@?rem\\_>\\|::\\).*" - (0 font-lock-comment-face t)) ("^:[^:].*" . 'bat-label-face) ("\\<_\\(defined\\|set\\)\\_>[ \t]*\\(\\w+\\)" @@ -121,6 +119,7 @@ (defvar bat-mode-syntax-table (let ((table (make-syntax-table))) + (modify-syntax-entry ?\n ">" table) ;; Beware: `w' should not be used for non-alphabetic chars. (modify-syntax-entry ?~ "_" table) (modify-syntax-entry ?% "." table) @@ -132,6 +131,10 @@ (modify-syntax-entry ?\\ "." table) table)) +(defconst bat--syntax-propertize + (syntax-propertize-rules + ("^[ \t]*\\(?:\\(@?r\\)em\\_>\\|\\(?1::\\):\\).*" (1 "<")))) + ;; 4 User functions (defun bat-cmd-help (cmd) @@ -171,6 +174,7 @@ with `bat-cmd-help'. Navigate between sections using `imenu'. Run script using `bat-run' and `bat-run-args'.\n \\{bat-mode-map}" (setq-local comment-start "rem ") + (setq-local syntax-propertize-function bat--syntax-propertize) (setq-local font-lock-defaults '(bat-font-lock-keywords nil t)) ; case-insensitive keywords (setq-local imenu-generic-expression '((nil "^:[^:].*" 0))) From a912c0163d1f6fac4d443522b712169c6d31b523 Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Thu, 8 Aug 2013 00:54:08 +0200 Subject: [PATCH 070/449] lisp/frameset.el: Convert `frameset' to vector and add new slots. (frameset): Use type vector, not list (incompatible change). Do not declare a new constructor, use the default one. Upgrade suggested properties `app', `name' and `desc' to slots `app', `name' and `description', respectively, and add read-only slot `timestamp'. Doc fixes. (frameset-copy, frameset-persistent-filter-alist) (frameset-filter-alist, frameset-switch-to-gui-p) (frameset-switch-to-tty-p, frameset-filter-tty-to-GUI) (frameset-filter-sanitize-color, frameset-filter-minibuffer) (frameset-filter-iconified, frameset-keep-original-display-p): Doc fixes. (frameset-filter-shelve-param, frameset-filter-unshelve-param): Rename from frameset-filter-(save|restore)-param. All callers changed. Doc fix. (frameset-p): Adapt to change to vector and be more thorough. Change arg name to OBJECT. Doc fix. (frameset-prop): Rename arg PROP to PROPERTY. Doc fix. (frameset-session-filter-alist): Rename from frameset-live-filter-alist. All callers changed. (frameset-frame-with-id): Rename from frameset-locate-frame-id. All callers changed. (frameset--record-minibuffer-relationships): Rename from frameset--process-minibuffer-frames. All callers changed. (frameset-save): Add new keyword arguments APP, NAME and DESCRIPTION. Use new default constructor (again). Doc fix. (frameset--find-frame-if): Rename from `frameset--find-frame. All callers changed. (frameset--reuse-frame): Rename arg FRAME-CFG to PARAMETERS. (frameset--initial-params): Rename arg FRAME-CFG to PARAMETERS. Doc fix. (frameset--restore-frame): Rename args FRAME-CFG and WINDOW-CFG to PARAMETERS and WINDOW-STATE, respectively. (frameset-restore): Add new keyword argument PREDICATE. Reset frameset--target-display to nil. Doc fix. lisp/desktop.el (desktop-save-frameset): Use new frameset-save args. Use lexical-binding. --- lisp/ChangeLog | 40 +++ lisp/desktop.el | 12 +- lisp/frameset.el | 667 +++++++++++++++++++++++++++++++++-------------- 3 files changed, 518 insertions(+), 201 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 20c20097532..93c10d858e7 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,43 @@ +2013-08-07 Juanma Barranquero + + * desktop.el (desktop-save-frameset): Use new frameset-save args. + Use lexical-binding. + + * frameset.el (frameset): Use type vector, not list (incompatible + change). Do not declare a new constructor, use the default one. + Upgrade suggested properties `app', `name' and `desc' to slots `app', + `name' and `description', respectively, and add read-only slot + `timestamp'. Doc fixes. + (frameset-copy, frameset-persistent-filter-alist) + (frameset-filter-alist, frameset-switch-to-gui-p) + (frameset-switch-to-tty-p, frameset-filter-tty-to-GUI) + (frameset-filter-sanitize-color, frameset-filter-minibuffer) + (frameset-filter-iconified, frameset-keep-original-display-p): + Doc fixes. + (frameset-filter-shelve-param, frameset-filter-unshelve-param): + Rename from frameset-filter-(save|restore)-param. All callers changed. + Doc fix. + (frameset-p): Adapt to change to vector and be more thorough. + Change arg name to OBJECT. Doc fix. + (frameset-prop): Rename arg PROP to PROPERTY. Doc fix. + (frameset-session-filter-alist): Rename from frameset-live-filter-alist. + All callers changed. + (frameset-frame-with-id): Rename from frameset-locate-frame-id. + All callers changed. + (frameset--record-minibuffer-relationships): Rename from + frameset--process-minibuffer-frames. All callers changed. + (frameset-save): Add new keyword arguments APP, NAME and DESCRIPTION. + Use new default constructor (again). Doc fix. + (frameset--find-frame-if): Rename from `frameset--find-frame. + All callers changed. + (frameset--reuse-frame): Rename arg FRAME-CFG to PARAMETERS. + (frameset--initial-params): Rename arg FRAME-CFG to PARAMETERS. + Doc fix. + (frameset--restore-frame): Rename args FRAME-CFG and WINDOW-CFG to + PARAMETERS and WINDOW-STATE, respectively. + (frameset-restore): Add new keyword argument PREDICATE. + Reset frameset--target-display to nil. Doc fix. + 2013-08-07 Stefan Monnier * progmodes/bat-mode.el (bat--syntax-propertize): New var. diff --git a/lisp/desktop.el b/lisp/desktop.el index 76aa30e4090..91635218228 100644 --- a/lisp/desktop.el +++ b/lisp/desktop.el @@ -1,4 +1,4 @@ -;;; desktop.el --- save partial status of Emacs when killed +;;; desktop.el --- save partial status of Emacs when killed -*- lexical-binding: t -*- ;; Copyright (C) 1993-1995, 1997, 2000-2013 Free Software Foundation, ;; Inc. @@ -910,12 +910,10 @@ DIRNAME must be the directory in which the desktop file will be saved." Frames with a non-nil `desktop-dont-save' parameter are not saved." (setq desktop-saved-frameset (and desktop-restore-frames - (let ((name (concat user-login-name "@" system-name - (format-time-string " %Y-%m-%d %T")))) - (frameset-save nil - :predicate #'desktop--check-dont-save - :properties (list :app desktop--app-id - :name name)))))) + (frameset-save nil + :app desktop--app-id + :name (concat user-login-name "@" system-name) + :predicate #'desktop--check-dont-save)))) ;;;###autoload (defun desktop-save (dirname &optional release auto-save) diff --git a/lisp/frameset.el b/lisp/frameset.el index 45cf86eb3cc..ad58a17c840 100644 --- a/lisp/frameset.el +++ b/lisp/frameset.el @@ -41,41 +41,35 @@ (require 'cl-lib) -(cl-defstruct (frameset (:type list) :named +(cl-defstruct (frameset (:type vector) :named ;; Copier and predicate functions are defined below. (:copier nil) - (:predicate nil) - ;; A BOA constructor, not the default "keywordy" one. - ;; This is for internal use; to create a frameset, - ;; the "right" way to do it is with frameset-save. - (:constructor make-frameset (properties states))) + (:predicate nil)) "A frameset encapsulates a serializable view of a set of frames and windows. It contains the following slots, which can be accessed with \(frameset-SLOT fs) and set with (setf (frameset-SLOT fs) VALUE): - version A non-modifiable version number, identifying the format - of the frameset struct. Currently its value is 1. + version A read-only version number, identifying the format + of the frameset struct. Currently its value is 1. + timestamp A read-only timestamp, the output of `current-time'. + app A symbol, or a list whose first element is a symbol, which + identifies the creator of the frameset and related info; + for example, desktop.el sets this slot to a list + `(desktop . ,desktop-file-version). + name A string, the name of the frameset instance. + description A string, a description for user consumption (to show in + menus, messages, etc). properties A property list, to store both frameset-specific and - user-defined serializable data (see suggestions below). - states An alist of items (FRAME-PARAMETERS . WINDOW-STATE), in no - particular order. Each item represents a frame to be + user-defined serializable data. + states A list of items (FRAME-PARAMETERS . WINDOW-STATE), in no + particular order. Each item represents a frame to be restored. FRAME-PARAMETERS is a frame's parameter alist, - extracted with (frame-parameters FRAME) and filtered through - `frame-parameters-alist' or a similar filter alist. - WINDOW-STATE is the output of `window-state-get', when - applied to the root window of the frame. - -Some suggested properties: - - :app APPINFO Can be used by applications and packages to indicate the - intended (but by no means exclusive) use of the frameset. - Freeform. For example, currently desktop.el framesets set - :app to `(desktop . ,desktop-file-version). - :name NAME The name of the frameset instance; a string. - :desc TEXT A description for user consumption (to show in a menu to - choose among framesets, etc.); a string. + extracted with (frame-parameters FRAME) and filtered + through `frameset-filter-params'. + WINDOW-STATE is the output of `window-state-get' applied + to the root window of the frame. To avoid collisions, it is recommended that applications wanting to add private serializable data to `properties' either store all info under a @@ -95,31 +89,41 @@ A frameset is intended to be used through the following simple API: `properties' slot. - The `frameset-SLOT' accessors described above." - (version 1 :read-only t) - properties states) + (version 1 :read-only t) + (timestamp (current-time) :read-only t) + (app nil) + (name nil) + (description nil) + (properties nil) + (states nil)) (defun frameset-copy (frameset) - "Return a copy of FRAMESET. -This is a deep copy done with `copy-tree'." + "Return a deep copy of FRAMESET. +FRAMESET is copied with `copy-tree'." (copy-tree frameset t)) ;;;###autoload -(defun frameset-p (frameset) - "If FRAMESET is a frameset, return its version number. +(defun frameset-p (object) + "If OBJECT is a frameset, return its version number. Else return nil." - (and (eq (car-safe frameset) 'frameset) ; is a list - (integerp (nth 1 frameset)) ; version is an int - (nth 3 frameset) ; states is non-null - (nth 1 frameset))) ; return version + (and (vectorp object) ; a vector + (eq (aref object 0) 'frameset) ; tagged as `frameset' + (integerp (aref object 1)) ; version is an int + (consp (aref object 2)) ; timestamp is a non-null list + (stringp (or (aref object 4) "")) ; name is a string or null + (stringp (or (aref object 5) "")) ; description is a string or null + (listp (aref object 6)) ; properties is a list + (consp (aref object 7)) ; and states is non-null + (aref object 1))) ; return version ;; A setf'able accessor to the frameset's properties -(defun frameset-prop (frameset prop) - "Return the value of the PROP property of FRAMESET. +(defun frameset-prop (frameset property) + "Return the value for FRAMESET of PROPERTY. Properties can be set with (setf (frameset-prop FRAMESET PROP) NEW-VALUE)" - (plist-get (frameset-properties frameset) prop)) + (plist-get (frameset-properties frameset) property)) (gv-define-setter frameset-prop (val fs prop) (macroexp-let2 nil v val @@ -131,8 +135,261 @@ Properties can be set with ;; Filtering +;; What's the deal with these "filter alists"? +;; +;; Let's say that Emacs' frame parameters were never designed as a tool to +;; precisely record (or restore) a frame's state. They grew organically, +;; and their uses and behaviors reflect their history. In using them to +;; implement framesets, the unwary implementor, or the prospective package +;; writer willing to use framesets in their code, might fall victim of some +;; unexpected... oddities. +;; +;; You can find frame parameters that: +;; +;; - can be used to get and set some data from the frame's current state +;; (`height', `width') +;; - can be set at creation time, and setting them afterwards has no effect +;; (`window-state', `minibuffer') +;; - can be set at creation time, and setting them afterwards will fail with +;; an error, *unless* you set it to the same value, a noop (`border-width') +;; - act differently when passed at frame creation time, and when set +;; afterwards (`height') +;; - affect the value of other parameters (`name', `visibility') +;; - can be ignored by window managers (most positional args, like `height', +;; `width', `left' and `top', and others, like `auto-raise', `auto-lower') +;; - can be set externally in X resources or Window registry (again, most +;; positional parameters, and also `toolbar-lines', `menu-bar-lines' etc.) +;, - can contain references to live objects (`buffer-list', `minibuffer') or +;; code (`buffer-predicate') +;; - are set automatically, and cannot be changed (`window-id', `parent-id'), +;; but setting them produces no error +;; - have a noticeable effect in some window managers, and are ignored in +;; others (`menu-bar-lines') +;; - can not be safely set in a tty session and then copied back to a GUI +;; session (`font', `background-color', `foreground-color') +;; +;; etc etc. +;; +;; Which means that, in order to save a parameter alist to disk and read it +;; back later to reconstruct a frame, some processing must be done. That's +;; what `frameset-filter-params' and the `frameset-*-filter-alist' variables +;; are for. +;; +;; First, a clarification: the word "filter" in these names refers to both +;; common meanings of filter: to filter out (i.e., to remove), and to pass +;; through a transformation function (think `filter-buffer-substring'). +;; +;; `frameset-filter-params' takes a parameter alist PARAMETERS, a filtering +;; alist FILTER-ALIST, and a flag SAVING to indicate whether we are filtering +;; parameters with the intent of saving a frame or restoring it. It then +;; accumulates an output list, FILTERED, by checking each parameter in +;; PARAMETERS against FILTER-ALIST and obeying any rule found there. The +;; absence of a rule just means the parameter/value pair (called CURRENT in +;; filtering functions) is copied to FILTERED as is. Keyword values :save, +;; :restore and :never tell the function to copy CURRENT to FILTERED in the +;; respective situations, that is, when saving, restoring, or never at all. +;; Values :save and :restore are not used in this package, because usually if +;; you don't want to save a parameter, you don't want to restore it either. +;; But they can be useful, for example, if you already have a saved frameset +;; created with some intent, and want to reuse it for a different objective +;; where the expected parameter list has different requirements. +;; +;; Finally, the value can also be a filtering function, or a filtering +;; function plus some arguments. The function is called for each matching +;; parameter, and receives CURRENT (the parameter/value pair being processed), +;; FILTERED (the output alist so far), PARAMETERS (the full parameter alist), +;; SAVING (the save/restore flag), plus any additional ARGS set along the +;; function in the `frameset-*-filter-alist' entry. The filtering function +;; then has the possibility to pass along CURRENT, or reject it altogether, +;; or pass back a (NEW-PARAM . NEW-VALUE) pair, which does not even need to +;; refer to the same parameter (so you can filter `width' and return `height' +;; and vice versa, if you're feeling silly and want to mess with the user's +;; mind). As a help in deciding what to do, the filtering function has +;; access to PARAMETERS, but must not change it in any way. It also has +;; access to FILTERED, which can be modified at will. This allows two or +;; more filters to coordinate themselves, because in general there's no way +;; to predict the order in which they will be run. +;; +;; So, which parameters are filtered by default, and why? Let's see. +;; +;; - `buffer-list', `buried-buffer-list', `buffer-predicate': They contain +;; references to live objects, or in the case of `buffer-predicate', it +;; could also contain an fbound symbol (a predicate function) that could +;; not be defined in a later session. +;; +;; - `window-id', `outer-window-id', `parent-id': They are assigned +;; automatically and cannot be set, so keeping them is harmless, but they +;; add clutter. `window-system' is similar: it's assigned at frame +;; creation, and does not serve any useful purpose later. +;; +;; - `left', `top': Only problematic when saving an iconified frame, because +;; when the frame is iconified they are set to (- 32000), which doesn't +;; really help in restoring the frame. Better to remove them and let the +;; window manager choose a default position for the frame. +;; +;; - `background-color', `foreground-color': In tty frames they can be set +;; to "unspecified-bg" and "unspecified-fg", which aren't understood on +;; GUI sessions. They have to be filtered out when switching from tty to +;; a graphical display. +;; +;; - `tty', `tty-type': These are tty-specific. When switching to a GUI +;; display they do no harm, but they clutter the parameter list. +;; +;; - `minibuffer': It can contain a reference to a live window, which cannot +;; be serialized. Because of Emacs' idiosyncratic treatment of this +;; parameter, frames created with (minibuffer . t) have a parameter +;; (minibuffer . #), while frames created with +;; (minibuffer . #) have (minibuffer . nil), which is madness +;; but helps to differentiate between minibufferless and "normal" frames. +;; So, changing (minibuffer . #) to (minibuffer . t) allows +;; Emacs to set up the new frame correctly. Nice, uh? +;; +;; - `name': If this parameter is directly set, `explicit-name' is +;; automatically set to t, and then `name' no longer changes dynamically. +;; So, in general, not saving `name' is the right thing to do, though +;; surely there are applications that will want to override this filter. +;; +;; - `font', `fullscreen', `height' and `width': These parameters suffer +;; from the fact that they are badly manged when going through a +;; tty session, though not all in the same way. When saving a GUI frame +;; and restoring it in a tty, the height and width of the new frame are +;; those of the tty screen (let's say 80x25, for example); going back +;; to a GUI session means getting frames of the tty screen size (so all +;; your frames are 80 cols x 25 rows). For `fullscreen' there's a +;; similar problem, because a tty frame cannot really be fullscreen or +;; maximized, so the state is lost. The problem with `font' is a bit +;; different, because a valid GUI font spec in `font' turns into +;; (font . "tty") in a tty frame, and when read back into a GUI session +;; it fails because `font's value is no longer a valid font spec. +;; +;; In most cases, the filtering functions just do the obvious thing: remove +;; CURRENT when it is meaningless to keep it, or pass a modified copy if +;; that helps (as in the case of `minibuffer'). +;; +;; The exception are the parameters in the last set, which should survive +;; the roundtrip though tty-land. The answer is to add "stashing +;; parameters", working in pairs, to shelve the GUI-specific contents and +;; restore it once we're back in pixel country. That's what functions +;; `frameset-filter-shelve-param' and `frameset-unshelve-param' do. +;; +;; Basically, if you set `frameset-filter-shelve-param' as the filter for +;; a parameter P, it will detect when it is restoring a GUI frame into a +;; tty session, and save P's value in the custom parameter X:P, but only +;; if X:P does not exist already (so it is not overwritten if you enter +;; the tty session more than once). If you're not switching to a tty +;; frame, the filter just passes CURRENT along. +;; +;; The parameter X:P, on the other hand, must have been setup to be +;; filtered by `frameset-filter-unshelve-param', which unshelves the +;; value: if we're entering a GUI session, returns P instead of CURRENT, +;; while in other cases it just passes it along. +;; +;; The only additional trick is that `frameset-filter-shelve-param' does +;; not set P if switching back to GUI and P already has a value, because +;; it assumes that `frameset-filter-unshelve-param' did set it up. And +;; `frameset-filter-unshelve-param', when unshelving P, must look into +;; FILTERED to determine if P has already been set and if so, modify it; +;; else just returns P. +;; +;; Currently, the value of X in X:P is `GUI', but you can use any prefix, +;; by passing its symbol as argument in the filter: +;; +;; (my-parameter frameset-filter-shelve-param MYPREFIX) +;; +;; instead of +;; +;; (my-parameter . frameset-filter-shelve-param) +;; +;; Note that `frameset-filter-unshelve-param' does not need MYPREFIX +;; because it is available from the parameter name in CURRENT. Also note +;; that the colon between the prefix and the parameter name is hardcoded. +;; The reason is that X:P is quite readable, and that the colon is a +;; very unusual character in symbol names, other than in initial position +;; in keywords (emacs -Q has only two such symbols, and one of them is a +;; URL). So the probability of a collision with existing or future +;; symbols is quite insignificant. +;; +;; Now, what about the filter alists? There are three of them, though +;; only two sets of parameters: +;; +;; - `frameset-session-filter-alist' contains these filters that allow to +;; save and restore framesets in-session, without the need to serialize +;; the frameset or save it to disk (for example, to save a frameset in a +;; register and restore it later). Filters in this list do not remove +;; live objects, except in `minibuffer', which is dealt especially by +;; `frameset-save' / `frameset-restore'. +;; +;; - `frameset-persistent-filter-alist' is the whole deal. It does all +;; the filtering described above, and the result is ready to be saved on +;; disk without loss of information. That's the format used by the +;; desktop.el package, for example. +;; +;; IMPORTANT: These variables share structure and should never be modified. +;; +;; - `frameset-filter-alist': The value of this variable is the default +;; value for the FILTERS arguments of `frameset-save' and +;; `frameset-restore'. It is set to `frameset-persistent-filter-alist', +;; though it can be changed by specific applications. +;; +;; How to use them? +;; +;; The simplest way is just do nothing. The default should work +;; reasonably and sensibly enough. But, what if you really need a +;; customized filter alist? Then you can create your own variable +;; +;; (defvar my-filter-alist +;; '((my-param1 . :never) +;; (my-param2 . :save) +;; (my-param3 . :restore) +;; (my-param4 . my-filtering-function-without-args) +;; (my-param5 my-filtering-function-with arg1 arg2) +;; ;;; many other parameters +;; ) +;; "My customized parameter filter alist.") +;; +;; or, if you're only changing a few items, +;; +;; (defvar my-filter-alist +;; (nconc '((my-param1 . :never) +;; (my-param2 . my-filtering-function)) +;; frameset-filter-alist) +;; "My brief customized parameter filter alist.") +;; +;; and pass it to the FILTER arg of the save/restore functions, +;; ALWAYS taking care of not modifying the original lists; if you're +;; going to do any modifying of my-filter-alist, please use +;; +;; (nconc '((my-param1 . :never) ...) +;; (copy-sequence frameset-filter-alist)) +;; +;; One thing you shouldn't forget is that they are alists, so searching +;; in them is sequential. If you just want to change the default of +;; `name' to allow it to be saved, you can set (name . nil) in your +;; customized filter alist; it will take precedence over the latter +;; setting. In case you decide that you *always* want to save `name', +;; you can add it to `frameset-filter-alist': +;; +;; (push '(name . nil) frameset-filter-alist) +;; +;; In certain applications, having a parameter filtering function like +;; `frameset-filter-params' can be useful, even if you're not using +;; framesets. The interface of `frameset-filter-params' is generic +;; and does not depend of global state, with one exception: it uses +;; the internal variable `frameset--target-display' to decide if, and +;; how, to modify the `display' parameter of FILTERED. But that +;; should not represent any problem, because it's only meaningful +;; when restoring, and customized uses of `frameset-filter-params' +;; are likely to use their own filter alist and just call +;; +;; (setq my-filtered (frameset-filter-params my-params my-filters t)) +;; +;; In case you want to use it with the standard filters, you can +;; wrap the call to `frameset-filter-params' in a let form to bind +;; `frameset--target-display' to nil or the desired value. +;; + ;;;###autoload -(defvar frameset-live-filter-alist +(defvar frameset-session-filter-alist '((name . :never) (left . frameset-filter-iconified) (minibuffer . frameset-filter-minibuffer) @@ -147,33 +404,35 @@ See `frameset-filter-alist' for a full description.") (buffer-list . :never) (buffer-predicate . :never) (buried-buffer-list . :never) - (font . frameset-filter-save-param) + (font . frameset-filter-shelve-param) (foreground-color . frameset-filter-sanitize-color) - (fullscreen . frameset-filter-save-param) - (GUI:font . frameset-filter-restore-param) - (GUI:fullscreen . frameset-filter-restore-param) - (GUI:height . frameset-filter-restore-param) - (GUI:width . frameset-filter-restore-param) - (height . frameset-filter-save-param) + (fullscreen . frameset-filter-shelve-param) + (GUI:font . frameset-filter-unshelve-param) + (GUI:fullscreen . frameset-filter-unshelve-param) + (GUI:height . frameset-filter-unshelve-param) + (GUI:width . frameset-filter-unshelve-param) + (height . frameset-filter-shelve-param) (outer-window-id . :never) (parent-id . :never) (tty . frameset-filter-tty-to-GUI) (tty-type . frameset-filter-tty-to-GUI) - (width . frameset-filter-save-param) + (width . frameset-filter-shelve-param) (window-id . :never) (window-system . :never)) - frameset-live-filter-alist) - "Recommended set of parameters to filter for persistent framesets. + frameset-session-filter-alist) + "Parameters to filter for persistent framesets. See `frameset-filter-alist' for a full description.") ;;;###autoload (defvar frameset-filter-alist frameset-persistent-filter-alist "Alist of frame parameters and filtering functions. -This alist is the default value of the :filters arguments of -`frameset-save' and `frameset-restore' (which see). On saving, -PARAMETERS is the parameter alist of each frame processed, and -FILTERED is the parameter alist that gets saved to the frameset. +This alist is the default value of the FILTERS argument of +`frameset-save' and `frameset-restore' (which see). + +On saving, PARAMETERS is the parameter alist of each frame processed, +and FILTERED is the parameter alist that gets saved to the frameset. + On restoring, PARAMETERS is the parameter alist extracted from the frameset, and FILTERED is the resulting frame parameter alist used to restore the frame. @@ -200,7 +459,7 @@ where FILTERED The resulting alist (so far). PARAMETERS The complete alist of parameters being filtered, SAVING Non-nil if filtering before saving state, nil if filtering - before restoring it. + before restoring it. ARGS Any additional arguments specified in the ACTION. FILTER-FUN is allowed to modify items in FILTERED, but no other arguments. @@ -223,20 +482,20 @@ defined with ACTION = nil.") (defun frameset-switch-to-gui-p (parameters) "True when switching to a graphic display. -Return t if PARAMETERS describes a text-only terminal and -the target is a graphic display; otherwise return nil. -Only meaningful when called from a filtering function in -`frameset-filter-alist'." +Return non-nil if the parameter alist PARAMETERS describes a frame on a +text-only terminal, and the frame is being restored on a graphic display; +otherwise return nil. Only meaningful when called from a filtering +function in `frameset-filter-alist'." (and frameset--target-display ; we're switching (null (cdr (assq 'display parameters))) ; from a tty (cdr frameset--target-display))) ; to a GUI display (defun frameset-switch-to-tty-p (parameters) "True when switching to a text-only terminal. -Return t if PARAMETERS describes a graphic display and -the target is a text-only terminal; otherwise return nil. -Only meaningful when called from a filtering function in -`frameset-filter-alist'." +Return non-nil if the parameter alist PARAMETERS describes a frame on a +graphic display, and the frame is being restored on a text-only terminal; +otherwise return nil. Only meaningful when called from a filtering +function in `frameset-filter-alist'." (and frameset--target-display ; we're switching (cdr (assq 'display parameters)) ; from a GUI display (null (cdr frameset--target-display)))) ; to a tty @@ -245,7 +504,7 @@ Only meaningful when called from a filtering function in "Remove CURRENT when switching from tty to a graphic display. For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, -see the docstring of `frameset-filter-alist'." +see `frameset-filter-alist'." (or saving (not (frameset-switch-to-gui-p parameters)))) @@ -254,30 +513,30 @@ see the docstring of `frameset-filter-alist'." Useful as a filter function for tty-specific parameters. For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, -see the docstring of `frameset-filter-alist'." +see `frameset-filter-alist'." (or saving (not (frameset-switch-to-gui-p parameters)) (not (stringp (cdr current))) (not (string-match-p "^unspecified-[fb]g$" (cdr current))))) (defun frameset-filter-minibuffer (current _filtered _parameters saving) - "When saving, convert (minibuffer . #) parameter to (minibuffer . t). + "When saving, convert (minibuffer . #) to (minibuffer . t). For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, -see the docstring of `frameset-filter-alist'." +see `frameset-filter-alist'." (or (not saving) (if (windowp (cdr current)) '(minibuffer . t) t))) -(defun frameset-filter-save-param (current _filtered parameters saving - &optional prefix) +(defun frameset-filter-shelve-param (current _filtered parameters saving + &optional prefix) "When switching to a tty frame, save parameter P as PREFIX:P. -The parameter can be later restored with `frameset-filter-restore-param'. +The parameter can be later restored with `frameset-filter-unshelve-param'. PREFIX defaults to `GUI'. For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, -see the docstring of `frameset-filter-alist'." +see `frameset-filter-alist'." (unless prefix (setq prefix 'GUI)) (cond (saving t) ((frameset-switch-to-tty-p parameters) @@ -289,12 +548,12 @@ see the docstring of `frameset-filter-alist'." (not (assq (intern (format "%s:%s" prefix (car current))) parameters))) (t t))) -(defun frameset-filter-restore-param (current filtered parameters saving) +(defun frameset-filter-unshelve-param (current filtered parameters saving) "When switching to a GUI frame, restore PREFIX:P parameter as P. CURRENT must be of the form (PREFIX:P . value). For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, -see the docstring of `frameset-filter-alist'." +see `frameset-filter-alist'." (or saving (not (frameset-switch-to-gui-p parameters)) (let* ((prefix:p (symbol-name (car current))) @@ -314,7 +573,7 @@ meaningless in an iconified frame, so the frame is restored in a default position. For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, -see the docstring of `frameset-filter-alist'." +see `frameset-filter-alist'." (not (and saving (eq (cdr (assq 'visibility parameters)) 'icon)))) (defun frameset-filter-params (parameters filter-alist saving) @@ -382,7 +641,7 @@ newest frame keeps the id and the old frame's is set to nil." (string= (frameset-frame-id frame) id)) ;;;###autoload -(defun frameset-locate-frame-id (id &optional frame-list) +(defun frameset-frame-with-id (id &optional frame-list) "Return the live frame with id ID, if exists; else nil. If FRAME-LIST is a list of frames, check these frames only. If nil, check all live frames." @@ -394,7 +653,7 @@ If nil, check all live frames." ;; Saving framesets -(defun frameset--process-minibuffer-frames (frame-list) +(defun frameset--record-minibuffer-relationships (frame-list) "Process FRAME-LIST and record minibuffer relationships. FRAME-LIST is a list of frames. Internal use only." ;; Record frames with their own minibuffer @@ -423,11 +682,16 @@ FRAME-LIST is a list of frames. Internal use only." (cons nil id))))))) ;;;###autoload -(cl-defun frameset-save (frame-list &key filters predicate properties) - "Return the frameset of FRAME-LIST, a list of frames. +(cl-defun frameset-save (frame-list + &key app name description + filters predicate properties) + "Return a frameset for FRAME-LIST, a list of frames. Dead frames and non-frame objects are silently removed from the list. If nil, FRAME-LIST defaults to the output of `frame-list' (all live frames). -FILTERS is an alist of parameter filters, or `frameset-filter-alist' if nil. +APP, NAME and DESCRIPTION are optional data; see the docstring of the +`frameset' defstruct for details. +FILTERS is an alist of parameter filters; if nil, the value of the variable +`frameset-filter-alist' is used instead. PREDICATE is a predicate function, which must return non-nil for frames that should be saved; if PREDICATE is nil, all frames from FRAME-LIST are saved. PROPERTIES is a user-defined property list to add to the frameset." @@ -436,16 +700,20 @@ PROPERTIES is a user-defined property list to add to the frameset." (if predicate (cl-delete-if-not predicate list) list)))) - (frameset--process-minibuffer-frames frames) - (make-frameset properties - (mapcar - (lambda (frame) - (cons - (frameset-filter-params (frame-parameters frame) - (or filters frameset-filter-alist) - t) - (window-state-get (frame-root-window frame) t))) - frames)))) + (frameset--record-minibuffer-relationships frames) + (make-frameset :app app + :name name + :description description + :properties properties + :states (mapcar + (lambda (frame) + (cons + (frameset-filter-params (frame-parameters frame) + (or filters + frameset-filter-alist) + t) + (window-state-get (frame-root-window frame) t))) + frames)))) ;; Restoring framesets @@ -534,7 +802,7 @@ NOTE: This only works for non-iconified frames." (when params (modify-frame-parameters frame params)))))) -(defun frameset--find-frame (predicate display &rest args) +(defun frameset--find-frame-if (predicate display &rest args) "Find a frame in `frameset--reuse-list' satisfying PREDICATE. Look through available frames whose display property matches DISPLAY and return the first one for which (PREDICATE frame ARGS) returns t. @@ -545,9 +813,9 @@ If PREDICATE is nil, it is always satisfied. Internal use only." (apply predicate frame args)))) frameset--reuse-list)) -(defun frameset--reuse-frame (display frame-cfg) - "Look for an existing frame to reuse. -DISPLAY is the display where the frame will be shown, and FRAME-CFG +(defun frameset--reuse-frame (display parameters) + "Return an existing frame to reuse, or nil if none found. +DISPLAY is the display where the frame will be shown, and PARAMETERS is the parameter alist of the frame being restored. Internal use only." (let ((frame nil) mini) @@ -561,19 +829,19 @@ is the parameter alist of the frame being restored. Internal use only." ;; will usually have only one frame, and should already work. (cond ((null display) ;; When the target is tty, every existing frame is reusable. - (setq frame (frameset--find-frame nil display))) - ((car (setq mini (cdr (assq 'frameset--mini frame-cfg)))) + (setq frame (frameset--find-frame-if nil display))) + ((car (setq mini (cdr (assq 'frameset--mini parameters)))) ;; If the frame has its own minibuffer, let's see whether ;; that frame has already been loaded (which can happen after ;; M-x desktop-read). - (setq frame (frameset--find-frame + (setq frame (frameset--find-frame-if (lambda (f id) (frameset-frame-id-equal-p f id)) - display (cdr (assq 'frameset--id frame-cfg)))) + display (cdr (assq 'frameset--id parameters)))) ;; If it has not been loaded, and it is not a minibuffer-only frame, ;; let's look for an existing non-minibuffer-only frame to reuse. - (unless (or frame (eq (cdr (assq 'minibuffer frame-cfg)) 'only)) - (setq frame (frameset--find-frame + (unless (or frame (eq (cdr (assq 'minibuffer parameters)) 'only)) + (setq frame (frameset--find-frame-if (lambda (f) (let ((w (frame-parameter f 'minibuffer))) (and (window-live-p w) @@ -583,39 +851,38 @@ is the parameter alist of the frame being restored. Internal use only." (mini ;; For minibufferless frames, check whether they already exist, ;; and that they are linked to the right minibuffer frame. - (setq frame (frameset--find-frame + (setq frame (frameset--find-frame-if (lambda (f id mini-id) (and (frameset-frame-id-equal-p f id) (frameset-frame-id-equal-p (window-frame (minibuffer-window f)) mini-id))) - display (cdr (assq 'frameset--id frame-cfg)) (cdr mini)))) + display (cdr (assq 'frameset--id parameters)) (cdr mini)))) (t ;; Default to just finding a frame in the same display. - (setq frame (frameset--find-frame nil display)))) + (setq frame (frameset--find-frame-if nil display)))) ;; If found, remove from the list. (when frame (setq frameset--reuse-list (delq frame frameset--reuse-list))) frame)) -(defun frameset--initial-params (frame-cfg) - "Return parameters from FRAME-CFG that should not be changed later. +(defun frameset--initial-params (parameters) + "Return a list of PARAMETERS that must be set when creating the frame. Setting position and size parameters as soon as possible helps reducing -flickering; other parameters, like `minibuffer' and `border-width', must -be set when creating the frame because they can not be changed later. -Internal use only." +flickering; other parameters, like `minibuffer' and `border-width', can +not be changed once the frame has been created. Internal use only." (cl-loop for param in '(left top with height border-width minibuffer) - collect (assq param frame-cfg))) + collect (assq param parameters))) -(defun frameset--restore-frame (frame-cfg window-cfg filters force-onscreen) +(defun frameset--restore-frame (parameters window-state filters force-onscreen) "Set up and return a frame according to its saved state. That means either reusing an existing frame or creating one anew. -FRAME-CFG is the frame's parameter alist; WINDOW-CFG is its window state. +PARAMETERS is the frame's parameter alist; WINDOW-STATE is its window state. For the meaning of FILTERS and FORCE-ONSCREEN, see `frameset-restore'. Internal use only." - (let* ((fullscreen (cdr (assq 'fullscreen frame-cfg))) - (lines (assq 'tool-bar-lines frame-cfg)) - (filtered-cfg (frameset-filter-params frame-cfg filters nil)) + (let* ((fullscreen (cdr (assq 'fullscreen parameters))) + (lines (assq 'tool-bar-lines parameters)) + (filtered-cfg (frameset-filter-params parameters filters nil)) (display (cdr (assq 'display filtered-cfg))) ;; post-filtering alt-cfg frame) @@ -673,7 +940,7 @@ Internal use only." (when lines (push lines alt-cfg)) (when alt-cfg (modify-frame-parameters frame alt-cfg)) ;; Now restore window state. - (window-state-put window-cfg (frame-root-window frame) 'safe) + (window-state-put window-state (frame-root-window frame) 'safe) frame)) (defun frameset--minibufferless-last-p (state1 state2) @@ -689,7 +956,8 @@ Internal use only." (t t)))) (defun frameset-keep-original-display-p (force-display) - "True if saved frames' displays should be honored." + "True if saved frames' displays should be honored. +For the meaning of FORCE-DISPLAY, see `frameset-restore'." (cond ((daemonp) t) ((eq system-type 'windows-nt) nil) ;; Does ns support more than one display? (t (not force-display)))) @@ -700,26 +968,35 @@ Internal use only." ;;;###autoload (cl-defun frameset-restore (frameset - &key filters reuse-frames force-display force-onscreen) + &key predicate filters reuse-frames + force-display force-onscreen) "Restore a FRAMESET into the current display(s). -FILTERS is an alist of parameter filters; defaults to `frameset-filter-alist'. +PREDICATE is a function called with two arguments, the parameter alist +and the window-state of the frame being restored, in that order (see +the docstring of the `frameset' defstruct for additional details). +If PREDICATE returns nil, the frame described by that parameter alist +and window-state is not restored. + +FILTERS is an alist of parameter filters; if nil, the value of +`frameset-filter-alist' is used instead. REUSE-FRAMES selects the policy to use to reuse frames when restoring: - t Reuse any existing frame if possible; delete leftover frames. + t Reuse existing frames if possible, and delete those not reused. nil Restore frameset in new frames and delete existing frames. :keep Restore frameset in new frames and keep the existing ones. - LIST A list of frames to reuse; only these are reused (if possible), - and any leftover ones are deleted; other frames not on this - list are left untouched. + LIST A list of frames to reuse; only these are reused (if possible). + Remaining frames in this list are deleted; other frames not + included on the list are left untouched. FORCE-DISPLAY can be: t Frames are restored in the current display. nil Frames are restored, if possible, in their original displays. :delete Frames in other displays are deleted instead of restored. - PRED A function called with one argument, the parameter alist; - it must return t, nil or `:delete', as above but affecting - only the frame that will be created from that parameter alist. + PRED A function called with two arguments, the parameter alist and + the window state (in that order). It must return t, nil or + `:delete', as above but affecting only the frame that will + be created from that parameter alist. FORCE-ONSCREEN can be: t Force onscreen only those frames that are fully offscreen. @@ -736,7 +1013,7 @@ affects existing frames, FILTERS and FORCE-DISPLAY affect the frame being restored before that happens, and FORCE-ONSCREEN affects the frame once it has been restored. -All keywords default to nil." +All keyword parameters default to nil." (cl-assert (frameset-p frameset)) @@ -751,8 +1028,8 @@ All keywords default to nil." ((pred consp) (setq frameset--reuse-list (copy-sequence reuse-frames) other-frames (cl-delete-if (lambda (frame) - (memq frame frameset--reuse-list)) - (frame-list)))) + (memq frame frameset--reuse-list)) + (frame-list)))) (_ (setq frameset--reuse-list (frame-list) other-frames nil))) @@ -761,73 +1038,74 @@ All keywords default to nil." ;; after the frames that contain their minibuffer windows. (dolist (state (sort (copy-sequence (frameset-states frameset)) #'frameset--minibufferless-last-p)) - (condition-case-unless-debug err - (pcase-let* ((`(,frame-cfg . ,window-cfg) state) - ((and d-mini `(,hasmini . ,mb-id)) - (cdr (assq 'frameset--mini frame-cfg))) - (default (and (booleanp mb-id) mb-id)) - (force-display (if (functionp force-display) - (funcall force-display frame-cfg) - force-display)) - (frame nil) (to-tty nil)) - ;; Only set target if forcing displays and the target display is different. - (cond ((frameset-keep-original-display-p force-display) - (setq frameset--target-display nil)) - ((eq (frame-parameter nil 'display) (cdr (assq 'display frame-cfg))) - (setq frameset--target-display nil)) - (t - (setq frameset--target-display (cons 'display - (frame-parameter nil 'display)) - to-tty (null (cdr frameset--target-display))))) - ;; Time to restore frames and set up their minibuffers as they were. - ;; We only skip a frame (thus deleting it) if either: - ;; - we're switching displays, and the user chose the option to delete, or - ;; - we're switching to tty, and the frame to restore is minibuffer-only. - (unless (and frameset--target-display - (or (eq force-display :delete) - (and to-tty - (eq (cdr (assq 'minibuffer frame-cfg)) 'only)))) - ;; If keeping non-reusable frames, and the frameset--id of one of them - ;; matches the id of a frame being restored (because, for example, the - ;; frameset has already been read in the same session), remove the - ;; frameset--id from the non-reusable frame, which is not useful anymore. - (when (and other-frames - (or (eq reuse-frames :keep) (consp reuse-frames))) - (let ((dup (frameset-locate-frame-id (cdr (assq 'frameset--id frame-cfg)) - other-frames))) - (when dup - (set-frame-parameter dup 'frameset--id nil)))) - ;; Restore minibuffers. Some of this stuff could be done in a filter - ;; function, but it would be messy because restoring minibuffers affects - ;; global state; it's best to do it here than add a bunch of global - ;; variables to pass info back-and-forth to/from the filter function. - (cond - ((null d-mini)) ;; No frameset--mini. Process as normal frame. - (to-tty) ;; Ignore minibuffer stuff and process as normal frame. - (hasmini ;; Frame has minibuffer (or it is minibuffer-only). - (when (eq (cdr (assq 'minibuffer frame-cfg)) 'only) - (setq frame-cfg (append '((tool-bar-lines . 0) (menu-bar-lines . 0)) - frame-cfg)))) - (t ;; Frame depends on other frame's minibuffer window. - (let* ((mb-frame (or (frameset-locate-frame-id mb-id) - (error "Minibuffer frame %S not found" mb-id))) - (mb-param (assq 'minibuffer frame-cfg)) - (mb-window (minibuffer-window mb-frame))) - (unless (and (window-live-p mb-window) - (window-minibuffer-p mb-window)) - (error "Not a minibuffer window %s" mb-window)) - (if mb-param - (setcdr mb-param mb-window) - (push (cons 'minibuffer mb-window) frame-cfg))))) - ;; OK, we're ready at last to create (or reuse) a frame and - ;; restore the window config. - (setq frame (frameset--restore-frame frame-cfg window-cfg - (or filters frameset-filter-alist) - force-onscreen)) - ;; Set default-minibuffer if required. - (when default (setq default-minibuffer-frame frame)))) - (error - (delay-warning 'frameset (error-message-string err) :error)))) + (pcase-let ((`(,frame-cfg . ,window-cfg) state)) + (when (or (null predicate) (funcall predicate frame-cfg window-cfg)) + (condition-case-unless-debug err + (let* ((d-mini (cdr (assq 'frameset--mini frame-cfg))) + (mb-id (cdr d-mini)) + (default (and (booleanp mb-id) mb-id)) + (force-display (if (functionp force-display) + (funcall force-display frame-cfg window-cfg) + force-display)) + frame to-tty) + ;; Only set target if forcing displays and the target display is different. + (cond ((frameset-keep-original-display-p force-display) + (setq frameset--target-display nil)) + ((eq (frame-parameter nil 'display) (cdr (assq 'display frame-cfg))) + (setq frameset--target-display nil)) + (t + (setq frameset--target-display (cons 'display + (frame-parameter nil 'display)) + to-tty (null (cdr frameset--target-display))))) + ;; Time to restore frames and set up their minibuffers as they were. + ;; We only skip a frame (thus deleting it) if either: + ;; - we're switching displays, and the user chose the option to delete, or + ;; - we're switching to tty, and the frame to restore is minibuffer-only. + (unless (and frameset--target-display + (or (eq force-display :delete) + (and to-tty + (eq (cdr (assq 'minibuffer frame-cfg)) 'only)))) + ;; If keeping non-reusable frames, and the frameset--id of one of them + ;; matches the id of a frame being restored (because, for example, the + ;; frameset has already been read in the same session), remove the + ;; frameset--id from the non-reusable frame, which is not useful anymore. + (when (and other-frames + (or (eq reuse-frames :keep) (consp reuse-frames))) + (let ((dup (frameset-frame-with-id (cdr (assq 'frameset--id frame-cfg)) + other-frames))) + (when dup + (set-frame-parameter dup 'frameset--id nil)))) + ;; Restore minibuffers. Some of this stuff could be done in a filter + ;; function, but it would be messy because restoring minibuffers affects + ;; global state; it's best to do it here than add a bunch of global + ;; variables to pass info back-and-forth to/from the filter function. + (cond + ((null d-mini)) ;; No frameset--mini. Process as normal frame. + (to-tty) ;; Ignore minibuffer stuff and process as normal frame. + ((car d-mini) ;; Frame has minibuffer (or it is minibuffer-only). + (when (eq (cdr (assq 'minibuffer frame-cfg)) 'only) + (setq frame-cfg (append '((tool-bar-lines . 0) (menu-bar-lines . 0)) + frame-cfg)))) + (t ;; Frame depends on other frame's minibuffer window. + (let* ((mb-frame (or (frameset-frame-with-id mb-id) + (error "Minibuffer frame %S not found" mb-id))) + (mb-param (assq 'minibuffer frame-cfg)) + (mb-window (minibuffer-window mb-frame))) + (unless (and (window-live-p mb-window) + (window-minibuffer-p mb-window)) + (error "Not a minibuffer window %s" mb-window)) + (if mb-param + (setcdr mb-param mb-window) + (push (cons 'minibuffer mb-window) frame-cfg))))) + ;; OK, we're ready at last to create (or reuse) a frame and + ;; restore the window config. + (setq frame (frameset--restore-frame frame-cfg window-cfg + (or filters frameset-filter-alist) + force-onscreen)) + ;; Set default-minibuffer if required. + (when default (setq default-minibuffer-frame frame)))) + (error + (delay-warning 'frameset (error-message-string err) :error)))))) ;; In case we try to delete the initial frame, we want to make sure that ;; other frames are already visible (discussed in thread for bug#14841). @@ -845,7 +1123,8 @@ All keywords default to nil." (delete-frame frame) (error (delay-warning 'frameset (error-message-string err)))))) - (setq frameset--reuse-list nil) + (setq frameset--reuse-list nil + frameset--target-display nil) ;; Make sure there's at least one visible frame. (unless (or (daemonp) (visible-frame-list)) From 2805a6512b464d65d8d8b00a126cde61a08cc291 Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Thu, 8 Aug 2013 02:44:22 +0200 Subject: [PATCH 071/449] * lisp/bindings.el (ctl-x-r-map): Bind ?f to frameset-to-register. * lisp/register.el: Add support for framesets. (frameset-frame-id, frameset-frame-with-id) (frameset-p, frameset-restore, frameset-save): Declare. (register-alist): Document framesets. (frameset-session-filter-alist): Declare. (frameset-to-register): New function. (jump-to-register): Implement jumping to framesets. Doc fix. (describe-register-1): Describe framesets. --- lisp/ChangeLog | 12 ++++++++++++ lisp/bindings.el | 2 +- lisp/register.el | 45 +++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 93c10d858e7..9f492ae0ac4 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,15 @@ +2013-08-08 Juanma Barranquero + + * register.el (frameset-frame-id, frameset-frame-with-id) + (frameset-p, frameset-restore, frameset-save): Declare. + (register-alist): Document framesets. + (frameset-session-filter-alist): Declare. + (frameset-to-register): New function. + (jump-to-register): Implement jumping to framesets. Doc fix. + (describe-register-1): Describe framesets. + + * bindings.el (ctl-x-r-map): Bind ?f to frameset-to-register. + 2013-08-07 Juanma Barranquero * desktop.el (desktop-save-frameset): Use new frameset-save args. diff --git a/lisp/bindings.el b/lisp/bindings.el index 005e43b3059..2ea6713216d 100644 --- a/lisp/bindings.el +++ b/lisp/bindings.el @@ -1220,7 +1220,7 @@ if `inhibit-field-text-motion' is non-nil." (define-key map "n" 'number-to-register) (define-key map "+" 'increment-register) (define-key map "w" 'window-configuration-to-register) - (define-key map "f" 'frame-configuration-to-register) + (define-key map "f" 'frameset-to-register) map) "Keymap for subcommands of C-x r.") (define-key ctl-x-map "r" ctl-x-r-map) diff --git a/lisp/register.el b/lisp/register.el index 4876c614642..84305f71d03 100644 --- a/lisp/register.el +++ b/lisp/register.el @@ -31,6 +31,12 @@ (eval-when-compile (require 'cl-lib)) +(declare-function frameset-frame-id "frameset" (frame)) +(declare-function frameset-frame-with-id "frameset" (id &optional frame-list)) +(declare-function frameset-p "frameset" (frameset)) +(declare-function frameset-restore "frameset" (frameset &rest keys) t) +(declare-function frameset-save "frameset" (frame-list &rest keys) t) + ;;; Code: (cl-defstruct @@ -71,7 +77,9 @@ A list of the form (file-query FILE-NAME POSITION) represents A list of the form (WINDOW-CONFIGURATION POSITION) represents a saved window configuration plus a saved value of point. A list of the form (FRAME-CONFIGURATION POSITION) - represents a saved frame configuration plus a saved value of point.") + represents a saved frame configuration plus a saved value of point. +A list of the form (FRAMESET FRAME-ID POSITION) + represents a saved frameset plus the value of point in frame FRAME-ID.") (defgroup register nil "Register commands." @@ -132,16 +140,32 @@ Argument is a character, naming the register." ;; of point in the current buffer, so record that separately. (set-register register (list (current-frame-configuration) (point-marker)))) +(defvar frameset-session-filter-alist) + +(defun frameset-to-register (register &optional _arg) + "Store the current frameset in register REGISTER. +Use \\[jump-to-register] to restore the frameset. +Argument is a character, naming the register." + (interactive "cFrameset to register: \nP") + (set-register register + (list (frameset-save nil + :app 'register + :filters frameset-session-filter-alist) + ;; frameset-save does not include the value of point + ;; in the current buffer, so record that separately. + (frameset-frame-id nil) + (point-marker)))) + (defalias 'register-to-point 'jump-to-register) (defun jump-to-register (register &optional delete) "Move point to location stored in a register. If the register contains a file name, find that file. \(To put a file name in a register, you must use `set-register'.) -If the register contains a window configuration (one frame) or a frame -configuration (all frames), restore that frame or all frames accordingly. +If the register contains a window configuration (one frame) or a frameset +\(all frames), restore that frame or all frames accordingly. First argument is a character, naming the register. Optional second arg non-nil (interactively, prefix argument) says to -delete any existing frames that the frame configuration doesn't mention. +delete any existing frames that the frameset doesn't mention. \(Otherwise, these frames are iconified.)" (interactive "cJump to register: \nP") (let ((val (get-register register))) @@ -157,6 +181,16 @@ delete any existing frames that the frame configuration doesn't mention. ((and (consp val) (window-configuration-p (car val))) (set-window-configuration (car val)) (goto-char (cadr val))) + ((and (consp val) (frameset-p (car val))) + (let ((iconify-list (if delete nil (frame-list))) + frame) + (frameset-restore (car val) + :filters frameset-session-filter-alist + :reuse-frames (if delete t :keep)) + (mapc #'iconify-frame iconify-list) + (when (setq frame (frameset-frame-with-id (cadr val))) + (select-frame-set-input-focus frame) + (goto-char (nth 2 val))))) ((markerp val) (or (marker-buffer val) (error "That register's buffer no longer exists")) @@ -269,6 +303,9 @@ The Lisp value REGISTER is a character." ((and (consp val) (frame-configuration-p (car val))) (princ "a frame configuration.")) + ((and (consp val) (frameset-p (car val))) + (princ "a frameset.")) + ((and (consp val) (eq (car val) 'file)) (princ "the file ") (prin1 (cdr val)) From 6585d561aa30fa91135cbd4c145906abd4d66a51 Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Thu, 8 Aug 2013 02:46:48 +0200 Subject: [PATCH 072/449] etc/NEWS: Document new keybinding of `C-x r f' to frameset-to-register. --- etc/ChangeLog | 4 ++++ etc/NEWS | 9 +++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/etc/ChangeLog b/etc/ChangeLog index 85a04f87f57..1de3abd549c 100644 --- a/etc/ChangeLog +++ b/etc/ChangeLog @@ -1,3 +1,7 @@ +2013-08-08 Juanma Barranquero + + * NEWS: Document new keybinding of `C-x r f' to frameset-to-register. + 2013-08-06 Dmitry Antipov * NEWS: Mention `cache-long-scans'. diff --git a/etc/NEWS b/etc/NEWS index 4758a4da31f..11b675add1d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -131,6 +131,11 @@ You can change the default by customizing the variable blink-cursor-blinks. Also timers for blinking are stopped when no blinking is done, so Emacs does not consume CPU cycles. +** New command `frameset-to-register' is now bound to `C-x r f', replacing +`frame-configuration-to-register'. It offers similar functionality, plus +some enhancements, like the ability to restore deleted frames. Command +`frame-configuration-to-register' is still available, but unbound. + * Editing Changes in Emacs 24.4 @@ -284,9 +289,9 @@ on the given date. auto-saves of the desktop. *** `desktop-restore-frames', enabled by default, allows saving and -restoring the window/frame configuration. Additional options +restoring the frame/window configuration (frameset). Additional options `desktop-restore-in-current-display', `desktop-restore-reuses-frames' -and `desktop-restore-forces-onscreen' allow further customization. +and `desktop-restore-forces-onscreen' offer further customization. ** Dired From 3677ffeb2844f86cb0aa2852a1cb495c49ff9f81 Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Thu, 8 Aug 2013 03:19:11 +0200 Subject: [PATCH 073/449] lisp/frameset.el (frameset-restore): Doc fix. --- lisp/ChangeLog | 2 ++ lisp/frameset.el | 18 +++++++++--------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 9f492ae0ac4..1ce417a5de6 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,7 @@ 2013-08-08 Juanma Barranquero + * frameset.el (frameset-restore): Doc fix. + * register.el (frameset-frame-id, frameset-frame-with-id) (frameset-p, frameset-restore, frameset-save): Declare. (register-alist): Document framesets. diff --git a/lisp/frameset.el b/lisp/frameset.el index ad58a17c840..88fb2634b9d 100644 --- a/lisp/frameset.el +++ b/lisp/frameset.el @@ -55,21 +55,21 @@ It contains the following slots, which can be accessed with of the frameset struct. Currently its value is 1. timestamp A read-only timestamp, the output of `current-time'. app A symbol, or a list whose first element is a symbol, which - identifies the creator of the frameset and related info; - for example, desktop.el sets this slot to a list - `(desktop . ,desktop-file-version). + identifies the creator of the frameset and related info; + for example, desktop.el sets this slot to a list + `(desktop . ,desktop-file-version). name A string, the name of the frameset instance. description A string, a description for user consumption (to show in - menus, messages, etc). + menus, messages, etc). properties A property list, to store both frameset-specific and user-defined serializable data. states A list of items (FRAME-PARAMETERS . WINDOW-STATE), in no particular order. Each item represents a frame to be restored. FRAME-PARAMETERS is a frame's parameter alist, extracted with (frame-parameters FRAME) and filtered - through `frameset-filter-params'. + through `frameset-filter-params'. WINDOW-STATE is the output of `window-state-get' applied - to the root window of the frame. + to the root window of the frame. To avoid collisions, it is recommended that applications wanting to add private serializable data to `properties' either store all info under a @@ -969,7 +969,7 @@ For the meaning of FORCE-DISPLAY, see `frameset-restore'." ;;;###autoload (cl-defun frameset-restore (frameset &key predicate filters reuse-frames - force-display force-onscreen) + force-display force-onscreen) "Restore a FRAMESET into the current display(s). PREDICATE is a function called with two arguments, the parameter alist @@ -1009,8 +1009,8 @@ FORCE-ONSCREEN can be: It must return non-nil to force the frame onscreen, nil otherwise. Note the timing and scope of the operations described above: REUSE-FRAMES -affects existing frames, FILTERS and FORCE-DISPLAY affect the frame being -restored before that happens, and FORCE-ONSCREEN affects the frame once +affects existing frames; PREDICATE, FILTERS and FORCE-DISPLAY affect the frame +being restored before that happens; and FORCE-ONSCREEN affects the frame once it has been restored. All keyword parameters default to nil." From c735544cede2fa856d62addf7e71efe39142132c Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Wed, 7 Aug 2013 21:37:47 -0400 Subject: [PATCH 074/449] * lisp/emacs-lisp/bytecomp.el (byte-compile-function-warn): New function, extracted from byte-compile-callargs-warn and byte-compile-normal-call. (byte-compile-callargs-warn, byte-compile-function-form): Use it. (byte-compile-normal-call): Remove obsolescence check. --- lisp/ChangeLog | 7 +++++ lisp/emacs-lisp/bytecomp.el | 55 ++++++++++++++----------------------- 2 files changed, 27 insertions(+), 35 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 1ce417a5de6..6b3bdfa49b5 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,10 @@ +2013-08-08 Stefan Monnier + + * emacs-lisp/bytecomp.el (byte-compile-function-warn): New function, + extracted from byte-compile-callargs-warn and byte-compile-normal-call. + (byte-compile-callargs-warn, byte-compile-function-form): Use it. + (byte-compile-normal-call): Remove obsolescence check. + 2013-08-08 Juanma Barranquero * frameset.el (frameset-restore): Doc fix. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index ce377dc5caf..5baef042757 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -1224,6 +1224,24 @@ Each function's symbol gets added to `byte-compile-noruntime-functions'." (format "%d" (car signature))) (t (format "%d-%d" (car signature) (cdr signature))))) +(defun byte-compile-function-warn (f nargs def) + (when (get f 'byte-obsolete-info) + (byte-compile-warn-obsolete f)) + + ;; Check to see if the function will be available at runtime + ;; and/or remember its arity if it's unknown. + (or (and (or def (fboundp f)) ; might be a subr or autoload. + (not (memq f byte-compile-noruntime-functions))) + (eq f byte-compile-current-form) ; ## This doesn't work + ; with recursion. + ;; It's a currently-undefined function. + ;; Remember number of args in call. + (let ((cons (assq f byte-compile-unresolved-functions))) + (if cons + (or (memq nargs (cdr cons)) + (push nargs (cdr cons))) + (push (list f nargs) + byte-compile-unresolved-functions))))) ;; Warn if the form is calling a function with the wrong number of arguments. (defun byte-compile-callargs-warn (form) @@ -1261,21 +1279,7 @@ Each function's symbol gets added to `byte-compile-noruntime-functions'." "accepts only") (byte-compile-arglist-signature-string sig)))) (byte-compile-format-warn form) - ;; Check to see if the function will be available at runtime - ;; and/or remember its arity if it's unknown. - (or (and (or def (fboundp (car form))) ; might be a subr or autoload. - (not (memq (car form) byte-compile-noruntime-functions))) - (eq (car form) byte-compile-current-form) ; ## This doesn't work - ; with recursion. - ;; It's a currently-undefined function. - ;; Remember number of args in call. - (let ((cons (assq (car form) byte-compile-unresolved-functions)) - (n (length (cdr form)))) - (if cons - (or (memq n (cdr cons)) - (push n (cdr cons))) - (push (list (car form) n) - byte-compile-unresolved-functions)))))) + (byte-compile-function-warn (car form) (length (cdr form)) def))) (defun byte-compile-format-warn (form) "Warn if FORM is `format'-like with inconsistent args. @@ -2960,8 +2964,6 @@ That command is designed for interactive use only" fn)) '(custom-declare-group custom-declare-variable custom-declare-face)) (byte-compile-nogroup-warn form)) - (when (get (car form) 'byte-obsolete-info) - (byte-compile-warn-obsolete (car form))) (byte-compile-callargs-warn form)) (if byte-compile-generate-call-tree (byte-compile-annotate-call-tree form)) @@ -3573,24 +3575,7 @@ discarding." (let ((f (nth 1 form))) (when (and (symbolp f) (byte-compile-warning-enabled-p 'callargs)) - (when (get f 'byte-obsolete-info) - (byte-compile-warn-obsolete (car form))) - - ;; Check to see if the function will be available at runtime - ;; and/or remember its arity if it's unknown. - (or (and (or (fboundp f) ; Might be a subr or autoload. - (byte-compile-fdefinition (car form) nil)) - (not (memq f byte-compile-noruntime-functions))) - (eq f byte-compile-current-form) ; ## This doesn't work - ; with recursion. - ;; It's a currently-undefined function. - ;; Remember number of args in call. - (let ((cons (assq f byte-compile-unresolved-functions))) - (if cons - (or (memq t (cdr cons)) - (push t (cdr cons))) - (push (list f t) - byte-compile-unresolved-functions))))) + (byte-compile-function-warn f t (byte-compile-fdefinition f nil))) (byte-compile-constant (if (eq 'lambda (car-safe f)) (byte-compile-lambda f) From bd0c3c0b12b33988cf649f09d861b359387726cb Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Thu, 8 Aug 2013 05:54:41 +0200 Subject: [PATCH 075/449] lisp/frameset.el (frameset-p, frameset-prop): Doc fixes. --- lisp/ChangeLog | 4 ++++ lisp/frameset.el | 5 ++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 6b3bdfa49b5..5968298904e 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,7 @@ +2013-08-08 Juanma Barranquero + + * frameset.el (frameset-p, frameset-prop): Doc fixes. + 2013-08-08 Stefan Monnier * emacs-lisp/bytecomp.el (byte-compile-function-warn): New function, diff --git a/lisp/frameset.el b/lisp/frameset.el index 88fb2634b9d..43f0e929c6c 100644 --- a/lisp/frameset.el +++ b/lisp/frameset.el @@ -104,8 +104,7 @@ FRAMESET is copied with `copy-tree'." ;;;###autoload (defun frameset-p (object) - "If OBJECT is a frameset, return its version number. -Else return nil." + "Return non-nil if OBJECT is a frameset, nil otherwise." (and (vectorp object) ; a vector (eq (aref object 0) 'frameset) ; tagged as `frameset' (integerp (aref object 1)) ; version is an int @@ -122,7 +121,7 @@ Else return nil." Properties can be set with - (setf (frameset-prop FRAMESET PROP) NEW-VALUE)" + (setf (frameset-prop FRAMESET PROPERTY) NEW-VALUE)" (plist-get (frameset-properties frameset) property)) (gv-define-setter frameset-prop (val fs prop) From 628fdc567a63c5cc6959ca5a4e09eb9b1d3e6092 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Thu, 8 Aug 2013 08:42:40 +0400 Subject: [PATCH 076/449] Do not reset window modification event counters excessively. These leftovers and poor man's tricky methods to catch extra redisplay's attention are no longer needed. * frame.c (set_menu_bar_lines_1): * minibuf.c (read_minibuf_unwind): * window.c (Fset_window_start, set_window_buffer, window_resize_apply) (grow_mini_window, shrink_mini_window, window_scroll_pixel_based) (window_scroll_line_based, Fset_window_configuration): * xdisp.c (redisplay_window): Do not reset last_modified and last_overlay_modified counters. --- src/ChangeLog | 13 +++++++++++++ src/frame.c | 1 - src/minibuf.c | 4 +--- src/window.c | 27 +++------------------------ src/xdisp.c | 5 ----- 5 files changed, 17 insertions(+), 33 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index ead50fa0517..6cb69f776f1 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +2013-08-08 Dmitry Antipov + + Do not reset window modification event counters excessively. + These leftovers and poor man's tricky methods to catch extra + redisplay's attention are no longer needed. + * frame.c (set_menu_bar_lines_1): + * minibuf.c (read_minibuf_unwind): + * window.c (Fset_window_start, set_window_buffer, window_resize_apply) + (grow_mini_window, shrink_mini_window, window_scroll_pixel_based) + (window_scroll_line_based, Fset_window_configuration): + * xdisp.c (redisplay_window): Do not reset last_modified and + last_overlay_modified counters. + 2013-08-07 Jan Djärv * xselect.c (x_send_client_event): Set send_event and serial, memset diff --git a/src/frame.c b/src/frame.c index 813c97ffe3e..853ec441343 100644 --- a/src/frame.c +++ b/src/frame.c @@ -185,7 +185,6 @@ set_menu_bar_lines_1 (Lisp_Object window, int n) { struct window *w = XWINDOW (window); - w->last_modified = 0; w->top_line += n; w->total_lines -= n; diff --git a/src/minibuf.c b/src/minibuf.c index b3648b8c1ae..7403fc6c32d 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -870,10 +870,8 @@ read_minibuf_unwind (void) if (minibuf_level == 0) resize_mini_window (XWINDOW (window), 0); - /* Make sure minibuffer window is erased, not ignored. */ + /* Enforce full redisplay. FIXME: make it more selective. */ windows_or_buffers_changed++; - XWINDOW (window)->last_modified = 0; - XWINDOW (window)->last_overlay_modified = 0; /* In case the previous minibuffer displayed in this miniwindow is dead, we may keep displaying this buffer (tho it's inactive), so reset it, diff --git a/src/window.c b/src/window.c index 118c5852275..8a514d64954 100644 --- a/src/window.c +++ b/src/window.c @@ -1614,9 +1614,8 @@ overriding motion of point in order to display at this exact start. */) if (NILP (noforce)) w->force_start = 1; w->update_mode_line = 1; - w->last_modified = 0; - w->last_overlay_modified = 0; if (!EQ (window, selected_window)) + /* Enforce full redisplay. FIXME: make it more selective. */ windows_or_buffers_changed++; return pos; @@ -3215,8 +3214,6 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, buffer); w->start_at_line_beg = 0; w->force_start = 0; - w->last_modified = 0; - w->last_overlay_modified = 0; } /* Maybe we could move this into the `if' but it's not obviously safe and I doubt it's worth the trouble. */ @@ -3677,10 +3674,6 @@ window_resize_apply (struct window *w, bool horflag) c = NILP (c->next) ? 0 : XWINDOW (c->next); } } - - /* Clear out some redisplay caches. */ - w->last_modified = 0; - w->last_overlay_modified = 0; } @@ -4199,9 +4192,7 @@ grow_mini_window (struct window *w, int delta) /* Grow the mini-window. */ w->top_line = r->top_line + r->total_lines; w->total_lines -= XINT (value); - w->last_modified = 0; - w->last_overlay_modified = 0; - + /* Enforce full redisplay. FIXME: make it more selective. */ windows_or_buffers_changed++; adjust_glyphs (f); unblock_input (); @@ -4235,10 +4226,7 @@ shrink_mini_window (struct window *w) /* Shrink the mini-window. */ w->top_line = r->top_line + r->total_lines; w->total_lines = 1; - - w->last_modified = 0; - w->last_overlay_modified = 0; - + /* Enforce full redisplay. FIXME: make it more selective. */ windows_or_buffers_changed++; adjust_glyphs (f); unblock_input (); @@ -4464,8 +4452,6 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror) w->contents); w->start_at_line_beg = 1; w->update_mode_line = 1; - w->last_modified = 0; - w->last_overlay_modified = 0; /* Set force_start so that redisplay_window will run the window-scroll-functions. */ w->force_start = 1; @@ -4610,8 +4596,6 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror) bytepos = marker_byte_position (w->start); w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n'); w->update_mode_line = 1; - w->last_modified = 0; - w->last_overlay_modified = 0; /* Set force_start so that redisplay_window will run the window-scroll-functions. */ w->force_start = 1; @@ -4810,8 +4794,6 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror) set_marker_restricted_both (w->start, w->contents, pos, pos_byte); w->start_at_line_beg = !NILP (bolp); w->update_mode_line = 1; - w->last_modified = 0; - w->last_overlay_modified = 0; /* Set force_start so that redisplay_window will run the window-scroll-functions. */ w->force_start = 1; @@ -5743,9 +5725,6 @@ the return value is nil. Otherwise the value is t. */) } } - w->last_modified = 0; - w->last_overlay_modified = 0; - if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer))) /* If saved buffer is alive, install it. */ { diff --git a/src/xdisp.c b/src/xdisp.c index 102eafbba49..d2dae3406d1 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -15555,8 +15555,6 @@ redisplay_window (Lisp_Object window, int just_this_one_p) startp = run_window_scroll_functions (window, startp); } - w->last_modified = 0; - w->last_overlay_modified = 0; if (CHARPOS (startp) < BEGV) SET_TEXT_POS (startp, BEGV, BEGV_BYTE); else if (CHARPOS (startp) > ZV) @@ -15802,9 +15800,6 @@ redisplay_window (Lisp_Object window, int just_this_one_p) try_to_scroll: - w->last_modified = 0; - w->last_overlay_modified = 0; - /* Redisplay the mode line. Select the buffer properly for that. */ if (!update_mode_line) { From 76c5e5ab36d7f05f34c1bcca4b3ec6d1fcbfce86 Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Thu, 8 Aug 2013 11:54:29 +0200 Subject: [PATCH 077/449] lisp/frameset.el: Revert to built-in frameset-p; document slot accessors. (frameset): Do not disable creation of the default frameset-p predicate. Doc fix. (frameset-valid-p): New function, copied from the old predicate-p. Add additional checks. (frameset-restore): Check with frameset-valid-p. (frameset-p, frameset-version, frameset-timestamp, frameset-app) (frameset-name, frameset-description, frameset-properties) (frameset-states): Add docstring. --- lisp/ChangeLog | 11 +++ lisp/frameset.el | 172 +++++++++++++++++++++++++++++------------------ 2 files changed, 116 insertions(+), 67 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 5968298904e..b7964fa4517 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,14 @@ +2013-08-08 Juanma Barranquero + + * frameset.el (frameset): Do not disable creation of the default + frameset-p predicate. Doc fix. + (frameset-valid-p): New function, copied from the old predicate-p. + Add additional checks. + (frameset-restore): Check with frameset-valid-p. + (frameset-p, frameset-version, frameset-timestamp, frameset-app) + (frameset-name, frameset-description, frameset-properties) + (frameset-states): Add docstring. + 2013-08-08 Juanma Barranquero * frameset.el (frameset-p, frameset-prop): Doc fixes. diff --git a/lisp/frameset.el b/lisp/frameset.el index 43f0e929c6c..52d01c70d64 100644 --- a/lisp/frameset.el +++ b/lisp/frameset.el @@ -42,9 +42,8 @@ (cl-defstruct (frameset (:type vector) :named - ;; Copier and predicate functions are defined below. - (:copier nil) - (:predicate nil)) + ;; Copier is defined below. + (:copier nil)) "A frameset encapsulates a serializable view of a set of frames and windows. @@ -81,9 +80,8 @@ A frameset is intended to be used through the following simple API: live frames, and returns a serializable snapshot of them (a frameset). - `frameset-restore' takes a frameset, and restores the frames and windows it describes, as faithfully as possible. - - `frameset-p' is the predicate for the frameset type. It returns nil - for non-frameset objects, and the frameset version number (see below) - for frameset objects. + - `frameset-p' is the predicate for the frameset type. + - `frameset-valid-p' checks a frameset's validity. - `frameset-copy' returns a deep copy of a frameset. - `frameset-prop' is a `setf'able accessor for the contents of the `properties' slot. @@ -97,23 +95,63 @@ A frameset is intended to be used through the following simple API: (properties nil) (states nil)) +;; Add nicer docstrings for built-in predicate and accessors. +(put 'frameset-p 'function-documentation + "Return non-nil if OBJECT is a frameset, nil otherwise.\n\n(fn OBJECT)") +(put 'frameset-version 'function-documentation + "Return the version number of FRAMESET.\n +It is an integer that identifies the format of the frameset struct. +This slot cannot be modified.\n\n(fn FRAMESET)") +(put 'frameset-timestamp 'function-documentation + "Return the creation timestamp of FRAMESET.\n +The value is in the format returned by `current-time'. +This slot cannot be modified.\n\n(fn FRAMESET)") +(put 'frameset-app 'function-documentation + "Return the application identifier for FRAMESET.\n +The value is either a symbol, like `my-app', or a list +\(my-app ADDITIONAL-DATA...).\n\n(fn FRAMESET)") +(put 'frameset-name 'function-documentation + "Return the name of FRAMESET (a string).\n\n(fn FRAMESET)") +(put 'frameset-description 'function-documentation + "Return the description of FRAMESET (a string).\n\n(fn FRAMESET)") +(put 'frameset-properties 'function-documentation + "Return the property list of FRAMESET.\n +This list is useful to store both frameset-specific and user-defined +serializable data. The simplest way to access and modify it is +through `frameset-prop' (which see).\n\n(fn FRAMESET)") +(put 'frameset-states 'function-documentation + "Return the list of frame states of FRAMESET.\n +A frame state is a pair (FRAME-PARAMETERS . WINDOW-STATE), where +FRAME-PARAMETERS is a frame's parameter alist, extracted with +\(frame-parameters FRAME) and filtered through `frameset-filter-params', +and WINDOW-STATE is the output of `window-state-get' applied to the +root window of the frame.\n +IMPORTANT: Modifying this slot may cause frameset functions to fail, +unless the type constraints defined above are respected.\n\n(fn FRAMESET)") + (defun frameset-copy (frameset) "Return a deep copy of FRAMESET. FRAMESET is copied with `copy-tree'." (copy-tree frameset t)) ;;;###autoload -(defun frameset-p (object) - "Return non-nil if OBJECT is a frameset, nil otherwise." +(defun frameset-valid-p (object) + "Return non-nil if OBJECT is a valid frameset, nil otherwise." (and (vectorp object) ; a vector (eq (aref object 0) 'frameset) ; tagged as `frameset' - (integerp (aref object 1)) ; version is an int - (consp (aref object 2)) ; timestamp is a non-null list - (stringp (or (aref object 4) "")) ; name is a string or null - (stringp (or (aref object 5) "")) ; description is a string or null - (listp (aref object 6)) ; properties is a list - (consp (aref object 7)) ; and states is non-null - (aref object 1))) ; return version + (integerp (aref object 1)) ; VERSION is an int + (consp (aref object 2)) ; TIMESTAMP is a non-null list + (let ((app (aref object 3))) + (or (null app) ; APP is nil + (symbolp app) ; or a symbol + (and (consp app) ; or a list + (symbolp (car app))))) ; starting with a symbol + (stringp (or (aref object 4) "")) ; NAME is a string or nil + (stringp (or (aref object 5) "")) ; DESCRIPTION is a string or nil + (listp (aref object 6)) ; PROPERTIES is a list + (consp (aref object 7)) ; and STATES is non-nil + (cl-every #'consp (aref object 7)) ; and an alist + (aref object 1))) ; return VERSION ;; A setf'able accessor to the frameset's properties (defun frameset-prop (frameset property) @@ -174,14 +212,14 @@ Properties can be set with ;; what `frameset-filter-params' and the `frameset-*-filter-alist' variables ;; are for. ;; -;; First, a clarification: the word "filter" in these names refers to both +;; First, a clarification. The word "filter" in these names refers to both ;; common meanings of filter: to filter out (i.e., to remove), and to pass ;; through a transformation function (think `filter-buffer-substring'). ;; ;; `frameset-filter-params' takes a parameter alist PARAMETERS, a filtering ;; alist FILTER-ALIST, and a flag SAVING to indicate whether we are filtering ;; parameters with the intent of saving a frame or restoring it. It then -;; accumulates an output list, FILTERED, by checking each parameter in +;; accumulates an output alist, FILTERED, by checking each parameter in ;; PARAMETERS against FILTER-ALIST and obeying any rule found there. The ;; absence of a rule just means the parameter/value pair (called CURRENT in ;; filtering functions) is copied to FILTERED as is. Keyword values :save, @@ -232,7 +270,7 @@ Properties can be set with ;; a graphical display. ;; ;; - `tty', `tty-type': These are tty-specific. When switching to a GUI -;; display they do no harm, but they clutter the parameter list. +;; display they do no harm, but they clutter the parameter alist. ;; ;; - `minibuffer': It can contain a reference to a live window, which cannot ;; be serialized. Because of Emacs' idiosyncratic treatment of this @@ -249,7 +287,7 @@ Properties can be set with ;; surely there are applications that will want to override this filter. ;; ;; - `font', `fullscreen', `height' and `width': These parameters suffer -;; from the fact that they are badly manged when going through a +;; from the fact that they are badly mangled when going through a ;; tty session, though not all in the same way. When saving a GUI frame ;; and restoring it in a tty, the height and width of the new frame are ;; those of the tty screen (let's say 80x25, for example); going back @@ -389,35 +427,35 @@ Properties can be set with ;;;###autoload (defvar frameset-session-filter-alist - '((name . :never) + '((name . :never) (left . frameset-filter-iconified) - (minibuffer . frameset-filter-minibuffer) - (top . frameset-filter-iconified)) + (minibuffer . frameset-filter-minibuffer) + (top . frameset-filter-iconified)) "Minimum set of parameters to filter for live (on-session) framesets. See `frameset-filter-alist' for a full description.") ;;;###autoload (defvar frameset-persistent-filter-alist (nconc - '((background-color . frameset-filter-sanitize-color) - (buffer-list . :never) - (buffer-predicate . :never) + '((background-color . frameset-filter-sanitize-color) + (buffer-list . :never) + (buffer-predicate . :never) (buried-buffer-list . :never) - (font . frameset-filter-shelve-param) - (foreground-color . frameset-filter-sanitize-color) - (fullscreen . frameset-filter-shelve-param) - (GUI:font . frameset-filter-unshelve-param) - (GUI:fullscreen . frameset-filter-unshelve-param) - (GUI:height . frameset-filter-unshelve-param) - (GUI:width . frameset-filter-unshelve-param) - (height . frameset-filter-shelve-param) - (outer-window-id . :never) - (parent-id . :never) - (tty . frameset-filter-tty-to-GUI) - (tty-type . frameset-filter-tty-to-GUI) - (width . frameset-filter-shelve-param) - (window-id . :never) - (window-system . :never)) + (font . frameset-filter-shelve-param) + (foreground-color . frameset-filter-sanitize-color) + (fullscreen . frameset-filter-shelve-param) + (GUI:font . frameset-filter-unshelve-param) + (GUI:fullscreen . frameset-filter-unshelve-param) + (GUI:height . frameset-filter-unshelve-param) + (GUI:width . frameset-filter-unshelve-param) + (height . frameset-filter-shelve-param) + (outer-window-id . :never) + (parent-id . :never) + (tty . frameset-filter-tty-to-GUI) + (tty-type . frameset-filter-tty-to-GUI) + (width . frameset-filter-shelve-param) + (window-id . :never) + (window-system . :never)) frameset-session-filter-alist) "Parameters to filter for persistent framesets. See `frameset-filter-alist' for a full description.") @@ -442,9 +480,9 @@ parameter), and ACTION can be: nil The parameter is copied to FILTERED. :never The parameter is never copied to FILTERED. - :save The parameter is copied only when saving the frame. + :save The parameter is copied only when saving the frame. :restore The parameter is copied only when restoring the frame. - FILTER A filter function. + FILTER A filter function. FILTER can be a symbol FILTER-FUN, or a list (FILTER-FUN ARGS...). FILTER-FUN is invoked with @@ -457,14 +495,14 @@ where filtered and VALUE is its current value. FILTERED The resulting alist (so far). PARAMETERS The complete alist of parameters being filtered, - SAVING Non-nil if filtering before saving state, nil if filtering + SAVING Non-nil if filtering before saving state, nil if filtering before restoring it. ARGS Any additional arguments specified in the ACTION. FILTER-FUN is allowed to modify items in FILTERED, but no other arguments. It must return: - nil Skip CURRENT (do not add it to FILTERED). - t Add CURRENT to FILTERED as is. + nil Skip CURRENT (do not add it to FILTERED). + t Add CURRENT to FILTERED as is. (NEW-PARAM . NEW-VALUE) Add this to FILTERED instead of CURRENT. Frame parameters not on this alist are passed intact, as if they were @@ -485,9 +523,9 @@ Return non-nil if the parameter alist PARAMETERS describes a frame on a text-only terminal, and the frame is being restored on a graphic display; otherwise return nil. Only meaningful when called from a filtering function in `frameset-filter-alist'." - (and frameset--target-display ; we're switching - (null (cdr (assq 'display parameters))) ; from a tty - (cdr frameset--target-display))) ; to a GUI display + (and frameset--target-display ; we're switching + (null (cdr (assq 'display parameters))) ; from a tty + (cdr frameset--target-display))) ; to a GUI display (defun frameset-switch-to-tty-p (parameters) "True when switching to a text-only terminal. @@ -495,9 +533,9 @@ Return non-nil if the parameter alist PARAMETERS describes a frame on a graphic display, and the frame is being restored on a text-only terminal; otherwise return nil. Only meaningful when called from a filtering function in `frameset-filter-alist'." - (and frameset--target-display ; we're switching - (cdr (assq 'display parameters)) ; from a GUI display - (null (cdr frameset--target-display)))) ; to a tty + (and frameset--target-display ; we're switching + (cdr (assq 'display parameters)) ; from a GUI display + (null (cdr frameset--target-display)))) ; to a tty (defun frameset-filter-tty-to-GUI (_current _filtered parameters saving) "Remove CURRENT when switching from tty to a graphic display. @@ -762,14 +800,14 @@ NOTE: This only works for non-iconified frames." (list fr-left fr-top fr-width fr-height) (list left top width height))) ;; Any corner is outside the screen. - (:all (or (< fr-bottom top) (> fr-bottom bottom) + (:all (or (< fr-bottom top) (> fr-bottom bottom) (< fr-left left) (> fr-left right) (< fr-right left) (> fr-right right) - (< fr-top top) (> fr-top bottom))) + (< fr-top top) (> fr-top bottom))) ;; Displaced to the left, right, above or below the screen. - (`t (or (> fr-left right) + (`t (or (> fr-left right) (< fr-right left) - (> fr-top bottom) + (> fr-top bottom) (< fr-bottom top))) ;; Fully inside, no need to do anything. (_ nil)) @@ -981,27 +1019,27 @@ FILTERS is an alist of parameter filters; if nil, the value of `frameset-filter-alist' is used instead. REUSE-FRAMES selects the policy to use to reuse frames when restoring: - t Reuse existing frames if possible, and delete those not reused. - nil Restore frameset in new frames and delete existing frames. - :keep Restore frameset in new frames and keep the existing ones. - LIST A list of frames to reuse; only these are reused (if possible). + t Reuse existing frames if possible, and delete those not reused. + nil Restore frameset in new frames and delete existing frames. + :keep Restore frameset in new frames and keep the existing ones. + LIST A list of frames to reuse; only these are reused (if possible). Remaining frames in this list are deleted; other frames not included on the list are left untouched. FORCE-DISPLAY can be: - t Frames are restored in the current display. - nil Frames are restored, if possible, in their original displays. + t Frames are restored in the current display. + nil Frames are restored, if possible, in their original displays. :delete Frames in other displays are deleted instead of restored. - PRED A function called with two arguments, the parameter alist and + PRED A function called with two arguments, the parameter alist and the window state (in that order). It must return t, nil or `:delete', as above but affecting only the frame that will be created from that parameter alist. FORCE-ONSCREEN can be: - t Force onscreen only those frames that are fully offscreen. - nil Do not force any frame back onscreen. - :all Force onscreen any frame fully or partially offscreen. - PRED A function called with three arguments, + t Force onscreen only those frames that are fully offscreen. + nil Do not force any frame back onscreen. + :all Force onscreen any frame fully or partially offscreen. + PRED A function called with three arguments, - the live frame just restored, - a list (LEFT TOP WIDTH HEIGHT), describing the frame, - a list (LEFT TOP WIDTH HEIGHT), describing the workarea. @@ -1014,7 +1052,7 @@ it has been restored. All keyword parameters default to nil." - (cl-assert (frameset-p frameset)) + (cl-assert (frameset-valid-p frameset)) (let (other-frames) From f9dbf1cbb89b503e1d02cd5ba9052c05c0fb81ac Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Thu, 8 Aug 2013 12:44:07 +0200 Subject: [PATCH 078/449] lisp/frameset.el: Doc fixes. --- lisp/ChangeLog | 2 ++ lisp/frameset.el | 13 +++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index b7964fa4517..6f5469f4d55 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -8,6 +8,8 @@ (frameset-p, frameset-version, frameset-timestamp, frameset-app) (frameset-name, frameset-description, frameset-properties) (frameset-states): Add docstring. + (frameset-session-filter-alist, frameset-persistent-filter-alist) + (frameset-filter-alist): Doc fixes. 2013-08-08 Juanma Barranquero diff --git a/lisp/frameset.el b/lisp/frameset.el index 52d01c70d64..c3fdfa52886 100644 --- a/lisp/frameset.el +++ b/lisp/frameset.el @@ -432,7 +432,7 @@ Properties can be set with (minibuffer . frameset-filter-minibuffer) (top . frameset-filter-iconified)) "Minimum set of parameters to filter for live (on-session) framesets. -See `frameset-filter-alist' for a full description.") +DO NOT MODIFY. See `frameset-filter-alist' for a full description.") ;;;###autoload (defvar frameset-persistent-filter-alist @@ -458,7 +458,7 @@ See `frameset-filter-alist' for a full description.") (window-system . :never)) frameset-session-filter-alist) "Parameters to filter for persistent framesets. -See `frameset-filter-alist' for a full description.") +DO NOT MODIFY. See `frameset-filter-alist' for a full description.") ;;;###autoload (defvar frameset-filter-alist frameset-persistent-filter-alist @@ -467,6 +467,15 @@ See `frameset-filter-alist' for a full description.") This alist is the default value of the FILTERS argument of `frameset-save' and `frameset-restore' (which see). +Initially, `frameset-filter-alist' is set to, and shares the value of, +`frameset-persistent-filter-alist'. You can override any item in +this alist by `push'ing a new item onto it. If, for some reason, you +intend to modify existing values, do + + (setq frameset-filter-alist (copy-tree frameset-filter-alist)) + +before changing anything. + On saving, PARAMETERS is the parameter alist of each frame processed, and FILTERED is the parameter alist that gets saved to the frameset. From 03300a14a08d3eb0afc85f2e4e7b123481ac7fcf Mon Sep 17 00:00:00 2001 From: Xue Fuqiao Date: Thu, 8 Aug 2013 20:31:38 +0800 Subject: [PATCH 079/449] Add documentation for working directory in Ido. * doc/misc/ido.texi (Top): Insert node "Working Directories" in menu. (Working Directories): New node. doc/misc/sc.texi: (What Supercite Does): Typo fix. --- doc/misc/ChangeLog | 6 +++ doc/misc/ido.texi | 108 ++++++++++++++++++++++++++++++++------------- doc/misc/sc.texi | 2 +- 3 files changed, 85 insertions(+), 31 deletions(-) diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog index 4ced6e2e97b..aa8cb3fa39c 100644 --- a/doc/misc/ChangeLog +++ b/doc/misc/ChangeLog @@ -1,3 +1,8 @@ +2013-08-08 Xue Fuqiao + + * ido.texi (Top): Insert node "Working Directories" in menu. + (Working Directories): New node. + 2013-08-07 Eli Zaretskii * todo-mode.texi: Update @dircategory. @@ -21,6 +26,7 @@ (Mail Field Commands) (Hints to MUA Authors, Thanks and History): Change from one space between sentences to two. + (What Supercite Does): Typo fix. * newsticker.texi (Usage): Use @key for RET. diff --git a/doc/misc/ido.texi b/doc/misc/ido.texi index dbc35b09bb8..bf0db3f28f2 100644 --- a/doc/misc/ido.texi +++ b/doc/misc/ido.texi @@ -53,45 +53,46 @@ modify this GNU manual.'' @end ifnottex @menu -* Overview:: Basics, activation. -* Matching:: Interactivity, matching, scrolling. -* Highlighting:: Highlighting of matching items. -* Hidden Buffers and Files:: Hidden buffers, files, and directories. -* Customization:: Change the Ido functionality. -* Misc:: Various other features. +* Overview:: Basics, activation. +* Matching:: Interactivity, matching, scrolling. +* Highlighting:: Highlighting of matching items. +* Hidden Buffers and Files:: Hidden buffers, files, and directories. +* Customization:: Change the Ido functionality. +* Misc:: Various other features. Appendices -* GNU Free Documentation License:: The license for this documentation. +* GNU Free Documentation License:: The license for this documentation. Indexes -* Variable Index:: An entry for each documented variable. +* Variable Index:: An entry for each documented variable. @detailmenu --- The Detailed Node Listing --- Overview -* Activation:: How to use this package. +* Activation:: How to use this package. +* Working Directories:: Where files have most recently been opened. Matching -* Interactive Substring Matching:: Interactivity, matching, scrolling. -* Prefix Matching:: Standard completion. -* Flexible Matching:: More flexible matching. -* Regexp Matching:: Matching using regular expression. +* Interactive Substring Matching:: Interactivity, matching, scrolling. +* Prefix Matching:: Standard completion. +* Flexible Matching:: More flexible matching. +* Regexp Matching:: Matching using regular expression. Customization -* Changing List Order:: Changing the list of files. -* Find File At Point:: Make Ido guess the context. -* Ignoring:: Ignorance is bliss. -* Misc Customization:: Miscellaneous customization for Ido. +* Changing List Order:: Changing the list of files. +* Find File At Point:: Make Ido guess the context. +* Ignoring:: Ignorance is bliss. +* Misc Customization:: Miscellaneous customization for Ido. Miscellaneous -* All Matching:: Seeing all the matching buffers or files. -* Replacement:: Replacement for @code{read-buffer} and @code{read-file-name}. -* Other Packages:: Don't want to depend on @code{ido-everywhere}? +* All Matching:: Seeing all the matching buffers or files. +* Replacement:: Replacement for @code{read-buffer} and @code{read-file-name}. +* Other Packages:: Don't want to depend on @code{ido-everywhere}? @end detailmenu @end menu @@ -116,7 +117,8 @@ This package was originally written by Kim F. Storm, based on the @file{iswitchb.el} package by Stephen Eglen. @menu -* Activation:: How to use this package. +* Activation:: How to use this package. +* Working Directories:: Where files have most recently been opened. @end menu @node Activation @@ -140,9 +142,56 @@ package. (ido-mode t) @end example -@c @node Working Directories -@c @section Working Directories -@c @cindex working directories +@node Working Directories +@section Working Directories +@cindex working directories + +@vindex ido-work-directory-list +@noindent +@dfn{Working directories} are directories where files have most +recently been opened. The current directory is inserted at the front +of this @code{ido-work-directory-list} whenever a file is opened with +@code{ido-find-file} and other file-related functions. + +@c @cindex merge +@c or maybe a new node for ``merge'' + +@c @findex ido-merge-work-directories +@c @defun ido-merge-work-directories +@c @end defun + +@c @findex ido-prev-work-directory +@c @defun ido-prev-work-directory +@c @end defun + +@c @findex ido-next-work-directory +@c @defun ido-next-work-directory +@c @end defun + +@c @findex ido-forget-work-directory +@c @defun ido-forget-work-directory +@c @end defun + +@c @vindex ido-use-merged-list +@c @vindex ido-try-merged-list +@c @vindex ido-pre-merge-state + +@defvr {User Option} ido-max-work-directory-list +This user option specifies maximum number of working directories to +record. +@end defvr + +@c see (info "(elisp) File Name Completion") +@defvr {User Option} ido-max-dir-file-cache +This user option specifies maximum number of working directories to be +cached. This is the size of the cache of +@code{file-name-all-completions} results. Each cache entry is time +stamped with the modification time of the directory. Some systems, +like MS-Windows, have unreliable directory modification times, so you +may choose to disable caching on such systems, or explicitly refresh +the cache contents using the command @code{ido-reread-directory} +(usually @kbd{C-l}) in the minibuffer. +@end defvr @node Matching @chapter Matching @@ -153,10 +202,10 @@ This section describes features of this package that have to do with various kinds of @emph{matching}: among buffers, files, and directories. @menu -* Interactive Substring Matching:: Interactivity, matching, scrolling. -* Prefix Matching:: Standard completion. -* Flexible Matching:: More flexible matching. -* Regexp Matching:: Matching using regular expression. +* Interactive Substring Matching:: Interactivity, matching, scrolling. +* Prefix Matching:: Standard completion. +* Flexible Matching:: More flexible matching. +* Regexp Matching:: Matching using regular expression. @end menu @node Interactive Substring Matching @@ -521,6 +570,7 @@ to ignore. The letter case will be ignored if @code{ido-downcase-unc-hosts} is non-@code{nil}. @end defvr +@c FIXME: Where to add this variable? This node or ``working directory''? @c @defvr {User Option} ido-work-directory-list-ignore-regexps To make Ido use @code{completion-ignored-extensions} you need to @@ -571,7 +621,6 @@ if you type a dot as first char (even if @code{ido-enable-prefix} is @c @defvr {User Option} ido-max-file-prompt-width @c @defvr {User Option} ido-max-window-height @c @defvr {User Option} ido-enable-last-directory-history -@c @defvr {User Option} ido-max-work-directory-list @c @defvr {User Option} ido-enable-tramp-completion @c @defvr {User Option} ido-unc-hosts @c @defvr {User Option} ido-downcase-unc-hosts @@ -582,7 +631,6 @@ if you type a dot as first char (even if @code{ido-enable-prefix} is @c @defvr {User Option} ido-auto-merge-delay-time @c @defvr {User Option} ido-auto-merge-inhibit-characters-regexp @c @defvr {User Option} ido-merged-indicator -@c @defvr {User Option} ido-max-dir-file-cache @c @defvr {User Option} ido-max-directory-size @c @defvr {User Option} ido-rotate-file-list-default @c @defvr {User Option} ido-enter-matching-directory diff --git a/doc/misc/sc.texi b/doc/misc/sc.texi index 7d7ef07ed61..aa0752c80cd 100644 --- a/doc/misc/sc.texi +++ b/doc/misc/sc.texi @@ -186,7 +186,7 @@ string carrying details about the citation it is about to perform. @cindex modeline Next, Supercite visits each line in the reply, transforming the line -according to a customizable ``script.'' Lines which were not previously +according to a customizable ``script''. Lines which were not previously cited in the original message are given a citation, while already cited lines remain untouched, or are coerced to your preferred style. Finally, Supercite installs a keymap into the reply buffer so that you From 15938cf47495515e2df9edffc84cea1d2cbd0fe5 Mon Sep 17 00:00:00 2001 From: Xue Fuqiao Date: Thu, 8 Aug 2013 20:52:25 +0800 Subject: [PATCH 080/449] Add documentation of `ido-confirm-unique-completion'. doc/misc/ido.texi: (Misc Customization): Add documentation of `ido-confirm-unique-completion'. --- doc/misc/ChangeLog | 1 + doc/misc/ido.texi | 56 +++++++++++++++++++++------------------------- 2 files changed, 27 insertions(+), 30 deletions(-) diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog index aa8cb3fa39c..d33c4512505 100644 --- a/doc/misc/ChangeLog +++ b/doc/misc/ChangeLog @@ -2,6 +2,7 @@ * ido.texi (Top): Insert node "Working Directories" in menu. (Working Directories): New node. + (Misc Customization): Add documentation of `ido-confirm-unique-completion'. 2013-08-07 Eli Zaretskii diff --git a/doc/misc/ido.texi b/doc/misc/ido.texi index bf0db3f28f2..a31db26fc27 100644 --- a/doc/misc/ido.texi +++ b/doc/misc/ido.texi @@ -156,25 +156,17 @@ of this @code{ido-work-directory-list} whenever a file is opened with @c @cindex merge @c or maybe a new node for ``merge'' -@c @findex ido-merge-work-directories -@c @defun ido-merge-work-directories -@c @end defun +@c @deffn Command ido-merge-work-directories -@c @findex ido-prev-work-directory -@c @defun ido-prev-work-directory -@c @end defun +@c @deffn Command ido-prev-work-directory -@c @findex ido-next-work-directory -@c @defun ido-next-work-directory -@c @end defun +@c @deffn Command ido-next-work-directory -@c @findex ido-forget-work-directory -@c @defun ido-forget-work-directory -@c @end defun +@c @deffn Command ido-forget-work-directory -@c @vindex ido-use-merged-list -@c @vindex ido-try-merged-list -@c @vindex ido-pre-merge-state +@c @defvar ido-use-merged-list +@c @defvar ido-try-merged-list +@c @defvar ido-pre-merge-state @defvr {User Option} ido-max-work-directory-list This user option specifies maximum number of working directories to @@ -314,7 +306,7 @@ of the list and hit @key{RET}. To go up to the parent directory, delete any partial file name already specified (e.g. using @key{DEL}) and hit @key{DEL}. -@c @defun ido-delete-backward-updir +@c @deffn Command ido-delete-backward-updir @cindex root directory @cindex home directory @@ -344,22 +336,20 @@ If for some reason you cannot specify the proper file using @code{ido-switch-buffer}. @c @kindex C-x b -@c @findex ido-switch-buffer -@c @defun ido-switch-buffer +@c @deffn Command ido-switch-buffer @c This command switch to another buffer interactively. -@c @end defun +@c @end deffn @c @kindex C-x C-f -@c @findex ido-find-file -@c @defun ido-find-file +@c @deffn Command ido-find-file @c Edit file with name obtained via minibuffer. -@c @end defun +@c @end deffn @c @kindex C-x d @c @findex ido-dired -@c @defun ido-dired +@c @deffn Command ido-dired @c Call Dired the Ido way. -@c @end defun +@c @end deffn @node Prefix Matching @section Prefix Matching @@ -454,7 +444,7 @@ buffers or files. You can toggle display of the hidden buffers and files with @kbd{C-a} (@code{ido-toggle-ignore}). -@c @defun ido-toggle-ignore +@c @deffn Command ido-toggle-ignore @node Customization @chapter Customization @@ -603,7 +593,7 @@ buffer and file names should ignore case. @end defvr @defvr {User Option} ido-show-dot-for-dired -If the value of this user option is non-@code{nil} , always put +If the value of this user option is non-@code{nil}, always put @samp{.} as the first item in file name lists. This allows the current directory to be opened immediately with Dired @end defvr @@ -615,7 +605,13 @@ if you type a dot as first char (even if @code{ido-enable-prefix} is @code{nil}). @end defvr -@c @defvr {User Option} ido-confirm-unique-completion +@defvr {User Option} ido-confirm-unique-completion +If the value of this user option is non-@code{nil} , even a unique +completion must be confirmed. This means that @code{ido-complete} +(@key{TAB}) must always be followed by @code{ido-exit-minibuffer} +(@key{RET}) even when there is only one unique completion. +@end defvr + @c @defvr {User Option} ido-cannot-complete-command @c @defvr {User Option} ido-record-commands @c @defvr {User Option} ido-max-file-prompt-width @@ -672,8 +668,8 @@ and you find that the file you are after is not in any buffer, you can press @kbd{C-f} to immediately drop into @code{ido-find-file}. And you can switch back to buffer selection with @kbd{C-b}. -@c @defun ido-magic-forward-char -@c @defun ido-magic-backward-char +@c @deffn Command ido-magic-forward-char +@c @deffn Command ido-magic-backward-char You can also use Ido in your Emacs Lisp programs: @@ -723,7 +719,7 @@ functions @code{read-buffer} and @code{read-file-name}. To use ido for all buffer and file selections in Emacs, customize the variable @code{ido-everywhere}. -@c @defun ido-everywhere +@c @deffn Command ido-everywhere @c @defvr {User Option} ido-everywhere @node Other Packages From 9dfc8491bb0b62e1a83265f6141d4a866e96d91d Mon Sep 17 00:00:00 2001 From: Xue Fuqiao Date: Thu, 8 Aug 2013 21:53:30 +0800 Subject: [PATCH 081/449] doc/lispref/buffers.texi: Add documentation of some user options for Ido. --- doc/misc/ChangeLog | 3 ++- doc/misc/ido.texi | 32 ++++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog index d33c4512505..4134895073f 100644 --- a/doc/misc/ChangeLog +++ b/doc/misc/ChangeLog @@ -2,7 +2,8 @@ * ido.texi (Top): Insert node "Working Directories" in menu. (Working Directories): New node. - (Misc Customization): Add documentation of `ido-confirm-unique-completion'. + (Misc Customization): Add documentation of + `ido-confirm-unique-completion' and some other user options. 2013-08-07 Eli Zaretskii diff --git a/doc/misc/ido.texi b/doc/misc/ido.texi index a31db26fc27..48636a9fb92 100644 --- a/doc/misc/ido.texi +++ b/doc/misc/ido.texi @@ -582,6 +582,9 @@ the name of an ignored file, Ido will still let you open it just fine. @section Miscellaneous Customization @cindex miscellaneous customization for Ido +@c Variables described in this sections may be moved to new nodes in +@c the future. + @defvr {User Option} ido-mode This user option determines for which functional group (buffer and files) Ido behavior should be enabled. @@ -606,16 +609,37 @@ if you type a dot as first char (even if @code{ido-enable-prefix} is @end defvr @defvr {User Option} ido-confirm-unique-completion -If the value of this user option is non-@code{nil} , even a unique +If the value of this user option is non-@code{nil}, even a unique completion must be confirmed. This means that @code{ido-complete} (@key{TAB}) must always be followed by @code{ido-exit-minibuffer} (@key{RET}) even when there is only one unique completion. @end defvr -@c @defvr {User Option} ido-cannot-complete-command +@defvr {User Option} ido-cannot-complete-command +When @code{ido-complete} can't complete any more, it will run the +command specified by this user option. The most useful values are +@code{ido-completion-help}, which pops up a window with completion +alternatives, or @code{ido-next-match} or @code{ido-prev-match}, which +cycle the buffer list. +@end defvr + +@defvr {User Option} ido-max-file-prompt-width +This user option specifies the upper limit of the prompt string. If +its value is an integer, it specifies the number of characters of the +string. If its value is a floating point number, it specifies a +fraction of the frame width. +@end defvr + +@defvr {User Option} ido-max-window-height +If the value of this user option is non@code{nil}, its value will +override the variable @code{max-mini-window-height}, which is the +maximum height for resizing mini-windows (the minibuffer and the echo +area). If it's a floating point number, it specifies a fraction of +the mini-window frame's height. If it's an integer, it specifies the +number of lines. +@end defvr + @c @defvr {User Option} ido-record-commands -@c @defvr {User Option} ido-max-file-prompt-width -@c @defvr {User Option} ido-max-window-height @c @defvr {User Option} ido-enable-last-directory-history @c @defvr {User Option} ido-enable-tramp-completion @c @defvr {User Option} ido-unc-hosts From 04263d23c5890d728cc62fd64873f687adff620c Mon Sep 17 00:00:00 2001 From: Xue Fuqiao Date: Thu, 8 Aug 2013 22:03:56 +0800 Subject: [PATCH 082/449] doc/lispref/buffers.texi: Add documentation for ido-record-command(s). * lisp/ido.el (ido-record-command): Add doc string. --- doc/misc/ido.texi | 9 +++++++-- lisp/ChangeLog | 4 ++++ lisp/ido.el | 10 +++++----- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/doc/misc/ido.texi b/doc/misc/ido.texi index 48636a9fb92..e0b28e3b2cb 100644 --- a/doc/misc/ido.texi +++ b/doc/misc/ido.texi @@ -631,7 +631,7 @@ fraction of the frame width. @end defvr @defvr {User Option} ido-max-window-height -If the value of this user option is non@code{nil}, its value will +If the value of this user option is non-@code{nil}, its value will override the variable @code{max-mini-window-height}, which is the maximum height for resizing mini-windows (the minibuffer and the echo area). If it's a floating point number, it specifies a fraction of @@ -639,7 +639,12 @@ the mini-window frame's height. If it's an integer, it specifies the number of lines. @end defvr -@c @defvr {User Option} ido-record-commands +@defvr {User Option} ido-record-commands +If the value of this user option is non-@code{nil}, Ido will record +commands in the variable @code{command-history}. Note that non-Ido +equivalent is recorded. +@end defvr + @c @defvr {User Option} ido-enable-last-directory-history @c @defvr {User Option} ido-enable-tramp-completion @c @defvr {User Option} ido-unc-hosts diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 6f5469f4d55..6ab96b11327 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,7 @@ +2013-08-08 Xue Fuqiao + + * ido.el (ido-record-command): Add doc string. + 2013-08-08 Juanma Barranquero * frameset.el (frameset): Do not disable creation of the default diff --git a/lisp/ido.el b/lisp/ido.el index d3c0e0f09f7..5d017069c5e 100644 --- a/lisp/ido.el +++ b/lisp/ido.el @@ -523,8 +523,8 @@ window with completion alternatives, or `ido-next-match' or (defcustom ido-record-commands t - "Non-nil means that `ido' will record commands in command history. -Note that the non-ido equivalent command is recorded." + "Non-nil means that Ido will record commands in command history. +Note that the non-Ido equivalent command is recorded." :type 'boolean :group 'ido) @@ -1789,10 +1789,10 @@ This function also adds a hook to the minibuffer." (ido-set-current-directory (expand-file-name (or dir "~/")))) (defun ido-record-command (command arg) - ;; Add (command arg) to command-history if ido-record-commands is t - (if ido-record-commands + "Add (COMMAND ARG) to `command-history' if `ido-record-commands' is non-nil." + (if ido-record-commands ; FIXME: use `when' instead of `if'? (let ((cmd (list command arg))) - (if (or (not command-history) + (if (or (not command-history) ; FIXME: ditto (not (equal cmd (car command-history)))) (setq command-history (cons cmd command-history)))))) From 656202640dc8857da0373ba690ea193394352ddb Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Thu, 8 Aug 2013 18:51:07 +0400 Subject: [PATCH 083/449] Redesign redisplay interface to drop global variable updated_window. Always pass currently updated window as a parameter to update routines. * dispextern.h (updated_window): Remove declaration. (struct redisplay_interface): Pass window parameter to write_glyphs, insert_glyphs, clear_end_of_line, cursor_to and after_update_window_hook. (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line, x_cursor_to): Adjust prototypes. * dispnew.c (updated_window): Remove. (redraw_overlapped_rows, update_marginal_area, update_text_area) (update_window_line): Adjust to match redisplay interface changes. * nsterm.m (ns_update_window_begin, ns_update_window_end) (ns_scroll_run, ns_after_update_window_line): * w32term.c (x_update_window_begin, x_update_window_end) (x_after_update_window_line, x_scroll_run): * xterm.c (x_update_window_begin, x_update_window_end) (x_after_update_window_line, x_scroll_run): * xdisp.c (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line): Likewise. Adjust comments where appropriate. (x_cursor_to): Simplify because this is always called during window update (but install debugging check anyway). (expose_window): Check must_be_updated_p flag to see whether this function is called during window update. --- src/ChangeLog | 26 ++++++++++++++++++ src/dispextern.h | 24 +++++++--------- src/dispnew.c | 44 ++++++++++++++---------------- src/nsterm.m | 9 ++---- src/w32term.c | 22 +++++---------- src/xdisp.c | 71 +++++++++++++++++------------------------------- src/xterm.c | 23 +++++----------- 7 files changed, 98 insertions(+), 121 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 6cb69f776f1..caf7b034401 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,29 @@ +2013-08-08 Dmitry Antipov + + Redesign redisplay interface to drop global variable updated_window. + Always pass currently updated window as a parameter to update routines. + * dispextern.h (updated_window): Remove declaration. + (struct redisplay_interface): Pass window parameter to + write_glyphs, insert_glyphs, clear_end_of_line, cursor_to + and after_update_window_hook. + (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line, x_cursor_to): + Adjust prototypes. + * dispnew.c (updated_window): Remove. + (redraw_overlapped_rows, update_marginal_area, update_text_area) + (update_window_line): Adjust to match redisplay interface changes. + * nsterm.m (ns_update_window_begin, ns_update_window_end) + (ns_scroll_run, ns_after_update_window_line): + * w32term.c (x_update_window_begin, x_update_window_end) + (x_after_update_window_line, x_scroll_run): + * xterm.c (x_update_window_begin, x_update_window_end) + (x_after_update_window_line, x_scroll_run): + * xdisp.c (x_write_glyphs, x_insert_glyphs, x_clear_end_of_line): + Likewise. Adjust comments where appropriate. + (x_cursor_to): Simplify because this is always called during window + update (but install debugging check anyway). + (expose_window): Check must_be_updated_p flag to see whether this + function is called during window update. + 2013-08-08 Dmitry Antipov Do not reset window modification event counters excessively. diff --git a/src/dispextern.h b/src/dispextern.h index d747700fd66..7a4fa2ea774 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1197,11 +1197,6 @@ extern bool fonts_changed_p; extern struct glyph space_glyph; -/* Window being updated by update_window. This is non-null as long as - update_window has not finished, and null otherwise. */ - -extern struct window *updated_window; - /* Glyph row and area updated by update_window_line. */ extern struct glyph_row *updated_row; @@ -2718,12 +2713,12 @@ struct redisplay_interface /* Write or insert LEN glyphs from STRING at the nominal output position. */ - void (*write_glyphs) (struct glyph *string, int len); - void (*insert_glyphs) (struct glyph *start, int len); + void (*write_glyphs) (struct window *w, struct glyph *string, int len); + void (*insert_glyphs) (struct window *w, struct glyph *start, int len); /* Clear from nominal output position to X. X < 0 means clear to right end of display. */ - void (*clear_end_of_line) (int x); + void (*clear_end_of_line) (struct window *w, int x); /* Function to call to scroll the display as described by RUN on window W. */ @@ -2732,7 +2727,8 @@ struct redisplay_interface /* Function to call after a line in a display has been completely updated. Used to draw truncation marks and alike. DESIRED_ROW is the desired row which has been updated. */ - void (*after_update_window_line_hook) (struct glyph_row *desired_row); + void (*after_update_window_line_hook) (struct window *w, + struct glyph_row *desired_row); /* Function to call before beginning to update window W in window-based redisplay. */ @@ -2749,7 +2745,7 @@ struct redisplay_interface /* Move cursor to row/column position VPOS/HPOS, pixel coordinates Y/X. HPOS/VPOS are window-relative row and column numbers and X/Y are window-relative pixel positions. */ - void (*cursor_to) (int vpos, int hpos, int y, int x); + void (*cursor_to) (struct window *w, int vpos, int hpos, int y, int x); /* Flush the display of frame F. For X, this is XFlush. */ void (*flush_display) (struct frame *f); @@ -3182,9 +3178,9 @@ extern void x_get_glyph_overhangs (struct glyph *, struct frame *, int *, int *); extern void x_produce_glyphs (struct it *); -extern void x_write_glyphs (struct glyph *, int); -extern void x_insert_glyphs (struct glyph *, int len); -extern void x_clear_end_of_line (int); +extern void x_write_glyphs (struct window *, struct glyph *, int); +extern void x_insert_glyphs (struct window *, struct glyph *, int len); +extern void x_clear_end_of_line (struct window *, int); extern struct cursor_pos output_cursor; @@ -3200,7 +3196,7 @@ extern void display_and_set_cursor (struct window *, int, int, int, int, int); extern void set_output_cursor (struct cursor_pos *); -extern void x_cursor_to (int, int, int, int); +extern void x_cursor_to (struct window *, int, int, int, int); extern void x_update_cursor (struct frame *, int); extern void x_clear_cursor (struct window *); diff --git a/src/dispnew.c b/src/dispnew.c index 2708252aa8a..519659a104c 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -135,10 +135,6 @@ struct frame *last_nonminibuf_frame; static bool delayed_size_change; -/* Updated window if != 0. Set by update_window. */ - -struct window *updated_window; - /* Glyph row updated in update_window_line, and area that is updated. */ struct glyph_row *updated_row; @@ -2286,7 +2282,7 @@ check_glyph_memory (void) screen. We build such a view by constructing a frame matrix from window matrices in this section. - Windows that must be updated have their must_be_update_p flag set. + Windows that must be updated have their must_be_updated_p flag set. For all such windows, their desired matrix is made part of the desired frame matrix. For other windows, their current matrix is made part of the desired frame matrix. @@ -3243,12 +3239,12 @@ redraw_overlapped_rows (struct window *w, int yb) { updated_row = row; updated_area = area; - FRAME_RIF (f)->cursor_to (i, 0, row->y, + FRAME_RIF (f)->cursor_to (w, i, 0, row->y, area == TEXT_AREA ? row->x : 0); if (row->used[area]) - FRAME_RIF (f)->write_glyphs (row->glyphs[area], + FRAME_RIF (f)->write_glyphs (w, row->glyphs[area], row->used[area]); - FRAME_RIF (f)->clear_end_of_line (-1); + FRAME_RIF (f)->clear_end_of_line (w, -1); } row->overlapped_p = 0; @@ -3534,10 +3530,10 @@ update_marginal_area (struct window *w, int area, int vpos) /* Set cursor to start of glyphs, write them, and clear to the end of the area. I don't think that something more sophisticated is necessary here, since marginal areas will not be the default. */ - rif->cursor_to (vpos, 0, desired_row->y, 0); + rif->cursor_to (w, vpos, 0, desired_row->y, 0); if (desired_row->used[area]) - rif->write_glyphs (desired_row->glyphs[area], desired_row->used[area]); - rif->clear_end_of_line (-1); + rif->write_glyphs (w, desired_row->glyphs[area], desired_row->used[area]); + rif->clear_end_of_line (w, -1); } @@ -3575,14 +3571,14 @@ update_text_area (struct window *w, int vpos) && !(current_row->mode_line_p && vpos > 0)) || current_row->x != desired_row->x) { - rif->cursor_to (vpos, 0, desired_row->y, desired_row->x); + rif->cursor_to (w, vpos, 0, desired_row->y, desired_row->x); if (desired_row->used[TEXT_AREA]) - rif->write_glyphs (desired_row->glyphs[TEXT_AREA], + rif->write_glyphs (w, desired_row->glyphs[TEXT_AREA], desired_row->used[TEXT_AREA]); /* Clear to end of window. */ - rif->clear_end_of_line (-1); + rif->clear_end_of_line (w, -1); changed_p = 1; /* This erases the cursor. We do this here because @@ -3718,8 +3714,8 @@ update_text_area (struct window *w, int vpos) break; } - rif->cursor_to (vpos, start_hpos, desired_row->y, start_x); - rif->write_glyphs (start, i - start_hpos); + rif->cursor_to (w, vpos, start_hpos, desired_row->y, start_x); + rif->write_glyphs (w, start, i - start_hpos); changed_p = 1; } } @@ -3727,8 +3723,8 @@ update_text_area (struct window *w, int vpos) /* Write the rest. */ if (i < desired_row->used[TEXT_AREA]) { - rif->cursor_to (vpos, i, desired_row->y, x); - rif->write_glyphs (desired_glyph, desired_row->used[TEXT_AREA] - i); + rif->cursor_to (w, vpos, i, desired_row->y, x); + rif->write_glyphs (w, desired_glyph, desired_row->used[TEXT_AREA] - i); changed_p = 1; } @@ -3748,9 +3744,9 @@ update_text_area (struct window *w, int vpos) { /* If old row extends to the end of the text area, clear. */ if (i >= desired_row->used[TEXT_AREA]) - rif->cursor_to (vpos, i, desired_row->y, + rif->cursor_to (w, vpos, i, desired_row->y, desired_row->pixel_width); - rif->clear_end_of_line (-1); + rif->clear_end_of_line (w, -1); changed_p = 1; } else if (desired_row->pixel_width < current_row->pixel_width) @@ -3760,7 +3756,7 @@ update_text_area (struct window *w, int vpos) int xlim; if (i >= desired_row->used[TEXT_AREA]) - rif->cursor_to (vpos, i, desired_row->y, + rif->cursor_to (w, vpos, i, desired_row->y, desired_row->pixel_width); /* If cursor is displayed at the end of the line, make sure @@ -3778,7 +3774,7 @@ update_text_area (struct window *w, int vpos) } else xlim = current_row->pixel_width; - rif->clear_end_of_line (xlim); + rif->clear_end_of_line (w, xlim); changed_p = 1; } } @@ -3850,7 +3846,7 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p) || desired_row->exact_window_width_line_p != current_row->exact_window_width_line_p || (MATRIX_ROW_CONTINUATION_LINE_P (desired_row) != MATRIX_ROW_CONTINUATION_LINE_P (current_row))) - rif->after_update_window_line_hook (desired_row); + rif->after_update_window_line_hook (w, desired_row); } /* Update current_row from desired_row. */ @@ -3939,7 +3935,7 @@ set_window_cursor_after_update (struct window *w) Horizontal position is -1 when cursor is on the left fringe. */ hpos = clip_to_bounds (-1, hpos, w->current_matrix->matrix_w - 1); vpos = clip_to_bounds (0, vpos, w->current_matrix->nrows - 1); - rif->cursor_to (vpos, hpos, cy, cx); + rif->cursor_to (w, vpos, hpos, cy, cx); } diff --git a/src/nsterm.m b/src/nsterm.m index 3672c7656da..56572d5b9f4 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -711,9 +711,9 @@ Free a pool and temporary objects it refers to (callable from C) -------------------------------------------------------------------------- */ { struct frame *f = XFRAME (WINDOW_FRAME (w)); - Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); + Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); + NSTRACE (ns_update_window_begin); - updated_window = w; set_output_cursor (&w->cursor); block_input (); @@ -770,7 +770,6 @@ Free a pool and temporary objects it refers to (callable from C) hlinfo->mouse_face_window = Qnil; } - updated_window = NULL; NSTRACE (update_window_end); } @@ -2084,7 +2083,6 @@ Free a pool and temporary objects it refers to (callable from C) block_input (); - updated_window = w; x_clear_cursor (w); { @@ -2102,12 +2100,11 @@ Free a pool and temporary objects it refers to (callable from C) static void -ns_after_update_window_line (struct glyph_row *desired_row) +ns_after_update_window_line (struct window *w, struct glyph_row *desired_row) /* -------------------------------------------------------------------------- External (RIF): preparatory to fringe update after text was updated -------------------------------------------------------------------------- */ { - struct window *w = updated_window; struct frame *f; int width, height; diff --git a/src/w32term.c b/src/w32term.c index 56793660d90..15812f93ff5 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -577,8 +577,7 @@ x_update_begin (struct frame *f) } -/* Start update of window W. Set the global variable updated_window - to the window being updated and set output_cursor to the cursor +/* Start update of window W. Set output_cursor to the cursor position of W. */ static void @@ -593,7 +592,6 @@ x_update_window_begin (struct window *w) SendMessage (w32_system_caret_hwnd, WM_EMACS_HIDE_CARET, 0, 0); } - updated_window = w; set_output_cursor (&w->cursor); block_input (); @@ -664,7 +662,7 @@ w32_draw_vertical_window_border (struct window *w, int x, int y0, int y1) } -/* End update of window W (which is equal to updated_window). +/* End update of window W. Draw vertical borders between horizontally adjacent windows, and display W's cursor if CURSOR_ON_P is non-zero. @@ -714,8 +712,6 @@ x_update_window_end (struct window *w, int cursor_on_p, { SendMessage (w32_system_caret_hwnd, WM_EMACS_SHOW_CARET, 0, 0); } - - updated_window = NULL; } @@ -733,9 +729,8 @@ x_update_end (struct frame *f) } -/* This function is called from various places in xdisp.c whenever a - complete update has been performed. The global variable - updated_window is not available here. */ +/* This function is called from various places in xdisp.c + whenever a complete update has been performed. */ static void w32_frame_up_to_date (struct frame *f) @@ -747,15 +742,13 @@ w32_frame_up_to_date (struct frame *f) /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay arrow bitmaps, or clear the fringes if no bitmaps are required - before DESIRED_ROW is made current. The window being updated is - found in updated_window. This function is called from + before DESIRED_ROW is made current. This function is called from update_window_line only if it is known that there are differences between bitmaps to be drawn between current row and DESIRED_ROW. */ static void -x_after_update_window_line (struct glyph_row *desired_row) +x_after_update_window_line (struct window *w, struct glyph_row *desired_row) { - struct window *w = updated_window; struct frame *f; int width, height; @@ -766,7 +759,7 @@ x_after_update_window_line (struct glyph_row *desired_row) /* When a window has disappeared, make sure that no rest of full-width rows stays visible in the internal border. Could - check here if updated_window is the leftmost/rightmost window, + check here if updated window is the leftmost/rightmost window, but I guess it's not worth doing since vertically split windows are almost never used, internal border is rarely set, and the overhead is very small. */ @@ -2806,7 +2799,6 @@ x_scroll_run (struct window *w, struct run *run) block_input (); /* Cursor off. Will be switched on again in x_update_window_end. */ - updated_window = w; x_clear_cursor (w); { diff --git a/src/xdisp.c b/src/xdisp.c index d2dae3406d1..ab625b9d6ec 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -11385,7 +11385,7 @@ struct cursor_pos output_cursor; /* EXPORT: Set the global variable output_cursor to CURSOR. All cursor - positions are relative to updated_window. */ + positions are relative to currently updated window. */ void set_output_cursor (struct cursor_pos *cursor) @@ -11400,41 +11400,24 @@ set_output_cursor (struct cursor_pos *cursor) /* EXPORT for RIF: Set a nominal cursor position. - HPOS and VPOS are column/row positions in a window glyph matrix. X - and Y are window text area relative pixel positions. + HPOS and VPOS are column/row positions in a window glyph matrix. + X and Y are window text area relative pixel positions. - If this is done during an update, updated_window will contain the - window that is being updated and the position is the future output - cursor position for that window. If updated_window is null, use - selected_window and display the cursor at the given position. */ + This is always done during window update, so the position is the + future output cursor position for currently updated window W. + NOTE: W is used only to check whether this function is called + in a consistent manner via the redisplay interface. */ void -x_cursor_to (int vpos, int hpos, int y, int x) +x_cursor_to (struct window *w, int vpos, int hpos, int y, int x) { - struct window *w; - - /* If updated_window is not set, work on selected_window. */ - if (updated_window) - w = updated_window; - else - w = XWINDOW (selected_window); + eassert (w); /* Set the output cursor. */ output_cursor.hpos = hpos; output_cursor.vpos = vpos; output_cursor.x = x; output_cursor.y = y; - - /* If not called as part of an update, really display the cursor. - This will also set the cursor position of W. */ - if (updated_window == NULL) - { - block_input (); - display_and_set_cursor (w, 1, hpos, vpos, x, y); - if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional) - FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ()); - unblock_input (); - } } #endif /* HAVE_WINDOW_SYSTEM */ @@ -25745,16 +25728,15 @@ x_produce_glyphs (struct it *it) /* EXPORT for RIF: Output LEN glyphs starting at START at the nominal cursor position. Advance the nominal cursor over the text. The global variable - updated_window contains the window being updated, updated_row is - the glyph row being updated, and updated_area is the area of that - row being updated. */ + updated_row is the glyph row being updated, and updated_area is the + area of that row being updated. */ void -x_write_glyphs (struct glyph *start, int len) +x_write_glyphs (struct window *w, struct glyph *start, int len) { - int x, hpos, chpos = updated_window->phys_cursor.hpos; + int x, hpos, chpos = w->phys_cursor.hpos; - eassert (updated_window && updated_row); + eassert (updated_row); /* When the window is hscrolled, cursor hpos can legitimately be out of bounds, but we draw the cursor at the corresponding window margin in that case. */ @@ -25768,18 +25750,18 @@ x_write_glyphs (struct glyph *start, int len) /* Write glyphs. */ hpos = start - updated_row->glyphs[updated_area]; - x = draw_glyphs (updated_window, output_cursor.x, + x = draw_glyphs (w, output_cursor.x, updated_row, updated_area, hpos, hpos + len, DRAW_NORMAL_TEXT, 0); /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */ if (updated_area == TEXT_AREA - && updated_window->phys_cursor_on_p - && updated_window->phys_cursor.vpos == output_cursor.vpos + && w->phys_cursor_on_p + && w->phys_cursor.vpos == output_cursor.vpos && chpos >= hpos && chpos < hpos + len) - updated_window->phys_cursor_on_p = 0; + w->phys_cursor_on_p = 0; unblock_input (); @@ -25793,19 +25775,17 @@ x_write_glyphs (struct glyph *start, int len) Insert LEN glyphs from START at the nominal cursor position. */ void -x_insert_glyphs (struct glyph *start, int len) +x_insert_glyphs (struct window *w, struct glyph *start, int len) { struct frame *f; - struct window *w; int line_height, shift_by_width, shifted_region_width; struct glyph_row *row; struct glyph *glyph; int frame_x, frame_y; ptrdiff_t hpos; - eassert (updated_window && updated_row); + eassert (updated_row); block_input (); - w = updated_window; f = XFRAME (WINDOW_FRAME (w)); /* Get the height of the line we are in. */ @@ -25847,18 +25827,17 @@ x_insert_glyphs (struct glyph *start, int len) (inclusive) to pixel column TO_X (exclusive). The idea is that everything from TO_X onward is already erased. - TO_X is a pixel position relative to updated_area of - updated_window. TO_X == -1 means clear to the end of this area. */ + TO_X is a pixel position relative to updated_area of currently + updated window W. TO_X == -1 means clear to the end of this area. */ void -x_clear_end_of_line (int to_x) +x_clear_end_of_line (struct window *w, int to_x) { struct frame *f; - struct window *w = updated_window; int max_x, min_y, max_y; int from_x, from_y, to_y; - eassert (updated_window && updated_row); + eassert (updated_row); f = XFRAME (w->frame); if (updated_row->full_width_p) @@ -28820,7 +28799,7 @@ expose_window (struct window *w, XRectangle *fr) /* When we're currently updating the window, display and current matrix usually don't agree. Arrange for a thorough display later. */ - if (w == updated_window) + if (w->must_be_updated_p) { SET_FRAME_GARBAGED (f); return 0; diff --git a/src/xterm.c b/src/xterm.c index a486242b8c3..6391154961f 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -320,7 +320,6 @@ static void x_clip_to_row (struct window *, struct glyph_row *, int, GC); static void x_flush (struct frame *f); static void x_update_begin (struct frame *); static void x_update_window_begin (struct window *); -static void x_after_update_window_line (struct glyph_row *); static struct scroll_bar *x_window_to_scroll_bar (Display *, Window); static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *, enum scroll_bar_part *, @@ -554,8 +553,7 @@ x_update_begin (struct frame *f) } -/* Start update of window W. Set the global variable updated_window - to the window being updated and set output_cursor to the cursor +/* Start update of window W. Set output_cursor to the cursor position of W. */ static void @@ -564,7 +562,6 @@ x_update_window_begin (struct window *w) struct frame *f = XFRAME (WINDOW_FRAME (w)); Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); - updated_window = w; set_output_cursor (&w->cursor); block_input (); @@ -601,7 +598,7 @@ x_draw_vertical_window_border (struct window *w, int x, int y0, int y1) f->output_data.x->normal_gc, x, y0, x, y1); } -/* End update of window W (which is equal to updated_window). +/* End update of window W. Draw vertical borders between horizontally adjacent windows, and display W's cursor if CURSOR_ON_P is non-zero. @@ -642,8 +639,6 @@ x_update_window_end (struct window *w, int cursor_on_p, int mouse_face_overwritt hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; hlinfo->mouse_face_window = Qnil; } - - updated_window = NULL; } @@ -664,9 +659,8 @@ x_update_end (struct frame *f) } -/* This function is called from various places in xdisp.c whenever a - complete update has been performed. The global variable - updated_window is not available here. */ +/* This function is called from various places in xdisp.c + whenever a complete update has been performed. */ static void XTframe_up_to_date (struct frame *f) @@ -678,15 +672,13 @@ XTframe_up_to_date (struct frame *f) /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay arrow bitmaps, or clear the fringes if no bitmaps are required - before DESIRED_ROW is made current. The window being updated is - found in updated_window. This function It is called from + before DESIRED_ROW is made current. This function is called from update_window_line only if it is known that there are differences between bitmaps to be drawn between current row and DESIRED_ROW. */ static void -x_after_update_window_line (struct glyph_row *desired_row) +x_after_update_window_line (struct window *w, struct glyph_row *desired_row) { - struct window *w = updated_window; struct frame *f; int width, height; @@ -697,7 +689,7 @@ x_after_update_window_line (struct glyph_row *desired_row) /* When a window has disappeared, make sure that no rest of full-width rows stays visible in the internal border. Could - check here if updated_window is the leftmost/rightmost window, + check here if updated window is the leftmost/rightmost window, but I guess it's not worth doing since vertically split windows are almost never used, internal border is rarely set, and the overhead is very small. */ @@ -3323,7 +3315,6 @@ x_scroll_run (struct window *w, struct run *run) block_input (); /* Cursor off. Will be switched on again in x_update_window_end. */ - updated_window = w; x_clear_cursor (w); XCopyArea (FRAME_X_DISPLAY (f), From c03c02eea4978cd6d11bc605aa988b99756b5a51 Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Thu, 8 Aug 2013 17:59:14 +0200 Subject: [PATCH 084/449] lisp/frameset.el (frameset-save): Check validity of the resulting frameset. (frameset-valid-p): Doc fix. --- lisp/ChangeLog | 5 +++++ lisp/frameset.el | 46 +++++++++++++++++++++++++++------------------- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 6ab96b11327..4a2712fdd21 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2013-08-08 Juanma Barranquero + + * frameset.el (frameset-valid-p): Doc fix. + (frameset-save): Check validity of the resulting frameset. + 2013-08-08 Xue Fuqiao * ido.el (ido-record-command): Add doc string. diff --git a/lisp/frameset.el b/lisp/frameset.el index c3fdfa52886..b1ad9f7702a 100644 --- a/lisp/frameset.el +++ b/lisp/frameset.el @@ -136,8 +136,12 @@ FRAMESET is copied with `copy-tree'." ;;;###autoload (defun frameset-valid-p (object) - "Return non-nil if OBJECT is a valid frameset, nil otherwise." + "Return non-nil if OBJECT is a valid frameset, nil otherwise. + +The return value is nil if OBJECT is not a frameset, or not +a valid one, and the frameset version if it is valid." (and (vectorp object) ; a vector + (>= (length object) 8) ; of the right length (future-proof) (eq (aref object 0) 'frameset) ; tagged as `frameset' (integerp (aref object 1)) ; VERSION is an int (consp (aref object 2)) ; TIMESTAMP is a non-null list @@ -307,7 +311,7 @@ Properties can be set with ;; the roundtrip though tty-land. The answer is to add "stashing ;; parameters", working in pairs, to shelve the GUI-specific contents and ;; restore it once we're back in pixel country. That's what functions -;; `frameset-filter-shelve-param' and `frameset-unshelve-param' do. +;; `frameset-filter-shelve-param' and `frameset-filter-unshelve-param' do. ;; ;; Basically, if you set `frameset-filter-shelve-param' as the filter for ;; a parameter P, it will detect when it is restoring a GUI frame into a @@ -346,8 +350,8 @@ Properties can be set with ;; URL). So the probability of a collision with existing or future ;; symbols is quite insignificant. ;; -;; Now, what about the filter alists? There are three of them, though -;; only two sets of parameters: +;; Now, what about the filter alist variables? There are three of them, +;; though only two sets of parameters: ;; ;; - `frameset-session-filter-alist' contains these filters that allow to ;; save and restore framesets in-session, without the need to serialize @@ -361,7 +365,7 @@ Properties can be set with ;; disk without loss of information. That's the format used by the ;; desktop.el package, for example. ;; -;; IMPORTANT: These variables share structure and should never be modified. +;; IMPORTANT: These variables share structure and should NEVER be modified. ;; ;; - `frameset-filter-alist': The value of this variable is the default ;; value for the FILTERS arguments of `frameset-save' and @@ -745,21 +749,25 @@ PROPERTIES is a user-defined property list to add to the frameset." (frames (cl-delete-if-not #'frame-live-p (if predicate (cl-delete-if-not predicate list) - list)))) + list))) + fs) (frameset--record-minibuffer-relationships frames) - (make-frameset :app app - :name name - :description description - :properties properties - :states (mapcar - (lambda (frame) - (cons - (frameset-filter-params (frame-parameters frame) - (or filters - frameset-filter-alist) - t) - (window-state-get (frame-root-window frame) t))) - frames)))) + (setq fs (make-frameset + :app app + :name name + :description description + :properties properties + :states (mapcar + (lambda (frame) + (cons + (frameset-filter-params (frame-parameters frame) + (or filters + frameset-filter-alist) + t) + (window-state-get (frame-root-window frame) t))) + frames))) + (cl-assert (frameset-valid-p fs)) + fs)) ;; Restoring framesets From a3738d206cf04ed2a0309267d1993a24e2b536d2 Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Thu, 8 Aug 2013 18:13:32 +0200 Subject: [PATCH 085/449] lisp/ChangeLog: Fix typo in previous change. --- lisp/ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 4a2712fdd21..d98c9cac530 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,6 +1,6 @@ 2013-08-08 Juanma Barranquero - * frameset.el (frameset-valid-p): Doc fix. + * frameset.el (frameset-valid-p): Check vector length. Doc fix. (frameset-save): Check validity of the resulting frameset. 2013-08-08 Xue Fuqiao From 10bf7f5a3d084050215a0fda1d313c7818801c42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Dj=C3=A4rv?= Date: Thu, 8 Aug 2013 19:52:00 +0200 Subject: [PATCH 086/449] * nsterm.m (ns_update_begin): Don't change clip path if it would be larger than the NSWindow. Fixes: debbugs:14934 --- src/ChangeLog | 5 +++++ src/nsterm.m | 19 ++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index caf7b034401..d57086f7141 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2013-08-08 Jan Djärv + + * nsterm.m (ns_update_begin): Don't change clip path if it would be + larger than the NSWindow (Bug#14934). + 2013-08-08 Dmitry Antipov Redesign redisplay interface to drop global variable updated_window. diff --git a/src/nsterm.m b/src/nsterm.m index 56572d5b9f4..4a1c04ffb8f 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -691,9 +691,18 @@ Free a pool and temporary objects it refers to (callable from C) { NSBezierPath *bp; NSRect r = [view frame]; - bp = [[NSBezierPath bezierPathWithRect: r] retain]; - [bp setClip]; - [bp release]; + NSRect cr = [[view window] frame]; + /* If a large frame size is set, r may be larger than the window frame + before constrained. In that case don't change the clip path, as we + will clear in to the tool bar and title bar. */ + if (r.size.height + + FRAME_NS_TITLEBAR_HEIGHT (f) + + FRAME_TOOLBAR_HEIGHT (f) <= cr.size.height) + { + bp = [[NSBezierPath bezierPathWithRect: r] retain]; + [bp setClip]; + [bp release]; + } } #endif @@ -784,9 +793,9 @@ Free a pool and temporary objects it refers to (callable from C) EmacsView *view = FRAME_NS_VIEW (f); /* if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */ - MOUSE_HL_INFO (f)->mouse_face_defer = 0; + MOUSE_HL_INFO (f)->mouse_face_defer = 0; - block_input (); + block_input (); [view unlockFocus]; [[view window] flushWindow]; From 74c5d24c74e3167db6e3ee01831584c99905bb70 Mon Sep 17 00:00:00 2001 From: Christopher Schmidt Date: Thu, 8 Aug 2013 21:22:58 +0200 Subject: [PATCH 087/449] * lisp/comint.el: Do not use an overlay to highlight the last prompt. (Bug#14744) (comint-mode): Make comint-last-prompt buffer local. (comint-last-prompt): New variable. (comint-last-prompt-overlay): Remove. Superseded by comint-last-prompt. (comint-snapshot-last-prompt, comint-output-filter): Use comint-last-prompt. --- lisp/ChangeLog | 11 ++++++++++ lisp/comint.el | 54 ++++++++++++++++++++++++-------------------------- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index d98c9cac530..294c6af6595 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,14 @@ +2013-08-08 Christopher Schmidt + + * comint.el: + Do not use an overlay to highlight the last prompt. (Bug#14744) + (comint-mode): Make comint-last-prompt buffer local. + (comint-last-prompt): New variable. + (comint-last-prompt-overlay): Remove. Superseded by + comint-last-prompt. + (comint-snapshot-last-prompt, comint-output-filter): Use + comint-last-prompt. + 2013-08-08 Juanma Barranquero * frameset.el (frameset-valid-p): Check vector length. Doc fix. diff --git a/lisp/comint.el b/lisp/comint.el index c2b69a42a8b..4517e9c65a0 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -636,7 +636,7 @@ Entry to this mode runs the hooks on `comint-mode-hook'." (setq-local comint-last-input-start (point-min-marker)) (setq-local comint-last-input-end (point-min-marker)) (setq-local comint-last-output-start (make-marker)) - (make-local-variable 'comint-last-prompt-overlay) + (make-local-variable 'comint-last-prompt) (make-local-variable 'comint-prompt-regexp) ; Don't set; default (make-local-variable 'comint-input-ring-size) ; ...to global val. (make-local-variable 'comint-input-ring) @@ -1902,21 +1902,24 @@ either globally or locally.") "If nil, Comint will interpret `carriage control' characters in output. See `comint-carriage-motion' for details.") -;; When non-nil, this is an overlay over the last recognized prompt in -;; the buffer; it is used when highlighting the prompt. -(defvar comint-last-prompt-overlay nil) +(defvar comint-last-prompt nil + "Markers pointing to the last prompt. +If non-nil, a cons cell containing markers. The car points to +the start, the cdr to the end of the last prompt recognized.") (defun comint-snapshot-last-prompt () - "`snapshot' any current `comint-last-prompt-overlay'. -Freeze its attributes in place, even when more input comes along -and moves the prompt overlay." - (when comint-last-prompt-overlay - (let ((inhibit-read-only t)) - (with-silent-modifications - (add-text-properties - (overlay-start comint-last-prompt-overlay) - (overlay-end comint-last-prompt-overlay) - (overlay-properties comint-last-prompt-overlay)))))) + "Snapshot the current `comint-last-prompt'. +Freezes the `font-lock-face' text property in place." + (when comint-last-prompt + (with-silent-modifications + (add-text-properties + (car comint-last-prompt) + (cdr comint-last-prompt) + '(font-lock-face comint-highlight-prompt))) + ;; Reset comint-last-prompt so later on comint-output-filter does + ;; not remove the font-lock-face text property of the previous + ;; (this) prompt. + (setq comint-last-prompt nil))) (defun comint-carriage-motion (start end) "Interpret carriage control characters in the region from START to END. @@ -2063,20 +2066,15 @@ Make backspaces delete the previous character." (add-text-properties prompt-start (point) '(read-only t rear-nonsticky t front-sticky (read-only))))) - (unless (and (bolp) (null comint-last-prompt-overlay)) - ;; Need to create or move the prompt overlay (in the case - ;; where there is no prompt ((bolp) == t), we still do - ;; this if there's already an existing overlay). - (if comint-last-prompt-overlay - ;; Just move an existing overlay - (move-overlay comint-last-prompt-overlay - prompt-start (point)) - ;; Need to create the overlay - (setq comint-last-prompt-overlay - (make-overlay prompt-start (point))) - (overlay-put comint-last-prompt-overlay - 'font-lock-face 'comint-highlight-prompt)))) - + (when comint-last-prompt + (remove-text-properties (car comint-last-prompt) + (cdr comint-last-prompt) + '(font-lock-face))) + (setq comint-last-prompt + (cons (copy-marker prompt-start) (point-marker))) + (add-text-properties (car comint-last-prompt) + (cdr comint-last-prompt) + '(font-lock-face comint-highlight-prompt))) (goto-char saved-point))))))) (defun comint-preinput-scroll-to-bottom () From 0ca3f70e4f83a1cbfaa4356865f1eec180419786 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Thu, 8 Aug 2013 19:14:20 -0400 Subject: [PATCH 088/449] * lisp/emacs-lisp/edebug.el (edebug-debugger): Use edebug-eval to run the break-condition in the context of the debugged code. Fixes: debbugs:12685 --- lisp/ChangeLog | 13 +++++++++---- lisp/emacs-lisp/edebug.el | 6 ++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 294c6af6595..8443ecb2855 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2013-08-08 Stefan Monnier + + * emacs-lisp/edebug.el (edebug-debugger): Use edebug-eval to run the + break-condition in the context of the debugged code (bug#12685). + 2013-08-08 Christopher Schmidt * comint.el: @@ -6,8 +11,8 @@ (comint-last-prompt): New variable. (comint-last-prompt-overlay): Remove. Superseded by comint-last-prompt. - (comint-snapshot-last-prompt, comint-output-filter): Use - comint-last-prompt. + (comint-snapshot-last-prompt, comint-output-filter): + Use comint-last-prompt. 2013-08-08 Juanma Barranquero @@ -164,8 +169,8 @@ 2013-08-06 Dmitry Antipov - * files.el (cache-long-line-scans): Make - obsolete alias to `cache-long-scans'. + * files.el (cache-long-line-scans): + Make obsolete alias to `cache-long-scans'. 2013-08-06 Juanma Barranquero diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 928d49f85ba..ec343eab631 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -2314,8 +2314,7 @@ MSG is printed after `::::} '." (if edebug-global-break-condition (condition-case nil (setq edebug-global-break-result - ;; FIXME: lexbind. - (eval edebug-global-break-condition)) + (edebug-eval edebug-global-break-condition)) (error nil)))) (edebug-break)) @@ -2326,8 +2325,7 @@ MSG is printed after `::::} '." (and edebug-break-data (or (not edebug-break-condition) (setq edebug-break-result - ;; FIXME: lexbind. - (eval edebug-break-condition)))))) + (edebug-eval edebug-break-condition)))))) (if (and edebug-break (nth 2 edebug-break-data)) ; is it temporary? ;; Delete the breakpoint. From 919a9575445cf99683217f28f48ffd327e25130b Mon Sep 17 00:00:00 2001 From: Xue Fuqiao Date: Fri, 9 Aug 2013 07:56:25 +0800 Subject: [PATCH 089/449] doc/misc/ido.texi: Document some user options. --- doc/misc/ido.texi | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/doc/misc/ido.texi b/doc/misc/ido.texi index e0b28e3b2cb..5688b7a922b 100644 --- a/doc/misc/ido.texi +++ b/doc/misc/ido.texi @@ -474,6 +474,9 @@ To modify the keybindings, use the @code{ido-setup-hook}. For example: (define-key ido-completion-map " " 'ido-next-match)) @end example +@c @defvr {User Option} ido-setup-hook +@c a new node for Ido hooks? + @menu * Changing List Order:: Changing the list of files. * Find File At Point:: Make Ido guess the context. @@ -645,11 +648,29 @@ commands in the variable @code{command-history}. Note that non-Ido equivalent is recorded. @end defvr -@c @defvr {User Option} ido-enable-last-directory-history +@defvr {User Option} ido-all-frames +This user option will be passed to @code{walk-windows} as its +@var{all-frames} argument when Ido is finding buffers. @xref{Cyclic +Window Ordering, , Cyclic Ordering of Windows, elisp, GNU Emacs Lisp +Reference Manual}. +@end defvr + +@defvr {User Option} ido-minibuffer-setup-hook +This hook variable contains Ido-specific customization of minibuffer +setup. It is run during minibuffer setup if Ido is active, and is +intended for use in customizing ido for interoperation with other +packages. +@end defvr + @c @defvr {User Option} ido-enable-tramp-completion +@c cross-reference to tramp.texi + +@c @cindex UNC host names, completion @c @defvr {User Option} ido-unc-hosts @c @defvr {User Option} ido-downcase-unc-hosts @c @defvr {User Option} ido-cache-unc-host-shares-time + +@c @defvr {User Option} ido-enable-last-directory-history @c @defvr {User Option} ido-max-work-file-list @c @defvr {User Option} ido-work-directory-match-only @c @defvr {User Option} ido-auto-merge-work-directories-length @@ -660,7 +681,6 @@ equivalent is recorded. @c @defvr {User Option} ido-rotate-file-list-default @c @defvr {User Option} ido-enter-matching-directory @c @defvr {User Option} ido-create-new-buffer -@c @defvr {User Option} ido-setup-hook @c @defvr {User Option} ido-separator @c @defvr {User Option} ido-decorations @c @defvr {User Option} ido-use-virtual-buffers @@ -671,8 +691,6 @@ equivalent is recorded. @c @defvr {User Option} ido-rewrite-file-prompt-functions @c @defvr {User Option} ido-completion-buffer @c @defvr {User Option} ido-completion-buffer-all-completions -@c @defvr {User Option} ido-all-frames -@c @defvr {User Option} ido-minibuffer-setup-hook @c @defvr {User Option} ido-save-directory-list-file @c @defvr {User Option} ido-read-file-name-as-directory-commands @c @defvr {User Option} ido-read-file-name-non-ido From 9d3aa82cf961afda732fc369a42321f4bfbc0021 Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Fri, 9 Aug 2013 01:59:14 +0200 Subject: [PATCH 090/449] lisp/*.el: Silence lexical-binding warnings. --- lisp/ChangeLog | 59 ++++++++++++++++++++++++++++++++ lisp/allout-widgets.el | 48 ++++++++++---------------- lisp/allout.el | 31 +++++++++-------- lisp/emacs-lisp/lisp-mode.el | 14 ++++---- lisp/help.el | 41 +++++++++++----------- lisp/international/characters.el | 11 +++--- lisp/international/fontset.el | 8 ++--- lisp/international/mule-cmds.el | 4 +-- lisp/international/mule.el | 19 +++++----- lisp/isearch.el | 2 +- lisp/term/common-win.el | 6 ++-- lisp/term/pc-win.el | 33 +++++++++--------- lisp/term/tty-colors.el | 4 +-- lisp/term/x-win.el | 2 +- lisp/vc/vc-hooks.el | 8 ++--- lisp/version.el | 2 +- lisp/window.el | 15 +++----- 17 files changed, 175 insertions(+), 132 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 8443ecb2855..f240aa445d0 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,62 @@ +2013-08-08 Juanma Barranquero + + * allout-widgets.el (allout-widgets-pre-command-business) + (allout-widgets-post-command-business) + (allout-widgets-after-change-handler) + (allout-decorate-item-and-context, allout-set-boundary-marker) + (allout-body-modification-handler) + (allout-graphics-modification-handler): Mark ignored arguments. + (allout-widgets-post-command-business) + (allout-widgets-exposure-change-processor) + (allout-widgets-exposure-undo-processor) + (allout-decorate-item-and-context, allout-redecorate-visible-subtree) + (allout-parse-item-at-point, allout-decorate-item-guides) + (allout-decorate-item-cue, allout-item-span): Remove unused variables. + * allout.el (epa-passphrase-callback-function): Declare. + (allout-overlay-insert-in-front-handler) + (allout-overlay-interior-modification-handler) + (allout-isearch-end-handler, allout-chart-siblings) + (allout-up-current-level, allout-end-of-level, allout-reindent-body) + (allout-yank-processing, allout-process-exposed) + (allout-latex-verb-quote, allout-latexify-one-item, outlineify-sticky) + (allout-latex-verbatim-quote-curr-line): Removed unused variables. + * emacs-lisp/lisp-mode.el (lisp-eval-defun, last-sexp-toggle-display) + (lisp-indent-defform): Mark ignored arguments. + (lisp-indent-line): Mark ignored arguments. Remove unused variables. + (calculate-lisp-indent): Remove unused variables. + * international/characters.el (indian-2-column, arabic-2-column) + (tibetan): Mark ignored arguments. + (use-cjk-char-width-table): Mark ignored arguments. + Remove unused variables. + * international/fontset.el (build-default-fontset-data) + (x-compose-font-name, create-fontset-from-fontset-spec): + Mark ignored arguments. + (fontset-plain-name): Remove unused variables. + * international/mule.el (charset-id, charset-bytes, generic-char-p) + (keyboard-coding-system): Mark ignored arguments. + (find-auto-coding): Remove unused variables. Use `ignore-errors'. + * help.el (resize-temp-buffer-window): + * window.el (display-buffer-in-major-side-window) + (display-buffer-in-side-window, display-buffer-in-previous-window): + Remove unused variables. + * isearch.el (isearch-forward-symbol): + * version.el (emacs-bzr-version-bzr): + * international/mule-cmds.el (current-language-environment): + * term/common-win.el (x-handle-iconic, x-handle-geometry) + (x-handle-display): + * term/pc-win.el (x-list-fonts, x-display-planes) + (x-display-color-cells, x-server-max-request-size, x-server-vendor) + (x-server-version, x-display-screens, x-display-mm-height) + (x-display-mm-width, x-display-backing-store, x-display-visual-class) + (x-selection-owner-p, x-own-selection-internal) + (x-disown-selection-internal, x-get-selection-internal) + (msdos-initialize-window-system): + * term/tty-colors.el (tty-color-alist, tty-color-clear): + * term/x-win.el (x-handle-no-bitmap-icon): + * vc/vc-hooks.el (vc-mode, vc-default-make-version-backups-p) + (vc-default-find-file-hook, vc-default-extra-menu): + Mark ignored arguments. + 2013-08-08 Stefan Monnier * emacs-lisp/edebug.el (edebug-debugger): Use edebug-eval to run the diff --git a/lisp/allout-widgets.el b/lisp/allout-widgets.el index fd8e5f8ff94..1c76156b91a 100644 --- a/lisp/allout-widgets.el +++ b/lisp/allout-widgets.el @@ -720,17 +720,17 @@ icon/bullet.") ;;;_ . Hooks and hook helpers ;;;_ , major command-loop business: ;;;_ > allout-widgets-pre-command-business (&optional recursing) -(defun allout-widgets-pre-command-business (&optional recursing) +(defun allout-widgets-pre-command-business (&optional _recursing) "Handle actions pending before `allout-mode' activity." ) ;;;_ > allout-widgets-post-command-business (&optional recursing) -(defun allout-widgets-post-command-business (&optional recursing) +(defun allout-widgets-post-command-business (&optional _recursing) "Handle actions pending after any `allout-mode' commands. Optional RECURSING is for internal use, to limit recursion." ;; - check changed text for nesting discontinuities and escape anything ;; that's: (1) asterisks at bol or (2) excessively nested. - (condition-case failure + (condition-case nil (when (and (boundp 'allout-mode) allout-mode) @@ -811,7 +811,7 @@ Optional RECURSING is for internal use, to limit recursion." (goto-char (widget-get this-widget :from)) (not (bolp))) (if (not - (condition-case err + (condition-case nil (yes-or-no-p (concat "Misplaced item won't be recognizable " " as part of outline - rectify? ")) @@ -873,7 +873,7 @@ Optional RECURSING is for internal use, to limit recursion." (error (substitute-command-keys allout-structure-unruly-deletion-message))))) ;;;_ > allout-widgets-after-change-handler -(defun allout-widgets-after-change-handler (beg end prelength) +(defun allout-widgets-after-change-handler (_beg _end _prelength) "Reconcile what needs to be reconciled for allout widgets after edits." ) ;;;_ > allout-current-decorated-p () @@ -999,7 +999,6 @@ Generally invoked via `allout-exposure-change-functions'." ;; have to distinguish between concealing and exposing so that, eg, ;; `allout-expose-topic's mix is handled properly. handled-expose - handled-conceal covered deactivate-mark) @@ -1188,7 +1187,7 @@ Dispatched by `allout-widgets-post-command-business' in response to (let* ((allout-undo-exposure-in-progress t) ;; inhibit undo recording while twiddling exposure to track undo: (widgets allout-widgets-undo-exposure-record) - widget widget-start-marker widget-end-marker + widget-start-marker widget-end-marker from-state icon-start-point to-state handled covered) (setq allout-widgets-undo-exposure-record nil) @@ -1552,7 +1551,7 @@ recursive operation." ;;;_ > allout-decorate-item-and-context (item-widget &optional redecorate ;;; blank-container parent) (defun allout-decorate-item-and-context (item-widget &optional redecorate - blank-container parent) + blank-container _parent) "Create or adjust widget decorations for ITEM-WIDGET and neighbors at point. The neighbors include its siblings and parent. @@ -1593,12 +1592,8 @@ We return the item-widget corresponding to the item at point." steady-point)) (parent (and (not is-container) (allout-get-or-create-parent-widget))) - parent-flags parent-depth successor-sibling - body doing-item - sub-item-widget - depth reverse-siblings-chart (buffer-undo-list t)) @@ -1615,7 +1610,6 @@ We return the item-widget corresponding to the item at point." ;; `allout-goto-prefix' will go to first non-container item: (allout-goto-prefix) (allout-next-heading)) - (setq depth (allout-recent-depth)) (setq reverse-siblings-chart (list allout-recent-prefix-beginning)) (while (allout-next-sibling) (push allout-recent-prefix-beginning reverse-siblings-chart))) @@ -1702,7 +1696,6 @@ Point is left at the last sibling in the visible subtree." (pending-chart (or chart (allout-chart-subtree nil 'visible))) item-widget previous-sibling-point - previous-sibling recent-sibling-point) (setq pending-chart (nreverse pending-chart)) (dolist (sibling-point pending-chart) @@ -1753,9 +1746,7 @@ may have subitems.)" (icon-start (1- icon-end)) body-start body-end - bullet has-subitems - (contents-depth (1+ depth)) ) (widget-put item-widget :depth depth) (if is-container @@ -1783,7 +1774,7 @@ may have subitems.)" ;; cue area: (setq body-start icon-end) - (widget-put item-widget :bullet (setq bullet (allout-get-bullet))) + (widget-put item-widget :bullet (allout-get-bullet)) (if (equal (char-after body-start) ? ) (setq body-start (1+ body-start))) (widget-put item-widget :body-start body-start) @@ -1809,7 +1800,7 @@ may have subitems.)" ;; has a subsequent item: (not (= body-end (point-max))) ;; subsequent item is deeper: - (< depth (setq contents-depth (allout-recent-depth)))))) + (< depth (allout-recent-depth))))) ;; note :expanded - true if widget item's content is currently visible? (widget-put item-widget :expanded (and has-subitems @@ -1818,7 +1809,7 @@ may have subitems.)" (goto-char allout-recent-prefix-beginning) (not (allout-hidden-p))))))) ;;;_ > allout-set-boundary-marker (boundary position &optional current-marker) -(defun allout-set-boundary-marker (boundary position &optional current-marker) +(defun allout-set-boundary-marker (_boundary position &optional current-marker) "Set or create item widget BOUNDARY type marker at POSITION. Optional CURRENT-MARKER is the marker currently being used for @@ -1872,8 +1863,8 @@ reapplying this method will rectify the glyphs." (when (not (widget-get item-widget :is-container)) (let* ((depth (widget-get item-widget :depth)) - (parent-depth (and parent-widget - (widget-get parent-widget :depth))) + ;; (parent-depth (and parent-widget + ;; (widget-get parent-widget :depth))) (parent-flags (and parent-widget (widget-get parent-widget :guide-column-flags))) (parent-flags-depth (length parent-flags)) @@ -1894,7 +1885,7 @@ reapplying this method will rectify the glyphs." (increment (length allout-header-prefix)) reverse-flags guide-name - extenders paint-extenders + extenders (inhibit-read-only t)) (when (not (equal was-flags flags)) @@ -2017,8 +2008,8 @@ reapplying this method will rectify the glyphs." (let* ((cue-start (or (widget-get item-widget :distinctive-end) (widget-get item-widget :icon-end))) (body-start (widget-get item-widget :body-start)) - (expanded (widget-get item-widget :expanded)) - (has-subitems (widget-get item-widget :has-subitems)) + ;(expanded (widget-get item-widget :expanded)) + ;(has-subitems (widget-get item-widget :has-subitems)) (inhibit-read-only t)) (allout-item-element-span-is item-widget :cue-span cue-start body-start) @@ -2032,7 +2023,6 @@ Optional FORCE means force reassignment of the region property." (let* ((allout-inhibit-body-modification-hook t) (body-start (widget-get item-widget :body-start)) (body-end (widget-get item-widget :body-end)) - (body-text-end body-end) (inhibit-read-only t)) (allout-item-element-span-is item-widget :body-span @@ -2135,9 +2125,7 @@ of the current span, if established, or nil if not yet set. When the START and END are passed, return the distance that the start of the item moved. We return 0 if the span was not previously established or is not moved." - (let ((overlay (widget-get item-widget :span-overlay)) - was-start was-end - changed) + (let ((overlay (widget-get item-widget :span-overlay))) (cond ((not overlay) (when start (setq overlay (make-overlay start end nil t nil)) (overlay-put overlay 'button item-widget) @@ -2259,7 +2247,7 @@ of the buffer." (allout-get-or-create-item-widget redecorate))) ;;;_ : X- Item ancillaries ;;;_ >X allout-body-modification-handler (beg end) -(defun allout-body-modification-handler (beg end) +(defun allout-body-modification-handler (_beg _end) "Do routine processing of body text before and after modification. Operation is inhibited by `allout-inhibit-body-modification-handler'." @@ -2281,7 +2269,7 @@ Operation is inhibited by `allout-inhibit-body-modification-handler'." ;; operation. (cond (allout-inhibit-body-modification-hook nil))) ;;;_ >X allout-graphics-modification-handler (beg end) -(defun allout-graphics-modification-handler (beg end) +(defun allout-graphics-modification-handler (beg _end) "Protect against incoherent deletion of decoration graphics. Deletes allowed only when `inhibit-read-only' is t." diff --git a/lisp/allout.el b/lisp/allout.el index a0d61eb6f35..0896ace5872 100644 --- a/lisp/allout.el +++ b/lisp/allout.el @@ -74,6 +74,9 @@ ;;; Code: +(declare-function epa-passphrase-callback-function + "epa" (context key-id handback)) + ;;;_* Dependency loads (require 'overlay) (eval-when-compile @@ -2121,8 +2124,8 @@ OPEN: A TOPIC that is not CLOSED, though its OFFSPRING or BODY may be." ;;;_ > allout-overlay-insert-in-front-handler (ol after beg end ;;; &optional prelen) -(defun allout-overlay-insert-in-front-handler (ol after beg end - &optional prelen) +(defun allout-overlay-insert-in-front-handler (ol after beg _end + &optional _prelen) "Shift the overlay so stuff inserted in front of it is excluded." (if after ;; ??? Shouldn't moving the overlay should be unnecessary, if overlay @@ -2131,7 +2134,7 @@ OPEN: A TOPIC that is not CLOSED, though its OFFSPRING or BODY may be." ;;;_ > allout-overlay-interior-modification-handler (ol after beg end ;;; &optional prelen) (defun allout-overlay-interior-modification-handler (ol after beg end - &optional prelen) + &optional _prelen) "Get confirmation before making arbitrary changes to invisible text. We expose the invisible text and ask for confirmation. Refusal or @@ -2194,7 +2197,7 @@ See `allout-overlay-interior-modification-handler' for details." (allout-overlay-interior-modification-handler overlay nil beg end nil)))))) ;;;_ > allout-isearch-end-handler (&optional overlay) -(defun allout-isearch-end-handler (&optional overlay) +(defun allout-isearch-end-handler (&optional _overlay) "Reconcile allout outline exposure on arriving in hidden text after isearch. Optional OVERLAY parameter is for when this function is used by @@ -2733,7 +2736,7 @@ starting point, and PREV-DEPTH is depth of prior topic." ; and maybe not preferable. )) ;;;_ > allout-chart-siblings (&optional start end) -(defun allout-chart-siblings (&optional start end) +(defun allout-chart-siblings (&optional _start _end) "Produce a list of locations of this and succeeding sibling topics. Effectively a top-level chart of siblings. See `allout-chart-subtree' for an explanation of charts." @@ -3051,7 +3054,7 @@ Returning depth if successful, nil if not." nil)) ) ;;;_ > allout-up-current-level (arg) -(defun allout-up-current-level (arg) +(defun allout-up-current-level (_arg) "Move out ARG levels from current visible topic." (interactive "p") (let ((start-point (point))) @@ -3198,7 +3201,7 @@ Presumes point is at the start of a topic prefix." "Go back to the first sibling at this level, visible or not." (allout-end-of-level 'backward)) ;;;_ > allout-end-of-level (&optional backward) -(defun allout-end-of-level (&optional backward) +(defun allout-end-of-level (&optional _backward) "Go to the last sibling at this level, visible or not." (let ((depth (allout-depth))) @@ -3930,7 +3933,7 @@ Maintains outline hanging topic indentation if (if (or allout-former-auto-filler allout-use-hanging-indents) (funcall use-auto-fill-function))))) ;;;_ > allout-reindent-body (old-depth new-depth &optional number) -(defun allout-reindent-body (old-depth new-depth &optional number) +(defun allout-reindent-body (old-depth new-depth &optional _number) "Reindent body lines which were indented at OLD-DEPTH to NEW-DEPTH. Optional arg NUMBER indicates numbering is being added, and it must @@ -4559,7 +4562,7 @@ Topic exposure is marked with text-properties, to be used by (if next (goto-char next))))) (set-buffer-modified-p was-modified)))) ;;;_ > allout-yank-processing () -(defun allout-yank-processing (&optional arg) +(defun allout-yank-processing (&optional _arg) "Incidental allout-specific business to be done just after text yanks. @@ -5521,7 +5524,7 @@ header and body. The elements of that list are: ;;_ > allout-process-exposed (&optional func from to frombuf ;;; tobuf format) (defun allout-process-exposed (&optional func from to frombuf tobuf - format start-num) + format _start-num) "Map function on exposed parts of current topic; results to another buffer. All args are options; default values itemized below. @@ -5685,7 +5688,7 @@ used verbatim." ;;;_ - LaTeX formatting ;;;_ > allout-latex-verb-quote (string &optional flow) -(defun allout-latex-verb-quote (string &optional flow) +(defun allout-latex-verb-quote (string &optional _flow) "Return copy of STRING for literal reproduction across LaTeX processing. Expresses the original characters (including carriage returns) of the string across LaTeX processing." @@ -5706,7 +5709,7 @@ across LaTeX processing, within the context of a `verbatim' environment. Leaves point at the end of the line." (let ((inhibit-field-text-motion t)) (beginning-of-line) - (let ((beg (point)) + (let (;(beg (point)) (end (point-at-eol))) (save-match-data (while (re-search-forward "\\\\" @@ -5790,7 +5793,7 @@ environment. Leaves point at the end of the line." (set-buffer buffer) (insert "\n\\end{document}\n")) ;;;_ > allout-latexify-one-item (depth prefix bullet text) -(defun allout-latexify-one-item (depth prefix bullet text) +(defun allout-latexify-one-item (depth _prefix bullet text) "Insert LaTeX commands for formatting one outline item. Args are the topics numeric DEPTH, the header PREFIX lead string, the @@ -6359,7 +6362,7 @@ save. See `allout-encrypt-unencrypted-on-saves' for more info." ;;;###autoload (defalias 'outlinify-sticky 'outlineify-sticky) ;;;###autoload -(defun outlineify-sticky (&optional arg) +(defun outlineify-sticky (&optional _arg) "Activate outline mode and establish file var so it is started subsequently. See `allout-layout' and customization of `allout-auto-activation' diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 3cbd6d4a585..f7105b7d3b4 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -575,7 +575,7 @@ if that value is non-nil." (defalias 'common-lisp-mode 'lisp-mode) ;; This will do unless inf-lisp.el is loaded. -(defun lisp-eval-defun (&optional and-go) +(defun lisp-eval-defun (&optional _and-go) "Send the current defun to the Lisp process made by \\[run-lisp]." (interactive) (error "Process lisp does not exist")) @@ -662,7 +662,7 @@ alternative printed representations that can be displayed." printed-value))))) -(defun last-sexp-toggle-display (&optional arg) +(defun last-sexp-toggle-display (&optional _arg) "Toggle between abbreviated and unabbreviated printed representations." (interactive "P") (save-restriction @@ -1002,12 +1002,12 @@ function is `common-lisp-indent-function'." :type 'function :group 'lisp) -(defun lisp-indent-line (&optional whole-exp) +(defun lisp-indent-line (&optional _whole-exp) "Indent current line as Lisp code. With argument, indent any additional lines of the same expression rigidly along with this one." (interactive "P") - (let ((indent (calculate-lisp-indent)) shift-amt end + (let ((indent (calculate-lisp-indent)) shift-amt (pos (- (point-max) (point))) (beg (progn (beginning-of-line) (point)))) (skip-chars-forward " \t") @@ -1047,7 +1047,7 @@ is the buffer position of the start of the containing expression." (save-excursion (beginning-of-line) (let ((indent-point (point)) - state paren-depth + state ;; setting this to a number inhibits calling hook (desired-indent nil) (retry t) @@ -1061,7 +1061,7 @@ is the buffer position of the start of the containing expression." ;; Find innermost containing sexp (while (and retry state - (> (setq paren-depth (elt state 0)) 0)) + (> (elt state 0) 0)) (setq retry nil) (setq calculate-lisp-indent-last-sexp (elt state 2)) (setq containing-sexp (elt state 1)) @@ -1290,7 +1290,7 @@ Lisp function does not specify a special indentation." body-indent normal-indent)))) -(defun lisp-indent-defform (state indent-point) +(defun lisp-indent-defform (state _indent-point) (goto-char (car (cdr state))) (forward-line 1) (if (> (point) (car (cdr (cdr state)))) diff --git a/lisp/help.el b/lisp/help.el index 25bc9c4b7c6..4ec0b99a593 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -1018,27 +1018,26 @@ smaller than `window-min-height'. Do nothing if WINDOW is not vertically combined, some of its contents are scrolled out of view, or WINDOW was not created by `display-buffer'." (setq window (window-normalize-window window t)) - (let ((buffer-name (buffer-name (window-buffer window)))) - (let ((height (if (functionp temp-buffer-max-height) - (with-selected-window window - (funcall temp-buffer-max-height (window-buffer))) - temp-buffer-max-height)) - (quit-cadr (cadr (window-parameter window 'quit-restore)))) - (cond - ;; Resize WINDOW iff it was split off by `display-buffer'. - ((and (eq quit-cadr 'window) - (pos-visible-in-window-p (point-min) window) - (window-combined-p window)) - (fit-window-to-buffer window height)) - ;; Resize FRAME iff it was created by `display-buffer'. - ((and fit-frame-to-buffer - (eq quit-cadr 'frame) - (eq window (frame-root-window window))) - (let ((frame (window-frame window))) - (fit-frame-to-buffer - frame (+ (frame-height frame) - (- (window-total-size window)) - height)))))))) + (let ((height (if (functionp temp-buffer-max-height) + (with-selected-window window + (funcall temp-buffer-max-height (window-buffer))) + temp-buffer-max-height)) + (quit-cadr (cadr (window-parameter window 'quit-restore)))) + (cond + ;; Resize WINDOW iff it was split off by `display-buffer'. + ((and (eq quit-cadr 'window) + (pos-visible-in-window-p (point-min) window) + (window-combined-p window)) + (fit-window-to-buffer window height)) + ;; Resize FRAME iff it was created by `display-buffer'. + ((and fit-frame-to-buffer + (eq quit-cadr 'frame) + (eq window (frame-root-window window))) + (let ((frame (window-frame window))) + (fit-frame-to-buffer + frame (+ (frame-height frame) + (- (window-total-size window)) + height))))))) ;;; Help windows. (defcustom help-window-select 'other diff --git a/lisp/international/characters.el b/lisp/international/characters.el index 9f56b1c8b7d..ce6256c1e47 100644 --- a/lisp/international/characters.el +++ b/lisp/international/characters.el @@ -1078,10 +1078,10 @@ with L, LRE, or LRO Unicode bidi character type.") ;; (lambda (range ignore) (set-char-table-range char-width-table range 2)) ;; 'tibetan) (map-charset-chars - (lambda (range ignore) (set-char-table-range char-width-table range 2)) + (lambda (range _ignore) (set-char-table-range char-width-table range 2)) 'indian-2-column) (map-charset-chars - (lambda (range ignore) (set-char-table-range char-width-table range 2)) + (lambda (range _ignore) (set-char-table-range char-width-table range 2)) 'arabic-2-column) ;; Internal use only. @@ -1110,8 +1110,7 @@ with L, LRE, or LRO Unicode bidi character type.") (defun use-cjk-char-width-table (locale-name) (while (char-table-parent char-width-table) (setq char-width-table (char-table-parent char-width-table))) - (let ((slot (assq locale-name cjk-char-width-table-list)) - table) + (let ((slot (assq locale-name cjk-char-width-table-list))) (or slot (error "Unknown locale for CJK language environment: %s" locale-name)) (unless (nth 1 slot) @@ -1119,7 +1118,7 @@ with L, LRE, or LRO Unicode bidi character type.") (dolist (charset-info (nthcdr 2 slot)) (let ((charset (car charset-info))) (dolist (code-range (cdr charset-info)) - (map-charset-chars #'(lambda (range arg) + (map-charset-chars #'(lambda (range _arg) (set-char-table-range table range 2)) charset nil (car code-range) (cdr code-range))))) @@ -1326,7 +1325,7 @@ Setup char-width-table appropriate for non-CJK language environment." (set-char-table-extra-slot char-script-table 0 (nreverse script-list))) (map-charset-chars - #'(lambda (range ignore) + #'(lambda (range _ignore) (set-char-table-range char-script-table range 'tibetan)) 'tibetan) diff --git a/lisp/international/fontset.el b/lisp/international/fontset.el index c2bbb171241..324d615c581 100644 --- a/lisp/international/fontset.el +++ b/lisp/international/fontset.el @@ -357,7 +357,7 @@ (dolist (elt cjk) (let ((mask (lsh 1 i))) (map-charset-chars - #'(lambda (range arg) + #'(lambda (range _arg) (let ((from (car range)) (to (cdr range))) (if (< to #x110000) (while (<= from to) @@ -876,7 +876,7 @@ Return nil if PATTERN doesn't conform to XLFD." (aset xlfd-fields i nil))) xlfd-fields))) -(defun x-compose-font-name (fields &optional reduce) +(defun x-compose-font-name (fields &optional _reduce) "Compose X fontname from FIELDS. FIELDS is a vector of XLFD fields, of length 12. If a field is nil, wild-card letter `*' is embedded. @@ -954,7 +954,7 @@ Done when `mouse-set-font' is called." (let ((family (aref xlfd-fields xlfd-regexp-family-subnum)) (weight (aref xlfd-fields xlfd-regexp-weight-subnum)) (slant (aref xlfd-fields xlfd-regexp-slant-subnum)) - (swidth (aref xlfd-fields xlfd-regexp-swidth-subnum)) + ;(swidth (aref xlfd-fields xlfd-regexp-swidth-subnum)) (size (aref xlfd-fields xlfd-regexp-pixelsize-subnum)) (nickname (aref xlfd-fields xlfd-regexp-registry-subnum)) name) @@ -1039,7 +1039,7 @@ This alist is used by the function `create-fontset-from-fontset-spec' to map charsets to scripts.") (defun create-fontset-from-fontset-spec (fontset-spec - &optional style-variant noerror) + &optional _style-variant _noerror) "Create a fontset from fontset specification string FONTSET-SPEC. FONTSET-SPEC is a string of the format: FONTSET-NAME,SCRIPT-NAME0:FONT-NAME0,SCRIPT-NAME1:FONT-NAME1, ... diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el index 62b96720771..34b1576d23e 100644 --- a/lisp/international/mule-cmds.el +++ b/lisp/international/mule-cmds.el @@ -1739,8 +1739,8 @@ This hook is mainly used for canceling the effect of This variable should be set only with \\[customize], which is equivalent to using the function `set-language-environment'." :link '(custom-manual "(emacs)Language Environments") - :set (lambda (symbol value) (set-language-environment value)) - :get (lambda (x) + :set (lambda (_symbol value) (set-language-environment value)) + :get (lambda (_x) (or (car-safe (assoc-string (if (symbolp current-language-environment) (symbol-name current-language-environment) diff --git a/lisp/international/mule.el b/lisp/international/mule.el index ed98c03fdcc..9af6bc369a4 100644 --- a/lisp/international/mule.el +++ b/lisp/international/mule.el @@ -407,12 +407,12 @@ PLIST (property list) may contain any type of information a user ;; because that makes a bootstrapping problem ;; if you need to recompile all the Lisp files using interpreted code. -(defun charset-id (charset) +(defun charset-id (_charset) "Always return 0. This is provided for backward compatibility." (declare (obsolete nil "23.1")) 0) -(defmacro charset-bytes (charset) +(defmacro charset-bytes (_charset) "Always return 0. This is provided for backward compatibility." (declare (obsolete nil "23.1")) 0) @@ -471,7 +471,7 @@ Return -1 if charset isn't an ISO 2022 one." ;;; CHARACTER (define-obsolete-function-alias 'char-valid-p 'characterp "23.1") -(defun generic-char-p (char) +(defun generic-char-p (_char) "Always return nil. This is provided for backward compatibility." (declare (obsolete nil "23.1")) nil) @@ -1429,7 +1429,7 @@ use either \\[customize] or \\[set-keyboard-coding-system]." :type '(coding-system :tag "Coding system") :link '(info-link "(emacs)Terminal Coding") :link '(info-link "(emacs)Unibyte Mode") - :set (lambda (symbol value) + :set (lambda (_symbol value) ;; Don't load encoded-kb unnecessarily. (if (or value (boundp 'encoded-kbd-setup-display)) (set-keyboard-coding-system value) @@ -1850,7 +1850,7 @@ If nothing is specified, the return value is nil." (head-end (+ head-start (min size 1024))) (tail-start (+ head-start (max (- size 3072) 0))) (tail-end (+ head-start size)) - coding-system head-found tail-found pos char-trans) + coding-system head-found tail-found char-trans) ;; Try a short cut by searching for the string "coding:" ;; and for "unibyte:" at the head and tail of SIZE bytes. (setq head-found (or (search-forward "coding:" head-end t) @@ -1960,11 +1960,10 @@ use \"coding: 'raw-text\" instead." :warning) (let ((funcs auto-coding-functions) (coding-system nil)) (while (and funcs (not coding-system)) - (setq coding-system (condition-case e - (save-excursion - (goto-char (point-min)) - (funcall (pop funcs) size)) - (error nil)))) + (setq coding-system (ignore-errors + (save-excursion + (goto-char (point-min)) + (funcall (pop funcs) size))))) (if coding-system (cons coding-system 'auto-coding-functions))))) diff --git a/lisp/isearch.el b/lisp/isearch.el index 072ccc26772..3ff75059b1a 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -777,7 +777,7 @@ See the command `isearch-forward' for more information." (interactive "P\np") (isearch-mode t nil nil (not no-recursive-edit) (null not-word))) -(defun isearch-forward-symbol (&optional not-symbol no-recursive-edit) +(defun isearch-forward-symbol (&optional _not-symbol no-recursive-edit) "Do incremental search forward for a symbol. The prefix argument is currently unused. Like ordinary incremental search except that your input is treated diff --git a/lisp/term/common-win.el b/lisp/term/common-win.el index 8fe10dc8e35..aadab96f75a 100644 --- a/lisp/term/common-win.el +++ b/lisp/term/common-win.el @@ -159,7 +159,7 @@ is not used)." initial-frame-alist))))) ;; Make -iconic apply only to the initial frame! -(defun x-handle-iconic (switch) +(defun x-handle-iconic (_switch) (setq initial-frame-alist (cons '(visibility . icon) initial-frame-alist))) @@ -175,7 +175,7 @@ is not used)." (declare-function x-parse-geometry "frame.c" (string)) ;; Handle the geometry option -(defun x-handle-geometry (switch) +(defun x-handle-geometry (_switch) (let* ((geo (x-parse-geometry (pop x-invocation-args))) (left (assq 'left geo)) (top (assq 'top geo)) @@ -216,7 +216,7 @@ is not used)." On X, the display name of individual X frames is recorded in the `display' frame parameter.") -(defun x-handle-display (switch) +(defun x-handle-display (_switch) "Handle -display DISPLAY option." (setq x-display-name (pop x-invocation-args)) ;; Make subshell programs see the same DISPLAY value Emacs really uses. diff --git a/lisp/term/pc-win.el b/lisp/term/pc-win.el index ab776ea6257..96831cea9a6 100644 --- a/lisp/term/pc-win.el +++ b/lisp/term/pc-win.el @@ -164,22 +164,22 @@ created." ;; platforms. (Bug#10783) ;; From src/xfns.c -(defun x-list-fonts (pattern &optional face frame maximum width) +(defun x-list-fonts (_pattern &optional _face _frame _maximum width) (if (or (null width) (and (numberp width) (= width 1))) (list "ms-dos") (list "no-such-font"))) (defun x-display-pixel-width (&optional frame) (frame-width frame)) (defun x-display-pixel-height (&optional frame) (frame-height frame)) -(defun x-display-planes (&optional frame) 4) ;bg switched to 16 colors as well -(defun x-display-color-cells (&optional frame) 16) -(defun x-server-max-request-size (&optional frame) 1000000) ; ??? -(defun x-server-vendor (&optional frame) t "GNU") -(defun x-server-version (&optional frame) '(1 0 0)) -(defun x-display-screens (&optional frame) 1) -(defun x-display-mm-height (&optional frame) 245) ; Guess the size of my -(defun x-display-mm-width (&optional frame) 322) ; monitor, EZ... -(defun x-display-backing-store (&optional frame) 'not-useful) -(defun x-display-visual-class (&optional frame) 'static-color) +(defun x-display-planes (&optional _frame) 4) ;bg switched to 16 colors as well +(defun x-display-color-cells (&optional _frame) 16) +(defun x-server-max-request-size (&optional _frame) 1000000) ; ??? +(defun x-server-vendor (&optional _frame) t "GNU") +(defun x-server-version (&optional _frame) '(1 0 0)) +(defun x-display-screens (&optional _frame) 1) +(defun x-display-mm-height (&optional _frame) 245) ; Guess the size of my +(defun x-display-mm-width (&optional _frame) 322) ; monitor, EZ... +(defun x-display-backing-store (&optional _frame) 'not-useful) +(defun x-display-visual-class (&optional _frame) 'static-color) (fset 'x-display-save-under 'ignore) (fset 'x-get-resource 'ignore) @@ -253,7 +253,7 @@ is not used)." (setq x-last-selected-text text)))))) ;; x-selection-owner-p is used in simple.el. -(defun x-selection-owner-p (&optional selection terminal) +(defun x-selection-owner-p (&optional _selection _terminal) "Whether the current Emacs process owns the given X Selection. The arg should be the name of the selection in question, typically one of the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'. @@ -285,7 +285,7 @@ On Nextstep, TERMINAL is unused. ;; x-own-selection-internal and x-disown-selection-internal are used ;; in select.el:x-set-selection. -(defun x-own-selection-internal (selection value &optional frame) +(defun x-own-selection-internal (_selection value &optional _frame) "Assert an X selection of the type SELECTION with and value VALUE. SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. \(Those are literal upper-case symbol names, since that's what X expects.) @@ -302,7 +302,7 @@ On Nextstep, FRAME is unused. (x-select-text value)) value) -(defun x-disown-selection-internal (selection &optional time-object terminal) +(defun x-disown-selection-internal (selection &optional _time-object _terminal) "If we own the selection SELECTION, disown it. Disowning it means there is no such selection. @@ -321,7 +321,8 @@ On MS-DOS, all this does is return non-nil if we own the selection. t)) ;; x-get-selection-internal is used in select.el -(defun x-get-selection-internal (selection-symbol target-type &optional time-stamp terminal) +(defun x-get-selection-internal (_selection-symbol _target-type + &optional _time-stamp _terminal) "Return text selected from some X window. SELECTION-SYMBOL is typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. \(Those are literal upper-case symbol names, since that's what X expects.) @@ -403,7 +404,7 @@ Errors out because it is not supposed to be called, ever." (error "terminal-init-internal called for window-system `%s'" (window-system))) -(defun msdos-initialize-window-system (&optional display) +(defun msdos-initialize-window-system (&optional _display) "Initialization function for the `pc' \"window system\"." (or (eq (window-system) 'pc) (error diff --git a/lisp/term/tty-colors.el b/lisp/term/tty-colors.el index 8002c53151b..5ba352a5c3a 100644 --- a/lisp/term/tty-colors.el +++ b/lisp/term/tty-colors.el @@ -767,7 +767,7 @@ (yes . 8)) "An alist of supported standard tty color modes and their aliases.") -(defun tty-color-alist (&optional frame) +(defun tty-color-alist (&optional _frame) "Return an alist of colors supported by FRAME's terminal. FRAME defaults to the selected frame. Each element of the returned alist is of the form: @@ -840,7 +840,7 @@ If FRAME is not specified or is nil, it defaults to the selected frame." (tty-modify-color-alist (append (list (tty-color-canonicalize name) index) rgb) frame)) -(defun tty-color-clear (&optional frame) +(defun tty-color-clear (&optional _frame) "Clear the list of supported tty colors for frame FRAME. If FRAME is unspecified or nil, it defaults to the selected frame." (setq tty-defined-color-alist nil)) diff --git a/lisp/term/x-win.el b/lisp/term/x-win.el index ab1556d5779..28fd3d7090c 100644 --- a/lisp/term/x-win.el +++ b/lisp/term/x-win.el @@ -87,7 +87,7 @@ (defvar x-session-id) (defvar x-session-previous-id) -(defun x-handle-no-bitmap-icon (switch) +(defun x-handle-no-bitmap-icon (_switch) (setq default-frame-alist (cons '(icon-type) default-frame-alist))) ;; Handle the --parent-id option. diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el index ae9aa0118ae..c47bc4c7f97 100644 --- a/lisp/vc/vc-hooks.el +++ b/lisp/vc/vc-hooks.el @@ -190,7 +190,7 @@ individually should stay local." (make-variable-buffer-local 'vc-mode) (put 'vc-mode 'permanent-local t) -(defun vc-mode (&optional arg) +(defun vc-mode (&optional _arg) ;; Dummy function for C-h m "Version Control minor mode. This minor mode is automatically activated whenever you visit a file under @@ -631,7 +631,7 @@ this function." (define-obsolete-function-alias 'vc-toggle-read-only 'toggle-read-only "24.1") -(defun vc-default-make-version-backups-p (backend file) +(defun vc-default-make-version-backups-p (_backend _file) "Return non-nil if unmodified versions should be backed up locally. The default is to switch off this feature." nil) @@ -834,7 +834,7 @@ current, and kill the buffer that visits the link." (set-buffer true-buffer) (kill-buffer this-buffer)))) -(defun vc-default-find-file-hook (backend) +(defun vc-default-find-file-hook (_backend) nil) (defun vc-find-file-hook () @@ -1033,7 +1033,7 @@ current, and kill the buffer that visits the link." '((ext-menu-separator "--")) ext-binding)))) -(defun vc-default-extra-menu (backend) +(defun vc-default-extra-menu (_backend) nil) (provide 'vc-hooks) diff --git a/lisp/version.el b/lisp/version.el index 5db45da860c..96674566781 100644 --- a/lisp/version.el +++ b/lisp/version.el @@ -104,7 +104,7 @@ Returns nil if unable to find this information." (looking-at "[0-9]+\0\\([^\0\n]+\\)\0") (match-string 1)))))) -(defun emacs-bzr-version-bzr (dir) +(defun emacs-bzr-version-bzr (_dir) "Ask bzr itself for the version information for directory DIR." ;; Comments on `bzr version-info': ;; i) Unknown files also cause clean != 1. diff --git a/lisp/window.el b/lisp/window.el index c36244f8f4e..b14d91cb924 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -685,10 +685,8 @@ symbols and values as passed to `display-buffer-in-side-window'. This function may be called only if no window on SIDE exists yet. The new window automatically becomes the \"major\" side window on SIDE. Return the new window, nil if its creation window failed." - (let* ((root (frame-root-window)) - (left-or-right (memq side '(left right))) + (let* ((left-or-right (memq side '(left right))) (major (window--major-side-window side)) - (selected-window (selected-window)) (on-side (cond ((eq side 'top) 'above) ((eq side 'bottom) 'below) @@ -698,8 +696,7 @@ SIDE. Return the new window, nil if its creation window failed." ;; parent window unless needed. (window-combination-resize 'side) (window-combination-limit nil) - (new (split-window major nil on-side)) - fun) + (new (split-window major nil on-side))) (when new ;; Initialize `window-side' parameter of new window to SIDE. (set-window-parameter new 'window-side side) @@ -749,8 +746,7 @@ following symbols can be used: A positive value means use a slot following (that is, below or on the right of) the middle slot. The default is zero." (let ((side (or (cdr (assq 'side alist)) 'bottom)) - (slot (or (cdr (assq 'slot alist)) 0)) - new) + (slot (or (cdr (assq 'slot alist)) 0))) (cond ((not (memq side '(top bottom left right))) (error "Invalid side %s specified" side)) @@ -776,9 +772,8 @@ following symbols can be used: ((eq side 'right) 2) ((eq side 'bottom) 3)) window-sides-slots)) - (selected-window (selected-window)) window this-window this-slot prev-window next-window - best-window best-slot abs-slot new-window) + best-window best-slot abs-slot) (cond ((and (numberp max-slots) (<= max-slots 0)) @@ -5730,7 +5725,7 @@ above, even if that window never showed BUFFER before." 0) (display-buffer-reuse-frames 0) (t (last-nonminibuffer-frame)))) - entry best-window second-best-window window) + best-window second-best-window window) ;; Scan windows whether they have shown the buffer recently. (catch 'best (dolist (window (window-list-1 (frame-first-window) 'nomini frames)) From 77187e6f36e423fbf291ce9ea824d4b8da66108d Mon Sep 17 00:00:00 2001 From: Juanma Barranquero Date: Fri, 9 Aug 2013 02:30:24 +0200 Subject: [PATCH 091/449] Move frameset-to-register stuff from register.el to frameset.el. lisp/register.el (frameset-frame-id, frameset-frame-with-id, frameset-p) (frameset-restore, frameset-save, frameset-session-filter-alist): Remove declarations. (register-alist): Doc fix. (frameset-to-register): Move to frameset.el. (jump-to-register, describe-register-1): Remove frameset-specific code. lisp/frameset.el (frameset-p): Add autoload cookie. (frameset--jump-to-register): New function, based on code moved from register.el. (frameset-to-register): Move from register.el. Adapt to `registerv'. --- lisp/ChangeLog | 14 ++++++++++++++ lisp/frameset.el | 38 ++++++++++++++++++++++++++++++++++++++ lisp/register.el | 39 +-------------------------------------- 3 files changed, 53 insertions(+), 38 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index f240aa445d0..382c5804330 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,17 @@ +2013-08-09 Juanma Barranquero + + * frameset.el (frameset-p): Add autoload cookie. + (frameset--jump-to-register): New function, based on code moved from + register.el. + (frameset-to-register): Move from register.el. Adapt to `registerv'. + + * register.el (frameset-frame-id, frameset-frame-with-id, frameset-p) + (frameset-restore, frameset-save, frameset-session-filter-alist): + Remove declarations. + (register-alist): Doc fix. + (frameset-to-register): Move to frameset.el. + (jump-to-register, describe-register-1): Remove frameset-specific code. + 2013-08-08 Juanma Barranquero * allout-widgets.el (allout-widgets-pre-command-business) diff --git a/lisp/frameset.el b/lisp/frameset.el index b1ad9f7702a..132cbcd4856 100644 --- a/lisp/frameset.el +++ b/lisp/frameset.el @@ -129,6 +129,9 @@ root window of the frame.\n IMPORTANT: Modifying this slot may cause frameset functions to fail, unless the type constraints defined above are respected.\n\n(fn FRAMESET)") +;;;###autoload (autoload 'frameset-p "frameset" +;;;###autoload "Return non-nil if OBJECT is a frameset, nil otherwise." nil) + (defun frameset-copy (frameset) "Return a deep copy of FRAMESET. FRAMESET is copied with `copy-tree'." @@ -1184,6 +1187,41 @@ All keyword parameters default to nil." (unless (or (daemonp) (visible-frame-list)) (make-frame-visible (car (frame-list)))))) + +;; Register support + +(defun frameset--jump-to-register (data) + "Restore frameset from DATA stored in register. +Called from `jump-to-register'. Internal use only." + (let* ((delete (and current-prefix-arg t)) + (iconify-list (if delete nil (frame-list)))) + (frameset-restore (aref data 0) + :filters frameset-session-filter-alist + :reuse-frames (if delete t :keep)) + (mapc #'iconify-frame iconify-list) + (let ((frame (frameset-frame-with-id (aref data 1)))) + (when frame + (select-frame-set-input-focus frame) + (goto-char (aref data 2)))))) + +;;;###autoload +(defun frameset-to-register (register &optional _arg) + "Store the current frameset in register REGISTER. +Use \\[jump-to-register] to restore the frameset. +Argument is a character, naming the register." + (interactive "cFrameset to register: \nP") + (set-register register + (registerv-make + (vector (frameset-save nil + :app 'register + :filters frameset-session-filter-alist) + ;; frameset-save does not include the value of point + ;; in the current buffer, so record that separately. + (frameset-frame-id nil) + (point-marker)) + :print-func (lambda (_data) (princ "a frameset.")) + :jump-func #'frameset--jump-to-register))) + (provide 'frameset) ;;; frameset.el ends here diff --git a/lisp/register.el b/lisp/register.el index 84305f71d03..78f18dbc7c1 100644 --- a/lisp/register.el +++ b/lisp/register.el @@ -31,12 +31,6 @@ (eval-when-compile (require 'cl-lib)) -(declare-function frameset-frame-id "frameset" (frame)) -(declare-function frameset-frame-with-id "frameset" (id &optional frame-list)) -(declare-function frameset-p "frameset" (frameset)) -(declare-function frameset-restore "frameset" (frameset &rest keys) t) -(declare-function frameset-save "frameset" (frame-list &rest keys) t) - ;;; Code: (cl-defstruct @@ -77,9 +71,7 @@ A list of the form (file-query FILE-NAME POSITION) represents A list of the form (WINDOW-CONFIGURATION POSITION) represents a saved window configuration plus a saved value of point. A list of the form (FRAME-CONFIGURATION POSITION) - represents a saved frame configuration plus a saved value of point. -A list of the form (FRAMESET FRAME-ID POSITION) - represents a saved frameset plus the value of point in frame FRAME-ID.") + represents a saved frame configuration plus a saved value of point.") (defgroup register nil "Register commands." @@ -140,22 +132,6 @@ Argument is a character, naming the register." ;; of point in the current buffer, so record that separately. (set-register register (list (current-frame-configuration) (point-marker)))) -(defvar frameset-session-filter-alist) - -(defun frameset-to-register (register &optional _arg) - "Store the current frameset in register REGISTER. -Use \\[jump-to-register] to restore the frameset. -Argument is a character, naming the register." - (interactive "cFrameset to register: \nP") - (set-register register - (list (frameset-save nil - :app 'register - :filters frameset-session-filter-alist) - ;; frameset-save does not include the value of point - ;; in the current buffer, so record that separately. - (frameset-frame-id nil) - (point-marker)))) - (defalias 'register-to-point 'jump-to-register) (defun jump-to-register (register &optional delete) "Move point to location stored in a register. @@ -181,16 +157,6 @@ delete any existing frames that the frameset doesn't mention. ((and (consp val) (window-configuration-p (car val))) (set-window-configuration (car val)) (goto-char (cadr val))) - ((and (consp val) (frameset-p (car val))) - (let ((iconify-list (if delete nil (frame-list))) - frame) - (frameset-restore (car val) - :filters frameset-session-filter-alist - :reuse-frames (if delete t :keep)) - (mapc #'iconify-frame iconify-list) - (when (setq frame (frameset-frame-with-id (cadr val))) - (select-frame-set-input-focus frame) - (goto-char (nth 2 val))))) ((markerp val) (or (marker-buffer val) (error "That register's buffer no longer exists")) @@ -303,9 +269,6 @@ The Lisp value REGISTER is a character." ((and (consp val) (frame-configuration-p (car val))) (princ "a frame configuration.")) - ((and (consp val) (frameset-p (car val))) - (princ "a frameset.")) - ((and (consp val) (eq (car val) 'file)) (princ "the file ") (prin1 (cdr val)) From 353ca646bb2de8184280db51e46b3939966f8847 Mon Sep 17 00:00:00 2001 From: Xue Fuqiao Date: Fri, 9 Aug 2013 08:46:25 +0800 Subject: [PATCH 092/449] * doc/misc/htmlfontify.texi (Customization): Remove documentation of `hfy-fast-lock-save'. --- doc/misc/ChangeLog | 5 +++++ doc/misc/htmlfontify.texi | 26 +------------------------- 2 files changed, 6 insertions(+), 25 deletions(-) diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog index 4134895073f..6dc322e5473 100644 --- a/doc/misc/ChangeLog +++ b/doc/misc/ChangeLog @@ -1,3 +1,8 @@ +2013-08-09 Xue Fuqiao + + * htmlfontify.texi (Customization): Remove documentation of + `hfy-fast-lock-save'. + 2013-08-08 Xue Fuqiao * ido.texi (Top): Insert node "Working Directories" in menu. diff --git a/doc/misc/htmlfontify.texi b/doc/misc/htmlfontify.texi index e45234872e2..1c84fa10afe 100644 --- a/doc/misc/htmlfontify.texi +++ b/doc/misc/htmlfontify.texi @@ -1275,6 +1275,7 @@ normally be applied. @vindex hfy-html-quote-regex @anchor{hfy-html-quote-regex} +@c FIXME: the cross-reference below looks ugly Regex to match (with a single back-reference per match) strings in HTML which should be quoted with @ref{hfy-html-quote} (and @pxref{hfy-html-quote-map}) to make them safe. @@ -1340,31 +1341,6 @@ See also: @ref{hfy-page-footer} String to add to the @samp{