Treat inactive TUI specially in "info win"
[deliverable/binutils-gdb.git] / gdb / tui / tui-win.c
1 /* TUI window generic functions.
2
3 Copyright (C) 1998-2019 Free Software Foundation, Inc.
4
5 Contributed by Hewlett-Packard Company.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21
22 /* This module contains procedures for handling tui window functions
23 like resize, scrolling, scrolling, changing focus, etc.
24
25 Author: Susan B. Macchia */
26
27 #include "defs.h"
28 #include "command.h"
29 #include "symtab.h"
30 #include "breakpoint.h"
31 #include "frame.h"
32 #include "cli/cli-cmds.h"
33 #include "cli/cli-style.h"
34 #include "top.h"
35 #include "source.h"
36 #include "event-loop.h"
37 #include "gdbcmd.h"
38
39 #include "tui/tui.h"
40 #include "tui/tui-io.h"
41 #include "tui/tui-command.h"
42 #include "tui/tui-data.h"
43 #include "tui/tui-layout.h"
44 #include "tui/tui-wingeneral.h"
45 #include "tui/tui-stack.h"
46 #include "tui/tui-regs.h"
47 #include "tui/tui-disasm.h"
48 #include "tui/tui-source.h"
49 #include "tui/tui-winsource.h"
50 #include "tui/tui-win.h"
51
52 #include "gdb_curses.h"
53 #include <ctype.h>
54 #include "readline/readline.h"
55 #include "gdbsupport/gdb_string_view.h"
56
57 #include <signal.h>
58
59 static enum tui_status tui_adjust_win_heights (struct tui_win_info *,
60 int);
61 static int new_height_ok (struct tui_win_info *, int);
62 static void tui_set_tab_width_command (const char *, int);
63 static void tui_refresh_all_command (const char *, int);
64 static void tui_all_windows_info (const char *, int);
65 static void tui_scroll_forward_command (const char *, int);
66 static void tui_scroll_backward_command (const char *, int);
67 static void tui_scroll_left_command (const char *, int);
68 static void tui_scroll_right_command (const char *, int);
69 static void parse_scrolling_args (const char *,
70 struct tui_win_info **,
71 int *);
72
73
74 #define WIN_HEIGHT_USAGE "Usage: winheight WINDOW-NAME [+ | -] NUM-LINES\n"
75 #define FOCUS_USAGE "Usage: focus [WINDOW-NAME | next | prev]\n"
76
77 #ifndef ACS_LRCORNER
78 # define ACS_LRCORNER '+'
79 #endif
80 #ifndef ACS_LLCORNER
81 # define ACS_LLCORNER '+'
82 #endif
83 #ifndef ACS_ULCORNER
84 # define ACS_ULCORNER '+'
85 #endif
86 #ifndef ACS_URCORNER
87 # define ACS_URCORNER '+'
88 #endif
89 #ifndef ACS_HLINE
90 # define ACS_HLINE '-'
91 #endif
92 #ifndef ACS_VLINE
93 # define ACS_VLINE '|'
94 #endif
95
96 /* Possible values for tui-border-kind variable. */
97 static const char *const tui_border_kind_enums[] = {
98 "space",
99 "ascii",
100 "acs",
101 NULL
102 };
103
104 /* Possible values for tui-border-mode and tui-active-border-mode. */
105 static const char *const tui_border_mode_enums[] = {
106 "normal",
107 "standout",
108 "reverse",
109 "half",
110 "half-standout",
111 "bold",
112 "bold-standout",
113 NULL
114 };
115
116 struct tui_translate
117 {
118 const char *name;
119 int value;
120 };
121
122 /* Translation table for border-mode variables.
123 The list of values must be terminated by a NULL.
124 After the NULL value, an entry defines the default. */
125 struct tui_translate tui_border_mode_translate[] = {
126 { "normal", A_NORMAL },
127 { "standout", A_STANDOUT },
128 { "reverse", A_REVERSE },
129 { "half", A_DIM },
130 { "half-standout", A_DIM | A_STANDOUT },
131 { "bold", A_BOLD },
132 { "bold-standout", A_BOLD | A_STANDOUT },
133 { 0, 0 },
134 { "normal", A_NORMAL }
135 };
136
137 /* Translation tables for border-kind, one for each border
138 character (see wborder, border curses operations).
139 -1 is used to indicate the ACS because ACS characters
140 are determined at run time by curses (depends on terminal). */
141 struct tui_translate tui_border_kind_translate_vline[] = {
142 { "space", ' ' },
143 { "ascii", '|' },
144 { "acs", -1 },
145 { 0, 0 },
146 { "ascii", '|' }
147 };
148
149 struct tui_translate tui_border_kind_translate_hline[] = {
150 { "space", ' ' },
151 { "ascii", '-' },
152 { "acs", -1 },
153 { 0, 0 },
154 { "ascii", '-' }
155 };
156
157 struct tui_translate tui_border_kind_translate_ulcorner[] = {
158 { "space", ' ' },
159 { "ascii", '+' },
160 { "acs", -1 },
161 { 0, 0 },
162 { "ascii", '+' }
163 };
164
165 struct tui_translate tui_border_kind_translate_urcorner[] = {
166 { "space", ' ' },
167 { "ascii", '+' },
168 { "acs", -1 },
169 { 0, 0 },
170 { "ascii", '+' }
171 };
172
173 struct tui_translate tui_border_kind_translate_llcorner[] = {
174 { "space", ' ' },
175 { "ascii", '+' },
176 { "acs", -1 },
177 { 0, 0 },
178 { "ascii", '+' }
179 };
180
181 struct tui_translate tui_border_kind_translate_lrcorner[] = {
182 { "space", ' ' },
183 { "ascii", '+' },
184 { "acs", -1 },
185 { 0, 0 },
186 { "ascii", '+' }
187 };
188
189
190 /* Tui configuration variables controlled with set/show command. */
191 const char *tui_active_border_mode = "bold-standout";
192 static void
193 show_tui_active_border_mode (struct ui_file *file,
194 int from_tty,
195 struct cmd_list_element *c,
196 const char *value)
197 {
198 fprintf_filtered (file, _("\
199 The attribute mode to use for the active TUI window border is \"%s\".\n"),
200 value);
201 }
202
203 const char *tui_border_mode = "normal";
204 static void
205 show_tui_border_mode (struct ui_file *file,
206 int from_tty,
207 struct cmd_list_element *c,
208 const char *value)
209 {
210 fprintf_filtered (file, _("\
211 The attribute mode to use for the TUI window borders is \"%s\".\n"),
212 value);
213 }
214
215 const char *tui_border_kind = "acs";
216 static void
217 show_tui_border_kind (struct ui_file *file,
218 int from_tty,
219 struct cmd_list_element *c,
220 const char *value)
221 {
222 fprintf_filtered (file, _("The kind of border for TUI windows is \"%s\".\n"),
223 value);
224 }
225
226
227 /* Tui internal configuration variables. These variables are updated
228 by tui_update_variables to reflect the tui configuration
229 variables. */
230 chtype tui_border_vline;
231 chtype tui_border_hline;
232 chtype tui_border_ulcorner;
233 chtype tui_border_urcorner;
234 chtype tui_border_llcorner;
235 chtype tui_border_lrcorner;
236
237 int tui_border_attrs;
238 int tui_active_border_attrs;
239
240 /* Identify the item in the translation table.
241 When the item is not recognized, use the default entry. */
242 static struct tui_translate *
243 translate (const char *name, struct tui_translate *table)
244 {
245 while (table->name)
246 {
247 if (name && strcmp (table->name, name) == 0)
248 return table;
249 table++;
250 }
251
252 /* Not found, return default entry. */
253 table++;
254 return table;
255 }
256
257 /* Update the tui internal configuration according to gdb settings.
258 Returns 1 if the configuration has changed and the screen should
259 be redrawn. */
260 int
261 tui_update_variables (void)
262 {
263 int need_redraw = 0;
264 struct tui_translate *entry;
265
266 entry = translate (tui_border_mode, tui_border_mode_translate);
267 if (tui_border_attrs != entry->value)
268 {
269 tui_border_attrs = entry->value;
270 need_redraw = 1;
271 }
272 entry = translate (tui_active_border_mode, tui_border_mode_translate);
273 if (tui_active_border_attrs != entry->value)
274 {
275 tui_active_border_attrs = entry->value;
276 need_redraw = 1;
277 }
278
279 /* If one corner changes, all characters are changed.
280 Only check the first one. The ACS characters are determined at
281 run time by curses terminal management. */
282 entry = translate (tui_border_kind, tui_border_kind_translate_lrcorner);
283 if (tui_border_lrcorner != (chtype) entry->value)
284 {
285 tui_border_lrcorner = (entry->value < 0) ? ACS_LRCORNER : entry->value;
286 need_redraw = 1;
287 }
288 entry = translate (tui_border_kind, tui_border_kind_translate_llcorner);
289 tui_border_llcorner = (entry->value < 0) ? ACS_LLCORNER : entry->value;
290
291 entry = translate (tui_border_kind, tui_border_kind_translate_ulcorner);
292 tui_border_ulcorner = (entry->value < 0) ? ACS_ULCORNER : entry->value;
293
294 entry = translate (tui_border_kind, tui_border_kind_translate_urcorner);
295 tui_border_urcorner = (entry->value < 0) ? ACS_URCORNER : entry->value;
296
297 entry = translate (tui_border_kind, tui_border_kind_translate_hline);
298 tui_border_hline = (entry->value < 0) ? ACS_HLINE : entry->value;
299
300 entry = translate (tui_border_kind, tui_border_kind_translate_vline);
301 tui_border_vline = (entry->value < 0) ? ACS_VLINE : entry->value;
302
303 return need_redraw;
304 }
305
306 static void
307 set_tui_cmd (const char *args, int from_tty)
308 {
309 }
310
311 static void
312 show_tui_cmd (const char *args, int from_tty)
313 {
314 }
315
316 static struct cmd_list_element *tuilist;
317
318 static void
319 tui_command (const char *args, int from_tty)
320 {
321 printf_unfiltered (_("\"tui\" must be followed by the name of a "
322 "tui command.\n"));
323 help_list (tuilist, "tui ", all_commands, gdb_stdout);
324 }
325
326 struct cmd_list_element **
327 tui_get_cmd_list (void)
328 {
329 if (tuilist == 0)
330 add_prefix_cmd ("tui", class_tui, tui_command,
331 _("Text User Interface commands."),
332 &tuilist, "tui ", 0, &cmdlist);
333 return &tuilist;
334 }
335
336 /* The set_func hook of "set tui ..." commands that affect the window
337 borders on the TUI display. */
338
339 static void
340 tui_set_var_cmd (const char *null_args,
341 int from_tty, struct cmd_list_element *c)
342 {
343 if (tui_update_variables () && tui_active)
344 tui_rehighlight_all ();
345 }
346
347 \f
348
349 /* True if TUI resizes should print a message. This is used by the
350 test suite. */
351
352 static bool resize_message;
353
354 static void
355 show_tui_resize_message (struct ui_file *file, int from_tty,
356 struct cmd_list_element *c, const char *value)
357 {
358 fprintf_filtered (file, _("TUI resize messaging is %s.\n"), value);
359 }
360
361 \f
362
363 /* Generic window name completion function. Complete window name pointed
364 to by TEXT and WORD. If INCLUDE_NEXT_PREV_P is true then the special
365 window names 'next' and 'prev' will also be considered as possible
366 completions of the window name. */
367
368 static void
369 window_name_completer (completion_tracker &tracker,
370 int include_next_prev_p,
371 const char *text, const char *word)
372 {
373 std::vector<const char *> completion_name_vec;
374
375 for (tui_win_info *win_info : all_tui_windows ())
376 {
377 const char *completion_name = NULL;
378
379 /* We can't focus on an invisible window. */
380 if (!win_info->is_visible ())
381 continue;
382
383 completion_name = win_info->name ();
384 gdb_assert (completion_name != NULL);
385 completion_name_vec.push_back (completion_name);
386 }
387
388 /* If no windows are considered visible then the TUI has not yet been
389 initialized. But still "focus src" and "focus cmd" will work because
390 invoking the focus command will entail initializing the TUI which sets the
391 default layout to SRC_COMMAND. */
392 if (completion_name_vec.empty ())
393 {
394 completion_name_vec.push_back (SRC_NAME);
395 completion_name_vec.push_back (CMD_NAME);
396 }
397
398 if (include_next_prev_p)
399 {
400 completion_name_vec.push_back ("next");
401 completion_name_vec.push_back ("prev");
402 }
403
404
405 completion_name_vec.push_back (NULL);
406 complete_on_enum (tracker, completion_name_vec.data (), text, word);
407 }
408
409 /* Complete possible window names to focus on. TEXT is the complete text
410 entered so far, WORD is the word currently being completed. */
411
412 static void
413 focus_completer (struct cmd_list_element *ignore,
414 completion_tracker &tracker,
415 const char *text, const char *word)
416 {
417 window_name_completer (tracker, 1, text, word);
418 }
419
420 /* Complete possible window names for winheight command. TEXT is the
421 complete text entered so far, WORD is the word currently being
422 completed. */
423
424 static void
425 winheight_completer (struct cmd_list_element *ignore,
426 completion_tracker &tracker,
427 const char *text, const char *word)
428 {
429 /* The first word is the window name. That we can complete. Subsequent
430 words can't be completed. */
431 if (word != text)
432 return;
433
434 window_name_completer (tracker, 0, text, word);
435 }
436
437 /* Update gdb's knowledge of the terminal size. */
438 void
439 tui_update_gdb_sizes (void)
440 {
441 int width, height;
442
443 if (tui_active)
444 {
445 width = TUI_CMD_WIN->width;
446 height = TUI_CMD_WIN->height;
447 }
448 else
449 {
450 width = tui_term_width ();
451 height = tui_term_height ();
452 }
453
454 set_screen_width_and_height (width, height);
455 }
456
457
458 /* Set the logical focus to win_info. */
459 void
460 tui_set_win_focus_to (struct tui_win_info *win_info)
461 {
462 if (win_info != NULL)
463 {
464 struct tui_win_info *win_with_focus = tui_win_with_focus ();
465
466 tui_unhighlight_win (win_with_focus);
467 tui_set_win_with_focus (win_info);
468 tui_highlight_win (win_info);
469 }
470 }
471
472
473 void
474 tui_win_info::forward_scroll (int num_to_scroll)
475 {
476 if (num_to_scroll == 0)
477 num_to_scroll = height - 3;
478
479 do_scroll_vertical (num_to_scroll);
480 }
481
482 void
483 tui_win_info::backward_scroll (int num_to_scroll)
484 {
485 if (num_to_scroll == 0)
486 num_to_scroll = height - 3;
487
488 do_scroll_vertical (-num_to_scroll);
489 }
490
491
492 void
493 tui_win_info::left_scroll (int num_to_scroll)
494 {
495 if (num_to_scroll == 0)
496 num_to_scroll = 1;
497
498 do_scroll_horizontal (num_to_scroll);
499 }
500
501
502 void
503 tui_win_info::right_scroll (int num_to_scroll)
504 {
505 if (num_to_scroll == 0)
506 num_to_scroll = 1;
507
508 do_scroll_horizontal (-num_to_scroll);
509 }
510
511
512 void
513 tui_refresh_all_win (void)
514 {
515 clearok (curscr, TRUE);
516 tui_refresh_all ();
517 }
518
519 void
520 tui_rehighlight_all (void)
521 {
522 for (tui_win_info *win_info : all_tui_windows ())
523 win_info->check_and_display_highlight_if_needed ();
524 }
525
526 /* Resize all the windows based on the terminal size. This function
527 gets called from within the readline SIGWINCH handler. */
528 void
529 tui_resize_all (void)
530 {
531 int height_diff, width_diff;
532 int screenheight, screenwidth;
533
534 rl_get_screen_size (&screenheight, &screenwidth);
535 width_diff = screenwidth - tui_term_width ();
536 height_diff = screenheight - tui_term_height ();
537 if (height_diff || width_diff)
538 {
539 enum tui_layout_type cur_layout = tui_current_layout ();
540 struct tui_win_info *win_with_focus = tui_win_with_focus ();
541 struct tui_win_info *first_win;
542 struct tui_win_info *second_win;
543 tui_source_window_base *src_win;
544 struct tui_locator_window *locator = tui_locator_win_info_ptr ();
545 int new_height, split_diff, cmd_split_diff, num_wins_displayed = 2;
546
547 #ifdef HAVE_RESIZE_TERM
548 resize_term (screenheight, screenwidth);
549 #endif
550 /* Turn keypad off while we resize. */
551 if (win_with_focus != TUI_CMD_WIN)
552 keypad (TUI_CMD_WIN->handle.get (), FALSE);
553 tui_update_gdb_sizes ();
554 tui_set_term_height_to (screenheight);
555 tui_set_term_width_to (screenwidth);
556 if (cur_layout == SRC_DISASSEM_COMMAND
557 || cur_layout == SRC_DATA_COMMAND
558 || cur_layout == DISASSEM_DATA_COMMAND)
559 num_wins_displayed++;
560 split_diff = height_diff / num_wins_displayed;
561 cmd_split_diff = split_diff;
562 if (height_diff % num_wins_displayed)
563 {
564 if (height_diff < 0)
565 cmd_split_diff--;
566 else
567 cmd_split_diff++;
568 }
569 /* Now adjust each window. */
570 /* erase + clearok are used instead of a straightforward clear as
571 AIX 5.3 does not define clear. */
572 erase ();
573 clearok (curscr, TRUE);
574 switch (cur_layout)
575 {
576 case SRC_COMMAND:
577 case DISASSEM_COMMAND:
578 src_win = *(tui_source_windows ().begin ());
579 /* Check for invalid heights. */
580 if (height_diff == 0)
581 new_height = src_win->height;
582 else if ((src_win->height + split_diff) >=
583 (screenheight - MIN_CMD_WIN_HEIGHT - 1))
584 new_height = screenheight - MIN_CMD_WIN_HEIGHT - 1;
585 else if ((src_win->height + split_diff) <= 0)
586 new_height = MIN_WIN_HEIGHT;
587 else
588 new_height = src_win->height + split_diff;
589
590 src_win->resize (new_height, screenwidth, 0, 0);
591
592 locator->resize (1, screenwidth, 0, new_height);
593
594 new_height = screenheight - (new_height + 1);
595 TUI_CMD_WIN->resize (new_height, screenwidth,
596 0, locator->origin.y + 1);
597 break;
598 default:
599 if (cur_layout == SRC_DISASSEM_COMMAND)
600 {
601 src_win = TUI_SRC_WIN;
602 first_win = src_win;
603 second_win = TUI_DISASM_WIN;
604 }
605 else
606 {
607 first_win = TUI_DATA_WIN;
608 src_win = *(tui_source_windows ().begin ());
609 second_win = src_win;
610 }
611 /* Change the first window's height/width. */
612 /* Check for invalid heights. */
613 if (height_diff == 0)
614 new_height = first_win->height;
615 else if ((first_win->height +
616 second_win->height + (split_diff * 2)) >=
617 (screenheight - MIN_CMD_WIN_HEIGHT - 1))
618 new_height = (screenheight - MIN_CMD_WIN_HEIGHT - 1) / 2;
619 else if ((first_win->height + split_diff) <= 0)
620 new_height = MIN_WIN_HEIGHT;
621 else
622 new_height = first_win->height + split_diff;
623
624 first_win->resize (new_height, screenwidth, 0, 0);
625
626 /* Change the second window's height/width. */
627 /* Check for invalid heights. */
628 if (height_diff == 0)
629 new_height = second_win->height;
630 else if ((first_win->height +
631 second_win->height + (split_diff * 2)) >=
632 (screenheight - MIN_CMD_WIN_HEIGHT - 1))
633 {
634 new_height = screenheight - MIN_CMD_WIN_HEIGHT - 1;
635 if (new_height % 2)
636 new_height = (new_height / 2) + 1;
637 else
638 new_height /= 2;
639 }
640 else if ((second_win->height + split_diff) <= 0)
641 new_height = MIN_WIN_HEIGHT;
642 else
643 new_height = second_win->height + split_diff;
644
645 second_win->resize (new_height, screenwidth,
646 0, first_win->height - 1);
647
648 locator->resize (1, screenwidth,
649 0, second_win->origin.y + new_height);
650
651 /* Change the command window's height/width. */
652 new_height = screenheight - (locator->origin.y + 1);
653 TUI_CMD_WIN->resize (new_height, screenwidth,
654 0, locator->origin.y + 1);
655 break;
656 }
657
658 tui_delete_invisible_windows ();
659 /* Turn keypad back on, unless focus is in the command
660 window. */
661 if (win_with_focus != TUI_CMD_WIN)
662 keypad (TUI_CMD_WIN->handle.get (), TRUE);
663 }
664 }
665
666 #ifdef SIGWINCH
667 /* Token for use by TUI's asynchronous SIGWINCH handler. */
668 static struct async_signal_handler *tui_sigwinch_token;
669
670 /* TUI's SIGWINCH signal handler. */
671 static void
672 tui_sigwinch_handler (int signal)
673 {
674 mark_async_signal_handler (tui_sigwinch_token);
675 tui_set_win_resized_to (true);
676 }
677
678 /* Callback for asynchronously resizing TUI following a SIGWINCH signal. */
679 static void
680 tui_async_resize_screen (gdb_client_data arg)
681 {
682 rl_resize_terminal ();
683
684 if (!tui_active)
685 {
686 int screen_height, screen_width;
687
688 rl_get_screen_size (&screen_height, &screen_width);
689 set_screen_width_and_height (screen_width, screen_height);
690
691 /* win_resized is left set so that the next call to tui_enable()
692 resizes the TUI windows. */
693 }
694 else
695 {
696 tui_set_win_resized_to (false);
697 tui_resize_all ();
698 tui_refresh_all_win ();
699 tui_update_gdb_sizes ();
700 if (resize_message)
701 {
702 static int count;
703 printf_unfiltered ("@@ resize done %d, size = %dx%d\n", count,
704 tui_term_width (), tui_term_height ());
705 ++count;
706 }
707 tui_redisplay_readline ();
708 }
709 }
710 #endif
711
712 /* Initialize TUI's SIGWINCH signal handler. Note that the handler is not
713 uninstalled when we exit TUI, so the handler should not assume that TUI is
714 always active. */
715 void
716 tui_initialize_win (void)
717 {
718 #ifdef SIGWINCH
719 tui_sigwinch_token
720 = create_async_signal_handler (tui_async_resize_screen, NULL);
721
722 {
723 #ifdef HAVE_SIGACTION
724 struct sigaction old_winch;
725
726 memset (&old_winch, 0, sizeof (old_winch));
727 old_winch.sa_handler = &tui_sigwinch_handler;
728 #ifdef SA_RESTART
729 old_winch.sa_flags = SA_RESTART;
730 #endif
731 sigaction (SIGWINCH, &old_winch, NULL);
732 #else
733 signal (SIGWINCH, &tui_sigwinch_handler);
734 #endif
735 }
736 #endif
737 }
738
739
740 static void
741 tui_scroll_forward_command (const char *arg, int from_tty)
742 {
743 int num_to_scroll = 1;
744 struct tui_win_info *win_to_scroll;
745
746 /* Make sure the curses mode is enabled. */
747 tui_enable ();
748 if (arg == NULL)
749 parse_scrolling_args (arg, &win_to_scroll, NULL);
750 else
751 parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll);
752 win_to_scroll->forward_scroll (num_to_scroll);
753 }
754
755
756 static void
757 tui_scroll_backward_command (const char *arg, int from_tty)
758 {
759 int num_to_scroll = 1;
760 struct tui_win_info *win_to_scroll;
761
762 /* Make sure the curses mode is enabled. */
763 tui_enable ();
764 if (arg == NULL)
765 parse_scrolling_args (arg, &win_to_scroll, NULL);
766 else
767 parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll);
768 win_to_scroll->backward_scroll (num_to_scroll);
769 }
770
771
772 static void
773 tui_scroll_left_command (const char *arg, int from_tty)
774 {
775 int num_to_scroll;
776 struct tui_win_info *win_to_scroll;
777
778 /* Make sure the curses mode is enabled. */
779 tui_enable ();
780 parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll);
781 win_to_scroll->left_scroll (num_to_scroll);
782 }
783
784
785 static void
786 tui_scroll_right_command (const char *arg, int from_tty)
787 {
788 int num_to_scroll;
789 struct tui_win_info *win_to_scroll;
790
791 /* Make sure the curses mode is enabled. */
792 tui_enable ();
793 parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll);
794 win_to_scroll->right_scroll (num_to_scroll);
795 }
796
797
798 /* Answer the window represented by name. */
799 static struct tui_win_info *
800 tui_partial_win_by_name (gdb::string_view name)
801 {
802 if (name != NULL)
803 {
804 for (tui_win_info *item : all_tui_windows ())
805 {
806 const char *cur_name = item->name ();
807
808 if (startswith (cur_name, name))
809 return item;
810 }
811 }
812
813 return NULL;
814 }
815
816 /* Set focus to the window named by 'arg'. */
817 static void
818 tui_set_focus_command (const char *arg, int from_tty)
819 {
820 tui_enable ();
821
822 if (arg != NULL)
823 {
824 struct tui_win_info *win_info = NULL;
825
826 if (subset_compare (arg, "next"))
827 win_info = tui_next_win (tui_win_with_focus ());
828 else if (subset_compare (arg, "prev"))
829 win_info = tui_prev_win (tui_win_with_focus ());
830 else
831 win_info = tui_partial_win_by_name (arg);
832
833 if (win_info == NULL)
834 error (_("Unrecognized window name \"%s\""), arg);
835 if (!win_info->is_visible ())
836 error (_("Window \"%s\" is not visible"), arg);
837
838 tui_set_win_focus_to (win_info);
839 keypad (TUI_CMD_WIN->handle.get (), win_info != TUI_CMD_WIN);
840 printf_filtered (_("Focus set to %s window.\n"),
841 tui_win_with_focus ()->name ());
842 }
843 else
844 error (_("Incorrect Number of Arguments.\n%s"), FOCUS_USAGE);
845 }
846
847 static void
848 tui_all_windows_info (const char *arg, int from_tty)
849 {
850 if (!tui_active)
851 {
852 printf_filtered (_("The TUI is not active.\n"));
853 return;
854 }
855
856 struct tui_win_info *win_with_focus = tui_win_with_focus ();
857 struct ui_out *uiout = current_uiout;
858
859 ui_out_emit_table table_emitter (uiout, 3, -1, "tui-windows");
860 uiout->table_header (10, ui_left, "name", "Name");
861 uiout->table_header (5, ui_right, "lines", "Lines");
862 uiout->table_header (10, ui_left, "focus", "Focus");
863 uiout->table_body ();
864
865 for (tui_win_info *win_info : all_tui_windows ())
866 if (win_info->is_visible ())
867 {
868 ui_out_emit_tuple tuple_emitter (uiout, nullptr);
869
870 uiout->field_string ("name", win_info->name ());
871 uiout->field_signed ("lines", win_info->height);
872 if (win_with_focus == win_info)
873 uiout->field_string ("focus", _("(has focus)"));
874 else
875 uiout->field_skip ("focus");
876 uiout->text ("\n");
877 }
878 }
879
880
881 static void
882 tui_refresh_all_command (const char *arg, int from_tty)
883 {
884 /* Make sure the curses mode is enabled. */
885 tui_enable ();
886
887 tui_refresh_all_win ();
888 }
889
890 /* The tab width that should be used by the TUI. */
891
892 unsigned int tui_tab_width = DEFAULT_TAB_LEN;
893
894 /* The tab width as set by the user. */
895
896 static unsigned int internal_tab_width = DEFAULT_TAB_LEN;
897
898 /* After the tab width is set, call this to update the relevant
899 windows. */
900
901 static void
902 update_tab_width ()
903 {
904 for (tui_win_info *win_info : all_tui_windows ())
905 {
906 if (win_info->is_visible ())
907 win_info->update_tab_width ();
908 }
909 }
910
911 /* Callback for "set tui tab-width". */
912
913 static void
914 tui_set_tab_width (const char *ignore,
915 int from_tty, struct cmd_list_element *c)
916 {
917 if (internal_tab_width == 0)
918 {
919 internal_tab_width = tui_tab_width;
920 error (_("Tab width must not be 0"));
921 }
922
923 tui_tab_width = internal_tab_width;
924 update_tab_width ();
925 }
926
927 /* Callback for "show tui tab-width". */
928
929 static void
930 tui_show_tab_width (struct ui_file *file, int from_tty,
931 struct cmd_list_element *c, const char *value)
932 {
933 fprintf_filtered (gdb_stdout, _("TUI tab width is %s spaces.\n"), value);
934
935 }
936
937 /* See tui-win.h. */
938
939 bool compact_source = false;
940
941 /* Callback for "set tui compact-source". */
942
943 static void
944 tui_set_compact_source (const char *ignore, int from_tty,
945 struct cmd_list_element *c)
946 {
947 if (TUI_SRC_WIN != nullptr)
948 TUI_SRC_WIN->refill ();
949 }
950
951 /* Callback for "show tui compact-source". */
952
953 static void
954 tui_show_compact_source (struct ui_file *file, int from_tty,
955 struct cmd_list_element *c, const char *value)
956 {
957 printf_filtered (_("TUI source window compactness is %s.\n"), value);
958 }
959
960 /* Set the tab width of the specified window. */
961 static void
962 tui_set_tab_width_command (const char *arg, int from_tty)
963 {
964 /* Make sure the curses mode is enabled. */
965 tui_enable ();
966 if (arg != NULL)
967 {
968 int ts;
969
970 ts = atoi (arg);
971 if (ts <= 0)
972 warning (_("Tab widths greater than 0 must be specified."));
973 else
974 {
975 internal_tab_width = ts;
976 tui_tab_width = ts;
977
978 update_tab_width ();
979 }
980 }
981 }
982
983
984 /* Set the height of the specified window. */
985 static void
986 tui_set_win_height_command (const char *arg, int from_tty)
987 {
988 /* Make sure the curses mode is enabled. */
989 tui_enable ();
990 if (arg != NULL)
991 {
992 const char *buf = arg;
993 const char *buf_ptr = buf;
994 int new_height;
995 struct tui_win_info *win_info;
996
997 buf_ptr = strchr (buf_ptr, ' ');
998 if (buf_ptr != NULL)
999 {
1000 /* Validate the window name. */
1001 gdb::string_view wname (buf, buf_ptr - buf);
1002 win_info = tui_partial_win_by_name (wname);
1003
1004 if (win_info == NULL)
1005 error (_("Unrecognized window name \"%s\""), arg);
1006 if (!win_info->is_visible ())
1007 error (_("Window \"%s\" is not visible"), arg);
1008
1009 /* Process the size. */
1010 buf_ptr = skip_spaces (buf_ptr);
1011
1012 if (*buf_ptr != '\0')
1013 {
1014 bool negate = false;
1015 bool fixed_size = true;
1016 int input_no;;
1017
1018 if (*buf_ptr == '+' || *buf_ptr == '-')
1019 {
1020 if (*buf_ptr == '-')
1021 negate = true;
1022 fixed_size = false;
1023 buf_ptr++;
1024 }
1025 input_no = atoi (buf_ptr);
1026 if (input_no > 0)
1027 {
1028 if (negate)
1029 input_no *= (-1);
1030 if (fixed_size)
1031 new_height = input_no;
1032 else
1033 new_height = win_info->height + input_no;
1034
1035 /* Now change the window's height, and adjust
1036 all other windows around it. */
1037 if (tui_adjust_win_heights (win_info,
1038 new_height) == TUI_FAILURE)
1039 warning (_("Invalid window height specified.\n%s"),
1040 WIN_HEIGHT_USAGE);
1041 else
1042 tui_update_gdb_sizes ();
1043 }
1044 else
1045 warning (_("Invalid window height specified.\n%s"),
1046 WIN_HEIGHT_USAGE);
1047 }
1048 }
1049 else
1050 printf_filtered (WIN_HEIGHT_USAGE);
1051 }
1052 else
1053 printf_filtered (WIN_HEIGHT_USAGE);
1054 }
1055
1056 /* Function to adjust all window heights around the primary. */
1057 static enum tui_status
1058 tui_adjust_win_heights (struct tui_win_info *primary_win_info,
1059 int new_height)
1060 {
1061 enum tui_status status = TUI_FAILURE;
1062
1063 if (new_height_ok (primary_win_info, new_height))
1064 {
1065 status = TUI_SUCCESS;
1066 if (new_height != primary_win_info->height)
1067 {
1068 int diff;
1069 struct tui_win_info *win_info;
1070 struct tui_locator_window *locator = tui_locator_win_info_ptr ();
1071 enum tui_layout_type cur_layout = tui_current_layout ();
1072 int width = tui_term_width ();
1073
1074 diff = (new_height - primary_win_info->height) * (-1);
1075 if (cur_layout == SRC_COMMAND
1076 || cur_layout == DISASSEM_COMMAND)
1077 {
1078 struct tui_win_info *src_win_info;
1079
1080 primary_win_info->resize (new_height, width,
1081 0, primary_win_info->origin.y);
1082 if (primary_win_info->type == CMD_WIN)
1083 {
1084 win_info = *(tui_source_windows ().begin ());
1085 src_win_info = win_info;
1086 }
1087 else
1088 {
1089 win_info = tui_win_list[CMD_WIN];
1090 src_win_info = primary_win_info;
1091 }
1092 win_info->resize (win_info->height + diff, width,
1093 0, win_info->origin.y);
1094 TUI_CMD_WIN->origin.y = locator->origin.y + 1;
1095 if ((src_win_info->type == SRC_WIN
1096 || src_win_info->type == DISASSEM_WIN))
1097 {
1098 tui_source_window_base *src_base
1099 = (tui_source_window_base *) src_win_info;
1100 if (src_base->content.empty ())
1101 src_base->erase_source_content ();
1102 }
1103 }
1104 else
1105 {
1106 struct tui_win_info *first_win;
1107 struct tui_source_window_base *second_win;
1108 tui_source_window_base *src1;
1109
1110 if (cur_layout == SRC_DISASSEM_COMMAND)
1111 {
1112 src1 = TUI_SRC_WIN;
1113 first_win = src1;
1114 second_win = TUI_DISASM_WIN;
1115 }
1116 else
1117 {
1118 src1 = nullptr;
1119 first_win = TUI_DATA_WIN;
1120 second_win = *(tui_source_windows ().begin ());
1121 }
1122 if (primary_win_info == TUI_CMD_WIN)
1123 { /* Split the change in height across the 1st & 2nd
1124 windows, adjusting them as well. */
1125 /* Subtract the locator. */
1126 int first_split_diff = diff / 2;
1127 int second_split_diff = first_split_diff;
1128
1129 if (diff % 2)
1130 {
1131 if (first_win->height >
1132 second_win->height)
1133 if (diff < 0)
1134 first_split_diff--;
1135 else
1136 first_split_diff++;
1137 else
1138 {
1139 if (diff < 0)
1140 second_split_diff--;
1141 else
1142 second_split_diff++;
1143 }
1144 }
1145 /* Make sure that the minimum heights are
1146 honored. */
1147 while ((first_win->height + first_split_diff) < 3)
1148 {
1149 first_split_diff++;
1150 second_split_diff--;
1151 }
1152 while ((second_win->height + second_split_diff) < 3)
1153 {
1154 second_split_diff++;
1155 first_split_diff--;
1156 }
1157 first_win->resize (first_win->height + first_split_diff,
1158 width,
1159 0, first_win->origin.y);
1160 second_win->resize (second_win->height + second_split_diff,
1161 width,
1162 0, first_win->height - 1);
1163 locator->resize (1, width,
1164 0, (second_win->origin.y
1165 + second_win->height + 1));
1166
1167 TUI_CMD_WIN->resize (new_height, width,
1168 0, locator->origin.y + 1);
1169 }
1170 else
1171 {
1172 if ((TUI_CMD_WIN->height + diff) < 1)
1173 { /* If there is no way to increase the command
1174 window take real estate from the 1st or 2nd
1175 window. */
1176 if ((TUI_CMD_WIN->height + diff) < 1)
1177 {
1178 int i;
1179
1180 for (i = TUI_CMD_WIN->height + diff;
1181 (i < 1); i++)
1182 if (primary_win_info == first_win)
1183 second_win->height--;
1184 else
1185 first_win->height--;
1186 }
1187 }
1188 if (primary_win_info == first_win)
1189 first_win->resize (new_height, width, 0, 0);
1190 else
1191 first_win->resize (first_win->height, width, 0, 0);
1192 second_win->origin.y = first_win->height - 1;
1193 if (primary_win_info == second_win)
1194 second_win->resize (new_height, width,
1195 0, first_win->height - 1);
1196 else
1197 second_win->resize (second_win->height, width,
1198 0, first_win->height - 1);
1199 locator->resize (1, width,
1200 0, (second_win->origin.y
1201 + second_win->height + 1));
1202 TUI_CMD_WIN->origin.y = locator->origin.y + 1;
1203 if ((TUI_CMD_WIN->height + diff) < 1)
1204 TUI_CMD_WIN->resize (1, width, 0, locator->origin.y + 1);
1205 else
1206 TUI_CMD_WIN->resize (TUI_CMD_WIN->height + diff, width,
1207 0, locator->origin.y + 1);
1208 }
1209 if (src1 != nullptr && src1->content.empty ())
1210 src1->erase_source_content ();
1211 if (second_win->content.empty ())
1212 second_win->erase_source_content ();
1213 }
1214 }
1215 }
1216
1217 return status;
1218 }
1219
1220 /* See tui-data.h. */
1221
1222 int
1223 tui_win_info::max_height () const
1224 {
1225 return tui_term_height () - 2;
1226 }
1227
1228 static int
1229 new_height_ok (struct tui_win_info *primary_win_info,
1230 int new_height)
1231 {
1232 int ok = (new_height < tui_term_height ());
1233
1234 if (ok)
1235 {
1236 int diff;
1237 enum tui_layout_type cur_layout = tui_current_layout ();
1238
1239 diff = (new_height - primary_win_info->height) * (-1);
1240 if (cur_layout == SRC_COMMAND || cur_layout == DISASSEM_COMMAND)
1241 {
1242 ok = (new_height <= primary_win_info->max_height ()
1243 && new_height >= MIN_CMD_WIN_HEIGHT);
1244 if (ok)
1245 { /* Check the total height. */
1246 struct tui_win_info *win_info;
1247
1248 if (primary_win_info == TUI_CMD_WIN)
1249 win_info = *(tui_source_windows ().begin ());
1250 else
1251 win_info = TUI_CMD_WIN;
1252 ok = ((new_height +
1253 (win_info->height + diff)) <= tui_term_height ());
1254 }
1255 }
1256 else
1257 {
1258 int cur_total_height, total_height, min_height = 0;
1259 struct tui_win_info *first_win;
1260 struct tui_win_info *second_win;
1261
1262 if (cur_layout == SRC_DISASSEM_COMMAND)
1263 {
1264 first_win = TUI_SRC_WIN;
1265 second_win = TUI_DISASM_WIN;
1266 }
1267 else
1268 {
1269 first_win = TUI_DATA_WIN;
1270 second_win = *(tui_source_windows ().begin ());
1271 }
1272 /* We could simply add all the heights to obtain the same
1273 result but below is more explicit since we subtract 1 for
1274 the line that the first and second windows share, and add
1275 one for the locator. */
1276 total_height = cur_total_height =
1277 (first_win->height + second_win->height - 1)
1278 + TUI_CMD_WIN->height + 1; /* Locator. */
1279 if (primary_win_info == TUI_CMD_WIN)
1280 {
1281 /* Locator included since first & second win share a line. */
1282 ok = ((first_win->height +
1283 second_win->height + diff) >=
1284 (MIN_WIN_HEIGHT * 2)
1285 && new_height >= MIN_CMD_WIN_HEIGHT);
1286 if (ok)
1287 {
1288 total_height = new_height +
1289 (first_win->height +
1290 second_win->height + diff);
1291 min_height = MIN_CMD_WIN_HEIGHT;
1292 }
1293 }
1294 else
1295 {
1296 min_height = MIN_WIN_HEIGHT;
1297
1298 /* First see if we can increase/decrease the command
1299 window. And make sure that the command window is at
1300 least 1 line. */
1301 ok = ((TUI_CMD_WIN->height + diff) > 0);
1302 if (!ok)
1303 { /* Looks like we have to increase/decrease one of
1304 the other windows. */
1305 if (primary_win_info == first_win)
1306 ok = (second_win->height + diff) >= min_height;
1307 else
1308 ok = (first_win->height + diff) >= min_height;
1309 }
1310 if (ok)
1311 {
1312 if (primary_win_info == first_win)
1313 total_height = new_height +
1314 second_win->height +
1315 TUI_CMD_WIN->height + diff;
1316 else
1317 total_height = new_height +
1318 first_win->height +
1319 TUI_CMD_WIN->height + diff;
1320 }
1321 }
1322 /* Now make sure that the proposed total height doesn't
1323 exceed the old total height. */
1324 if (ok)
1325 ok = (new_height >= min_height
1326 && total_height <= cur_total_height);
1327 }
1328 }
1329
1330 return ok;
1331 }
1332
1333
1334 static void
1335 parse_scrolling_args (const char *arg,
1336 struct tui_win_info **win_to_scroll,
1337 int *num_to_scroll)
1338 {
1339 if (num_to_scroll)
1340 *num_to_scroll = 0;
1341 *win_to_scroll = tui_win_with_focus ();
1342
1343 /* First set up the default window to scroll, in case there is no
1344 window name arg. */
1345 if (arg != NULL)
1346 {
1347 char *buf_ptr;
1348
1349 /* Process the number of lines to scroll. */
1350 std::string copy = arg;
1351 buf_ptr = &copy[0];
1352 if (isdigit (*buf_ptr))
1353 {
1354 char *num_str;
1355
1356 num_str = buf_ptr;
1357 buf_ptr = strchr (buf_ptr, ' ');
1358 if (buf_ptr != NULL)
1359 {
1360 *buf_ptr = '\0';
1361 if (num_to_scroll)
1362 *num_to_scroll = atoi (num_str);
1363 buf_ptr++;
1364 }
1365 else if (num_to_scroll)
1366 *num_to_scroll = atoi (num_str);
1367 }
1368
1369 /* Process the window name if one is specified. */
1370 if (buf_ptr != NULL)
1371 {
1372 const char *wname;
1373
1374 wname = skip_spaces (buf_ptr);
1375
1376 if (*wname != '\0')
1377 {
1378 *win_to_scroll = tui_partial_win_by_name (wname);
1379
1380 if (*win_to_scroll == NULL)
1381 error (_("Unrecognized window `%s'"), wname);
1382 if (!(*win_to_scroll)->is_visible ())
1383 error (_("Window is not visible"));
1384 else if (*win_to_scroll == TUI_CMD_WIN)
1385 *win_to_scroll = *(tui_source_windows ().begin ());
1386 }
1387 }
1388 }
1389 }
1390
1391 /* Function to initialize gdb commands, for tui window
1392 manipulation. */
1393
1394 void
1395 _initialize_tui_win (void)
1396 {
1397 static struct cmd_list_element *tui_setlist;
1398 static struct cmd_list_element *tui_showlist;
1399 struct cmd_list_element *cmd;
1400
1401 /* Define the classes of commands.
1402 They will appear in the help list in the reverse of this order. */
1403 add_prefix_cmd ("tui", class_tui, set_tui_cmd,
1404 _("TUI configuration variables."),
1405 &tui_setlist, "set tui ",
1406 0 /* allow-unknown */, &setlist);
1407 add_prefix_cmd ("tui", class_tui, show_tui_cmd,
1408 _("TUI configuration variables."),
1409 &tui_showlist, "show tui ",
1410 0 /* allow-unknown */, &showlist);
1411
1412 add_com ("refresh", class_tui, tui_refresh_all_command,
1413 _("Refresh the terminal display."));
1414
1415 cmd = add_com ("tabset", class_tui, tui_set_tab_width_command, _("\
1416 Set the width (in characters) of tab stops.\n\
1417 Usage: tabset N"));
1418 deprecate_cmd (cmd, "set tui tab-width");
1419
1420 cmd = add_com ("winheight", class_tui, tui_set_win_height_command, _("\
1421 Set or modify the height of a specified window.\n"
1422 WIN_HEIGHT_USAGE
1423 "Window names are:\n\
1424 src : the source window\n\
1425 cmd : the command window\n\
1426 asm : the disassembly window\n\
1427 regs : the register display"));
1428 add_com_alias ("wh", "winheight", class_tui, 0);
1429 set_cmd_completer (cmd, winheight_completer);
1430 add_info ("win", tui_all_windows_info,
1431 _("List of all displayed windows."));
1432 cmd = add_com ("focus", class_tui, tui_set_focus_command, _("\
1433 Set focus to named window or next/prev window.\n"
1434 FOCUS_USAGE
1435 "Valid Window names are:\n\
1436 src : the source window\n\
1437 asm : the disassembly window\n\
1438 regs : the register display\n\
1439 cmd : the command window"));
1440 add_com_alias ("fs", "focus", class_tui, 0);
1441 set_cmd_completer (cmd, focus_completer);
1442 add_com ("+", class_tui, tui_scroll_forward_command, _("\
1443 Scroll window forward.\n\
1444 Usage: + [WIN] [N]"));
1445 add_com ("-", class_tui, tui_scroll_backward_command, _("\
1446 Scroll window backward.\n\
1447 Usage: - [WIN] [N]"));
1448 add_com ("<", class_tui, tui_scroll_left_command, _("\
1449 Scroll window text to the left.\n\
1450 Usage: < [WIN] [N]"));
1451 add_com (">", class_tui, tui_scroll_right_command, _("\
1452 Scroll window text to the right.\n\
1453 Usage: > [WIN] [N]"));
1454
1455 /* Define the tui control variables. */
1456 add_setshow_enum_cmd ("border-kind", no_class, tui_border_kind_enums,
1457 &tui_border_kind, _("\
1458 Set the kind of border for TUI windows."), _("\
1459 Show the kind of border for TUI windows."), _("\
1460 This variable controls the border of TUI windows:\n\
1461 space use a white space\n\
1462 ascii use ascii characters + - | for the border\n\
1463 acs use the Alternate Character Set"),
1464 tui_set_var_cmd,
1465 show_tui_border_kind,
1466 &tui_setlist, &tui_showlist);
1467
1468 add_setshow_enum_cmd ("border-mode", no_class, tui_border_mode_enums,
1469 &tui_border_mode, _("\
1470 Set the attribute mode to use for the TUI window borders."), _("\
1471 Show the attribute mode to use for the TUI window borders."), _("\
1472 This variable controls the attributes to use for the window borders:\n\
1473 normal normal display\n\
1474 standout use highlight mode of terminal\n\
1475 reverse use reverse video mode\n\
1476 half use half bright\n\
1477 half-standout use half bright and standout mode\n\
1478 bold use extra bright or bold\n\
1479 bold-standout use extra bright or bold with standout mode"),
1480 tui_set_var_cmd,
1481 show_tui_border_mode,
1482 &tui_setlist, &tui_showlist);
1483
1484 add_setshow_enum_cmd ("active-border-mode", no_class, tui_border_mode_enums,
1485 &tui_active_border_mode, _("\
1486 Set the attribute mode to use for the active TUI window border."), _("\
1487 Show the attribute mode to use for the active TUI window border."), _("\
1488 This variable controls the attributes to use for the active window border:\n\
1489 normal normal display\n\
1490 standout use highlight mode of terminal\n\
1491 reverse use reverse video mode\n\
1492 half use half bright\n\
1493 half-standout use half bright and standout mode\n\
1494 bold use extra bright or bold\n\
1495 bold-standout use extra bright or bold with standout mode"),
1496 tui_set_var_cmd,
1497 show_tui_active_border_mode,
1498 &tui_setlist, &tui_showlist);
1499
1500 add_setshow_zuinteger_cmd ("tab-width", no_class,
1501 &internal_tab_width, _("\
1502 Set the tab width, in characters, for the TUI."), _("\
1503 Show the tab witdh, in characters, for the TUI."), _("\
1504 This variable controls how many spaces are used to display a tab character."),
1505 tui_set_tab_width, tui_show_tab_width,
1506 &tui_setlist, &tui_showlist);
1507
1508 add_setshow_boolean_cmd ("tui-resize-message", class_maintenance,
1509 &resize_message, _("\
1510 Set TUI resize messaging."), _("\
1511 Show TUI resize messaging."), _("\
1512 When enabled GDB will print a message when the terminal is resized."),
1513 nullptr,
1514 show_tui_resize_message,
1515 &maintenance_set_cmdlist,
1516 &maintenance_show_cmdlist);
1517
1518 add_setshow_boolean_cmd ("compact-source", class_tui,
1519 &compact_source, _("\
1520 Set whether the TUI source window is compact."), _("\
1521 Show whether the TUI source window is compact."), _("\
1522 This variable controls whether the TUI source window is shown\n\
1523 in a compact form. The compact form puts the source closer to\n\
1524 the line numbers and uses less horizontal space."),
1525 tui_set_compact_source, tui_show_compact_source,
1526 &tui_setlist, &tui_showlist);
1527
1528 tui_border_style.changed.attach (tui_rehighlight_all);
1529 tui_active_border_style.changed.attach (tui_rehighlight_all);
1530 }
This page took 0.064499 seconds and 4 git commands to generate.