commit ca369a8ca67a4cb279a5412cca36109e719a520e (HEAD, refs/remotes/origin/master) Author: Eli Zaretskii Date: Sat Jun 9 11:03:20 2018 +0300 Allow to reset Deleted flag when exporting messages in Rmail * lisp/mail/rmailout.el (rmail-output-reset-deleted-flag): New defcustom. (rmail-output): When 'rmail-output-reset-deleted-flag' is non-nil, reset the Deleted flag of the appended messages, and if COUNT is greater than 1, do not ignore deleted messages. Update the doc string accordingly. (Bug#31271) * doc/emacs/rmail.texi (Rmail Output): Document 'rmail-output-reset-deleted-flag'. * etc/NEWS: Mention the new user option. diff --git a/doc/emacs/rmail.texi b/doc/emacs/rmail.texi index 068111cab1..a17ef4938e 100644 --- a/doc/emacs/rmail.texi +++ b/doc/emacs/rmail.texi @@ -529,13 +529,18 @@ file name from the message @samp{Subject} header. @kindex C-o @r{(Rmail)} @findex rmail-output-as-seen The commands @kbd{o} and @kbd{C-o} copy the current message into a -specified file, adding it at the end. The two commands differ mainly -in how much to copy: @kbd{o} copies the full message headers, even if -they are not all visible, while @kbd{C-o} copies exactly the headers -currently displayed and no more. @xref{Rmail Display}. In addition, -@kbd{o} converts the message to Babyl format (used by Rmail in Emacs -version 22 and before) if the file is in Babyl format; @kbd{C-o} -cannot output to Babyl files at all. +specified file, adding it at the end. A positive prefix argument +serves as a repeat count: that many consecutive messages will be +copied to the specified file, starting with the current one and +ignoring deleted messages. + +The two commands differ mainly in how much to copy: @kbd{o} copies the +full message headers, even if they are not all visible, while +@kbd{C-o} copies exactly the headers currently displayed and no more. +@xref{Rmail Display}. In addition, @kbd{o} converts the message to +Babyl format (used by Rmail in Emacs version 22 and before) if the +file is in Babyl format; @kbd{C-o} cannot output to Babyl files at +all. @c FIXME remove BABYL mention in some future version? If the output file is currently visited in an Emacs buffer, the @@ -565,17 +570,29 @@ second says which files in that directory to offer (all those that match the regular expression). If no files match, you cannot select this menu item. -@vindex rmail-delete-after-output Copying a message with @kbd{o} or @kbd{C-o} gives the original copy of the message the @samp{filed} attribute, so that @samp{filed} appears in the mode line when such a message is current. +@vindex rmail-delete-after-output If you like to keep just a single copy of every mail message, set the variable @code{rmail-delete-after-output} to @code{t}; then the @kbd{o}, @kbd{C-o} and @kbd{w} commands delete the original message after copying it. (You can undelete it afterward if you wish, see @ref{Rmail Deletion}.) +@vindex rmail-output-reset-deleted-flag + By default, @kbd{o} will leave the deleted status of a message it +outputs as it was on the original message; thus, a message deleted +before it was output will appear as deleted in the output file. +Setting the variable @code{rmail-output-reset-deleted-flag} to a +non-@code{nil} value countermands that: the copy of the message will +have its deleted status reset, so the message will appear as undeleted +in the output file. In addition, when this variable is +non-@code{nil}, specifying a positive argument to @kbd{o} will not +ignore deleted messages when looking for consecutive messages to +output. + @vindex rmail-output-file-alist The variable @code{rmail-output-file-alist} lets you specify intelligent defaults for the output file, based on the contents of the diff --git a/etc/NEWS b/etc/NEWS index 3371718473..4ea3440754 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -482,6 +482,13 @@ It now applies to epg functions as well as epa functions. been removed. Use 'encode-coding-string', 'decode-coding-string', and 'select-safe-coding-system' instead. +** Rmail + ++++ +*** New user option 'rmail-output-reset-deleted-flag'. +If this option is non-nil, messages appended to an output file by the +'rmail-output' command have their Deleted flag reset. + * New Modes and Packages in Emacs 27.1 +++ diff --git a/lisp/mail/rmailout.el b/lisp/mail/rmailout.el index eee8805ab4..824b1a59fb 100644 --- a/lisp/mail/rmailout.el +++ b/lisp/mail/rmailout.el @@ -56,6 +56,13 @@ The function `rmail-delete-unwanted-fields' uses this, ignoring case." regexp) :group 'rmail-output) +(defcustom rmail-output-reset-deleted-flag nil + "Non-nil means reset the \"deleted\" flag when outputting a message to a file." + :type '(choice (const :tag "Output with the \"deleted\" flag reset" t) + (const :tag "Output with the \"deleted\" flag intact" nil)) + :version "27.1" + :group 'rmail-output) + (defun rmail-output-read-file-name () "Read the file name to use for `rmail-output'. Set `rmail-default-file' to this name as well as returning it. @@ -472,9 +479,15 @@ buffer, updates it accordingly. This command always outputs the complete message header, even if the header display is currently pruned. +If `rmail-output-reset-deleted-flag' is non-nil, the message's +deleted flag is reset in the message appended to the destination +file. Otherwise, the appended message will remain marked as +deleted if it was deleted before invoking this command. + Optional prefix argument COUNT (default 1) says to output that many consecutive messages, starting with the current one (ignoring -deleted messages). If `rmail-delete-after-output' is non-nil, deletes +deleted messages, unless `rmail-output-reset-deleted-flag' is +non-nil). If `rmail-delete-after-output' is non-nil, deletes messages after output. The optional third argument NOATTRIBUTE, if non-nil, says not to @@ -533,30 +546,47 @@ from a non-Rmail buffer. In this case, COUNT is ignored." (if (zerop rmail-total-messages) (error "No messages to output")) (let ((orig-count count) - beg end) + beg end delete-attr-reset-p) (while (> count 0) - (setq beg (rmail-msgbeg rmail-current-message) - end (rmail-msgend rmail-current-message)) - ;; All access to the buffer's local variables is now finished... - (save-excursion - ;; ... so it is ok to go to a different buffer. - (if (rmail-buffers-swapped-p) (set-buffer rmail-view-buffer)) - (setq cur (current-buffer)) - (save-restriction - (widen) - (with-temp-buffer - (insert-buffer-substring cur beg end) - (if babyl-format - (rmail-output-as-babyl file-name noattribute) - (rmail-output-as-mbox file-name noattribute))))) + (when (and rmail-output-reset-deleted-flag + (rmail-message-deleted-p rmail-current-message)) + (rmail-set-attribute rmail-deleted-attr-index nil) + (setq delete-attr-reset-p t)) + ;; Make sure we undo our messing with the DELETED attribute. + (unwind-protect + (progn + (setq beg (rmail-msgbeg rmail-current-message) + end (rmail-msgend rmail-current-message)) + ;; All access to the buffer's local variables is now finished... + (save-excursion + ;; ... so it is ok to go to a different buffer. + (if (rmail-buffers-swapped-p) (set-buffer rmail-view-buffer)) + (setq cur (current-buffer)) + (save-restriction + (widen) + (with-temp-buffer + (insert-buffer-substring cur beg end) + (if babyl-format + (rmail-output-as-babyl file-name noattribute) + (rmail-output-as-mbox file-name noattribute)))))) + (if delete-attr-reset-p + (rmail-set-attribute rmail-deleted-attr-index t))) (or noattribute ; mark message as "filed" (rmail-set-attribute rmail-filed-attr-index t)) (setq count (1- count)) (let ((next-message-p - (if rmail-delete-after-output - (rmail-delete-forward) - (if (> count 0) - (rmail-next-undeleted-message 1)))) + (if rmail-output-reset-deleted-flag + (progn + (if rmail-delete-after-output + (rmail-delete-message)) + (if (> count 0) + (let ((msgnum rmail-current-message)) + (rmail-next-message 1) + (eq rmail-current-message (1+ msgnum))))) + (if rmail-delete-after-output + (rmail-delete-forward) + (if (> count 0) + (rmail-next-undeleted-message 1))))) (num-appended (- orig-count count))) (if (and (> count 0) (not next-message-p)) (error "Only %d message%s appended" num-appended commit f716ad94a8b0417d006a86baaa1977a40574407c Merge: c8dd1bc0fb 49ba7544c2 Author: Eli Zaretskii Date: Sat Jun 9 09:55:46 2018 +0300 Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs commit 49ba7544c2ebbcfc50ce1e02add6bd739f475c4c Author: Paul Eggert Date: Fri Jun 8 23:53:58 2018 -0700 Remove AddressSanitizer bug workaround This workaround no longer appears to be needed. * src/alloc.c (USE_ALIGNED_ALLOC): Don’t leave undefined merely because ADDRESS_SANITIZER is defined, as that bug in -fsanitize=address appears to have been fixed. See: https://github.com/google/sanitizers/issues/337 * src/conf_post.h (vfork): Improve comment. diff --git a/src/alloc.c b/src/alloc.c index 4186347440..f600c89ae2 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -1146,11 +1146,10 @@ lisp_free (void *block) verify (POWER_OF_2 (BLOCK_ALIGN)); /* Use aligned_alloc if it or a simple substitute is available. - Address sanitization breaks aligned allocation, as of gcc 4.8.2 and - clang 3.3 anyway. Aligned allocation is incompatible with - unexmacosx.c, so don't use it on Darwin. */ + Aligned allocation is incompatible with unexmacosx.c, so don't use + it on Darwin unless CANNOT_DUMP. */ -#if ! ADDRESS_SANITIZER && !defined DARWIN_OS +#if !defined DARWIN_OS || defined CANNOT_DUMP # if (defined HAVE_ALIGNED_ALLOC \ || (defined HYBRID_MALLOC \ ? defined HAVE_POSIX_MEMALIGN \ @@ -1446,7 +1445,7 @@ laligned (void *p, size_t size) static void * lmalloc (size_t size) { -#if USE_ALIGNED_ALLOC +#ifdef USE_ALIGNED_ALLOC if (! MALLOC_IS_GC_ALIGNED && size % GCALIGNMENT == 0) return aligned_alloc (GCALIGNMENT, size); #endif diff --git a/src/conf_post.h b/src/conf_post.h index bf2cfc4f05..30f3b95305 100644 --- a/src/conf_post.h +++ b/src/conf_post.h @@ -350,7 +350,8 @@ extern int emacs_setenv_TZ (char const *); # define ATTRIBUTE_NO_SANITIZE_UNDEFINED #endif -/* gcc -fsanitize=address does not work with vfork in Fedora 25 x86-64. +/* gcc -fsanitize=address does not work with vfork in Fedora 28 x86-64. See: + https://lists.gnu.org/r/emacs-devel/2017-05/msg00464.html For now, assume that this problem occurs on all platforms. */ #if ADDRESS_SANITIZER && !defined vfork # define vfork fork commit c8dd1bc0fb9f9485eaf3766303b36f8e5243ab57 Author: Basil L. Contovounesios Date: Sun Jun 3 19:34:37 2018 +0100 Fix default candidate of find-face-definition * lisp/emacs-lisp/find-func.el (find-function-read): Use face-at-point instead of variable-at-point for faces. (bug#31699) diff --git a/lisp/emacs-lisp/find-func.el b/lisp/emacs-lisp/find-func.el index 300bfab323..c5424693ec 100644 --- a/lisp/emacs-lisp/find-func.el +++ b/lisp/emacs-lisp/find-func.el @@ -466,6 +466,7 @@ If TYPE is nil, defaults using `function-called-at-point', otherwise uses `variable-at-point'." (let* ((symb1 (cond ((null type) (function-called-at-point)) ((eq type 'defvar) (variable-at-point)) + ((eq type 'defface) (face-at-point t)) (t (variable-at-point t)))) (symb (unless (eq symb1 0) symb1)) (predicate (cdr (assq type '((nil . fboundp) commit c67befd662571a822f3183c114ce3b1ad02e0ed9 Author: Daniel Colascione Date: Fri Jun 8 23:22:23 2018 -0700 Avoid unnecessary readahead early in TTY frame init We query some properties of the terminal early in initialization, and just before we do, we perform ordinary redisplay. This redisplay can result in unsightly flickering if we change some aspects of the display immediately afterward and redisplay again. By avoiding redisplay in xquery--query as long as we get timely responses from the terminal, we can avoid this early unwanted redisplay. * lisp/term/xterm.el: (xterm-query-redisplay-timeout): New variable. (xterm--read-event-for-query): New function. (xterm--report-background-handler,xterm--version-handler,xterm--query): Call it. diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el index 6410a4b83c..06a9d443bf 100644 --- a/lisp/term/xterm.el +++ b/lisp/term/xterm.el @@ -652,7 +652,7 @@ Return the pasted text as a string." (let ((str "") chr) ;; The reply should be: \e ] 11 ; rgb: NUMBER1 / NUMBER2 / NUMBER3 \e \\ - (while (and (setq chr (read-event nil nil 2)) (not (equal chr ?\\))) + (while (and (setq chr (xterm--read-event-for-query)) (not (equal chr ?\\))) (setq str (concat str (string chr)))) (when (string-match "rgb:\\([a-f0-9]+\\)/\\([a-f0-9]+\\)/\\([a-f0-9]+\\)" str) @@ -680,7 +680,7 @@ Return the pasted text as a string." ;; respond to this escape sequence. RMS' opinion was to remove ;; it completely. That might be right, but let's first try to ;; see if by using a longer timeout we get rid of most issues. - (while (and (setq chr (read-event nil nil 2)) (not (equal chr ?c))) + (while (and (setq chr (xterm--read-event-for-query)) (not (equal chr ?c))) (setq str (concat str (string chr)))) ;; Since xterm-280, the terminal type (NUMBER1) is now 41 instead of 0. (when (string-match "\\([0-9]+\\);\\([0-9]+\\);0" str) @@ -730,6 +730,24 @@ Return the pasted text as a string." "Seconds to wait for an answer from the terminal. Can be nil to mean \"no timeout\".") +(defvar xterm-query-redisplay-timeout 0.2 + "Seconds to wait before allowing redisplay during terminal + query." ) + +(defun xterm--read-event-for-query () + "Like read-event, but inhibit redisplay. + +By not redisplaying right away for xterm queries, we can avoid +unsightly flashing during initialization. Give up and redisplay +anyway if we've been waiting a little while." + (let ((start-time (float-time))) + (or (let ((inhibit-redisplay t)) + (read-event nil nil xterm-query-redisplay-timeout)) + (read-event nil nil + (and xterm-query-timeout + (max 0 (+ start-time xterm-query-timeout + (- (float-time))))))))) + (defun xterm--query (query handlers &optional no-async) "Send QUERY string to the terminal and watch for a response. HANDLERS is an alist with elements of the form (STRING . FUNCTION). @@ -762,7 +780,7 @@ We run the first FUNCTION whose STRING matches the input events." (let ((handler (pop handlers)) (i 0)) (while (and (< i (length (car handler))) - (let ((evt (read-event nil nil xterm-query-timeout))) + (let ((evt (xterm--read-event-for-query))) (if (and (null evt) (= i 0) (not no-async)) ;; Timeout on the first event: fallback on async. (progn commit 6fdc3fac5658a7ab142c358cddd90f3db5665ef5 Author: Daniel Colascione Date: Fri Jun 8 22:47:27 2018 -0700 Support terminal focus notifications * lisp/frame.el (handle-focus-in,handle-focus-out): Make event argument optional. (blink-cursor-check): Make sure that the current frame is a window-system frame before restarting the blink timer. TTY frames can get focus, but don't need a blink timer because the terminal will do the blinking. * lisp/term/xterm.el (xterm-handle-focus-in,xterm-handle-focus-out): New functions. (xterm-rxvt-function-map): Recognize focus notification sequences. (xterm--init-focus-tracking): New function. (terminal-init-xterm): Call it. diff --git a/etc/NEWS b/etc/NEWS index 46a57b1888..3371718473 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -575,6 +575,11 @@ manual for more details. * Lisp Changes in Emacs 27.1 ++++ +** Emacs now requests and recognizes focus-change notifications from + terminals that support the feature, meaning that `focus-in-hook' + and `focus-out-hook' may run for TTY frames. + +++ ** Face specifications (of the kind used in `face-remapping-alist') now support filters, allowing faces to vary between windows display diff --git a/lisp/frame.el b/lisp/frame.el index 359c503655..c3daff4440 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -129,7 +129,7 @@ appended when the minibuffer frame is created." ;; Gildea@x.org says it is ok to ask questions before terminating. (save-buffers-kill-emacs)))) -(defun handle-focus-in (_event) +(defun handle-focus-in (&optional _event) "Handle a focus-in event. Focus-in events are usually bound to this function. Focus-in events occur when a frame has focus, but a switch-frame event @@ -138,7 +138,7 @@ This function runs the hook `focus-in-hook'." (interactive "e") (run-hooks 'focus-in-hook)) -(defun handle-focus-out (_event) +(defun handle-focus-out (&optional _event) "Handle a focus-out event. Focus-out events are usually bound to this function. Focus-out events occur when no frame has focus. @@ -2339,7 +2339,8 @@ frame receives focus." This is done when a frame gets focus. Blink timers may be stopped by `blink-cursor-suspend'." (when (and blink-cursor-mode - (not blink-cursor-idle-timer)) + (not blink-cursor-idle-timer) + (display-graphic-p)) (remove-hook 'post-command-hook 'blink-cursor-check) (blink-cursor--start-idle-timer))) diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el index fea9851d72..6410a4b83c 100644 --- a/lisp/term/xterm.el +++ b/lisp/term/xterm.el @@ -104,6 +104,16 @@ Return the pasted text as a string." (define-key global-map [xterm-paste] #'xterm-paste) +(defun xterm-handle-focus-in () + (interactive) + (handle-focus-in)) +(define-key global-map [xterm-focus-in] #'xterm-handle-focus-in) + +(defun xterm-handle-focus-out () + (interactive) + (handle-focus-out)) +(define-key global-map [xterm-focus-out] #'xterm-handle-focus-out) + (defvar xterm-rxvt-function-map (let ((map (make-sparse-keymap))) (define-key map "\e[2~" [insert]) @@ -136,6 +146,9 @@ Return the pasted text as a string." ;; internally recognizes the end. (define-key map "\e[200~" [xterm-paste]) + (define-key map "\e[I" [xterm-focus-in]) + (define-key map "\e[O" [xterm-focus-out]) + map) "Keymap of escape sequences, shared between xterm and rxvt support.") @@ -817,6 +830,8 @@ We run the first FUNCTION whose STRING matches the input events." ;; Unconditionally enable bracketed paste mode: terminals that don't ;; support it just ignore the sequence. (xterm--init-bracketed-paste-mode) + ;; We likewise unconditionally enable support for focus tracking. + (xterm--init-focus-tracking) (run-hooks 'terminal-init-xterm-hook)) @@ -832,6 +847,12 @@ We run the first FUNCTION whose STRING matches the input events." (push "\e[?2004l" (terminal-parameter nil 'tty-mode-reset-strings)) (push "\e[?2004h" (terminal-parameter nil 'tty-mode-set-strings))) +(defun xterm--init-focus-tracking () + "Terminal initialization for focus tracking mode." + (send-string-to-terminal "\e[?1004h") + (push "\e[?1004l" (terminal-parameter nil 'tty-mode-reset-strings)) + (push "\e[?1004h" (terminal-parameter nil 'tty-mode-set-strings))) + (defun xterm--init-activate-get-selection () "Terminal initialization for `gui-get-selection'." (set-terminal-parameter nil 'xterm--get-selection t)) commit f1e65b73ca20f72717d0b50fa5d983668a49bc38 Author: Daniel Colascione Date: Fri Jun 8 21:21:47 2018 -0700 Fix formatting in the face filter change * src/xfaces.c: (evaluate_face_filter,filter_face_ref) (merge_face_ref,syms_of_xfaces): Fix comments, formatting. diff --git a/src/xfaces.c b/src/xfaces.c index 961bef7c9c..265581cca8 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -2193,8 +2193,10 @@ merge_named_face (struct window *w, (:window PARAMETER VALUE), which matches if the current window has a PARAMETER EQ to VALUE. - If the filter is invalid, set *OK to false and, if ERR_MSGS is - true, log an error message. */ + This function returns true if the face filter matches and false if + it doesn't or if the function encountered an error. If the filter + is invalid, set *OK to false and, if ERR_MSGS is true, log an error + message. On success, *OK is untouched. */ static bool evaluate_face_filter (Lisp_Object filter, struct window *w, bool *ok, bool err_msgs) @@ -2211,7 +2213,7 @@ evaluate_face_filter (Lisp_Object filter, struct window *w, if (!CONSP (filter)) goto err; - if (!EQ (XCAR (filter), Qwindow_kw)) + if (!EQ (XCAR (filter), QCwindow)) goto err; filter = XCDR (filter); @@ -2226,11 +2228,12 @@ evaluate_face_filter (Lisp_Object filter, struct window *w, goto err; bool match = false; - if (w) { - Lisp_Object found = assq_no_quit (parameter, w->window_parameters); - if (!NILP (found) && EQ (XCDR (found), value)) - match = true; - } + if (w) + { + Lisp_Object found = assq_no_quit (parameter, w->window_parameters); + if (!NILP (found) && EQ (XCDR (found), value)) + match = true; + } return match; } @@ -2243,15 +2246,16 @@ evaluate_face_filter (Lisp_Object filter, struct window *w, } /* Determine whether FACE_REF is a "filter" face specification (case - #4 in merge_face_ref). If it is, evaluate the filter, and if the - filter matches, return the filtered expression. Otherwise, return - the original expression. + #4 in merge_face_ref). If it is, evaluate the filter, and if the + filter matches, return the filtered expression. If the filter does + not match, return `nil'. If FACE_REF is not a filtered face + specification, return FACE_REF. On error, set *OK to false, having logged an error message if - ERR_MSGS is true, with return value unspecified. + ERR_MSGS is true, and return `nil'. - W is either NULL or a window used to evaluate filters. If W is - null, no window-based face specification filter matches. + W is either NULL or a window used to evaluate filters. If W is + NULL, no window-based face specification filter matches. */ static Lisp_Object filter_face_ref (Lisp_Object face_ref, @@ -2263,8 +2267,10 @@ filter_face_ref (Lisp_Object face_ref, if (!CONSP (face_ref)) return face_ref; + /* Inner braces keep compiler happy about the goto skipping variable + initialization. */ { - if (!EQ (XCAR (face_ref), Qfiltered_kw)) + if (!EQ (XCAR (face_ref), QCfiltered)) return face_ref; face_ref = XCDR (face_ref); @@ -2336,7 +2342,8 @@ merge_face_ref (struct window *w, { face_ref = filtered_face_ref; filtered_face_ref = filter_face_ref (face_ref, w, &ok, err_msgs); - } while (ok && !EQ (face_ref, filtered_face_ref)); + } + while (ok && !EQ (face_ref, filtered_face_ref)); if (!ok) return false; @@ -4569,8 +4576,8 @@ face_for_font (struct frame *f, Lisp_Object font_object, struct face *base_face) frame F suitable for displaying ASCII characters. Value is -1 if the face couldn't be determined, which might happen if the default face isn't realized and cannot be realized. If window W is given, - consider face remappings specified for W or for W's buffer. If W is - NULL, consider only frame-level face configuration. */ + consider face remappings specified for W or for W's buffer. If W + is NULL, consider only frame-level face configuration. */ int lookup_named_face (struct window *w, struct frame *f, Lisp_Object symbol, bool signal_p) @@ -6564,8 +6571,8 @@ syms_of_xfaces (void) /* Used for limiting character attributes to windows with specific characteristics. */ - DEFSYM (Qwindow_kw, ":window"); - DEFSYM (Qfiltered_kw, ":filtered"); + DEFSYM (QCwindow, ":window"); + DEFSYM (QCfiltered, ":filtered"); /* The symbol `face-alias'. A symbol having that property is an alias for another face. Value of the property is the name of @@ -6643,8 +6650,10 @@ syms_of_xfaces (void) #endif DEFVAR_BOOL ("face-filters-always-match", face_filters_always_match, - doc: /* Non-nil means that face filters are always deemed to -match. Use only when evaluating face attributes. */); + doc: /* Non-nil means that face filters are always +deemed to match. This variable is intended for use only by code that +evaluates the "specifity" of a face specification and should be +let-bound only for this purpose. */); DEFVAR_LISP ("face-new-frame-defaults", Vface_new_frame_defaults, doc: /* List of global face definitions (for internal use only.) */); commit d1febb42f48cd9906713d2a2f4501a7059d7d171 Author: Daniel Colascione Date: Fri Jun 8 16:21:39 2018 -0700 Make setting inhibit-startup-screen in early init work * lisp/startup.el (command-line): Bind `inhibit-startup-screen' around loading the site file instead of unconditionally resetting it. diff --git a/lisp/startup.el b/lisp/startup.el index 83fd190ea2..245b9ac5ba 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -1287,11 +1287,10 @@ please check its value") ;; should check init-file-user instead, since that is already set. ;; See cus-edit.el for an example. (if site-run-file - (load site-run-file t t)) - - ;; Sites should not disable this. Only individuals should disable - ;; the startup screen. - (setq inhibit-startup-screen nil) + ;; Sites should not disable the startup screen. + ;; Only individuals should disable the startup screen. + (let ((inhibit-startup-screen inhibit-startup-screen)) + (load site-run-file t t))) ;; Load that user's init file, or the default one, or none. (load-user-init-file commit 38111b5e98380c518aeb1bb7be52b7972a248332 Author: João Távora Date: Fri Jun 8 22:30:46 2018 +0100 Describe flymake-start-on-save-buffer in manual and NEWS Fixes: bug#31738 * doc/misc/flymake.texi (Using Flymake, Customizable variables): Mention flymake-start-on-save-buffer. * etc/NEWS: Mention flymake-start-on-save-buffer. diff --git a/doc/misc/flymake.texi b/doc/misc/flymake.texi index e7f4da75bb..502d408f2b 100644 --- a/doc/misc/flymake.texi +++ b/doc/misc/flymake.texi @@ -83,6 +83,10 @@ Syntax check is done ``on-the-fly''. It is started whenever @code{flymake-mode} is started, unless @code{flymake-start-on-flymake-mode} is nil; +@item +the buffer is saved, unless @code{flymake-start-on-save-buffer} is +nil; + @item a newline character is added to the buffer, unless @code{flymake-start-syntax-check-on-newline} is nil; @@ -220,6 +224,10 @@ after a newline character is inserted into the buffer. A boolean flag indicating whether to start syntax check immediately after enabling @code{flymake-mode}. +@item flymake-start-on-save-buffer +A boolean flag indicating whether to start syntax check after saving +the buffer. + @item flymake-error A custom face for highlighting regions for which an error has been reported. diff --git a/etc/NEWS b/etc/NEWS index 3282340f91..46a57b1888 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -183,6 +183,9 @@ shown in the currently selected window. You should instead set properties on known diagnostic symbols, like ':error' and ':warning', as demonstrated in the Flymake manual. +*** New customizable variable 'flymake-start-on-save-buffer' +Control whether Flymake starts checking the buffer on save. + ** Package *** New 'package-quickstart' feature When 'package-quickstart' is non-nil, package.el precomputes a big autoloads commit 21c6534ef31c7e6439884a0df8523e28e4b12040 Author: João Távora Date: Fri Jun 8 19:35:31 2018 +0100 New flymake-start-on-save-buffer custom variable Fixes: bug#21419 * lisp/progmodes/flymake.el (flymake-after-save-hook): Use flymake-start-on-save-buffer. (flymake-start-on-save-buffer): New custom variable. (flymake-start-on-flymake-mode): Tweak docstring. diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index d8959c8356..fdb22ccaf3 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -196,11 +196,17 @@ If nil, never start checking buffer automatically like this." 'flymake-start-on-flymake-mode "26.1") (defcustom flymake-start-on-flymake-mode t - "Start syntax check when `flymake-mode' is enabled. + "If non-nil, start syntax check when `flymake-mode' is enabled. Specifically, start it when the buffer is actually displayed." :version "26.1" :type 'boolean) +(defcustom flymake-start-on-save-buffer t + "If non-nil start syntax check when a buffer is saved. +Specifically, start it when the saved buffer is actually displayed." + :version "27.1" + :type 'boolean) + (defcustom flymake-log-level -1 "Obsolete and ignored variable." :type 'integer) @@ -962,7 +968,7 @@ Do it only if `flymake-no-changes-timeout' is non-nil." (flymake--schedule-timer-maybe))) (defun flymake-after-save-hook () - (when flymake-mode + (when flymake-start-on-save-buffer (flymake-log :debug "starting syntax check as buffer was saved") (flymake-start t))) commit fe06f643b2808b198bb58bda04a8c863e55a2a56 Author: Alan Mackenzie Date: Fri Jun 8 16:42:18 2018 +0000 CC Mode: Fontify unbalanced quotes in unconstrained multiline strings, etc. ("Unconstrained" meaning that every string is multiline, without needing such special marking as used by Pike Mode.) * lisp/progmodes/cc-mode.el (c-pps-to-string-delim): Don't process the char before BOB. (c-multiline-string-check-final-quote): New function. (c-bc-changed-stringiness): New variable. (c-before-change-check-unbalanced-strings): Add handling for unconstrained multiline strings. (c-after-change-re-mark-unbalanced-strings): Add handling for unconstrained multiline strings. Handle escaped double quotes more accurately. diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index a1411ad5ea..e619fac43f 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el @@ -1110,13 +1110,56 @@ Note that the style variables are always made local to the buffer." (goto-char start) (while (progn (parse-partial-sexp (point) end nil nil st-s 'syntax-table) - (c-clear-char-property (1- (point)) 'syntax-table) + (unless (bobp) + (c-clear-char-property (1- (point)) 'syntax-table)) (setq st-pos (point)) (and (< (point) end) (not (eq (char-before) ?\"))))) (goto-char (min no-st-pos st-pos)) nil)) +(defun c-multiline-string-check-final-quote () + ;; Check that the final quote in the buffer is correctly marked or not with + ;; a string-fence syntax-table text propery. The return value has no + ;; significance. + (let (pos-ll pos-lt) + (save-excursion + (goto-char (point-max)) + (skip-chars-backward "^\"") + (while + (and + (not (bobp)) + (cond + ((progn + (setq pos-ll (c-literal-limits) + pos-lt (c-literal-type pos-ll)) + (memq pos-lt '(c c++))) + ;; In a comment. + (goto-char (car pos-ll))) + ((save-excursion + (backward-char) ; over " + (eq (logand (skip-chars-backward "\\\\") 1) 1)) + ;; At an escaped string. + (backward-char) + t) + (t + ;; At a significant " + (c-clear-char-property (1- (point)) 'syntax-table) + (setq pos-ll (c-literal-limits) + pos-lt (c-literal-type pos-ll)) + nil))) + (skip-chars-backward "^\"")) + (cond + ((bobp)) + ((eq pos-lt 'string) + (c-put-char-property (1- (point)) 'syntax-table '(15))) + (t nil))))) + +(defvar c-bc-changed-stringiness nil) +;; Non-nil when, in a before-change function, the deletion of a range of text +;; will change the "stringiness" of the subsequent text. Only used when +;; `c-multiline-sting-start-char' is a non-nil value which isn't a character. + (defun c-before-change-check-unbalanced-strings (beg end) ;; If BEG or END is inside an unbalanced string, remove the syntax-table ;; text property from respectively the start or end of the string. Also @@ -1175,6 +1218,18 @@ Note that the style variables are always made local to the buffer." (< (point) (point-max)))))) (setq c-new-END (max (point) c-new-END))) + (c-multiline-string-start-char + (setq c-bc-changed-stringiness + (not (eq (eq end-literal-type 'string) + (eq beg-literal-type 'string)))) + ;; Deal with deletion of backslashes before "s. + (goto-char end) + (if (and (looking-at "\\\\*\"") + (eq (logand (skip-chars-backward "\\\\" beg) 1) 1)) + (setq c-bc-changed-stringiness (not c-bc-changed-stringiness))) + (if (eq beg-literal-type 'string) + (setq c-new-BEG (min (car beg-limits) c-new-BEG)))) + ((< c-new-END (point-max)) (goto-char (1+ c-new-END)) ; might be a newline. ;; In the following regexp, the initial \n caters for a newline getting @@ -1183,7 +1238,6 @@ Note that the style variables are always made local to the buffer." nil t) ;; We're at an EOLL or point-max. (setq c-new-END (min (1+ (point)) (point-max))) - ;; FIXME!!! Write a clever comment here. (goto-char c-new-END) (if (equal (c-get-char-property (1- (point)) 'syntax-table) '(15)) (if (memq (char-before) '(?\n ?\r)) @@ -1202,14 +1256,16 @@ Note that the style variables are always made local to the buffer." (if (c-search-backward-char-property 'syntax-table '(15) c-new-BEG) (c-clear-char-property (point) 'syntax-table)))) - (when (eq end-literal-type 'string) - (c-clear-char-property (1- (cdr end-limits)) 'syntax-table)) + (unless (and c-multiline-string-start-char + (not (c-characterp c-multiline-string-start-char))) + (when (eq end-literal-type 'string) + (c-clear-char-property (1- (cdr end-limits)) 'syntax-table)) - (when (eq beg-literal-type 'string) - (setq c-new-BEG (min c-new-BEG (car beg-limits))) - (c-clear-char-property (car beg-limits) 'syntax-table)))) + (when (eq beg-literal-type 'string) + (setq c-new-BEG (min c-new-BEG (car beg-limits))) + (c-clear-char-property (car beg-limits) 'syntax-table))))) -(defun c-after-change-re-mark-unbalanced-strings (beg _end _old-len) +(defun c-after-change-re-mark-unbalanced-strings (beg end _old-len) ;; Mark any unbalanced strings in the region (c-new-BEG c-new-END) with ;; string fence syntax-table text properties. ;; @@ -1218,66 +1274,90 @@ Note that the style variables are always made local to the buffer." ;; ;; This function is called exclusively as an after-change function via ;; `c-before-font-lock-functions'. - (c-save-buffer-state - ((cll (progn (goto-char c-new-BEG) - (c-literal-limits))) - (beg-literal-type (and cll (c-literal-type cll))) - (beg-limits - (cond - ((and (eq beg-literal-type 'string) - (c-unescaped-nls-in-string-p (car cll))) - (cons - (car cll) + (if (and c-multiline-string-start-char + (not (c-characterp c-multiline-string-start-char))) + ;; Only the last " might need to be marked. + (c-save-buffer-state + ((beg-literal-limits + (progn (goto-char beg) (c-literal-limits))) + (beg-literal-type (c-literal-type beg-literal-limits)) + end-literal-limits end-literal-type) + (when (and (eq beg-literal-type 'string) + (c-get-char-property (car beg-literal-limits) 'syntax-table)) + (c-clear-char-property (car beg-literal-limits) 'syntax-table) + (setq c-bc-changed-stringiness (not c-bc-changed-stringiness))) + (setq end-literal-limits (progn (goto-char end) (c-literal-limits)) + end-literal-type (c-literal-type end-literal-limits)) + ;; Deal with the insertion of backslashes before a ". + (goto-char end) + (if (and (looking-at "\\\\*\"") + (eq (logand (skip-chars-backward "\\\\" beg) 1) 1)) + (setq c-bc-changed-stringiness (not c-bc-changed-stringiness))) + (when (eq (eq (eq beg-literal-type 'string) + (eq end-literal-type 'string)) + c-bc-changed-stringiness) + (c-multiline-string-check-final-quote))) + ;; There could be several "s needing marking. + (c-save-buffer-state + ((cll (progn (goto-char c-new-BEG) + (c-literal-limits))) + (beg-literal-type (and cll (c-literal-type cll))) + (beg-limits + (cond + ((and (eq beg-literal-type 'string) + (c-unescaped-nls-in-string-p (car cll))) + (cons + (car cll) + (progn + (goto-char (1+ (car cll))) + (search-forward-regexp + (cdr (assq (char-after (car cll)) c-string-innards-re-alist)) + nil t) + (min (1+ (point)) (point-max))))) + ((and (null beg-literal-type) + (goto-char beg) + (eq (char-before) c-multiline-string-start-char) + (memq (char-after) c-string-delims)) + (cons (point) + (progn + (forward-char) + (search-forward-regexp + (cdr (assq (char-before) c-string-innards-re-alist)) nil t) + (1+ (point))))) + (cll))) + s) + (goto-char + (cond ((null beg-literal-type) + c-new-BEG) + ((eq beg-literal-type 'string) + (car beg-limits)) + (t ; comment + (cdr beg-limits)))) + (while + (and + (< (point) c-new-END) (progn - (goto-char (1+ (car cll))) - (search-forward-regexp - (cdr (assq (char-after (car cll)) c-string-innards-re-alist)) - nil t) - (min (1+ (point)) (point-max))))) - ((and (null beg-literal-type) - (goto-char beg) - (eq (char-before) c-multiline-string-start-char) - (memq (char-after) c-string-delims)) - (cons (point) - (progn - (forward-char) - (search-forward-regexp - (cdr (assq (char-before) c-string-innards-re-alist)) nil t) - (1+ (point))))) - (cll))) - s) - (goto-char - (cond ((null beg-literal-type) - c-new-BEG) - ((eq beg-literal-type 'string) - (car beg-limits)) - (t ; comment - (cdr beg-limits)))) - (while - (and - (< (point) c-new-END) - (progn - ;; Skip over any comments before the next string. - (while (progn - (setq s (parse-partial-sexp (point) c-new-END nil - nil s 'syntax-table)) - (and (not (nth 3 s)) - (< (point) c-new-END) - (not (memq (char-before) c-string-delims))))) - ;; We're at the start of a string. - (memq (char-before) c-string-delims))) - (if (c-unescaped-nls-in-string-p (1- (point))) - (looking-at "[^\"]*") - (looking-at (cdr (assq (char-before) c-string-innards-re-alist)))) - (cond - ((memq (char-after (match-end 0)) '(?\n ?\r)) - (c-put-char-property (1- (point)) 'syntax-table '(15)) - (c-put-char-property (match-end 0) 'syntax-table '(15))) - ((or (eq (match-end 0) (point-max)) - (eq (char-after (match-end 0)) ?\\)) ; \ at EOB - (c-put-char-property (1- (point)) 'syntax-table '(15)))) - (goto-char (min (1+ (match-end 0)) (point-max))) - (setq s nil)))) + ;; Skip over any comments before the next string. + (while (progn + (setq s (parse-partial-sexp (point) c-new-END nil + nil s 'syntax-table)) + (and (not (nth 3 s)) + (< (point) c-new-END) + (not (memq (char-before) c-string-delims))))) + ;; We're at the start of a string. + (memq (char-before) c-string-delims))) + (if (c-unescaped-nls-in-string-p (1- (point))) + (looking-at "\\(\\\\\\(.\\|\n|\\\r\\)\\|[^\"]\\)*") + (looking-at (cdr (assq (char-before) c-string-innards-re-alist)))) + (cond + ((memq (char-after (match-end 0)) '(?\n ?\r)) + (c-put-char-property (1- (point)) 'syntax-table '(15)) + (c-put-char-property (match-end 0) 'syntax-table '(15))) + ((or (eq (match-end 0) (point-max)) + (eq (char-after (match-end 0)) ?\\)) ; \ at EOB + (c-put-char-property (1- (point)) 'syntax-table '(15)))) + (goto-char (min (1+ (match-end 0)) (point-max))) + (setq s nil))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Parsing of quotes. commit db353b8649cdae54146308e4c875e53d02b0aaee Author: Paul Eggert Date: Fri Jun 8 08:08:03 2018 -0700 Port alignment verification to x86 --with-wide-int Problem reported by Eli Zaretskii in: https://lists.gnu.org/r/emacs-devel/2018-06/msg00238.html * src/lisp.h (struct Lisp_Symbol, union vectorlike_header) (struct Lisp_Cons, struct Lisp_String): Do not check alignment if !USE_LSB_TAG, as alignment is needed only if we are tagging the low-order bits. diff --git a/src/lisp.h b/src/lisp.h index 10012b29db..293cf2783c 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -785,7 +785,7 @@ struct Lisp_Symbol GCALIGNED_UNION } u; }; -verify (alignof (struct Lisp_Symbol) % GCALIGNMENT == 0); +verify (!USE_LSB_TAG || alignof (struct Lisp_Symbol) % GCALIGNMENT == 0); /* Declare a Lisp-callable function. The MAXARGS parameter has the same meaning as in the DEFUN macro, and is used to construct a prototype. */ @@ -898,7 +898,7 @@ union vectorlike_header ptrdiff_t size; GCALIGNED_UNION }; -verify (alignof (union vectorlike_header) % GCALIGNMENT == 0); +verify (!USE_LSB_TAG || alignof (union vectorlike_header) % GCALIGNMENT == 0); INLINE bool (SYMBOLP) (Lisp_Object x) @@ -1259,7 +1259,7 @@ struct Lisp_Cons GCALIGNED_UNION } u; }; -verify (alignof (struct Lisp_Cons) % GCALIGNMENT == 0); +verify (!USE_LSB_TAG || alignof (struct Lisp_Cons) % GCALIGNMENT == 0); INLINE bool (NILP) (Lisp_Object x) @@ -1381,7 +1381,7 @@ struct Lisp_String GCALIGNED_UNION } u; }; -verify (alignof (struct Lisp_String) % GCALIGNMENT == 0); +verify (!USE_LSB_TAG || alignof (struct Lisp_String) % GCALIGNMENT == 0); INLINE bool STRINGP (Lisp_Object x)