aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Aranda2025-03-09 19:07:40 -0300
committerMauro Aranda2025-03-09 19:07:40 -0300
commit0861da138b91b936a1b307fd59622d98f9b22cc6 (patch)
tree5cd6be7aeea6a4685dd0087b005b264c0bb66d97
parent731af8747cb07aea532d9e9fd246857a88625a44 (diff)
downloademacs-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.el11
-rw-r--r--lisp/frame.el88
-rw-r--r--src/frame.c4
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
60name string. The cdr is a symbol giving the window-system that 60name string. The cdr is a symbol giving the window-system that
61handles the corresponding kind of display.") 61handles 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
111It is not necessary to include (minibuffer . only); that is 185It is not necessary to include (minibuffer . only); that is
112appended when the minibuffer frame is created." 186appended 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. */
4395static const struct frame_parm_table frame_parms[] = 4399static const struct frame_parm_table frame_parms[] =
4396{ 4400{
4397 {"auto-raise", SYMBOL_INDEX (Qauto_raise)}, 4401 {"auto-raise", SYMBOL_INDEX (Qauto_raise)},