diff options
| author | Mauro Aranda | 2025-03-09 19:07:40 -0300 |
|---|---|---|
| committer | Mauro Aranda | 2025-03-09 19:07:40 -0300 |
| commit | 0861da138b91b936a1b307fd59622d98f9b22cc6 (patch) | |
| tree | 5cd6be7aeea6a4685dd0087b005b264c0bb66d97 | |
| parent | 731af8747cb07aea532d9e9fd246857a88625a44 (diff) | |
| download | emacs-0861da138b91b936a1b307fd59622d98f9b22cc6.tar.gz emacs-0861da138b91b936a1b307fd59622d98f9b22cc6.zip | |
Provide better completion for customizing frame parameters
* lisp/frame.el (frame--special-parameters): New const.
(frame--complete-parameter-value): New function.
(initial-frame-alist, minibuffer-frame-alist): Use them in
:type. (Bug#39143)
* lisp/cus-start.el (default-frame-alist): Use them here as well.
* src/frame.c (frame_parms): Add comment to try to keep
frame--special-parameters updated.
| -rw-r--r-- | lisp/cus-start.el | 11 | ||||
| -rw-r--r-- | lisp/frame.el | 88 | ||||
| -rw-r--r-- | src/frame.c | 4 |
3 files changed, 93 insertions, 10 deletions
diff --git a/lisp/cus-start.el b/lisp/cus-start.el index b4c20caccc1..7d17249f78d 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el | |||
| @@ -317,10 +317,13 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of | |||
| 317 | (vertical-centering-font-regexp display | 317 | (vertical-centering-font-regexp display |
| 318 | (choice (const nil) regexp)) | 318 | (choice (const nil) regexp)) |
| 319 | ;; frame.c | 319 | ;; frame.c |
| 320 | (default-frame-alist frames | 320 | (default-frame-alist |
| 321 | (repeat (cons :format "%v" | 321 | frames |
| 322 | (symbol :tag "Parameter") | 322 | (repeat (cons :format "%v" |
| 323 | (sexp :tag "Value")))) | 323 | (symbol :tag "Parameter" |
| 324 | :completions ,frame--special-parameters) | ||
| 325 | (sexp :tag "Value" | ||
| 326 | :complete frame--complete-parameter-value)))) | ||
| 324 | (mouse-highlight mouse (choice (const :tag "disabled" nil) | 327 | (mouse-highlight mouse (choice (const :tag "disabled" nil) |
| 325 | (const :tag "always shown" t) | 328 | (const :tag "always shown" t) |
| 326 | (other :tag "hidden by keypress" 1)) | 329 | (other :tag "hidden by keypress" 1)) |
diff --git a/lisp/frame.el b/lisp/frame.el index e66270130d2..3eccb9a5848 100644 --- a/lisp/frame.el +++ b/lisp/frame.el | |||
| @@ -60,6 +60,78 @@ The car of each entry is a regular expression matching a display | |||
| 60 | name string. The cdr is a symbol giving the window-system that | 60 | name string. The cdr is a symbol giving the window-system that |
| 61 | handles the corresponding kind of display.") | 61 | handles the corresponding kind of display.") |
| 62 | 62 | ||
| 63 | ;; If you're adding a new frame parameter to `frame_parms' in frame.c, | ||
| 64 | ;; consider if it makes sense for the user to customize it via | ||
| 65 | ;; `initial-frame-alist' and the like. | ||
| 66 | ;; If it does, add it here, in order to provide completion for | ||
| 67 | ;; that parameter in the Customize UI. | ||
| 68 | ;; If the parameter has some special values, modify | ||
| 69 | ;; `frame--complete-parameter-value' to provide completion for those | ||
| 70 | ;; values as well. | ||
| 71 | (defconst frame--special-parameters | ||
| 72 | '("alpha" "alpha-background" "auto-hide-function" "auto-lower" | ||
| 73 | "auto-raise" "background-color" "background-mode" "border-color" | ||
| 74 | "border-width" "bottom-divider-width" "bottom-visible" "buffer-list" | ||
| 75 | "buffer-predicate" "child-frame-border-width" "cursor-color" | ||
| 76 | "cursor-type" "delete-before" "display" "display-type" | ||
| 77 | "drag-internal-border" "drag-with-header-line" "drag-with-mode-line" | ||
| 78 | "drag-with-tab-line" "explicit-name" "fit-frame-to-buffer-margins" | ||
| 79 | "fit-frame-to-buffer-sizes" "font" "font-backend" "foreground-color" | ||
| 80 | "fullscreen" "fullscreen-restore" "height" "horizontal-scroll-bars" | ||
| 81 | "icon-left" "icon-name" "icon-top" "icon-type" | ||
| 82 | "inhibit-double-buffering" "internal-border-width" "keep-ratio" | ||
| 83 | "left" "left-fringe" "line-spacing" "menu-bar-lines" "min-height" | ||
| 84 | "min-width" "minibuffer" "minibuffer-exit" "mouse-color" | ||
| 85 | "mouse-wheel-frame" "name" "no-accept-focus" "no-focus-on-map" | ||
| 86 | "no-other-frame" "no-special-glyphs" "ns-appearance" | ||
| 87 | "ns-transparent-titlebar" "outer-window-id" "override-redirect" | ||
| 88 | "parent-frame" "right-fringe" "rigth-divider-width" "screen-gamma" | ||
| 89 | "scroll-bar-background" "scroll-bar-foreground" "scroll-bar-height" | ||
| 90 | "scroll-bar-width" "shaded" "skip-taskbar" "snap-width" "sticky" | ||
| 91 | "tab-bar-lines" "title" "tool-bar-lines" "tool-bar-position" "top" | ||
| 92 | "top-visible" "tty-color-mode" "undecorated" "unspittable" | ||
| 93 | "use-frame-synchronization" "user-position" "user-size" | ||
| 94 | "vertical-scroll-bars" "visibility" "wait-for-wm" "width" "z-group") | ||
| 95 | "List of special frame parameters that makes sense to customize.") | ||
| 96 | |||
| 97 | (declare-function "widget-field-text-end" "wid-edit") | ||
| 98 | (declare-function "widget-field-start" "wid-edit") | ||
| 99 | |||
| 100 | (defun frame--complete-parameter-value (widget) | ||
| 101 | "Provide completion for WIDGET, which holds frame parameter's values." | ||
| 102 | (let* ((parameter (widget-value | ||
| 103 | (nth 0 | ||
| 104 | (widget-get (widget-get widget :parent) :children)))) | ||
| 105 | (comps (cond ((eq parameter 'display-type) | ||
| 106 | '("color" "grayscale" "mono")) | ||
| 107 | ((eq parameter 'z-group) '("nil" "above" "below")) | ||
| 108 | ((memq parameter '(fullscreen fullscreen-restore)) | ||
| 109 | '("fullwidth" "fullheight" "fullboth" "maximized")) | ||
| 110 | ((eq parameter 'cursor-type) | ||
| 111 | '("t" "nil" "box" "hollow" "bar" "hbar")) | ||
| 112 | ((eq parameter 'vertical-scroll-bars) | ||
| 113 | '("nil" "left" "right")) | ||
| 114 | ((eq parameter 'tool-bar-position) | ||
| 115 | '("top" "bottom" "left" "right")) | ||
| 116 | ((eq parameter 'minibuffer) | ||
| 117 | '("t" "nil" "only")) | ||
| 118 | ((eq parameter 'minibuffer-exit) | ||
| 119 | '("nil" "t" "iconify-frame" "delete-frame")) | ||
| 120 | ((eq parameter 'visibility) '("nil" "t" "icon")) | ||
| 121 | ((memq parameter '(ns-appearance background-mode)) | ||
| 122 | '("dark" "light")) | ||
| 123 | ((eq parameter 'font-backend) | ||
| 124 | '("x" "xft" "xfthb" "ftcr" "ftcrhb" "gdi" | ||
| 125 | "uniscribe" "harfbuzz")) | ||
| 126 | ((memq parameter '(buffer-predicate auto-hide-function)) | ||
| 127 | (apply-partially | ||
| 128 | #'completion-table-with-predicate | ||
| 129 | obarray #'fboundp 'strict)) | ||
| 130 | (t nil)))) | ||
| 131 | (completion-in-region (widget-field-start widget) | ||
| 132 | (max (point) (widget-field-text-end widget)) | ||
| 133 | comps))) | ||
| 134 | |||
| 63 | ;; The initial value given here used to ask for a minibuffer. | 135 | ;; The initial value given here used to ask for a minibuffer. |
| 64 | ;; But that's not necessary, because the default is to have one. | 136 | ;; But that's not necessary, because the default is to have one. |
| 65 | ;; By not specifying it here, we let an X resource specify it. | 137 | ;; By not specifying it here, we let an X resource specify it. |
| @@ -91,9 +163,11 @@ process: | |||
| 91 | * Set `initial-frame-alist' in your normal init file in a way | 163 | * Set `initial-frame-alist' in your normal init file in a way |
| 92 | that matches the X resources, to override what you put in | 164 | that matches the X resources, to override what you put in |
| 93 | `default-frame-alist'." | 165 | `default-frame-alist'." |
| 94 | :type '(repeat (cons :format "%v" | 166 | :type `(repeat (cons :format "%v" |
| 95 | (symbol :tag "Parameter") | 167 | (symbol :tag "Parameter" |
| 96 | (sexp :tag "Value"))) | 168 | :completions ,frame--special-parameters) |
| 169 | (sexp :tag "Value" | ||
| 170 | :complete frame--complete-parameter-value))) | ||
| 97 | :group 'frames) | 171 | :group 'frames) |
| 98 | 172 | ||
| 99 | (defcustom minibuffer-frame-alist '((width . 80) (height . 2)) | 173 | (defcustom minibuffer-frame-alist '((width . 80) (height . 2)) |
| @@ -110,9 +184,11 @@ You can set this in your init file; for example, | |||
| 110 | 184 | ||
| 111 | It is not necessary to include (minibuffer . only); that is | 185 | It is not necessary to include (minibuffer . only); that is |
| 112 | appended when the minibuffer frame is created." | 186 | appended when the minibuffer frame is created." |
| 113 | :type '(repeat (cons :format "%v" | 187 | :type `(repeat (cons :format "%v" |
| 114 | (symbol :tag "Parameter") | 188 | (symbol :tag "Parameter" |
| 115 | (sexp :tag "Value"))) | 189 | :completions ,frame--special-parameters) |
| 190 | (sexp :tag "Value" | ||
| 191 | :complete frame--complete-parameter-value))) | ||
| 116 | :group 'frames) | 192 | :group 'frames) |
| 117 | 193 | ||
| 118 | (defun frame-deletable-p (&optional frame) | 194 | (defun frame-deletable-p (&optional frame) |
diff --git a/src/frame.c b/src/frame.c index 1a5c2f5c3d4..b386839f34c 100644 --- a/src/frame.c +++ b/src/frame.c | |||
| @@ -4392,6 +4392,10 @@ struct frame_parm_table { | |||
| 4392 | int sym; | 4392 | int sym; |
| 4393 | }; | 4393 | }; |
| 4394 | 4394 | ||
| 4395 | /* If you're adding a new frame parameter here, consider if it makes sense | ||
| 4396 | for the user to customize it via `initial-frame-alist' and the like. | ||
| 4397 | If it does, add it to `frame--special-parameters' in frame.el, in order | ||
| 4398 | to provide completion in the Customize UI for the new parameter. */ | ||
| 4395 | static const struct frame_parm_table frame_parms[] = | 4399 | static const struct frame_parm_table frame_parms[] = |
| 4396 | { | 4400 | { |
| 4397 | {"auto-raise", SYMBOL_INDEX (Qauto_raise)}, | 4401 | {"auto-raise", SYMBOL_INDEX (Qauto_raise)}, |