commit 60f2bb862f834fcb580d839ac79b30a8b4cd4167 (HEAD, refs/remotes/origin/master) Merge: 690f7ac86a 56026242e4 Author: Stefan Kangas Date: Wed Nov 16 08:41:29 2022 +0100 Merge from origin/emacs-28 56026242e4 Explain how to bind keys to non-ASCII sequences 7d592db0ab Document that 'transient-mark-mode' is off in batch mode # Conflicts: # doc/emacs/custom.texi # doc/emacs/mark.texi commit 690f7ac86ad9a9d714b1107d05c5e856a43bb18d Author: Po Lu Date: Wed Nov 16 11:19:20 2022 +0800 Fix calculation of tab bar lines during automatic height adjustment * src/haikufns.c (haiku_change_tab_bar_height): * src/nsfns.m (ns_change_tab_bar_height): * src/pgtkfns.c (pgtk_change_tab_bar_height): * src/w32fns.c (w32_change_tab_bar_height): * src/xfns.c (x_change_tab_bar_height): Do not round tab bar height up. (bug#59285, bug#59271) diff --git a/src/haikufns.c b/src/haikufns.c index 711202c5df..5717d0354f 100644 --- a/src/haikufns.c +++ b/src/haikufns.c @@ -175,10 +175,19 @@ haiku_change_tool_bar_height (struct frame *f, int height) void haiku_change_tab_bar_height (struct frame *f, int height) { - int unit = FRAME_LINE_HEIGHT (f); - int old_height = FRAME_TAB_BAR_HEIGHT (f); - int lines = (height + unit - 1) / unit; - Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); + int unit, old_height, lines; + Lisp_Object fullscreen; + + unit = FRAME_LINE_HEIGHT (f); + old_height = FRAME_TAB_BAR_HEIGHT (f); + fullscreen = get_frame_param (f, Qfullscreen); + + /* This differs from the tool bar code in that the tab bar height is + not rounded up. Otherwise, if redisplay_tab_bar decides to grow + the tab bar by even 1 pixel, FRAME_TAB_BAR_LINES will be changed, + leading to the tab bar height being incorrectly set upon the next + call to x_set_font. (bug#59285) */ + lines = height / unit; /* Make sure we redisplay all windows in this frame. */ fset_redisplay (f); diff --git a/src/nsfns.m b/src/nsfns.m index 2699cf37a5..d793bcf13f 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -632,10 +632,19 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side. void ns_change_tab_bar_height (struct frame *f, int height) { - int unit = FRAME_LINE_HEIGHT (f); - int old_height = FRAME_TAB_BAR_HEIGHT (f); - int lines = (height + unit - 1) / unit; - Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); + int unit, old_height, lines; + Lisp_Object fullscreen; + + unit = FRAME_LINE_HEIGHT (f); + old_height = FRAME_TAB_BAR_HEIGHT (f); + fullscreen = get_frame_param (f, Qfullscreen); + + /* This differs from the tool bar code in that the tab bar height is + not rounded up. Otherwise, if redisplay_tab_bar decides to grow + the tab bar by even 1 pixel, FRAME_TAB_BAR_LINES will be changed, + leading to the tab bar height being incorrectly set upon the next + call to x_set_font. (bug#59285) */ + lines = height / unit; /* Make sure we redisplay all windows in this frame. */ fset_redisplay (f); diff --git a/src/pgtkfns.c b/src/pgtkfns.c index 9473e14f5c..f370f03978 100644 --- a/src/pgtkfns.c +++ b/src/pgtkfns.c @@ -473,10 +473,19 @@ pgtk_set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) void pgtk_change_tab_bar_height (struct frame *f, int height) { - int unit = FRAME_LINE_HEIGHT (f); - int old_height = FRAME_TAB_BAR_HEIGHT (f); - int lines = (height + unit - 1) / unit; - Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); + int unit, old_height, lines; + Lisp_Object fullscreen; + + unit = FRAME_LINE_HEIGHT (f); + old_height = FRAME_TAB_BAR_HEIGHT (f); + fullscreen = get_frame_param (f, Qfullscreen); + + /* This differs from the tool bar code in that the tab bar height is + not rounded up. Otherwise, if redisplay_tab_bar decides to grow + the tab bar by even 1 pixel, FRAME_TAB_BAR_LINES will be changed, + leading to the tab bar height being incorrectly set upon the next + call to x_set_font. (bug#59285) */ + lines = height / unit; /* Make sure we redisplay all windows in this frame. */ fset_redisplay (f); diff --git a/src/w32fns.c b/src/w32fns.c index c7eddcba6d..e441665804 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -1717,10 +1717,19 @@ w32_set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) void w32_change_tab_bar_height (struct frame *f, int height) { - int unit = FRAME_LINE_HEIGHT (f); - int old_height = FRAME_TAB_BAR_HEIGHT (f); - int lines = (height + unit - 1) / unit; - Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); + int unit, old_height, lines; + Lisp_Object fullscreen; + + unit = FRAME_LINE_HEIGHT (f); + old_height = FRAME_TAB_BAR_HEIGHT (f); + fullscreen = get_frame_param (f, Qfullscreen); + + /* This differs from the tool bar code in that the tab bar height is + not rounded up. Otherwise, if redisplay_tab_bar decides to grow + the tab bar by even 1 pixel, FRAME_TAB_BAR_LINES will be changed, + leading to the tab bar height being incorrectly set upon the next + call to x_set_font. (bug#59285) */ + lines = height / unit; /* Make sure we redisplay all windows in this frame. */ fset_redisplay (f); diff --git a/src/xfns.c b/src/xfns.c index 6bd613ba69..8ee26d713a 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -1750,10 +1750,19 @@ x_set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) void x_change_tab_bar_height (struct frame *f, int height) { - int unit = FRAME_LINE_HEIGHT (f); - int old_height = FRAME_TAB_BAR_HEIGHT (f); - int lines = (height + unit - 1) / unit; - Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); + int unit, old_height, lines; + Lisp_Object fullscreen; + + unit = FRAME_LINE_HEIGHT (f); + old_height = FRAME_TAB_BAR_HEIGHT (f); + fullscreen = get_frame_param (f, Qfullscreen); + + /* This differs from the tool bar code in that the tab bar height is + not rounded up. Otherwise, if redisplay_tab_bar decides to grow + the tab bar by even 1 pixel, FRAME_TAB_BAR_LINES will be changed, + leading to the tab bar height being incorrectly set upon the next + call to x_set_font. (bug#59285) */ + lines = height / unit; /* Make sure we redisplay all windows in this frame. */ fset_redisplay (f); commit 0600065ff276d5c55c3ff2f466dfbce74586164f Author: Po Lu Date: Wed Nov 16 10:37:14 2022 +0800 Fix error trapping in x_focus_frame * src/xterm.c (x_focus_frame): Improve commentary. Dno not trap errors around x_get_server_time. diff --git a/src/xterm.c b/src/xterm.c index 7a1fd6086c..d6ba532f16 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -27632,8 +27632,6 @@ x_focus_frame (struct frame *f, bool noactivate) return; } - /* Ignore any BadMatch error this request might result in. */ - x_ignore_errors_for_next_request (dpyinfo); if (NILP (Vx_no_window_manager)) { /* Use the last user time. It is invalid to use CurrentTime @@ -27651,15 +27649,24 @@ x_focus_frame (struct frame *f, bool noactivate) && !dpyinfo->x_focus_frame) time = x_get_server_time (f); + /* Ignore any BadMatch error this request might result in. + A BadMatch error can occur if the window was obscured + after the time of the last user interaction without + changing the last-focus-change-time. */ + x_ignore_errors_for_next_request (dpyinfo); XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), RevertToParent, time); + x_stop_ignoring_errors (dpyinfo); } else - XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), - /* But when no window manager is in use, we - don't care. */ - RevertToParent, CurrentTime); - x_stop_ignoring_errors (dpyinfo); + { + x_ignore_errors_for_next_request (dpyinfo); + XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), + /* But when no window manager is in use, we + don't care. */ + RevertToParent, CurrentTime); + x_stop_ignoring_errors (dpyinfo); + } } } commit d2ba4538cb561b5f93f53c1088d55530f12bf483 Author: Juanma Barranquero Date: Tue Nov 15 11:27:56 2022 +0100 ; * lisp/subr.el (match-buffers): Fix typo diff --git a/lisp/subr.el b/lisp/subr.el index 6b83196d05..adaa0a9135 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -7061,7 +7061,7 @@ CONDITION is either: (defun match-buffers (condition &optional buffers arg) "Return a list of buffers that match CONDITION. -See `buffer-match' for details on CONDITION. By default all +See `buffer-match-p' for details on CONDITION. By default all buffers are checked, this can be restricted by passing an optional argument BUFFERS, set to a list of buffers to check. ARG is passed to `buffer-match', for predicate conditions in commit 125b5684c3fb85ed77eeaeca3237393507e4df55 Author: Juri Linkov Date: Tue Nov 15 20:54:39 2022 +0200 New command 'project-list-buffers' bound to 'C-x p C-b' (bug#59153) * doc/emacs/maintaining.texi (Project Buffer Commands): Add 'project-list-buffers'. * lisp/buff-menu.el (Buffer-menu-filter-predicate): New defvar-local. (list-buffers-noselect): Add new optional arg 'filter-predicate'. Set 'Buffer-menu-filter-predicate' to 'filter-predicate'. (list-buffers--refresh): Use 'Buffer-menu-filter-predicate'. * lisp/progmodes/project.el (project-prefix-map): Bind "\C-b" to 'project-list-buffers'. (project-list-buffers): New command. diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index 3e03bd817a..44e9e1896f 100644 --- a/doc/emacs/maintaining.texi +++ b/doc/emacs/maintaining.texi @@ -1832,6 +1832,8 @@ directory. @xref{Top,Eshell,Eshell, eshell, Eshell: The Emacs Shell}. @item C-x p b Switch to another buffer belonging to the current project (@code{project-switch-to-buffer}). +@item C-x p C-b +List the project buffers (@code{project-list-buffers}). @item C-x p k Kill all live buffers that belong to the current project (@code{project-kill-buffers}). @@ -1847,6 +1849,11 @@ switch between buffers that belong to the current project by prompting for a buffer to switch and considering only the current project's buffers as candidates for completion. +@findex project-list-buffers + Like the command @code{list-buffers} (@pxref{List Buffers}), the +command @kbd{C-x p C-b} (@code{project-list-buffers}) displays a list +of existing buffers, but only belonging to the current project. + @findex project-kill-buffers @vindex project-kill-buffer-conditions @vindex project-kill-buffers-display-buffer-list diff --git a/etc/NEWS b/etc/NEWS index 7cd192b9d3..e39833a704 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2212,6 +2212,10 @@ it with new 'term-{faint,italic,slow-blink,fast-blink}' faces. *** 'project-find-file' and 'project-or-external-find-file' now accept a prefix argument which is interpreted to mean "include all files". ++++ +*** New command 'project-list-buffers' bound to 'C-x p C-b'. +This command displays a list of buffers from the current project. + +++ *** 'project-kill-buffers' can display the list of buffers to kill. Customize the user option 'project-kill-buffers-display-buffer-list' diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el index 34221ee440..aa5f70edf2 100644 --- a/lisp/buff-menu.el +++ b/lisp/buff-menu.el @@ -100,6 +100,13 @@ as it is by default." This is set by the prefix argument to `buffer-menu' and related commands.") +(defvar-local Buffer-menu-filter-predicate nil + "Function to filter out buffers in the buffer list. +Buffers that don't satisfy the predicate will be skipped. +The value should be a function of one argument; it will be +called with the buffer. If this function returns non-nil, +then the buffer will be displayed in the buffer list.") + (defvar-keymap Buffer-menu-mode-map :doc "Local keymap for `Buffer-menu-mode' buffers." :parent tabulated-list-mode-map @@ -616,19 +623,23 @@ This behaves like invoking \\[read-only-mode] in that buffer." ;;; Functions for populating the Buffer Menu. ;;;###autoload -(defun list-buffers-noselect (&optional files-only buffer-list) +(defun list-buffers-noselect (&optional files-only buffer-list filter-predicate) "Create and return a Buffer Menu buffer. This is called by `buffer-menu' and others as a subroutine. If FILES-ONLY is non-nil, show only file-visiting buffers. If BUFFER-LIST is non-nil, it should be a list of buffers; it -means list those buffers and no others." +means list those buffers and no others. +If FILTER-PREDICATE is non-nil, it should be a function +that filters out buffers from the list of buffers. +See more at `Buffer-menu-filter-predicate'." (let ((old-buffer (current-buffer)) (buffer (get-buffer-create "*Buffer List*"))) (with-current-buffer buffer (Buffer-menu-mode) (setq Buffer-menu-files-only (and files-only (>= (prefix-numeric-value files-only) 0))) + (setq Buffer-menu-filter-predicate filter-predicate) (list-buffers--refresh buffer-list old-buffer) (tabulated-list-print)) buffer)) @@ -650,6 +661,8 @@ means list those buffers and no others." (marked-buffers (Buffer-menu-marked-buffers)) (buffer-menu-buffer (current-buffer)) (show-non-file (not Buffer-menu-files-only)) + (filter-predicate (and (functionp Buffer-menu-filter-predicate) + Buffer-menu-filter-predicate)) entries name-width) ;; Collect info for each buffer we're interested in. (dolist (buffer (or buffer-list @@ -663,7 +676,9 @@ means list those buffers and no others." (and (or (not (string= (substring name 0 1) " ")) file) (not (eq buffer buffer-menu-buffer)) - (or file show-non-file)))) + (or file show-non-file) + (or (not filter-predicate) + (funcall filter-predicate buffer))))) (push (list buffer (vector (cond ((eq buffer old-buffer) ".") diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index ed26872ae7..63510e9050 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -712,6 +712,7 @@ DIRS must contain directory names." (define-key map "G" 'project-or-external-find-regexp) (define-key map "r" 'project-query-replace-regexp) (define-key map "x" 'project-execute-extended-command) + (define-key map "\C-b" 'project-list-buffers) map) "Keymap for project commands.") @@ -1222,6 +1223,28 @@ displayed." (interactive (list (project--read-project-buffer))) (display-buffer-other-frame buffer-or-name)) +;;;###autoload +(defun project-list-buffers (&optional arg) + "Display a list of project buffers. +The list is displayed in a buffer named \"*Buffer List*\". + +By default, all project buffers are listed except those whose names +start with a space (which are for internal use). With prefix argument +ARG, show only buffers that are visiting files." + (interactive "P") + (let ((pr (project-current t))) + (display-buffer + (if (version< emacs-version "29.0.50") + (let ((buf (list-buffers-noselect arg (project-buffers pr)))) + (with-current-buffer buf + (setq-local revert-buffer-function + (lambda (&rest _ignored) + (list-buffers--refresh (project-buffers pr)) + (tabulated-list-print t)))) + buf) + (list-buffers-noselect + arg nil (lambda (buf) (memq buf (project-buffers pr)))))))) + (defcustom project-kill-buffer-conditions '(buffer-file-name ; All file-visiting buffers are included. ;; Most of temp and logging buffers (aside from hidden ones): commit 69d1278527f0a883d55b91088c8e1b04d9e07e81 Author: Eli Zaretskii Date: Tue Nov 15 19:58:52 2022 +0200 ; Fix some doc strings in elisp-mode.el * lisp/progmodes/elisp-mode.el (elisp-enable-lexical-binding) (elisp--local-variables-1, elisp--expect-function-p) (eval-print-last-sexp, eval-last-sexp, elisp--eval-defun-1) (eval-defun, elisp--eldoc-last-data, elisp-eldoc-funcall) (elisp-eldoc-var-docstring) (elisp-eldoc-var-docstring-with-value) (elisp-get-fnsym-args-string) (elisp--highlight-function-argument): Doc fixes. diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 537b9484bd..5b3e0146fa 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -280,7 +280,9 @@ Comments in the form will be lost." (remove-hook 'electric-pair-mode-hook #'emacs-lisp-set-electric-text-pairs)) (defun elisp-enable-lexical-binding (&optional interactive) - "Make the current buffer use `lexical-binding'." + "Make the current buffer use `lexical-binding'. +INTERACTIVE non-nil means ask the user for confirmation; this +happens in interactive invocations." (interactive "p") (if lexical-binding (when interactive @@ -360,7 +362,7 @@ be used instead. ;;; Completion at point for Elisp (defun elisp--local-variables-1 (vars sexp) - "Return the vars locally bound around the witness, or nil if not found." + "Return VARS locally bound around the witness, or nil if not found." (let (res) (while (unless @@ -463,7 +465,7 @@ be used instead. lastvars))))) (defun elisp--expect-function-p (pos) - "Return non-nil if the symbol at point is expected to be a function." + "Return non-nil if the symbol at position POS is expected to be a function." (or (and (eq (char-before pos) ?') (eq (char-before (1- pos)) ?#)) @@ -1331,12 +1333,12 @@ Semicolons start comments. (defun eval-print-last-sexp (&optional eval-last-sexp-arg-internal) "Evaluate sexp before point; print value into current buffer. +Interactively, EVAL-LAST-SEXP-ARG-INTERNAL is the prefix numeric argument. Normally, this function truncates long output according to the value of the variables `eval-expression-print-length' and -`eval-expression-print-level'. With a prefix argument of zero, -however, there is no such truncation. Such a prefix argument -also causes integers to be printed in several additional formats -\(octal, hexadecimal, and character). +`eval-expression-print-level'. But if EVAL-LAST-SEXP-ARG-INTERNAL is zero, +there is no such truncation, and integers are printed in several additional +formats (octal, hexadecimal, and character). If `eval-expression-debug-on-error' is non-nil, which is the default, this command arranges for all errors to enter the debugger." @@ -1557,8 +1559,8 @@ POS specifies the starting position where EXP was found and defaults to point." (defun eval-last-sexp (eval-last-sexp-arg-internal) "Evaluate sexp before point; print value in the echo area. -Interactively, with a non `-' prefix argument, print output into -current buffer. +Interactively, EVAL-LAST-SEXP-ARG-INTERNAL is the prefix argument. +With a non `-' prefix argument, print output into current buffer. This commands handles `defvar', `defcustom' and `defface' the same way that `eval-defun' does. See the doc string of that @@ -1588,7 +1590,7 @@ this command arranges for all errors to enter the debugger." (car value)))) (defun elisp--eval-defun-1 (form) - "Treat some expressions specially. + "Treat some expressions in FORM specially. Reset the `defvar' and `defcustom' variables to the initial value. \(For `defcustom', use the :set function if there is one.) Reinitialize the face according to the `defface' specification." @@ -1688,7 +1690,7 @@ Return the result of evaluation." elisp--eval-defun-result)) (defun eval-defun (edebug-it) - "Evaluate the top-level form containing point. + "Evaluate EDEBUG-IT or the top-level form containing point. If point isn't in a top-level form, evaluate the first top-level form after point. If there is no top-level form after point, eval the first preceeding top-level form. @@ -1734,7 +1736,8 @@ which see." ;;; ElDoc Support (defvar elisp--eldoc-last-data (make-vector 3 nil) - "Bookkeeping; elements are as follows: + "Bookkeeping. +Elements are as follows: 0 - contains the last symbol read from the buffer. 1 - contains the string last displayed in the echo area for variables, or argument string for functions. @@ -1766,7 +1769,7 @@ it is preferable to use ElDoc's interfaces directly.") "use ElDoc's interfaces instead." "28.1") (defun elisp-eldoc-funcall (callback &rest _ignored) - "Document function call at point. + "Document function call at point by calling CALLBACK. Intended for `eldoc-documentation-functions' (which see)." (let* ((sym-info (elisp--fnsym-in-current-sexp)) (fn-sym (car sym-info))) @@ -1778,7 +1781,7 @@ Intended for `eldoc-documentation-functions' (which see)." 'font-lock-keyword-face))))) (defun elisp-eldoc-var-docstring (callback &rest _ignored) - "Document variable at point. + "Document variable at point by calling CALLBACK. Intended for `eldoc-documentation-functions' (which see). Also see `elisp-eldoc-var-docstring-with-value'." (let* ((sym (elisp--current-symbol)) @@ -1789,7 +1792,7 @@ Also see `elisp-eldoc-var-docstring-with-value'." :face 'font-lock-variable-name-face)))) (defun elisp-eldoc-var-docstring-with-value (callback &rest _) - "Document variable at point. + "Document variable at point by calling CALLBACK. Intended for `eldoc-documentation-functions' (which see). Compared to `elisp-eldoc-var-docstring', this also includes the current variable value and a bigger chunk of the docstring." @@ -1817,6 +1820,7 @@ current variable value and a bigger chunk of the docstring." (defun elisp-get-fnsym-args-string (sym &optional index) "Return a string containing the parameter list of the function SYM. +INDEX is the index of the parameter in the returned string to highlight. If SYM is a subr and no arglist is obtainable from the docstring or elsewhere, return a 1-line docstring." (let ((argstring @@ -1847,7 +1851,8 @@ or elsewhere, return a 1-line docstring." sym argstring index)))) (defun elisp--highlight-function-argument (sym args index) - "Highlight argument INDEX in ARGS list for function SYM." + "Highlight the argument of function SYM whose index is INDEX. +ARGS is the argument list of function SYM." ;; FIXME: This should probably work on the list representation of `args' ;; rather than its string representation. ;; FIXME: This function is much too long, we need to split it up! commit 3b137bcbe88cc09f6c39d0f278af2343664af756 Author: Eli Zaretskii Date: Tue Nov 15 19:36:49 2022 +0200 ; Improve doc strings in seq.el * lisp/emacs-lisp/seq.el (seq-doseq, seq-setq, seq-elt) (seq-length, seq-rest, seq-do, seq-mapn, seq-drop, seq-take) (seq-drop-while, seq-take-while, seq-sort, seq-sort-by) (seq-concatenate, seq-into, seq-filter, seq-remove) (seq-remove-at-position, seq-every-p, seq-some, seq-find) (seq-count, seq-contains, seq-contains-p, seq-set-equal-p) (seq-position, seq-positions, seq-uniq, seq-mapcat) (seq-partition, seq-union, seq-intersection, seq-difference) (seq--count-successive, seq--elt-safe, seq-random-elt) (seq-split, seq-keep): Doc fixes. diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 82ade0ac0c..37b843bcca 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -63,8 +63,7 @@ ;; preloaded. See also Bug#39761#26. (defmacro seq-doseq (spec &rest body) - "Loop over a sequence. -Evaluate BODY with VAR bound to each element of SEQUENCE, in turn. + "Loop over a SEQUENCE, evaluating BODY with VAR bound to each of its elements. Similar to `dolist' but can be applied to lists, strings, and vectors. @@ -95,7 +94,7 @@ name to be bound to the rest of SEQUENCE." ,@body)) (defmacro seq-setq (args sequence) - "Assign to the variables in ARGS the elements of SEQUENCE. + "Assign the elements of SEQUENCE to the variables in ARGS. ARGS can also include the `&rest' marker followed by a variable name to be bound to the rest of SEQUENCE." @@ -105,7 +104,7 @@ name to be bound to the rest of SEQUENCE." ;;; Basic seq functions that have to be implemented by new sequence types (cl-defgeneric seq-elt (sequence n) - "Return Nth element of SEQUENCE." + "Return the Nth element of SEQUENCE." (elt sequence n)) ;; Default gv setters for `seq-elt'. @@ -118,7 +117,7 @@ name to be bound to the rest of SEQUENCE." (setcar (nthcdr n sequence) store)) (cl-defgeneric seq-length (sequence) - "Return the number of elements of SEQUENCE." + "Return the number of elements in SEQUENCE." (length sequence)) (defun seq-first (sequence) @@ -126,11 +125,12 @@ name to be bound to the rest of SEQUENCE." (seq-elt sequence 0)) (defun seq-rest (sequence) - "Return a sequence of the elements of SEQUENCE except the first one." + "Return SEQUENCE with its first element removed." (seq-drop sequence 1)) (cl-defgeneric seq-do (function sequence) - "Apply FUNCTION to each element of SEQUENCE, presumably for side effects. + "Apply FUNCTION to each element of SEQUENCE. +Presumably, FUNCTION has useful side effects. Return SEQUENCE." (mapc function sequence)) @@ -216,8 +216,9 @@ the sequence, and its index within the sequence." (mapcar function sequence)) (cl-defgeneric seq-mapn (function sequence &rest sequences) - "Like `seq-map' but FUNCTION is mapped over all SEQUENCES. -The arity of FUNCTION must match the number of SEQUENCES, and the + "Return the result of applying FUNCTION to each element of SEQUENCEs. +Like `seq-map', but FUNCTION is mapped over all SEQUENCEs. +The arity of FUNCTION must match the number of SEQUENCEs, and the mapping stops on the shortest sequence. Return a list of the results. @@ -232,7 +233,7 @@ Return a list of the results. (nreverse result))) (cl-defgeneric seq-drop (sequence n) - "Remove the first N elements of SEQUENCE and return the result. + "Remove the first N elements of SEQUENCE and return the resulting sequence. The result is a sequence of the same type as SEQUENCE. If N is a negative integer or zero, SEQUENCE is returned." @@ -243,7 +244,7 @@ If N is a negative integer or zero, SEQUENCE is returned." ;;;###autoload (cl-defgeneric seq-take (sequence n) - "Take the first N elements of SEQUENCE and return the result. + "Return the sequence made of the first N elements of SEQUENCE. The result is a sequence of the same type as SEQUENCE. If N is a negative integer or zero, an empty sequence is @@ -252,14 +253,17 @@ returned." (cl-defgeneric seq-drop-while (pred sequence) "Remove the successive elements of SEQUENCE for which PRED returns non-nil. -PRED is a function of one argument. The result is a sequence of -the same type as SEQUENCE." +PRED is a function of one argument. The function keeps removing +elements from SEQUENCE until PRED returns nil for an element. +Value is a sequence of the same type as SEQUENCE." (seq-drop sequence (seq--count-successive pred sequence))) (cl-defgeneric seq-take-while (pred sequence) "Take the successive elements of SEQUENCE for which PRED returns non-nil. -PRED is a function of one argument. The result is a sequence of -the same type as SEQUENCE." +PRED is a function of one argument. The function keeps collecting +elements from SEQUENCE and adding them to the result until PRED +returns nil for an element. +Value is a sequence of the same type as SEQUENCE." (seq-take sequence (seq--count-successive pred sequence))) (cl-defgeneric seq-empty-p (sequence) @@ -267,7 +271,7 @@ the same type as SEQUENCE." (= 0 (seq-length sequence))) (cl-defgeneric seq-sort (pred sequence) - "Sort SEQUENCE using PRED as comparison function. + "Sort SEQUENCE using PRED as the sorting comparison function. The result is a sequence of the same type as SEQUENCE." (let ((result (seq-sort pred (append sequence nil)))) (seq-into result (type-of sequence)))) @@ -277,7 +281,7 @@ The result is a sequence of the same type as SEQUENCE." ;;;###autoload (defun seq-sort-by (function pred sequence) - "Sort SEQUENCE using PRED as a comparison function. + "Sort SEQUENCE transformed by FUNCTION using PRED as the comparison function. Elements of SEQUENCE are transformed by FUNCTION before being sorted. FUNCTION must be a function of one argument." (seq-sort (lambda (a b) @@ -300,7 +304,7 @@ sorted. FUNCTION must be a function of one argument." (cl-defgeneric seq-concatenate (type &rest sequences) "Concatenate SEQUENCES into a single sequence of type TYPE. -TYPE must be one of following symbols: vector, string or list. +TYPE must be one of following symbols: `vector', `string' or `list'. \n(fn TYPE SEQUENCE...)" (setq sequences (mapcar #'seq-into-sequence sequences)) @@ -322,8 +326,8 @@ of sequence." (cl-defgeneric seq-into (sequence type) "Concatenate the elements of SEQUENCE into a sequence of type TYPE. -TYPE can be one of the following symbols: vector, string or -list." +TYPE can be one of the following symbols: `vector', `string' or +`list'." (pcase type (`vector (seq--into-vector sequence)) (`string (seq--into-string sequence)) @@ -332,7 +336,7 @@ list." ;;;###autoload (cl-defgeneric seq-filter (pred sequence) - "Return a list of all elements for which (PRED element) is non-nil in SEQUENCE." + "Return a list of the all elements in SEQUENCE for which PRED returns non-nil." (let ((exclude (make-symbol "exclude"))) (delq exclude (seq-map (lambda (elt) (if (funcall pred elt) @@ -342,13 +346,13 @@ list." ;;;###autoload (cl-defgeneric seq-remove (pred sequence) - "Return a list of all the elements for which (PRED element) is nil in SEQUENCE." + "Return a list of all the elements in SEQUENCE for which PRED returns nil." (seq-filter (lambda (elt) (not (funcall pred elt))) sequence)) ;;;###autoload (cl-defgeneric seq-remove-at-position (sequence n) - "Return a copy of SEQUENCE where the element at N got removed. + "Return a copy of SEQUENCE with the element at index N removed. N is the (zero-based) index of the element that should not be in the result. @@ -381,7 +385,7 @@ If SEQUENCE is empty, return INITIAL-VALUE and FUNCTION is not called." ;;;###autoload (cl-defgeneric seq-every-p (pred sequence) - "Return non-nil if (PRED element) is non-nil for all elements of SEQUENCE." + "Return non-nil if PRED returns non-nil for all the elements of SEQUENCE." (catch 'seq--break (seq-doseq (elt sequence) (or (funcall pred elt) @@ -390,8 +394,8 @@ If SEQUENCE is empty, return INITIAL-VALUE and FUNCTION is not called." ;;;###autoload (cl-defgeneric seq-some (pred sequence) - "Return non-nil if PRED is satisfied for at least one element of SEQUENCE. -If so, return the first non-nil value returned by PRED." + "Return non-nil if PRED returns non-nil for at least one element of SEQUENCE. +If the value is non-nil, it is the first non-nil value returned by PRED." (catch 'seq--break (seq-doseq (elt sequence) (let ((result (funcall pred elt))) @@ -401,12 +405,12 @@ If so, return the first non-nil value returned by PRED." ;;;###autoload (cl-defgeneric seq-find (pred sequence &optional default) - "Return the first element for which (PRED element) is non-nil in SEQUENCE. -If no element is found, return DEFAULT. + "Return the first element in SEQUENCE for which PRED returns non-nil. +If no such element is found, return DEFAULT. Note that `seq-find' has an ambiguity if the found element is -identical to DEFAULT, as it cannot be known if an element was -found or not." +identical to DEFAULT, as in that case it is impossible to know +whether an element was found or not." (catch 'seq--break (seq-doseq (elt sequence) (when (funcall pred elt) @@ -414,7 +418,7 @@ found or not." default)) (cl-defgeneric seq-count (pred sequence) - "Return the number of elements for which (PRED element) is non-nil in SEQUENCE." + "Return the number of elements in SEQUENCE for which PRED returns non-nil." (let ((count 0)) (seq-doseq (elt sequence) (when (funcall pred elt) @@ -422,8 +426,8 @@ found or not." count)) (cl-defgeneric seq-contains (sequence elt &optional testfn) - "Return the first element in SEQUENCE that is equal to ELT. -Equality is defined by the function TESTFN, which defaults to `equal'." + "Return the first element in SEQUENCE that is \"equal\" to ELT. +\"Equality\" is defined by the function TESTFN, which defaults to `equal'." (declare (obsolete seq-contains-p "27.1")) (seq-some (lambda (e) (when (funcall (or testfn #'equal) elt e) @@ -431,8 +435,8 @@ Equality is defined by the function TESTFN, which defaults to `equal'." sequence)) (cl-defgeneric seq-contains-p (sequence elt &optional testfn) - "Return non-nil if SEQUENCE contains an element equal to ELT. -Equality is defined by the function TESTFN, which defaults to `equal'." + "Return non-nil if SEQUENCE contains an element \"equal\" to ELT. +\"Equality\" is defined by the function TESTFN, which defaults to `equal'." (catch 'seq--break (seq-doseq (e sequence) (let ((r (funcall (or testfn #'equal) e elt))) @@ -442,15 +446,16 @@ Equality is defined by the function TESTFN, which defaults to `equal'." (cl-defgeneric seq-set-equal-p (sequence1 sequence2 &optional testfn) "Return non-nil if SEQUENCE1 and SEQUENCE2 contain the same elements. -This does not depend on the order of the elements. -Equality is defined by the function TESTFN, which defaults to `equal'." +The order of the elements in the sequences is not important. +\"Equality\" of elements is defined by the function TESTFN, which +defaults to `equal'." (and (seq-every-p (lambda (item1) (seq-contains-p sequence2 item1 testfn)) sequence1) (seq-every-p (lambda (item2) (seq-contains-p sequence1 item2 testfn)) sequence2))) ;;;###autoload (cl-defgeneric seq-position (sequence elt &optional testfn) - "Return the (zero-based) index of the first element in SEQUENCE equal to ELT. -Equality is defined by the function TESTFN, which defaults to `equal'." + "Return the (zero-based) index of the first element in SEQUENCE \"equal\" to ELT. +\"Equality\" is defined by the function TESTFN, which defaults to `equal'." (let ((index 0)) (catch 'seq--break (seq-doseq (e sequence) @@ -461,11 +466,11 @@ Equality is defined by the function TESTFN, which defaults to `equal'." ;;;###autoload (cl-defgeneric seq-positions (sequence elt &optional testfn) - "Return indices for which (TESTFN (seq-elt SEQUENCE index) ELT) is non-nil. + "Return list of indices of SEQUENCE elements for which TESTFN returns non-nil. -TESTFN is a two-argument function which is passed each element of -SEQUENCE as first argument and ELT as second. TESTFN defaults to -`equal'. +TESTFN is a two-argument function which is called with each element of +SEQUENCE as the first argument and ELT as the second. +TESTFN defaults to `equal'. The result is a list of (zero-based) indices." (let ((result '())) @@ -479,7 +484,7 @@ The result is a list of (zero-based) indices." ;;;###autoload (cl-defgeneric seq-uniq (sequence &optional testfn) "Return a list of the elements of SEQUENCE with duplicates removed. -TESTFN is used to compare elements, or `equal' if TESTFN is nil." +TESTFN is used to compare elements, and defaults to `equal'." (let ((result '())) (seq-doseq (elt sequence) (unless (seq-contains-p result elt testfn) @@ -514,15 +519,15 @@ TESTFN is used to compare elements, or `equal' if TESTFN is nil." (nreverse result))) (cl-defgeneric seq-mapcat (function sequence &optional type) - "Concatenate the result of applying FUNCTION to each element of SEQUENCE. -The result is a sequence of type TYPE, or a list if TYPE is nil." + "Concatenate the results of applying FUNCTION to each element of SEQUENCE. +The result is a sequence of type TYPE; TYPE defaults to `list'." (apply #'seq-concatenate (or type 'list) (seq-map function sequence))) (cl-defgeneric seq-partition (sequence n) "Return list of elements of SEQUENCE grouped into sub-sequences of length N. The last sequence may contain less than N elements. If N is a -negative integer or 0, nil is returned." +negative integer or 0, the function returns nil." (unless (< n 1) (let ((result '())) (while (not (seq-empty-p sequence)) @@ -532,8 +537,9 @@ negative integer or 0, nil is returned." ;;;###autoload (cl-defgeneric seq-union (sequence1 sequence2 &optional testfn) - "Return a list of all elements that appear in either SEQUENCE1 or SEQUENCE2. -Equality is defined by the function TESTFN, which defaults to `equal'." + "Return a list of all the elements that appear in either SEQUENCE1 or SEQUENCE2. +\"Equality\" of elements is defined by the function TESTFN, which +defaults to `equal'." (let* ((accum (lambda (acc elt) (if (seq-contains-p acc elt testfn) acc @@ -544,8 +550,9 @@ Equality is defined by the function TESTFN, which defaults to `equal'." ;;;###autoload (cl-defgeneric seq-intersection (sequence1 sequence2 &optional testfn) - "Return a list of the elements that appear in both SEQUENCE1 and SEQUENCE2. -Equality is defined by the function TESTFN, which defaults to `equal'." + "Return a list of all the elements that appear in both SEQUENCE1 and SEQUENCE2. +\"Equality\" of elements is defined by the function TESTFN, which +defaults to `equal'." (seq-reduce (lambda (acc elt) (if (seq-contains-p sequence2 elt testfn) (cons elt acc) @@ -554,8 +561,9 @@ Equality is defined by the function TESTFN, which defaults to `equal'." '())) (cl-defgeneric seq-difference (sequence1 sequence2 &optional testfn) - "Return a list of the elements that appear in SEQUENCE1 but not in SEQUENCE2. -Equality is defined by the function TESTFN, which defaults to `equal'." + "Return list of all the elements that appear in SEQUENCE1 but not in SEQUENCE2. +\"Equality\" of elements is defined by the function TESTFN, which +defaults to `equal'." (seq-reduce (lambda (acc elt) (if (seq-contains-p sequence2 elt testfn) acc @@ -591,7 +599,7 @@ SEQUENCE must be a sequence of numbers or markers." (apply #'max (seq-into sequence 'list))) (defun seq--count-successive (pred sequence) - "Count successive elements for which (PRED element) is non-nil in SEQUENCE." + "Count successive elements in SEQUENCE for which PRED returns non-nil." (let ((n 0) (len (seq-length sequence))) (while (and (< n len) @@ -628,13 +636,13 @@ SEQUENCE must be a sequence of numbers or markers." ;; TODO: make public? (defun seq--elt-safe (sequence n) - "Return element of SEQUENCE at the index N. + "Return the element of SEQUENCE whose zero-based index is N. If no element is found, return nil." (ignore-errors (seq-elt sequence n))) ;;;###autoload (cl-defgeneric seq-random-elt (sequence) - "Return a random element from SEQUENCE. + "Return a randomly chosen element from SEQUENCE. Signal an error if SEQUENCE is empty." (if (seq-empty-p sequence) (error "Sequence cannot be empty") @@ -681,8 +689,8 @@ Signal an error if SEQUENCE is empty." (concat sequence))) (defun seq-split (sequence length) - "Split SEQUENCE into a list of sub-sequences of at most LENGTH. -All the sub-sequences will be of LENGTH, except the last one, + "Split SEQUENCE into a list of sub-sequences of at most LENGTH elements. +All the sub-sequences will be LENGTH long, except the last one, which may be shorter." (when (< length 1) (error "Sub-sequence length must be larger than zero")) @@ -696,7 +704,7 @@ which may be shorter." (nreverse result))) (defun seq-keep (function sequence) - "Apply FUNCTION to SEQUENCE and return all non-nil results." + "Apply FUNCTION to SEQUENCE and return the list of all the non-nil results." (delq nil (seq-map function sequence))) (provide 'seq) commit 7d5cf08de946f5486ba9db16b28d2367307dcbf9 Author: Vibhav Pant Date: Tue Nov 15 20:06:56 2022 +0530 ; .clang-format: Support macros in comp.c, align operands correctly. * .clang-format (WhitespaceSensitiveMacros): Add comp.c macros that stringify arguments, telling clang-format to not format them. (AlignOperands): Set to Align, to make clang-format correctly align multi-line expressions involving binary and ternary expressions. (ForEachMacros): Add FOR_EACH_ALIST_VALUE. diff --git a/.clang-format b/.clang-format index 464375bd41..2208240a66 100644 --- a/.clang-format +++ b/.clang-format @@ -1,15 +1,18 @@ Language: Cpp BasedOnStyle: GNU AlignEscapedNewlinesLeft: true +AlignOperands: Align AlwaysBreakAfterReturnType: TopLevelDefinitions BreakBeforeBinaryOperators: All BreakBeforeBraces: GNU ColumnLimit: 70 ContinuationIndentWidth: 2 -ForEachMacros: [FOR_EACH_TAIL, - FOR_EACH_TAIL_SAFE, - FOR_EACH_LIVE_BUFFER, - ITREE_FOREACH] +ForEachMacros: + - FOR_EACH_TAIL + - FOR_EACH_TAIL_SAFE + - FOR_EACH_LIVE_BUFFER + - ITREE_FOREACH + - FOR_EACH_ALIST_VALUE IncludeCategories: - Regex: '^$' Priority: -1 @@ -19,6 +22,11 @@ IncludeCategories: Priority: 2 - Regex: '.*' Priority: 3 +WhitespaceSensitiveMacros: + - STR + - CALL1I + - CALL2I + - STR_VALUE KeepEmptyLinesAtTheStartOfBlocks: false MaxEmptyLinesToKeep: 1 PenaltyBreakBeforeFirstCallParameter: 2000 commit c63d77ac6b10dc453d08afc852debc6a9a3cde36 Author: Po Lu Date: Tue Nov 15 21:42:59 2022 +0800 Fix last change again * src/frame.c (Freconsider_frame_fonts): Apply value of default face again. (bug#59283) diff --git a/src/frame.c b/src/frame.c index 6eb6f392ec..bfdd03e501 100644 --- a/src/frame.c +++ b/src/frame.c @@ -5962,9 +5962,16 @@ have changed. */) f = decode_window_system_frame (frame); + /* First, call this to reinitialize any font backend specific + stuff. */ + if (FRAME_RIF (f)->default_font_parameter) FRAME_RIF (f)->default_font_parameter (f, Qnil); + /* Now call this to apply the existing value(s) of the `default' + face. */ + call1 (Qface_set_after_frame_default, frame); + return Qnil; } commit c6df541783246ea867cd128c74e50afb8c9bf662 Author: Po Lu Date: Tue Nov 15 19:45:28 2022 +0800 More fixes to last change * lisp/dynamic-setting.el (font-setting-change-default-font): Call `reconsider-frame-fonts'. * src/frame.c (Freconsider_frame_fonts): New function. (syms_of_frame): Add new function. diff --git a/lisp/dynamic-setting.el b/lisp/dynamic-setting.el index ff7bf182d1..ee6d1ceb35 100644 --- a/lisp/dynamic-setting.el +++ b/lisp/dynamic-setting.el @@ -51,12 +51,11 @@ the current form for the frame (i.e. hinting or somesuch changed)." ;; Set the font on all current and future frames, as though ;; the `default' face had been "set for this session": (set-frame-font new-font nil frame-list) - ;; Just redraw the existing fonts on all frames, by clearing - ;; the font and face caches. This will cause all fonts to be - ;; recreated. - (clear-font-cache) - (clear-face-cache t) - (redraw-display))))) + ;; Just reconsider the existing fonts on all frames on each + ;; display, by clearing the font and face caches. This will + ;; cause all fonts to be recreated. + (dolist (frame frame-list) + (reconsider-frame-fonts frame)))))) (defun dynamic-setting-handle-config-changed-event (event) "Handle config-changed-event on the display in EVENT. diff --git a/src/frame.c b/src/frame.c index f076a5ba54..6eb6f392ec 100644 --- a/src/frame.c +++ b/src/frame.c @@ -4749,7 +4749,7 @@ gui_set_font_backend (struct frame *f, Lisp_Object new_value, Lisp_Object old_va if (FRAME_FONT (f)) { /* Reconsider default font after backend(s) change (Bug#23386). */ - FRAME_RIF(f)->default_font_parameter (f, Qnil); + FRAME_RIF (f)->default_font_parameter (f, Qnil); face_change = true; windows_or_buffers_changed = 18; } @@ -5946,6 +5946,30 @@ This function is for internal use only. */) return f->was_invisible ? Qt : Qnil; } + +#ifdef HAVE_WINDOW_SYSTEM + +DEFUN ("reconsider-frame-fonts", Freconsider_frame_fonts, + Sreconsider_frame_fonts, 1, 1, 0, + doc: /* Recreate FRAME's default font using updated font parameters. +Signal an error if FRAME is not a window system frame. This should be +called after a `config-changed' event is received, signalling that the +parameters (such as pixel density) used by the system to open fonts +have changed. */) + (Lisp_Object frame) +{ + struct frame *f; + + f = decode_window_system_frame (frame); + + if (FRAME_RIF (f)->default_font_parameter) + FRAME_RIF (f)->default_font_parameter (f, Qnil); + + return Qnil; +} + +#endif + /*********************************************************************** Multimonitor data @@ -6634,6 +6658,6 @@ iconify the top level frame instead. */); #ifdef HAVE_WINDOW_SYSTEM defsubr (&Sx_get_resource); defsubr (&Sx_parse_geometry); + defsubr (&Sreconsider_frame_fonts); #endif - } diff --git a/src/xfns.c b/src/xfns.c index 3ff7a8c286..6bd613ba69 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -4506,9 +4506,11 @@ x_default_font_parameter (struct frame *f, Lisp_Object parms) } if (NILP (font)) - font = !NILP (font_param) ? font_param - : gui_display_get_arg (dpyinfo, parms, Qfont, "font", "Font", - RES_TYPE_STRING); + font = (!NILP (font_param) + ? font_param + : gui_display_get_arg (dpyinfo, parms, + Qfont, "font", "Font", + RES_TYPE_STRING)); if (! FONTP (font) && ! STRINGP (font)) { diff --git a/src/xterm.h b/src/xterm.h index 1124dcceb4..b6ab42e72d 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -1615,7 +1615,7 @@ extern void x_real_pos_and_offsets (struct frame *f, int *xptr, int *yptr, int *outer_border); -extern void x_default_font_parameter (struct frame* f, Lisp_Object parms); +extern void x_default_font_parameter (struct frame *, Lisp_Object); /* From xrdb.c. */ commit 833e60ae1a5dd4301eb556460285414f4fea9fec Author: Po Lu Date: Tue Nov 15 19:07:44 2022 +0800 Fix recent Cairo xsettings changes * lisp/dynamic-setting.el (font-setting-change-default-font): Instead of setting the font frame parameter, just clear the font and face cache and redraw the display. This will re-open all fonts as well. * src/ftcrfont.c (ftcrfont_get_default_font_options): New function. * src/ftfont.h: Export. * src/xsettings.c (apply_xft_settings): Call that function to obtain the default font settings on Cairo. (bug#58912, bug#59283, bug#59271) diff --git a/lisp/dynamic-setting.el b/lisp/dynamic-setting.el index 8ac9a1e9e6..ff7bf182d1 100644 --- a/lisp/dynamic-setting.el +++ b/lisp/dynamic-setting.el @@ -51,19 +51,12 @@ the current form for the frame (i.e. hinting or somesuch changed)." ;; Set the font on all current and future frames, as though ;; the `default' face had been "set for this session": (set-frame-font new-font nil frame-list) - ;; Just redraw the existing fonts on all frames: - (dolist (f frame-list) - (let ((frame-font - (or (font-get (face-attribute 'default :font f 'default) - :user-spec) - (frame-parameter f 'font-parameter)))) - (when frame-font - (set-frame-parameter f 'font-parameter frame-font) - (set-face-attribute 'default f - :width 'normal - :weight 'normal - :slant 'normal - :font frame-font)))))))) + ;; Just redraw the existing fonts on all frames, by clearing + ;; the font and face caches. This will cause all fonts to be + ;; recreated. + (clear-font-cache) + (clear-face-cache t) + (redraw-display))))) (defun dynamic-setting-handle-config-changed-event (event) "Handle config-changed-event on the display in EVENT. diff --git a/src/ftcrfont.c b/src/ftcrfont.c index dc765e5aee..ede8f1323c 100644 --- a/src/ftcrfont.c +++ b/src/ftcrfont.c @@ -737,7 +737,7 @@ struct font_driver const ftcrfont_driver = .filter_properties = ftfont_filter_properties, .combining_capability = ftfont_combining_capability, #ifdef HAVE_PGTK - .cached_font_ok = ftcrfont_cached_font_ok + .cached_font_ok = ftcrfont_cached_font_ok, #endif }; #ifdef HAVE_HARFBUZZ @@ -755,6 +755,42 @@ syms_of_ftcrfont (void) pdumper_do_now_and_after_load (syms_of_ftcrfont_for_pdumper); } +#ifdef HAVE_X_WINDOWS + +/* Place the default font options used by Cairo on the given display + in OPTIONS. */ + +void +ftcrfont_get_default_font_options (struct x_display_info *dpyinfo, + cairo_font_options_t *options) +{ + Pixmap drawable; + cairo_surface_t *surface; + + /* Cairo doesn't allow fetching the default font options for a + display, so the only option is to create a drawable, and an Xlib + surface for that drawable, and to get the font options from there + instead. */ + + drawable = XCreatePixmap (dpyinfo->display, dpyinfo->root_window, + 1, 1, dpyinfo->n_planes); + surface = cairo_xlib_surface_create (dpyinfo->display, drawable, + dpyinfo->visual, 1, 1); + + if (!surface) + { + XFreePixmap (dpyinfo->display, drawable); + return; + } + + cairo_surface_get_font_options (surface, options); + XFreePixmap (dpyinfo->display, drawable); + cairo_surface_destroy (surface); + return; +} + +#endif + static void syms_of_ftcrfont_for_pdumper (void) { diff --git a/src/ftfont.h b/src/ftfont.h index cfab8d3154..ee56e2d760 100644 --- a/src/ftfont.h +++ b/src/ftfont.h @@ -84,4 +84,11 @@ struct font_info #endif }; +#if defined USE_CAIRO && defined HAVE_X_WINDOWS + +extern void ftcrfont_get_default_font_options (struct x_display_info *, + cairo_font_options_t *); + +#endif /* USE_CAIRO && HAVE_X_WINDOWS */ + #endif /* EMACS_FTFONT_H */ diff --git a/src/xsettings.c b/src/xsettings.c index 15e7ff5499..1a9f1a8d5a 100644 --- a/src/xsettings.c +++ b/src/xsettings.c @@ -56,6 +56,7 @@ typedef unsigned int CARD32; #ifdef USE_CAIRO #include +#include "ftfont.h" #elif defined HAVE_XFT #include #endif @@ -826,6 +827,7 @@ apply_xft_settings (Display_Info *dpyinfo, #else FcConfigSubstitute (NULL, pat, FcMatchPattern); options = cairo_font_options_create (); + ftcrfont_get_default_font_options (dpyinfo, options); cairo_ft_font_options_substitute (options, pat); cairo_font_options_destroy (options); FcDefaultSubstitute (pat); commit 56026242e462e8834337f118baaa9c49e2411f7d (refs/remotes/origin/emacs-28) Author: Robert Pluim Date: Mon Nov 14 17:12:49 2022 +0100 Explain how to bind keys to non-ASCII sequences * doc/emacs/custom.texi (Init Rebinding): Explain how to use `kbd' when binding keys to non-ASCII sequences. diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi index 2bc1d3820d..65970ce412 100644 --- a/doc/emacs/custom.texi +++ b/doc/emacs/custom.texi @@ -1868,6 +1868,22 @@ characters. For example, here's how to bind @kbd{C-x M-l} to @example (global-set-key "\C-x\M-l" 'make-symbolic-link) +@end example + + Similarly, a key sequence can be bound to a Lisp string or a vector +instead of a command. A vector is only required if the intended +result contains non-@acronym{ASCII} characters, and @code{kbd} can +again be used to create that vector. For example, to bind @kbd{C-c h} +to the string @samp{hello}: + +@example +(global-set-key (kbd "C-c h") "hello") +@end example + + But to bind it to the string @samp{olá} instead: + +@example +(global-set-key (kbd "C-c h") (kbd "olá")) @end example To bind a key sequence including @key{TAB}, @key{RET}, @key{ESC}, or commit 7d592db0ab606e8988ef662e6a1377348a87d188 Author: Eli Zaretskii Date: Sat Nov 12 13:10:24 2022 +0200 Document that 'transient-mark-mode' is off in batch mode * doc/emacs/mark.texi (Mark, Disabled Transient Mark): Document, belatedly, that 'transient-mark-mode' is turned on by default only in interactive sessions. (Bug#59201) diff --git a/doc/emacs/mark.texi b/doc/emacs/mark.texi index 91c44d527b..01ebfb2c85 100644 --- a/doc/emacs/mark.texi +++ b/doc/emacs/mark.texi @@ -35,10 +35,10 @@ the mark; this turns off the highlighting. You can also explicitly deactivate the mark at any time, by typing @kbd{C-g} (@pxref{Quitting}). - The above default behavior is known as Transient Mark mode. -Disabling Transient Mark mode switches Emacs to an alternative -behavior, in which the region is usually not highlighted. -@xref{Disabled Transient Mark}. + The above behavior, which is the default in interactive sessions, is +known as Transient Mark mode. Disabling Transient Mark mode switches +Emacs to an alternative behavior, in which the region is usually not +highlighted. @xref{Disabled Transient Mark}. @vindex highlight-nonselected-windows Setting the mark in one buffer has no effect on the marks in other @@ -429,10 +429,11 @@ motion keys will extend the region set by shift-selection. The default behavior of the mark and region, in which setting the mark activates it and highlights the region, is called Transient Mark -mode. This is a minor mode that is enabled by default. It can be -toggled with @kbd{M-x transient-mark-mode}, or with the -@samp{Highlight Active Region} menu item in the @samp{Options} menu. -Turning it off switches Emacs to an alternative mode of operation: +mode. This is a minor mode that is enabled by default in interactive +sessions. It can be toggled with @kbd{M-x transient-mark-mode}, or +with the @samp{Highlight Active Region} menu item in the +@samp{Options} menu. Turning it off switches Emacs to an alternative +mode of operation: @itemize @bullet @item