aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Mackenzie2020-11-05 19:27:43 +0000
committerAlan Mackenzie2020-11-05 19:27:43 +0000
commit2ecbf4cfae7bd504fbdca28e1e51ee2574fe5d12 (patch)
treedb4eee9a921e881edad01513dd57701633479d93 /src
parentbfd31242025cde90c8252db92dc54d0be4115c91 (diff)
downloademacs-2ecbf4cfae7bd504fbdca28e1e51ee2574fe5d12.tar.gz
emacs-2ecbf4cfae7bd504fbdca28e1e51ee2574fe5d12.zip
Allow minibuffer to stay in its original frame. Tidy up this area.
* doc/emacs/mini.texi (Basic Minibuffer): Add an entry for minibuffer-follows-selected-frame. * doc/lispref/minibuf.texi (Minibuffer Misc): Describe the new parameter to minibufferp, LIVE. * etc/NEWS: Add an entry describing the new minibuffer strategy. * lisp/cus-start.el (minibuffer-prompt-properties--setter): Add an entry for minibuffer-follows-selected-frame. * lisp/minibuffer.el (minibuffer-message): Check for the current buffer being an _active_ minibuffer rather than merely a minibuffer. * src/frame.c (do_switch_frame): Call move_minibuffer_onto_frame. * src/lisp.h (Top level): Add prototypes for move_minibuffer_onto_frame and is_minibuffer. * src/minibuf.c (minibuf_follows_frame): New function which ignores local and let-bound values of minibuffer-follows-selected-frame. (choose_minibuf_frame): Reformulate this function to reuse a minibuffer window where possible, and to ensure no other frame has its minibuffer current, but only when `minibuffer-follows-selected-frame'. (move_minibuffer_onto_frame): New function. (live_minibuffer_p): New function. (Fminibufferp): Add a new &optional parameter LIVE. Reformulate, possibly calling live_minibuffer_p. (read_minibuf): move the incrementation of minibuf_level to before the call of choose_minibuf_frame. Empty the miniwindows of frames without an active minibuffer, rather than of all but the current frame. (is_minibuffer): New function. (read_minibuf_unwind): Note the miniwindow being restored and resize all other miniwindows to zero size. (minibuffer-follows-selected-frame): New configuration variable. * src/window.c (candidate_window_p): In some scenarios, check the miniwindow holds an active minibuffer. * src/xdisp.c (get_window_cursor_type): Suppress the cursor for non-active miniwindows, regardless of minibuf_level.
Diffstat (limited to 'src')
-rw-r--r--src/frame.c1
-rw-r--r--src/lisp.h2
-rw-r--r--src/minibuf.c164
-rw-r--r--src/window.c6
-rw-r--r--src/xdisp.c4
5 files changed, 136 insertions, 41 deletions
diff --git a/src/frame.c b/src/frame.c
index 7c377da4456..512aaf5f45c 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -1482,6 +1482,7 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
1482#endif 1482#endif
1483 internal_last_event_frame = Qnil; 1483 internal_last_event_frame = Qnil;
1484 1484
1485 move_minibuffer_onto_frame ();
1485 return frame; 1486 return frame;
1486} 1487}
1487 1488
diff --git a/src/lisp.h b/src/lisp.h
index a3cfb5044d4..cf33031342d 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4336,6 +4336,8 @@ extern void clear_regexp_cache (void);
4336 4336
4337extern Lisp_Object Vminibuffer_list; 4337extern Lisp_Object Vminibuffer_list;
4338extern Lisp_Object last_minibuf_string; 4338extern Lisp_Object last_minibuf_string;
4339extern void move_minibuffer_onto_frame (void);
4340extern bool is_minibuffer (EMACS_INT, Lisp_Object);
4339extern Lisp_Object get_minibuffer (EMACS_INT); 4341extern Lisp_Object get_minibuffer (EMACS_INT);
4340extern void init_minibuf_once (void); 4342extern void init_minibuf_once (void);
4341extern void syms_of_minibuf (void); 4343extern void syms_of_minibuf (void);
diff --git a/src/minibuf.c b/src/minibuf.c
index f957b2ae173..ebc00ae4e4e 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -64,6 +64,12 @@ static Lisp_Object minibuf_prompt;
64static ptrdiff_t minibuf_prompt_width; 64static ptrdiff_t minibuf_prompt_width;
65 65
66 66
67static bool
68minibuf_follows_frame (void)
69{
70 return !NILP (Fdefault_toplevel_value (Qminibuffer_follows_selected_frame));
71}
72
67/* Put minibuf on currently selected frame's minibuffer. 73/* Put minibuf on currently selected frame's minibuffer.
68 We do this whenever the user starts a new minibuffer 74 We do this whenever the user starts a new minibuffer
69 or when a minibuffer exits. */ 75 or when a minibuffer exits. */
@@ -76,37 +82,72 @@ choose_minibuf_frame (void)
76 && !EQ (minibuf_window, XFRAME (selected_frame)->minibuffer_window)) 82 && !EQ (minibuf_window, XFRAME (selected_frame)->minibuffer_window))
77 { 83 {
78 struct frame *sf = XFRAME (selected_frame); 84 struct frame *sf = XFRAME (selected_frame);
79 Lisp_Object buffer;
80
81 /* I don't think that any frames may validly have a null minibuffer 85 /* I don't think that any frames may validly have a null minibuffer
82 window anymore. */ 86 window anymore. */
83 if (NILP (sf->minibuffer_window)) 87 if (NILP (sf->minibuffer_window))
84 emacs_abort (); 88 emacs_abort ();
85 89
86 /* Under X, we come here with minibuf_window being the
87 minibuffer window of the unused termcap window created in
88 init_window_once. That window doesn't have a buffer. */
89 buffer = XWINDOW (minibuf_window)->contents;
90 if (BUFFERP (buffer))
91 /* Use set_window_buffer instead of Fset_window_buffer (see
92 discussion of bug#11984, bug#12025, bug#12026). */
93 set_window_buffer (sf->minibuffer_window, buffer, 0, 0);
94 minibuf_window = sf->minibuffer_window; 90 minibuf_window = sf->minibuffer_window;
91 /* If we've still got another minibuffer open, use its mini-window
92 instead. */
93 if (minibuf_level && !minibuf_follows_frame ())
94 {
95 Lisp_Object buffer = get_minibuffer (minibuf_level);
96 Lisp_Object tail, frame;
97
98 FOR_EACH_FRAME (tail, frame)
99 if (EQ (XWINDOW (XFRAME (frame)->minibuffer_window)->contents,
100 buffer))
101 {
102 minibuf_window = XFRAME (frame)->minibuffer_window;
103 break;
104 }
105 }
95 } 106 }
96 107
97 /* Make sure no other frame has a minibuffer as its selected window, 108 if (minibuf_follows_frame ())
98 because the text would not be displayed in it, and that would be 109 /* Make sure no other frame has a minibuffer as its selected window,
99 confusing. Only allow the selected frame to do this, 110 because the text would not be displayed in it, and that would be
100 and that only if the minibuffer is active. */ 111 confusing. Only allow the selected frame to do this,
101 { 112 and that only if the minibuffer is active. */
102 Lisp_Object tail, frame; 113 {
114 Lisp_Object tail, frame;
115
116 FOR_EACH_FRAME (tail, frame)
117 if (MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (XFRAME (frame))))
118 && !(EQ (frame, selected_frame)
119 && minibuf_level > 0))
120 Fset_frame_selected_window (frame, Fframe_first_window (frame),
121 Qnil);
122 }
123}
103 124
104 FOR_EACH_FRAME (tail, frame) 125/* If `minibuffer_follows_selected_frame' and we have a minibuffer, move it
105 if (MINI_WINDOW_P (XWINDOW (FRAME_SELECTED_WINDOW (XFRAME (frame)))) 126 from its current frame to the selected frame. This function is
106 && !(EQ (frame, selected_frame) 127 intended to be called from `do_switch_frame' in frame.c. */
107 && minibuf_level > 0)) 128void move_minibuffer_onto_frame (void)
108 Fset_frame_selected_window (frame, Fframe_first_window (frame), Qnil); 129{
109 } 130 if (!minibuf_level)
131 return;
132 if (!minibuf_follows_frame ())
133 return;
134 if (FRAMEP (selected_frame)
135 && FRAME_LIVE_P (XFRAME (selected_frame))
136 && !EQ (minibuf_window, XFRAME (selected_frame)->minibuffer_window))
137 {
138 struct frame *sf = XFRAME (selected_frame);
139 Lisp_Object old_frame = XWINDOW (minibuf_window)->frame;
140 struct frame *of = XFRAME (old_frame);
141 Lisp_Object buffer = XWINDOW (minibuf_window)->contents;
142
143 set_window_buffer (sf->minibuffer_window, buffer, 0, 0);
144 minibuf_window = sf->minibuffer_window;
145 if (XWINDOW (minibuf_window)->frame == selected_frame)
146 /* The minibuffer might be on another frame. */
147 Fset_frame_selected_window (selected_frame, sf->minibuffer_window,
148 Qnil);
149 set_window_buffer (of->minibuffer_window, get_minibuffer (0), 0, 0);
150 }
110} 151}
111 152
112DEFUN ("active-minibuffer-window", Factive_minibuffer_window, 153DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
@@ -261,15 +302,31 @@ read_minibuf_noninteractive (Lisp_Object prompt, bool expflag,
261 return val; 302 return val;
262} 303}
263 304
305/* Return true when BUFFER is an active minibuffer. */
306static bool
307live_minibuffer_p (Lisp_Object buffer)
308{
309 Lisp_Object tem;
310 EMACS_INT i;
311
312 if (EQ (buffer, Fcar (Vminibuffer_list)))
313 /* *Minibuf-0* is never active. */
314 return false;
315 tem = Fcdr (Vminibuffer_list);
316 for (i = 1; i <= minibuf_level; i++, tem = Fcdr (tem))
317 if (EQ (Fcar (tem), buffer))
318 return true;
319 return false;
320}
321
264DEFUN ("minibufferp", Fminibufferp, 322DEFUN ("minibufferp", Fminibufferp,
265 Sminibufferp, 0, 1, 0, 323 Sminibufferp, 0, 2, 0,
266 doc: /* Return t if BUFFER is a minibuffer. 324 doc: /* Return t if BUFFER is a minibuffer.
267No argument or nil as argument means use current buffer as BUFFER. 325No argument or nil as argument means use current buffer as BUFFER.
268BUFFER can be a buffer or a buffer name. */) 326BUFFER can be a buffer or a buffer name. If LIVE is non-nil, then
269 (Lisp_Object buffer) 327return t only if BUFFER is an active minibuffer. */)
328 (Lisp_Object buffer, Lisp_Object live)
270{ 329{
271 Lisp_Object tem;
272
273 if (NILP (buffer)) 330 if (NILP (buffer))
274 buffer = Fcurrent_buffer (); 331 buffer = Fcurrent_buffer ();
275 else if (STRINGP (buffer)) 332 else if (STRINGP (buffer))
@@ -277,8 +334,10 @@ BUFFER can be a buffer or a buffer name. */)
277 else 334 else
278 CHECK_BUFFER (buffer); 335 CHECK_BUFFER (buffer);
279 336
280 tem = Fmemq (buffer, Vminibuffer_list); 337 return (NILP (live)
281 return ! NILP (tem) ? Qt : Qnil; 338 ? !NILP (Fmemq (buffer, Vminibuffer_list))
339 : live_minibuffer_p (buffer))
340 ? Qt : Qnil;
282} 341}
283 342
284DEFUN ("minibuffer-prompt-end", Fminibuffer_prompt_end, 343DEFUN ("minibuffer-prompt-end", Fminibuffer_prompt_end,
@@ -433,6 +492,8 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
433 return unbind_to (count, val); 492 return unbind_to (count, val);
434 } 493 }
435 494
495 minibuf_level++; /* Before calling choose_minibuf_frame. */
496
436 /* Choose the minibuffer window and frame, and take action on them. */ 497 /* Choose the minibuffer window and frame, and take action on them. */
437 498
438 /* Prepare for restoring the current buffer since choose_minibuf_frame 499 /* Prepare for restoring the current buffer since choose_minibuf_frame
@@ -484,7 +545,6 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
484 = Fcons (Fthis_command_keys_vector (), minibuf_save_list); 545 = Fcons (Fthis_command_keys_vector (), minibuf_save_list);
485 546
486 record_unwind_protect_void (read_minibuf_unwind); 547 record_unwind_protect_void (read_minibuf_unwind);
487 minibuf_level++;
488 /* We are exiting the minibuffer one way or the other, so run the hook. 548 /* We are exiting the minibuffer one way or the other, so run the hook.
489 It should be run before unwinding the minibuf settings. Do it 549 It should be run before unwinding the minibuf settings. Do it
490 separately from read_minibuf_unwind because we need to make sure that 550 separately from read_minibuf_unwind because we need to make sure that
@@ -566,8 +626,8 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
566 if (minibuf_level == 1 || !EQ (minibuf_window, selected_window)) 626 if (minibuf_level == 1 || !EQ (minibuf_window, selected_window))
567 minibuf_selected_window = selected_window; 627 minibuf_selected_window = selected_window;
568 628
569 /* Empty out the minibuffers of all frames other than the one 629 /* Empty out the minibuffers of all frames, except those frames
570 where we are going to display one now. 630 where there is an active minibuffer.
571 Set them to point to ` *Minibuf-0*', which is always empty. */ 631 Set them to point to ` *Minibuf-0*', which is always empty. */
572 empty_minibuf = get_minibuffer (0); 632 empty_minibuf = get_minibuffer (0);
573 633
@@ -575,12 +635,17 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
575 { 635 {
576 Lisp_Object root_window = Fframe_root_window (frame); 636 Lisp_Object root_window = Fframe_root_window (frame);
577 Lisp_Object mini_window = XWINDOW (root_window)->next; 637 Lisp_Object mini_window = XWINDOW (root_window)->next;
638 Lisp_Object buffer;
578 639
579 if (! NILP (mini_window) && ! EQ (mini_window, minibuf_window) 640 if (!NILP (mini_window) && !EQ (mini_window, minibuf_window)
580 && !NILP (Fwindow_minibuffer_p (mini_window))) 641 && !NILP (Fwindow_minibuffer_p (mini_window)))
581 /* Use set_window_buffer instead of Fset_window_buffer (see 642 {
582 discussion of bug#11984, bug#12025, bug#12026). */ 643 buffer = XWINDOW (mini_window)->contents;
583 set_window_buffer (mini_window, empty_minibuf, 0, 0); 644 if (!live_minibuffer_p (buffer))
645 /* Use set_window_buffer instead of Fset_window_buffer (see
646 discussion of bug#11984, bug#12025, bug#12026). */
647 set_window_buffer (mini_window, empty_minibuf, 0, 0);
648 }
584 } 649 }
585 650
586 /* Display this minibuffer in the proper window. */ 651 /* Display this minibuffer in the proper window. */
@@ -714,6 +779,16 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
714 return val; 779 return val;
715} 780}
716 781
782/* Return true if BUF is a particular existing minibuffer. */
783bool
784is_minibuffer (EMACS_INT depth, Lisp_Object buf)
785{
786 Lisp_Object tail = Fnthcdr (make_fixnum (depth), Vminibuffer_list);
787 return
788 !NILP (tail)
789 && EQ (Fcar (tail), buf);
790}
791
717/* Return a buffer to be used as the minibuffer at depth `depth'. 792/* Return a buffer to be used as the minibuffer at depth `depth'.
718 depth = 0 is the lowest allowed argument, and that is the value 793 depth = 0 is the lowest allowed argument, and that is the value
719 used for nonrecursive minibuffer invocations. */ 794 used for nonrecursive minibuffer invocations. */
@@ -775,6 +850,7 @@ read_minibuf_unwind (void)
775{ 850{
776 Lisp_Object old_deactivate_mark; 851 Lisp_Object old_deactivate_mark;
777 Lisp_Object window; 852 Lisp_Object window;
853 Lisp_Object future_mini_window;
778 854
779 /* If this was a recursive minibuffer, 855 /* If this was a recursive minibuffer,
780 tie the minibuffer window back to the outer level minibuffer buffer. */ 856 tie the minibuffer window back to the outer level minibuffer buffer. */
@@ -809,6 +885,7 @@ read_minibuf_unwind (void)
809 if (FRAME_LIVE_P (XFRAME (WINDOW_FRAME (XWINDOW (temp))))) 885 if (FRAME_LIVE_P (XFRAME (WINDOW_FRAME (XWINDOW (temp)))))
810 minibuf_window = temp; 886 minibuf_window = temp;
811#endif 887#endif
888 future_mini_window = Fcar (minibuf_save_list);
812 minibuf_save_list = Fcdr (minibuf_save_list); 889 minibuf_save_list = Fcdr (minibuf_save_list);
813 890
814 /* Erase the minibuffer we were using at this level. */ 891 /* Erase the minibuffer we were using at this level. */
@@ -825,7 +902,8 @@ read_minibuf_unwind (void)
825 902
826 /* When we get to the outmost level, make sure we resize the 903 /* When we get to the outmost level, make sure we resize the
827 mini-window back to its normal size. */ 904 mini-window back to its normal size. */
828 if (minibuf_level == 0) 905 if (minibuf_level == 0
906 || !EQ (selected_frame, WINDOW_FRAME (XWINDOW (future_mini_window))))
829 resize_mini_window (XWINDOW (window), 0); 907 resize_mini_window (XWINDOW (window), 0);
830 908
831 /* Deal with frames that should be removed when exiting the 909 /* Deal with frames that should be removed when exiting the
@@ -1911,6 +1989,8 @@ syms_of_minibuf (void)
1911 staticpro (&minibuf_prompt); 1989 staticpro (&minibuf_prompt);
1912 staticpro (&minibuf_save_list); 1990 staticpro (&minibuf_save_list);
1913 1991
1992 DEFSYM (Qminibuffer_follows_selected_frame,
1993 "minibuffer-follows-selected-frame");
1914 DEFSYM (Qcompletion_ignore_case, "completion-ignore-case"); 1994 DEFSYM (Qcompletion_ignore_case, "completion-ignore-case");
1915 DEFSYM (Qminibuffer_default, "minibuffer-default"); 1995 DEFSYM (Qminibuffer_default, "minibuffer-default");
1916 Fset (Qminibuffer_default, Qnil); 1996 Fset (Qminibuffer_default, Qnil);
@@ -1954,6 +2034,14 @@ For example, `eval-expression' uses this. */);
1954The function is called with the arguments passed to `read-buffer'. */); 2034The function is called with the arguments passed to `read-buffer'. */);
1955 Vread_buffer_function = Qnil; 2035 Vread_buffer_function = Qnil;
1956 2036
2037 DEFVAR_BOOL ("minibuffer-follows-selected-frame", minibuffer_follows_selected_frame,
2038 doc: /* Non-nil means the active minibuffer always displays on the selected frame.
2039Nil means that a minibuffer will appear only in the frame which created it.
2040
2041Any buffer local or dynamic binding of this variable is ignored. Only the
2042default top level value is used. */);
2043 minibuffer_follows_selected_frame = 1;
2044
1957 DEFVAR_BOOL ("read-buffer-completion-ignore-case", 2045 DEFVAR_BOOL ("read-buffer-completion-ignore-case",
1958 read_buffer_completion_ignore_case, 2046 read_buffer_completion_ignore_case,
1959 doc: /* Non-nil means completion ignores case when reading a buffer name. */); 2047 doc: /* Non-nil means completion ignores case when reading a buffer name. */);
diff --git a/src/window.c b/src/window.c
index e7433969d29..a6de34f3db6 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2643,8 +2643,10 @@ candidate_window_p (Lisp_Object window, Lisp_Object owindow,
2643 /* To qualify as candidate, it's not sufficient for WINDOW's frame 2643 /* To qualify as candidate, it's not sufficient for WINDOW's frame
2644 to just share the minibuffer window - it must be active as well 2644 to just share the minibuffer window - it must be active as well
2645 (see Bug#24500). */ 2645 (see Bug#24500). */
2646 candidate_p = (EQ (XWINDOW (all_frames)->frame, w->frame) 2646 candidate_p = ((EQ (XWINDOW (all_frames)->frame, w->frame)
2647 || EQ (XWINDOW (all_frames)->frame, FRAME_FOCUS_FRAME (f))); 2647 || (EQ (f->minibuffer_window, all_frames)
2648 && EQ (XWINDOW (all_frames)->frame, FRAME_FOCUS_FRAME (f))))
2649 && !is_minibuffer (0, XWINDOW (all_frames)->contents));
2648 else if (FRAMEP (all_frames)) 2650 else if (FRAMEP (all_frames))
2649 candidate_p = EQ (all_frames, w->frame); 2651 candidate_p = EQ (all_frames, w->frame);
2650 2652
diff --git a/src/xdisp.c b/src/xdisp.c
index 618ec688e89..bff14e584de 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -31224,7 +31224,9 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
31224 { 31224 {
31225 *active_cursor = false; 31225 *active_cursor = false;
31226 31226
31227 if (MINI_WINDOW_P (w) && minibuf_level == 0) 31227 if (MINI_WINDOW_P (w) &&
31228 (minibuf_level == 0
31229 || is_minibuffer (0, w->contents)))
31228 return NO_CURSOR; 31230 return NO_CURSOR;
31229 31231
31230 non_selected = true; 31232 non_selected = true;