b6204beb216836ef7b136a83efcf9d48c6a58cfb
[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 struct tui_win_info *win_with_focus = tui_win_with_focus ();
851 struct ui_out *uiout = current_uiout;
852
853 ui_out_emit_table table_emitter (uiout, 3, -1, "tui-windows");
854 uiout->table_header (10, ui_left, "name", "Name");
855 uiout->table_header (5, ui_right, "lines", "Lines");
856 uiout->table_header (10, ui_left, "focus", "Focus");
857 uiout->table_body ();
858
859 for (tui_win_info *win_info : all_tui_windows ())
860 if (win_info->is_visible ())
861 {
862 ui_out_emit_tuple tuple_emitter (uiout, nullptr);
863
864 uiout->field_string ("name", win_info->name ());
865 uiout->field_signed ("lines", win_info->height);
866 if (win_with_focus == win_info)
867 uiout->field_string ("focus", _("(has focus)"));
868 else
869 uiout->field_skip ("focus");
870 uiout->text ("\n");
871 }
872 }
873
874
875 static void
876 tui_refresh_all_command (const char *arg, int from_tty)
877 {
878 /* Make sure the curses mode is enabled. */
879 tui_enable ();
880
881 tui_refresh_all_win ();
882 }
883
884 /* The tab width that should be used by the TUI. */
885
886 unsigned int tui_tab_width = DEFAULT_TAB_LEN;
887
888 /* The tab width as set by the user. */
889
890 static unsigned int internal_tab_width = DEFAULT_TAB_LEN;
891
892 /* After the tab width is set, call this to update the relevant
893 windows. */
894
895 static void
896 update_tab_width ()
897 {
898 for (tui_win_info *win_info : all_tui_windows ())
899 {
900 if (win_info->is_visible ())
901 win_info->update_tab_width ();
902 }
903 }
904
905 /* Callback for "set tui tab-width". */
906
907 static void
908 tui_set_tab_width (const char *ignore,
909 int from_tty, struct cmd_list_element *c)
910 {
911 if (internal_tab_width == 0)
912 {
913 internal_tab_width = tui_tab_width;
914 error (_("Tab width must not be 0"));
915 }
916
917 tui_tab_width = internal_tab_width;
918 update_tab_width ();
919 }
920
921 /* Callback for "show tui tab-width". */
922
923 static void
924 tui_show_tab_width (struct ui_file *file, int from_tty,
925 struct cmd_list_element *c, const char *value)
926 {
927 fprintf_filtered (gdb_stdout, _("TUI tab width is %s spaces.\n"), value);
928
929 }
930
931 /* See tui-win.h. */
932
933 bool compact_source = false;
934
935 /* Callback for "set tui compact-source". */
936
937 static void
938 tui_set_compact_source (const char *ignore, int from_tty,
939 struct cmd_list_element *c)
940 {
941 if (TUI_SRC_WIN != nullptr)
942 TUI_SRC_WIN->refill ();
943 }
944
945 /* Callback for "show tui compact-source". */
946
947 static void
948 tui_show_compact_source (struct ui_file *file, int from_tty,
949 struct cmd_list_element *c, const char *value)
950 {
951 printf_filtered (_("TUI source window compactness is %s.\n"), value);
952 }
953
954 /* Set the tab width of the specified window. */
955 static void
956 tui_set_tab_width_command (const char *arg, int from_tty)
957 {
958 /* Make sure the curses mode is enabled. */
959 tui_enable ();
960 if (arg != NULL)
961 {
962 int ts;
963
964 ts = atoi (arg);
965 if (ts <= 0)
966 warning (_("Tab widths greater than 0 must be specified."));
967 else
968 {
969 internal_tab_width = ts;
970 tui_tab_width = ts;
971
972 update_tab_width ();
973 }
974 }
975 }
976
977
978 /* Set the height of the specified window. */
979 static void
980 tui_set_win_height_command (const char *arg, int from_tty)
981 {
982 /* Make sure the curses mode is enabled. */
983 tui_enable ();
984 if (arg != NULL)
985 {
986 const char *buf = arg;
987 const char *buf_ptr = buf;
988 int new_height;
989 struct tui_win_info *win_info;
990
991 buf_ptr = strchr (buf_ptr, ' ');
992 if (buf_ptr != NULL)
993 {
994 /* Validate the window name. */
995 gdb::string_view wname (buf, buf_ptr - buf);
996 win_info = tui_partial_win_by_name (wname);
997
998 if (win_info == NULL)
999 error (_("Unrecognized window name \"%s\""), arg);
1000 if (!win_info->is_visible ())
1001 error (_("Window \"%s\" is not visible"), arg);
1002
1003 /* Process the size. */
1004 buf_ptr = skip_spaces (buf_ptr);
1005
1006 if (*buf_ptr != '\0')
1007 {
1008 bool negate = false;
1009 bool fixed_size = true;
1010 int input_no;;
1011
1012 if (*buf_ptr == '+' || *buf_ptr == '-')
1013 {
1014 if (*buf_ptr == '-')
1015 negate = true;
1016 fixed_size = false;
1017 buf_ptr++;
1018 }
1019 input_no = atoi (buf_ptr);
1020 if (input_no > 0)
1021 {
1022 if (negate)
1023 input_no *= (-1);
1024 if (fixed_size)
1025 new_height = input_no;
1026 else
1027 new_height = win_info->height + input_no;
1028
1029 /* Now change the window's height, and adjust
1030 all other windows around it. */
1031 if (tui_adjust_win_heights (win_info,
1032 new_height) == TUI_FAILURE)
1033 warning (_("Invalid window height specified.\n%s"),
1034 WIN_HEIGHT_USAGE);
1035 else
1036 tui_update_gdb_sizes ();
1037 }
1038 else
1039 warning (_("Invalid window height specified.\n%s"),
1040 WIN_HEIGHT_USAGE);
1041 }
1042 }
1043 else
1044 printf_filtered (WIN_HEIGHT_USAGE);
1045 }
1046 else
1047 printf_filtered (WIN_HEIGHT_USAGE);
1048 }
1049
1050 /* Function to adjust all window heights around the primary. */
1051 static enum tui_status
1052 tui_adjust_win_heights (struct tui_win_info *primary_win_info,
1053 int new_height)
1054 {
1055 enum tui_status status = TUI_FAILURE;
1056
1057 if (new_height_ok (primary_win_info, new_height))
1058 {
1059 status = TUI_SUCCESS;
1060 if (new_height != primary_win_info->height)
1061 {
1062 int diff;
1063 struct tui_win_info *win_info;
1064 struct tui_locator_window *locator = tui_locator_win_info_ptr ();
1065 enum tui_layout_type cur_layout = tui_current_layout ();
1066 int width = tui_term_width ();
1067
1068 diff = (new_height - primary_win_info->height) * (-1);
1069 if (cur_layout == SRC_COMMAND
1070 || cur_layout == DISASSEM_COMMAND)
1071 {
1072 struct tui_win_info *src_win_info;
1073
1074 primary_win_info->resize (new_height, width,
1075 0, primary_win_info->origin.y);
1076 if (primary_win_info->type == CMD_WIN)
1077 {
1078 win_info = *(tui_source_windows ().begin ());
1079 src_win_info = win_info;
1080 }
1081 else
1082 {
1083 win_info = tui_win_list[CMD_WIN];
1084 src_win_info = primary_win_info;
1085 }
1086 win_info->resize (win_info->height + diff, width,
1087 0, win_info->origin.y);
1088 TUI_CMD_WIN->origin.y = locator->origin.y + 1;
1089 if ((src_win_info->type == SRC_WIN
1090 || src_win_info->type == DISASSEM_WIN))
1091 {
1092 tui_source_window_base *src_base
1093 = (tui_source_window_base *) src_win_info;
1094 if (src_base->content.empty ())
1095 src_base->erase_source_content ();
1096 }
1097 }
1098 else
1099 {
1100 struct tui_win_info *first_win;
1101 struct tui_source_window_base *second_win;
1102 tui_source_window_base *src1;
1103
1104 if (cur_layout == SRC_DISASSEM_COMMAND)
1105 {
1106 src1 = TUI_SRC_WIN;
1107 first_win = src1;
1108 second_win = TUI_DISASM_WIN;
1109 }
1110 else
1111 {
1112 src1 = nullptr;
1113 first_win = TUI_DATA_WIN;
1114 second_win = *(tui_source_windows ().begin ());
1115 }
1116 if (primary_win_info == TUI_CMD_WIN)
1117 { /* Split the change in height across the 1st & 2nd
1118 windows, adjusting them as well. */
1119 /* Subtract the locator. */
1120 int first_split_diff = diff / 2;
1121 int second_split_diff = first_split_diff;
1122
1123 if (diff % 2)
1124 {
1125 if (first_win->height >
1126 second_win->height)
1127 if (diff < 0)
1128 first_split_diff--;
1129 else
1130 first_split_diff++;
1131 else
1132 {
1133 if (diff < 0)
1134 second_split_diff--;
1135 else
1136 second_split_diff++;
1137 }
1138 }
1139 /* Make sure that the minimum heights are
1140 honored. */
1141 while ((first_win->height + first_split_diff) < 3)
1142 {
1143 first_split_diff++;
1144 second_split_diff--;
1145 }
1146 while ((second_win->height + second_split_diff) < 3)
1147 {
1148 second_split_diff++;
1149 first_split_diff--;
1150 }
1151 first_win->resize (first_win->height + first_split_diff,
1152 width,
1153 0, first_win->origin.y);
1154 second_win->resize (second_win->height + second_split_diff,
1155 width,
1156 0, first_win->height - 1);
1157 locator->resize (1, width,
1158 0, (second_win->origin.y
1159 + second_win->height + 1));
1160
1161 TUI_CMD_WIN->resize (new_height, width,
1162 0, locator->origin.y + 1);
1163 }
1164 else
1165 {
1166 if ((TUI_CMD_WIN->height + diff) < 1)
1167 { /* If there is no way to increase the command
1168 window take real estate from the 1st or 2nd
1169 window. */
1170 if ((TUI_CMD_WIN->height + diff) < 1)
1171 {
1172 int i;
1173
1174 for (i = TUI_CMD_WIN->height + diff;
1175 (i < 1); i++)
1176 if (primary_win_info == first_win)
1177 second_win->height--;
1178 else
1179 first_win->height--;
1180 }
1181 }
1182 if (primary_win_info == first_win)
1183 first_win->resize (new_height, width, 0, 0);
1184 else
1185 first_win->resize (first_win->height, width, 0, 0);
1186 second_win->origin.y = first_win->height - 1;
1187 if (primary_win_info == second_win)
1188 second_win->resize (new_height, width,
1189 0, first_win->height - 1);
1190 else
1191 second_win->resize (second_win->height, width,
1192 0, first_win->height - 1);
1193 locator->resize (1, width,
1194 0, (second_win->origin.y
1195 + second_win->height + 1));
1196 TUI_CMD_WIN->origin.y = locator->origin.y + 1;
1197 if ((TUI_CMD_WIN->height + diff) < 1)
1198 TUI_CMD_WIN->resize (1, width, 0, locator->origin.y + 1);
1199 else
1200 TUI_CMD_WIN->resize (TUI_CMD_WIN->height + diff, width,
1201 0, locator->origin.y + 1);
1202 }
1203 if (src1 != nullptr && src1->content.empty ())
1204 src1->erase_source_content ();
1205 if (second_win->content.empty ())
1206 second_win->erase_source_content ();
1207 }
1208 }
1209 }
1210
1211 return status;
1212 }
1213
1214 /* See tui-data.h. */
1215
1216 int
1217 tui_win_info::max_height () const
1218 {
1219 return tui_term_height () - 2;
1220 }
1221
1222 static int
1223 new_height_ok (struct tui_win_info *primary_win_info,
1224 int new_height)
1225 {
1226 int ok = (new_height < tui_term_height ());
1227
1228 if (ok)
1229 {
1230 int diff;
1231 enum tui_layout_type cur_layout = tui_current_layout ();
1232
1233 diff = (new_height - primary_win_info->height) * (-1);
1234 if (cur_layout == SRC_COMMAND || cur_layout == DISASSEM_COMMAND)
1235 {
1236 ok = (new_height <= primary_win_info->max_height ()
1237 && new_height >= MIN_CMD_WIN_HEIGHT);
1238 if (ok)
1239 { /* Check the total height. */
1240 struct tui_win_info *win_info;
1241
1242 if (primary_win_info == TUI_CMD_WIN)
1243 win_info = *(tui_source_windows ().begin ());
1244 else
1245 win_info = TUI_CMD_WIN;
1246 ok = ((new_height +
1247 (win_info->height + diff)) <= tui_term_height ());
1248 }
1249 }
1250 else
1251 {
1252 int cur_total_height, total_height, min_height = 0;
1253 struct tui_win_info *first_win;
1254 struct tui_win_info *second_win;
1255
1256 if (cur_layout == SRC_DISASSEM_COMMAND)
1257 {
1258 first_win = TUI_SRC_WIN;
1259 second_win = TUI_DISASM_WIN;
1260 }
1261 else
1262 {
1263 first_win = TUI_DATA_WIN;
1264 second_win = *(tui_source_windows ().begin ());
1265 }
1266 /* We could simply add all the heights to obtain the same
1267 result but below is more explicit since we subtract 1 for
1268 the line that the first and second windows share, and add
1269 one for the locator. */
1270 total_height = cur_total_height =
1271 (first_win->height + second_win->height - 1)
1272 + TUI_CMD_WIN->height + 1; /* Locator. */
1273 if (primary_win_info == TUI_CMD_WIN)
1274 {
1275 /* Locator included since first & second win share a line. */
1276 ok = ((first_win->height +
1277 second_win->height + diff) >=
1278 (MIN_WIN_HEIGHT * 2)
1279 && new_height >= MIN_CMD_WIN_HEIGHT);
1280 if (ok)
1281 {
1282 total_height = new_height +
1283 (first_win->height +
1284 second_win->height + diff);
1285 min_height = MIN_CMD_WIN_HEIGHT;
1286 }
1287 }
1288 else
1289 {
1290 min_height = MIN_WIN_HEIGHT;
1291
1292 /* First see if we can increase/decrease the command
1293 window. And make sure that the command window is at
1294 least 1 line. */
1295 ok = ((TUI_CMD_WIN->height + diff) > 0);
1296 if (!ok)
1297 { /* Looks like we have to increase/decrease one of
1298 the other windows. */
1299 if (primary_win_info == first_win)
1300 ok = (second_win->height + diff) >= min_height;
1301 else
1302 ok = (first_win->height + diff) >= min_height;
1303 }
1304 if (ok)
1305 {
1306 if (primary_win_info == first_win)
1307 total_height = new_height +
1308 second_win->height +
1309 TUI_CMD_WIN->height + diff;
1310 else
1311 total_height = new_height +
1312 first_win->height +
1313 TUI_CMD_WIN->height + diff;
1314 }
1315 }
1316 /* Now make sure that the proposed total height doesn't
1317 exceed the old total height. */
1318 if (ok)
1319 ok = (new_height >= min_height
1320 && total_height <= cur_total_height);
1321 }
1322 }
1323
1324 return ok;
1325 }
1326
1327
1328 static void
1329 parse_scrolling_args (const char *arg,
1330 struct tui_win_info **win_to_scroll,
1331 int *num_to_scroll)
1332 {
1333 if (num_to_scroll)
1334 *num_to_scroll = 0;
1335 *win_to_scroll = tui_win_with_focus ();
1336
1337 /* First set up the default window to scroll, in case there is no
1338 window name arg. */
1339 if (arg != NULL)
1340 {
1341 char *buf_ptr;
1342
1343 /* Process the number of lines to scroll. */
1344 std::string copy = arg;
1345 buf_ptr = &copy[0];
1346 if (isdigit (*buf_ptr))
1347 {
1348 char *num_str;
1349
1350 num_str = buf_ptr;
1351 buf_ptr = strchr (buf_ptr, ' ');
1352 if (buf_ptr != NULL)
1353 {
1354 *buf_ptr = '\0';
1355 if (num_to_scroll)
1356 *num_to_scroll = atoi (num_str);
1357 buf_ptr++;
1358 }
1359 else if (num_to_scroll)
1360 *num_to_scroll = atoi (num_str);
1361 }
1362
1363 /* Process the window name if one is specified. */
1364 if (buf_ptr != NULL)
1365 {
1366 const char *wname;
1367
1368 wname = skip_spaces (buf_ptr);
1369
1370 if (*wname != '\0')
1371 {
1372 *win_to_scroll = tui_partial_win_by_name (wname);
1373
1374 if (*win_to_scroll == NULL)
1375 error (_("Unrecognized window `%s'"), wname);
1376 if (!(*win_to_scroll)->is_visible ())
1377 error (_("Window is not visible"));
1378 else if (*win_to_scroll == TUI_CMD_WIN)
1379 *win_to_scroll = *(tui_source_windows ().begin ());
1380 }
1381 }
1382 }
1383 }
1384
1385 /* Function to initialize gdb commands, for tui window
1386 manipulation. */
1387
1388 void
1389 _initialize_tui_win (void)
1390 {
1391 static struct cmd_list_element *tui_setlist;
1392 static struct cmd_list_element *tui_showlist;
1393 struct cmd_list_element *cmd;
1394
1395 /* Define the classes of commands.
1396 They will appear in the help list in the reverse of this order. */
1397 add_prefix_cmd ("tui", class_tui, set_tui_cmd,
1398 _("TUI configuration variables."),
1399 &tui_setlist, "set tui ",
1400 0 /* allow-unknown */, &setlist);
1401 add_prefix_cmd ("tui", class_tui, show_tui_cmd,
1402 _("TUI configuration variables."),
1403 &tui_showlist, "show tui ",
1404 0 /* allow-unknown */, &showlist);
1405
1406 add_com ("refresh", class_tui, tui_refresh_all_command,
1407 _("Refresh the terminal display."));
1408
1409 cmd = add_com ("tabset", class_tui, tui_set_tab_width_command, _("\
1410 Set the width (in characters) of tab stops.\n\
1411 Usage: tabset N"));
1412 deprecate_cmd (cmd, "set tui tab-width");
1413
1414 cmd = add_com ("winheight", class_tui, tui_set_win_height_command, _("\
1415 Set or modify the height of a specified window.\n"
1416 WIN_HEIGHT_USAGE
1417 "Window names are:\n\
1418 src : the source window\n\
1419 cmd : the command window\n\
1420 asm : the disassembly window\n\
1421 regs : the register display"));
1422 add_com_alias ("wh", "winheight", class_tui, 0);
1423 set_cmd_completer (cmd, winheight_completer);
1424 add_info ("win", tui_all_windows_info,
1425 _("List of all displayed windows."));
1426 cmd = add_com ("focus", class_tui, tui_set_focus_command, _("\
1427 Set focus to named window or next/prev window.\n"
1428 FOCUS_USAGE
1429 "Valid Window names are:\n\
1430 src : the source window\n\
1431 asm : the disassembly window\n\
1432 regs : the register display\n\
1433 cmd : the command window"));
1434 add_com_alias ("fs", "focus", class_tui, 0);
1435 set_cmd_completer (cmd, focus_completer);
1436 add_com ("+", class_tui, tui_scroll_forward_command, _("\
1437 Scroll window forward.\n\
1438 Usage: + [WIN] [N]"));
1439 add_com ("-", class_tui, tui_scroll_backward_command, _("\
1440 Scroll window backward.\n\
1441 Usage: - [WIN] [N]"));
1442 add_com ("<", class_tui, tui_scroll_left_command, _("\
1443 Scroll window text to the left.\n\
1444 Usage: < [WIN] [N]"));
1445 add_com (">", class_tui, tui_scroll_right_command, _("\
1446 Scroll window text to the right.\n\
1447 Usage: > [WIN] [N]"));
1448
1449 /* Define the tui control variables. */
1450 add_setshow_enum_cmd ("border-kind", no_class, tui_border_kind_enums,
1451 &tui_border_kind, _("\
1452 Set the kind of border for TUI windows."), _("\
1453 Show the kind of border for TUI windows."), _("\
1454 This variable controls the border of TUI windows:\n\
1455 space use a white space\n\
1456 ascii use ascii characters + - | for the border\n\
1457 acs use the Alternate Character Set"),
1458 tui_set_var_cmd,
1459 show_tui_border_kind,
1460 &tui_setlist, &tui_showlist);
1461
1462 add_setshow_enum_cmd ("border-mode", no_class, tui_border_mode_enums,
1463 &tui_border_mode, _("\
1464 Set the attribute mode to use for the TUI window borders."), _("\
1465 Show the attribute mode to use for the TUI window borders."), _("\
1466 This variable controls the attributes to use for the window borders:\n\
1467 normal normal display\n\
1468 standout use highlight mode of terminal\n\
1469 reverse use reverse video mode\n\
1470 half use half bright\n\
1471 half-standout use half bright and standout mode\n\
1472 bold use extra bright or bold\n\
1473 bold-standout use extra bright or bold with standout mode"),
1474 tui_set_var_cmd,
1475 show_tui_border_mode,
1476 &tui_setlist, &tui_showlist);
1477
1478 add_setshow_enum_cmd ("active-border-mode", no_class, tui_border_mode_enums,
1479 &tui_active_border_mode, _("\
1480 Set the attribute mode to use for the active TUI window border."), _("\
1481 Show the attribute mode to use for the active TUI window border."), _("\
1482 This variable controls the attributes to use for the active window border:\n\
1483 normal normal display\n\
1484 standout use highlight mode of terminal\n\
1485 reverse use reverse video mode\n\
1486 half use half bright\n\
1487 half-standout use half bright and standout mode\n\
1488 bold use extra bright or bold\n\
1489 bold-standout use extra bright or bold with standout mode"),
1490 tui_set_var_cmd,
1491 show_tui_active_border_mode,
1492 &tui_setlist, &tui_showlist);
1493
1494 add_setshow_zuinteger_cmd ("tab-width", no_class,
1495 &internal_tab_width, _("\
1496 Set the tab width, in characters, for the TUI."), _("\
1497 Show the tab witdh, in characters, for the TUI."), _("\
1498 This variable controls how many spaces are used to display a tab character."),
1499 tui_set_tab_width, tui_show_tab_width,
1500 &tui_setlist, &tui_showlist);
1501
1502 add_setshow_boolean_cmd ("tui-resize-message", class_maintenance,
1503 &resize_message, _("\
1504 Set TUI resize messaging."), _("\
1505 Show TUI resize messaging."), _("\
1506 When enabled GDB will print a message when the terminal is resized."),
1507 nullptr,
1508 show_tui_resize_message,
1509 &maintenance_set_cmdlist,
1510 &maintenance_show_cmdlist);
1511
1512 add_setshow_boolean_cmd ("compact-source", class_tui,
1513 &compact_source, _("\
1514 Set whether the TUI source window is compact."), _("\
1515 Show whether the TUI source window is compact."), _("\
1516 This variable controls whether the TUI source window is shown\n\
1517 in a compact form. The compact form puts the source closer to\n\
1518 the line numbers and uses less horizontal space."),
1519 tui_set_compact_source, tui_show_compact_source,
1520 &tui_setlist, &tui_showlist);
1521
1522 tui_border_style.changed.attach (tui_rehighlight_all);
1523 tui_active_border_style.changed.attach (tui_rehighlight_all);
1524 }
This page took 0.099418 seconds and 4 git commands to generate.