1 /* TUI window generic functions.
3 Copyright (C) 1998-2019 Free Software Foundation, Inc.
5 Contributed by Hewlett-Packard Company.
7 This file is part of GDB.
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.
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.
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/>. */
22 /* This module contains procedures for handling tui window functions
23 like resize, scrolling, scrolling, changing focus, etc.
25 Author: Susan B. Macchia */
30 #include "breakpoint.h"
32 #include "cli/cli-cmds.h"
35 #include "event-loop.h"
38 #include "tui/tui-io.h"
39 #include "tui/tui-data.h"
40 #include "tui/tui-wingeneral.h"
41 #include "tui/tui-stack.h"
42 #include "tui/tui-regs.h"
43 #include "tui/tui-disasm.h"
44 #include "tui/tui-source.h"
45 #include "tui/tui-winsource.h"
46 #include "tui/tui-windata.h"
47 #include "tui/tui-win.h"
49 #include "gdb_curses.h"
51 #include "readline/readline.h"
55 /*******************************
57 ********************************/
58 static void make_visible_with_new_height (struct tui_win_info
*);
59 static void make_invisible_and_set_new_height (struct tui_win_info
*,
61 static enum tui_status
tui_adjust_win_heights (struct tui_win_info
*,
63 static int new_height_ok (struct tui_win_info
*, int);
64 static void tui_set_tab_width_command (const char *, int);
65 static void tui_refresh_all_command (const char *, int);
66 static void tui_set_win_height_command (const char *, int);
67 static void tui_all_windows_info (const char *, int);
68 static void tui_set_focus_command (const char *, int);
69 static void tui_scroll_forward_command (const char *, int);
70 static void tui_scroll_backward_command (const char *, int);
71 static void tui_scroll_left_command (const char *, int);
72 static void tui_scroll_right_command (const char *, int);
73 static void parse_scrolling_args (const char *,
74 struct tui_win_info
**,
78 /***************************************
80 ***************************************/
81 #define WIN_HEIGHT_USAGE "Usage: winheight WINDOW-NAME [+ | -] NUM-LINES\n"
82 #define FOCUS_USAGE "Usage: focus [WINDOW-NAME | next | prev]\n"
84 /***************************************
86 ***************************************/
89 # define ACS_LRCORNER '+'
92 # define ACS_LLCORNER '+'
95 # define ACS_ULCORNER '+'
98 # define ACS_URCORNER '+'
101 # define ACS_HLINE '-'
104 # define ACS_VLINE '|'
107 /* Possible values for tui-border-kind variable. */
108 static const char *const tui_border_kind_enums
[] = {
115 /* Possible values for tui-border-mode and tui-active-border-mode. */
116 static const char *const tui_border_mode_enums
[] = {
133 /* Translation table for border-mode variables.
134 The list of values must be terminated by a NULL.
135 After the NULL value, an entry defines the default. */
136 struct tui_translate tui_border_mode_translate
[] = {
137 { "normal", A_NORMAL
},
138 { "standout", A_STANDOUT
},
139 { "reverse", A_REVERSE
},
141 { "half-standout", A_DIM
| A_STANDOUT
},
143 { "bold-standout", A_BOLD
| A_STANDOUT
},
145 { "normal", A_NORMAL
}
148 /* Translation tables for border-kind, one for each border
149 character (see wborder, border curses operations).
150 -1 is used to indicate the ACS because ACS characters
151 are determined at run time by curses (depends on terminal). */
152 struct tui_translate tui_border_kind_translate_vline
[] = {
160 struct tui_translate tui_border_kind_translate_hline
[] = {
168 struct tui_translate tui_border_kind_translate_ulcorner
[] = {
176 struct tui_translate tui_border_kind_translate_urcorner
[] = {
184 struct tui_translate tui_border_kind_translate_llcorner
[] = {
192 struct tui_translate tui_border_kind_translate_lrcorner
[] = {
201 /* Tui configuration variables controlled with set/show command. */
202 const char *tui_active_border_mode
= "bold-standout";
204 show_tui_active_border_mode (struct ui_file
*file
,
206 struct cmd_list_element
*c
,
209 fprintf_filtered (file
, _("\
210 The attribute mode to use for the active TUI window border is \"%s\".\n"),
214 const char *tui_border_mode
= "normal";
216 show_tui_border_mode (struct ui_file
*file
,
218 struct cmd_list_element
*c
,
221 fprintf_filtered (file
, _("\
222 The attribute mode to use for the TUI window borders is \"%s\".\n"),
226 const char *tui_border_kind
= "acs";
228 show_tui_border_kind (struct ui_file
*file
,
230 struct cmd_list_element
*c
,
233 fprintf_filtered (file
, _("The kind of border for TUI windows is \"%s\".\n"),
238 /* Tui internal configuration variables. These variables are updated
239 by tui_update_variables to reflect the tui configuration
241 chtype tui_border_vline
;
242 chtype tui_border_hline
;
243 chtype tui_border_ulcorner
;
244 chtype tui_border_urcorner
;
245 chtype tui_border_llcorner
;
246 chtype tui_border_lrcorner
;
248 int tui_border_attrs
;
249 int tui_active_border_attrs
;
251 /* Identify the item in the translation table.
252 When the item is not recognized, use the default entry. */
253 static struct tui_translate
*
254 translate (const char *name
, struct tui_translate
*table
)
258 if (name
&& strcmp (table
->name
, name
) == 0)
263 /* Not found, return default entry. */
268 /* Update the tui internal configuration according to gdb settings.
269 Returns 1 if the configuration has changed and the screen should
272 tui_update_variables (void)
275 struct tui_translate
*entry
;
277 entry
= translate (tui_border_mode
, tui_border_mode_translate
);
278 if (tui_border_attrs
!= entry
->value
)
280 tui_border_attrs
= entry
->value
;
283 entry
= translate (tui_active_border_mode
, tui_border_mode_translate
);
284 if (tui_active_border_attrs
!= entry
->value
)
286 tui_active_border_attrs
= entry
->value
;
290 /* If one corner changes, all characters are changed.
291 Only check the first one. The ACS characters are determined at
292 run time by curses terminal management. */
293 entry
= translate (tui_border_kind
, tui_border_kind_translate_lrcorner
);
294 if (tui_border_lrcorner
!= (chtype
) entry
->value
)
296 tui_border_lrcorner
= (entry
->value
< 0) ? ACS_LRCORNER
: entry
->value
;
299 entry
= translate (tui_border_kind
, tui_border_kind_translate_llcorner
);
300 tui_border_llcorner
= (entry
->value
< 0) ? ACS_LLCORNER
: entry
->value
;
302 entry
= translate (tui_border_kind
, tui_border_kind_translate_ulcorner
);
303 tui_border_ulcorner
= (entry
->value
< 0) ? ACS_ULCORNER
: entry
->value
;
305 entry
= translate (tui_border_kind
, tui_border_kind_translate_urcorner
);
306 tui_border_urcorner
= (entry
->value
< 0) ? ACS_URCORNER
: entry
->value
;
308 entry
= translate (tui_border_kind
, tui_border_kind_translate_hline
);
309 tui_border_hline
= (entry
->value
< 0) ? ACS_HLINE
: entry
->value
;
311 entry
= translate (tui_border_kind
, tui_border_kind_translate_vline
);
312 tui_border_vline
= (entry
->value
< 0) ? ACS_VLINE
: entry
->value
;
318 set_tui_cmd (const char *args
, int from_tty
)
323 show_tui_cmd (const char *args
, int from_tty
)
327 static struct cmd_list_element
*tuilist
;
330 tui_command (const char *args
, int from_tty
)
332 printf_unfiltered (_("\"tui\" must be followed by the name of a "
334 help_list (tuilist
, "tui ", all_commands
, gdb_stdout
);
337 struct cmd_list_element
**
338 tui_get_cmd_list (void)
341 add_prefix_cmd ("tui", class_tui
, tui_command
,
342 _("Text User Interface commands."),
343 &tuilist
, "tui ", 0, &cmdlist
);
347 /* The set_func hook of "set tui ..." commands that affect the window
348 borders on the TUI display. */
350 tui_set_var_cmd (const char *null_args
,
351 int from_tty
, struct cmd_list_element
*c
)
353 if (tui_update_variables () && tui_active
)
354 tui_rehighlight_all ();
357 /* Generic window name completion function. Complete window name pointed
358 to by TEXT and WORD. If INCLUDE_NEXT_PREV_P is true then the special
359 window names 'next' and 'prev' will also be considered as possible
360 completions of the window name. */
363 window_name_completer (completion_tracker
&tracker
,
364 int include_next_prev_p
,
365 const char *text
, const char *word
)
367 std::vector
<const char *> completion_name_vec
;
370 for (win_type
= SRC_WIN
; win_type
< MAX_MAJOR_WINDOWS
; win_type
++)
372 const char *completion_name
= NULL
;
374 /* We can't focus on an invisible window. */
375 if (tui_win_list
[win_type
] == NULL
376 || !tui_win_list
[win_type
]->generic
.is_visible
)
379 completion_name
= tui_win_name (&tui_win_list
[win_type
]->generic
);
380 gdb_assert (completion_name
!= NULL
);
381 completion_name_vec
.push_back (completion_name
);
384 /* If no windows are considered visible then the TUI has not yet been
385 initialized. But still "focus src" and "focus cmd" will work because
386 invoking the focus command will entail initializing the TUI which sets the
387 default layout to SRC_COMMAND. */
388 if (completion_name_vec
.empty ())
390 completion_name_vec
.push_back (SRC_NAME
);
391 completion_name_vec
.push_back (CMD_NAME
);
394 if (include_next_prev_p
)
396 completion_name_vec
.push_back ("next");
397 completion_name_vec
.push_back ("prev");
401 completion_name_vec
.push_back (NULL
);
402 complete_on_enum (tracker
, completion_name_vec
.data (), text
, word
);
405 /* Complete possible window names to focus on. TEXT is the complete text
406 entered so far, WORD is the word currently being completed. */
409 focus_completer (struct cmd_list_element
*ignore
,
410 completion_tracker
&tracker
,
411 const char *text
, const char *word
)
413 window_name_completer (tracker
, 1, text
, word
);
416 /* Complete possible window names for winheight command. TEXT is the
417 complete text entered so far, WORD is the word currently being
421 winheight_completer (struct cmd_list_element
*ignore
,
422 completion_tracker
&tracker
,
423 const char *text
, const char *word
)
425 /* The first word is the window name. That we can complete. Subsequent
426 words can't be completed. */
430 window_name_completer (tracker
, 0, text
, word
);
433 /* Update gdb's knowledge of the terminal size. */
435 tui_update_gdb_sizes (void)
441 width
= TUI_CMD_WIN
->generic
.width
;
442 height
= TUI_CMD_WIN
->generic
.height
;
446 width
= tui_term_width ();
447 height
= tui_term_height ();
450 set_screen_width_and_height (width
, height
);
454 /* Set the logical focus to win_info. */
456 tui_set_win_focus_to (struct tui_win_info
*win_info
)
458 if (win_info
!= NULL
)
460 struct tui_win_info
*win_with_focus
= tui_win_with_focus ();
462 if (win_with_focus
!= NULL
463 && win_with_focus
->generic
.type
!= CMD_WIN
)
464 tui_unhighlight_win (win_with_focus
);
465 tui_set_win_with_focus (win_info
);
466 if (win_info
->generic
.type
!= CMD_WIN
)
467 tui_highlight_win (win_info
);
473 tui_win_info::forward_scroll (int num_to_scroll
)
475 if (num_to_scroll
== 0)
476 num_to_scroll
= generic
.height
- 3;
478 do_scroll_vertical (FORWARD_SCROLL
, num_to_scroll
);
482 tui_win_info::backward_scroll (int num_to_scroll
)
484 if (num_to_scroll
== 0)
485 num_to_scroll
= generic
.height
- 3;
487 do_scroll_vertical (BACKWARD_SCROLL
, num_to_scroll
);
492 tui_win_info::left_scroll (int num_to_scroll
)
494 if (num_to_scroll
== 0)
497 do_scroll_horizontal (LEFT_SCROLL
, num_to_scroll
);
502 tui_win_info::right_scroll (int num_to_scroll
)
504 if (num_to_scroll
== 0)
507 do_scroll_horizontal (RIGHT_SCROLL
, num_to_scroll
);
512 tui_refresh_all_win (void)
516 clearok (curscr
, TRUE
);
517 tui_refresh_all (tui_win_list
);
518 for (type
= SRC_WIN
; type
< MAX_MAJOR_WINDOWS
; type
++)
520 if (tui_win_list
[type
]
521 && tui_win_list
[type
]->generic
.is_visible
)
527 tui_show_source_content (tui_win_list
[type
]);
528 tui_check_and_display_highlight_if_needed (tui_win_list
[type
]);
529 tui_erase_exec_info_content (tui_win_list
[type
]);
530 tui_update_exec_info (tui_win_list
[type
]);
533 tui_refresh_data_win ();
540 tui_show_locator_content ();
544 tui_rehighlight_all (void)
548 for (type
= SRC_WIN
; type
< MAX_MAJOR_WINDOWS
; type
++)
549 tui_check_and_display_highlight_if_needed (tui_win_list
[type
]);
552 /* Resize all the windows based on the terminal size. This function
553 gets called from within the readline sinwinch handler. */
555 tui_resize_all (void)
557 int height_diff
, width_diff
;
558 int screenheight
, screenwidth
;
560 rl_get_screen_size (&screenheight
, &screenwidth
);
561 width_diff
= screenwidth
- tui_term_width ();
562 height_diff
= screenheight
- tui_term_height ();
563 if (height_diff
|| width_diff
)
565 enum tui_layout_type cur_layout
= tui_current_layout ();
566 struct tui_win_info
*win_with_focus
= tui_win_with_focus ();
567 struct tui_win_info
*first_win
;
568 struct tui_win_info
*second_win
;
569 struct tui_gen_win_info
*locator
= tui_locator_win_info_ptr ();
571 int new_height
, split_diff
, cmd_split_diff
, num_wins_displayed
= 2;
573 #ifdef HAVE_RESIZE_TERM
574 resize_term (screenheight
, screenwidth
);
576 /* Turn keypad off while we resize. */
577 if (win_with_focus
!= TUI_CMD_WIN
)
578 keypad (TUI_CMD_WIN
->generic
.handle
, FALSE
);
579 tui_update_gdb_sizes ();
580 tui_set_term_height_to (screenheight
);
581 tui_set_term_width_to (screenwidth
);
582 if (cur_layout
== SRC_DISASSEM_COMMAND
583 || cur_layout
== SRC_DATA_COMMAND
584 || cur_layout
== DISASSEM_DATA_COMMAND
)
585 num_wins_displayed
++;
586 split_diff
= height_diff
/ num_wins_displayed
;
587 cmd_split_diff
= split_diff
;
588 if (height_diff
% num_wins_displayed
)
595 /* Now adjust each window. */
596 /* erase + clearok are used instead of a straightforward clear as
597 AIX 5.3 does not define clear. */
599 clearok (curscr
, TRUE
);
604 case DISASSEM_COMMAND
:
605 first_win
= tui_source_windows ()[0];
606 first_win
->generic
.width
+= width_diff
;
607 locator
->width
+= width_diff
;
608 /* Check for invalid heights. */
609 if (height_diff
== 0)
610 new_height
= first_win
->generic
.height
;
611 else if ((first_win
->generic
.height
+ split_diff
) >=
612 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
613 new_height
= screenheight
- MIN_CMD_WIN_HEIGHT
- 1;
614 else if ((first_win
->generic
.height
+ split_diff
) <= 0)
615 new_height
= MIN_WIN_HEIGHT
;
617 new_height
= first_win
->generic
.height
+ split_diff
;
619 locator
->origin
.y
= new_height
+ 1;
620 make_invisible_and_set_new_height (first_win
, new_height
);
621 TUI_CMD_WIN
->generic
.origin
.y
= locator
->origin
.y
+ 1;
622 TUI_CMD_WIN
->generic
.width
+= width_diff
;
623 new_height
= screenheight
- TUI_CMD_WIN
->generic
.origin
.y
;
624 make_invisible_and_set_new_height (TUI_CMD_WIN
, new_height
);
625 make_visible_with_new_height (first_win
);
626 make_visible_with_new_height (TUI_CMD_WIN
);
627 if (first_win
->generic
.content_size
<= 0)
628 tui_erase_source_content (first_win
, EMPTY_SOURCE_PROMPT
);
631 if (cur_layout
== SRC_DISASSEM_COMMAND
)
633 first_win
= TUI_SRC_WIN
;
634 first_win
->generic
.width
+= width_diff
;
635 second_win
= TUI_DISASM_WIN
;
636 second_win
->generic
.width
+= width_diff
;
640 first_win
= TUI_DATA_WIN
;
641 first_win
->generic
.width
+= width_diff
;
642 second_win
= tui_source_windows ()[0];
643 second_win
->generic
.width
+= width_diff
;
645 /* Change the first window's height/width. */
646 /* Check for invalid heights. */
647 if (height_diff
== 0)
648 new_height
= first_win
->generic
.height
;
649 else if ((first_win
->generic
.height
+
650 second_win
->generic
.height
+ (split_diff
* 2)) >=
651 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
652 new_height
= (screenheight
- MIN_CMD_WIN_HEIGHT
- 1) / 2;
653 else if ((first_win
->generic
.height
+ split_diff
) <= 0)
654 new_height
= MIN_WIN_HEIGHT
;
656 new_height
= first_win
->generic
.height
+ split_diff
;
657 make_invisible_and_set_new_height (first_win
, new_height
);
659 locator
->width
+= width_diff
;
661 /* Change the second window's height/width. */
662 /* Check for invalid heights. */
663 if (height_diff
== 0)
664 new_height
= second_win
->generic
.height
;
665 else if ((first_win
->generic
.height
+
666 second_win
->generic
.height
+ (split_diff
* 2)) >=
667 (screenheight
- MIN_CMD_WIN_HEIGHT
- 1))
669 new_height
= screenheight
- MIN_CMD_WIN_HEIGHT
- 1;
671 new_height
= (new_height
/ 2) + 1;
675 else if ((second_win
->generic
.height
+ split_diff
) <= 0)
676 new_height
= MIN_WIN_HEIGHT
;
678 new_height
= second_win
->generic
.height
+ split_diff
;
679 second_win
->generic
.origin
.y
= first_win
->generic
.height
- 1;
680 make_invisible_and_set_new_height (second_win
, new_height
);
682 /* Change the command window's height/width. */
683 TUI_CMD_WIN
->generic
.origin
.y
= locator
->origin
.y
+ 1;
684 make_invisible_and_set_new_height (TUI_CMD_WIN
,
685 TUI_CMD_WIN
->generic
.height
687 make_visible_with_new_height (first_win
);
688 make_visible_with_new_height (second_win
);
689 make_visible_with_new_height (TUI_CMD_WIN
);
690 if (first_win
->generic
.content_size
<= 0)
691 tui_erase_source_content (first_win
, EMPTY_SOURCE_PROMPT
);
692 if (second_win
->generic
.content_size
<= 0)
693 tui_erase_source_content (second_win
, EMPTY_SOURCE_PROMPT
);
696 /* Now remove all invisible windows, and their content so that
697 they get created again when called for with the new size. */
698 for (win_type
= SRC_WIN
; (win_type
< MAX_MAJOR_WINDOWS
); win_type
++)
700 if (win_type
!= CMD_WIN
701 && (tui_win_list
[win_type
] != NULL
)
702 && !tui_win_list
[win_type
]->generic
.is_visible
)
704 delete tui_win_list
[win_type
];
705 tui_win_list
[win_type
] = NULL
;
708 /* Turn keypad back on, unless focus is in the command
710 if (win_with_focus
!= TUI_CMD_WIN
)
711 keypad (TUI_CMD_WIN
->generic
.handle
, TRUE
);
716 /* Token for use by TUI's asynchronous SIGWINCH handler. */
717 static struct async_signal_handler
*tui_sigwinch_token
;
719 /* TUI's SIGWINCH signal handler. */
721 tui_sigwinch_handler (int signal
)
723 mark_async_signal_handler (tui_sigwinch_token
);
724 tui_set_win_resized_to (TRUE
);
727 /* Callback for asynchronously resizing TUI following a SIGWINCH signal. */
729 tui_async_resize_screen (gdb_client_data arg
)
731 rl_resize_terminal ();
735 int screen_height
, screen_width
;
737 rl_get_screen_size (&screen_height
, &screen_width
);
738 set_screen_width_and_height (screen_width
, screen_height
);
740 /* win_resized is left set so that the next call to tui_enable()
741 resizes the TUI windows. */
745 tui_set_win_resized_to (FALSE
);
747 tui_refresh_all_win ();
748 tui_update_gdb_sizes ();
749 tui_redisplay_readline ();
754 /* Initialize TUI's SIGWINCH signal handler. Note that the handler is not
755 uninstalled when we exit TUI, so the handler should not assume that TUI is
758 tui_initialize_win (void)
762 = create_async_signal_handler (tui_async_resize_screen
, NULL
);
765 #ifdef HAVE_SIGACTION
766 struct sigaction old_winch
;
768 memset (&old_winch
, 0, sizeof (old_winch
));
769 old_winch
.sa_handler
= &tui_sigwinch_handler
;
771 old_winch
.sa_flags
= SA_RESTART
;
773 sigaction (SIGWINCH
, &old_winch
, NULL
);
775 signal (SIGWINCH
, &tui_sigwinch_handler
);
782 /*************************
783 ** STATIC LOCAL FUNCTIONS
784 **************************/
788 tui_scroll_forward_command (const char *arg
, int from_tty
)
790 int num_to_scroll
= 1;
791 struct tui_win_info
*win_to_scroll
;
793 /* Make sure the curses mode is enabled. */
796 parse_scrolling_args (arg
, &win_to_scroll
, NULL
);
798 parse_scrolling_args (arg
, &win_to_scroll
, &num_to_scroll
);
799 win_to_scroll
->forward_scroll (num_to_scroll
);
804 tui_scroll_backward_command (const char *arg
, int from_tty
)
806 int num_to_scroll
= 1;
807 struct tui_win_info
*win_to_scroll
;
809 /* Make sure the curses mode is enabled. */
812 parse_scrolling_args (arg
, &win_to_scroll
, NULL
);
814 parse_scrolling_args (arg
, &win_to_scroll
, &num_to_scroll
);
815 win_to_scroll
->backward_scroll (num_to_scroll
);
820 tui_scroll_left_command (const char *arg
, int from_tty
)
823 struct tui_win_info
*win_to_scroll
;
825 /* Make sure the curses mode is enabled. */
827 parse_scrolling_args (arg
, &win_to_scroll
, &num_to_scroll
);
828 win_to_scroll
->left_scroll (num_to_scroll
);
833 tui_scroll_right_command (const char *arg
, int from_tty
)
836 struct tui_win_info
*win_to_scroll
;
838 /* Make sure the curses mode is enabled. */
840 parse_scrolling_args (arg
, &win_to_scroll
, &num_to_scroll
);
841 win_to_scroll
->right_scroll (num_to_scroll
);
845 /* Set focus to the window named by 'arg'. */
847 tui_set_focus (const char *arg
, int from_tty
)
851 char *buf_ptr
= xstrdup (arg
);
853 struct tui_win_info
*win_info
= NULL
;
855 for (i
= 0; (i
< strlen (buf_ptr
)); i
++)
856 buf_ptr
[i
] = tolower (arg
[i
]);
858 if (subset_compare (buf_ptr
, "next"))
859 win_info
= tui_next_win (tui_win_with_focus ());
860 else if (subset_compare (buf_ptr
, "prev"))
861 win_info
= tui_prev_win (tui_win_with_focus ());
863 win_info
= tui_partial_win_by_name (buf_ptr
);
865 if (win_info
== NULL
|| !win_info
->generic
.is_visible
)
866 warning (_("Invalid window specified. \n\
867 The window name specified must be valid and visible.\n"));
870 tui_set_win_focus_to (win_info
);
871 keypad (TUI_CMD_WIN
->generic
.handle
, (win_info
!= TUI_CMD_WIN
));
874 if (TUI_DATA_WIN
&& TUI_DATA_WIN
->generic
.is_visible
)
875 tui_refresh_data_win ();
877 printf_filtered (_("Focus set to %s window.\n"),
878 tui_win_name (&tui_win_with_focus ()->generic
));
881 warning (_("Incorrect Number of Arguments.\n%s"), FOCUS_USAGE
);
885 tui_set_focus_command (const char *arg
, int from_tty
)
887 /* Make sure the curses mode is enabled. */
889 tui_set_focus (arg
, from_tty
);
894 tui_all_windows_info (const char *arg
, int from_tty
)
897 struct tui_win_info
*win_with_focus
= tui_win_with_focus ();
899 for (type
= SRC_WIN
; (type
< MAX_MAJOR_WINDOWS
); type
++)
900 if (tui_win_list
[type
]
901 && tui_win_list
[type
]->generic
.is_visible
)
903 if (win_with_focus
== tui_win_list
[type
])
904 printf_filtered (" %s\t(%d lines) <has focus>\n",
905 tui_win_name (&tui_win_list
[type
]->generic
),
906 tui_win_list
[type
]->generic
.height
);
908 printf_filtered (" %s\t(%d lines)\n",
909 tui_win_name (&tui_win_list
[type
]->generic
),
910 tui_win_list
[type
]->generic
.height
);
916 tui_refresh_all_command (const char *arg
, int from_tty
)
918 /* Make sure the curses mode is enabled. */
921 tui_refresh_all_win ();
924 /* The tab width that should be used by the TUI. */
926 unsigned int tui_tab_width
= DEFAULT_TAB_LEN
;
928 /* The tab width as set by the user. */
930 static unsigned int internal_tab_width
= DEFAULT_TAB_LEN
;
932 /* After the tab width is set, call this to update the relevant
938 /* We don't really change the height of any windows, but
939 calling these 2 functions causes a complete regeneration
940 and redisplay of the window's contents, which will take
941 the new tab width into account. */
942 if (tui_win_list
[SRC_WIN
]
943 && tui_win_list
[SRC_WIN
]->generic
.is_visible
)
945 make_invisible_and_set_new_height (TUI_SRC_WIN
,
946 TUI_SRC_WIN
->generic
.height
);
947 make_visible_with_new_height (TUI_SRC_WIN
);
949 if (tui_win_list
[DISASSEM_WIN
]
950 && tui_win_list
[DISASSEM_WIN
]->generic
.is_visible
)
952 make_invisible_and_set_new_height (TUI_DISASM_WIN
,
953 TUI_DISASM_WIN
->generic
.height
);
954 make_visible_with_new_height (TUI_DISASM_WIN
);
958 /* Callback for "set tui tab-width". */
961 tui_set_tab_width (const char *ignore
,
962 int from_tty
, struct cmd_list_element
*c
)
964 if (internal_tab_width
== 0)
966 internal_tab_width
= tui_tab_width
;
967 error (_("Tab width must not be 0"));
970 tui_tab_width
= internal_tab_width
;
974 /* Callback for "show tui tab-width". */
977 tui_show_tab_width (struct ui_file
*file
, int from_tty
,
978 struct cmd_list_element
*c
, const char *value
)
980 fprintf_filtered (gdb_stdout
, _("TUI tab width is %s spaces.\n"), value
);
984 /* Set the tab width of the specified window. */
986 tui_set_tab_width_command (const char *arg
, int from_tty
)
988 /* Make sure the curses mode is enabled. */
996 warning (_("Tab widths greater than 0 must be specified."));
999 internal_tab_width
= ts
;
1002 update_tab_width ();
1008 /* Set the height of the specified window. */
1010 tui_set_win_height (const char *arg
, int from_tty
)
1012 /* Make sure the curses mode is enabled. */
1016 std::string copy
= arg
;
1017 char *buf
= ©
[0];
1018 char *buf_ptr
= buf
;
1021 struct tui_win_info
*win_info
;
1024 buf_ptr
= strchr (buf_ptr
, ' ');
1025 if (buf_ptr
!= NULL
)
1027 *buf_ptr
= (char) 0;
1029 /* Validate the window name. */
1030 for (i
= 0; i
< strlen (wname
); i
++)
1031 wname
[i
] = tolower (wname
[i
]);
1032 win_info
= tui_partial_win_by_name (wname
);
1034 if (win_info
== NULL
|| !win_info
->generic
.is_visible
)
1035 warning (_("Invalid window specified. \n\
1036 The window name specified must be valid and visible.\n"));
1039 /* Process the size. */
1040 while (*(++buf_ptr
) == ' ')
1043 if (*buf_ptr
!= (char) 0)
1046 int fixed_size
= TRUE
;
1049 if (*buf_ptr
== '+' || *buf_ptr
== '-')
1051 if (*buf_ptr
== '-')
1056 input_no
= atoi (buf_ptr
);
1062 new_height
= input_no
;
1064 new_height
= win_info
->generic
.height
+ input_no
;
1066 /* Now change the window's height, and adjust
1067 all other windows around it. */
1068 if (tui_adjust_win_heights (win_info
,
1069 new_height
) == TUI_FAILURE
)
1070 warning (_("Invalid window height specified.\n%s"),
1073 tui_update_gdb_sizes ();
1076 warning (_("Invalid window height specified.\n%s"),
1082 printf_filtered (WIN_HEIGHT_USAGE
);
1085 printf_filtered (WIN_HEIGHT_USAGE
);
1088 /* Set the height of the specified window, with va_list. */
1090 tui_set_win_height_command (const char *arg
, int from_tty
)
1092 /* Make sure the curses mode is enabled. */
1094 tui_set_win_height (arg
, from_tty
);
1097 /* Function to adjust all window heights around the primary. */
1098 static enum tui_status
1099 tui_adjust_win_heights (struct tui_win_info
*primary_win_info
,
1102 enum tui_status status
= TUI_FAILURE
;
1104 if (new_height_ok (primary_win_info
, new_height
))
1106 status
= TUI_SUCCESS
;
1107 if (new_height
!= primary_win_info
->generic
.height
)
1110 struct tui_win_info
*win_info
;
1111 struct tui_gen_win_info
*locator
= tui_locator_win_info_ptr ();
1112 enum tui_layout_type cur_layout
= tui_current_layout ();
1114 diff
= (new_height
- primary_win_info
->generic
.height
) * (-1);
1115 if (cur_layout
== SRC_COMMAND
1116 || cur_layout
== DISASSEM_COMMAND
)
1118 struct tui_win_info
*src_win_info
;
1120 make_invisible_and_set_new_height (primary_win_info
, new_height
);
1121 if (primary_win_info
->generic
.type
== CMD_WIN
)
1123 win_info
= tui_source_windows ()[0];
1124 src_win_info
= win_info
;
1128 win_info
= tui_win_list
[CMD_WIN
];
1129 src_win_info
= primary_win_info
;
1131 make_invisible_and_set_new_height (win_info
,
1132 win_info
->generic
.height
+ diff
);
1133 TUI_CMD_WIN
->generic
.origin
.y
= locator
->origin
.y
+ 1;
1134 make_visible_with_new_height (win_info
);
1135 make_visible_with_new_height (primary_win_info
);
1136 if (src_win_info
->generic
.content_size
<= 0)
1137 tui_erase_source_content (src_win_info
, EMPTY_SOURCE_PROMPT
);
1141 struct tui_win_info
*first_win
;
1142 struct tui_win_info
*second_win
;
1144 if (cur_layout
== SRC_DISASSEM_COMMAND
)
1146 first_win
= TUI_SRC_WIN
;
1147 second_win
= TUI_DISASM_WIN
;
1151 first_win
= TUI_DATA_WIN
;
1152 second_win
= tui_source_windows ()[0];
1154 if (primary_win_info
== TUI_CMD_WIN
)
1155 { /* Split the change in height accross the 1st & 2nd
1156 windows, adjusting them as well. */
1157 /* Subtract the locator. */
1158 int first_split_diff
= diff
/ 2;
1159 int second_split_diff
= first_split_diff
;
1163 if (first_win
->generic
.height
>
1164 second_win
->generic
.height
)
1172 second_split_diff
--;
1174 second_split_diff
++;
1177 /* Make sure that the minimum hieghts are
1179 while ((first_win
->generic
.height
+ first_split_diff
) < 3)
1182 second_split_diff
--;
1184 while ((second_win
->generic
.height
+ second_split_diff
) < 3)
1186 second_split_diff
++;
1189 make_invisible_and_set_new_height (
1191 first_win
->generic
.height
+ first_split_diff
);
1192 second_win
->generic
.origin
.y
= first_win
->generic
.height
- 1;
1193 make_invisible_and_set_new_height (second_win
,
1194 second_win
->generic
.height
1195 + second_split_diff
);
1196 TUI_CMD_WIN
->generic
.origin
.y
= locator
->origin
.y
+ 1;
1197 make_invisible_and_set_new_height (TUI_CMD_WIN
, new_height
);
1201 if ((TUI_CMD_WIN
->generic
.height
+ diff
) < 1)
1202 { /* If there is no way to increase the command
1203 window take real estate from the 1st or 2nd
1205 if ((TUI_CMD_WIN
->generic
.height
+ diff
) < 1)
1209 for (i
= TUI_CMD_WIN
->generic
.height
+ diff
;
1211 if (primary_win_info
== first_win
)
1212 second_win
->generic
.height
--;
1214 first_win
->generic
.height
--;
1217 if (primary_win_info
== first_win
)
1218 make_invisible_and_set_new_height (first_win
, new_height
);
1220 make_invisible_and_set_new_height (
1222 first_win
->generic
.height
);
1223 second_win
->generic
.origin
.y
= first_win
->generic
.height
- 1;
1224 if (primary_win_info
== second_win
)
1225 make_invisible_and_set_new_height (second_win
, new_height
);
1227 make_invisible_and_set_new_height (
1228 second_win
, second_win
->generic
.height
);
1229 TUI_CMD_WIN
->generic
.origin
.y
= locator
->origin
.y
+ 1;
1230 if ((TUI_CMD_WIN
->generic
.height
+ diff
) < 1)
1231 make_invisible_and_set_new_height (TUI_CMD_WIN
, 1);
1233 make_invisible_and_set_new_height (TUI_CMD_WIN
,
1234 TUI_CMD_WIN
->generic
.height
+ diff
);
1236 make_visible_with_new_height (TUI_CMD_WIN
);
1237 make_visible_with_new_height (second_win
);
1238 make_visible_with_new_height (first_win
);
1239 if (first_win
->generic
.content_size
<= 0)
1240 tui_erase_source_content (first_win
, EMPTY_SOURCE_PROMPT
);
1241 if (second_win
->generic
.content_size
<= 0)
1242 tui_erase_source_content (second_win
, EMPTY_SOURCE_PROMPT
);
1251 /* Function make the target window (and auxillary windows associated
1252 with the targer) invisible, and set the new height and
1255 make_invisible_and_set_new_height (struct tui_win_info
*win_info
,
1259 struct tui_gen_win_info
*gen_win_info
;
1261 tui_make_invisible (&win_info
->generic
);
1262 win_info
->generic
.height
= height
;
1264 win_info
->generic
.viewport_height
= height
- 1;
1266 win_info
->generic
.viewport_height
= height
;
1267 if (win_info
!= TUI_CMD_WIN
)
1268 win_info
->generic
.viewport_height
--;
1270 /* Now deal with the auxillary windows associated with win_info. */
1271 switch (win_info
->generic
.type
)
1275 gen_win_info
= win_info
->detail
.source_info
.execution_info
;
1276 tui_make_invisible (gen_win_info
);
1277 gen_win_info
->height
= height
;
1278 gen_win_info
->origin
.y
= win_info
->generic
.origin
.y
;
1280 gen_win_info
->viewport_height
= height
- 1;
1282 gen_win_info
->viewport_height
= height
;
1283 if (win_info
!= TUI_CMD_WIN
)
1284 gen_win_info
->viewport_height
--;
1286 if (tui_win_has_locator (win_info
))
1288 gen_win_info
= tui_locator_win_info_ptr ();
1289 tui_make_invisible (gen_win_info
);
1290 gen_win_info
->origin
.y
= win_info
->generic
.origin
.y
+ height
;
1294 /* Delete all data item windows. */
1295 for (i
= 0; i
< win_info
->generic
.content_size
; i
++)
1298 = &win_info
->generic
.content
[i
]->which_element
.data_window
;
1299 tui_delete_win (gen_win_info
->handle
);
1300 gen_win_info
->handle
= NULL
;
1309 /* Function to make the windows with new heights visible. This means
1310 re-creating the windows' content since the window had to be
1311 destroyed to be made invisible. */
1313 make_visible_with_new_height (struct tui_win_info
*win_info
)
1317 tui_make_visible (&win_info
->generic
);
1318 tui_check_and_display_highlight_if_needed (win_info
);
1319 switch (win_info
->generic
.type
)
1323 tui_free_win_content (win_info
->detail
.source_info
.execution_info
);
1324 tui_make_visible (win_info
->detail
.source_info
.execution_info
);
1325 if (win_info
->generic
.content
!= NULL
)
1327 struct gdbarch
*gdbarch
= win_info
->detail
.source_info
.gdbarch
;
1328 struct tui_line_or_address line_or_addr
;
1329 struct symtab_and_line cursal
1330 = get_current_source_symtab_and_line ();
1332 line_or_addr
= win_info
->detail
.source_info
.start_line_or_addr
;
1333 tui_free_win_content (&win_info
->generic
);
1334 tui_update_source_window (win_info
, gdbarch
,
1335 cursal
.symtab
, line_or_addr
, TRUE
);
1337 else if (deprecated_safe_get_selected_frame () != NULL
)
1339 struct tui_line_or_address line
;
1340 struct symtab_and_line cursal
1341 = get_current_source_symtab_and_line ();
1342 struct frame_info
*frame
= deprecated_safe_get_selected_frame ();
1343 struct gdbarch
*gdbarch
= get_frame_arch (frame
);
1345 s
= find_pc_line_symtab (get_frame_pc (frame
));
1346 if (win_info
->generic
.type
== SRC_WIN
)
1348 line
.loa
= LOA_LINE
;
1349 line
.u
.line_no
= cursal
.line
;
1353 line
.loa
= LOA_ADDRESS
;
1354 find_line_pc (s
, cursal
.line
, &line
.u
.addr
);
1356 tui_update_source_window (win_info
, gdbarch
, s
, line
, TRUE
);
1358 if (tui_win_has_locator (win_info
))
1360 tui_make_visible (tui_locator_win_info_ptr ());
1361 tui_show_locator_content ();
1365 tui_display_all_data ();
1369 wresize (TUI_CMD_WIN
->generic
.handle
,
1370 TUI_CMD_WIN
->generic
.height
,
1371 TUI_CMD_WIN
->generic
.width
);
1373 mvwin (TUI_CMD_WIN
->generic
.handle
,
1374 TUI_CMD_WIN
->generic
.origin
.y
,
1375 TUI_CMD_WIN
->generic
.origin
.x
);
1376 wmove (win_info
->generic
.handle
, 0, 0);
1385 new_height_ok (struct tui_win_info
*primary_win_info
,
1388 int ok
= (new_height
< tui_term_height ());
1393 enum tui_layout_type cur_layout
= tui_current_layout ();
1395 diff
= (new_height
- primary_win_info
->generic
.height
) * (-1);
1396 if (cur_layout
== SRC_COMMAND
|| cur_layout
== DISASSEM_COMMAND
)
1398 ok
= ((primary_win_info
->generic
.type
== CMD_WIN
1399 && new_height
<= (tui_term_height () - 4)
1400 && new_height
>= MIN_CMD_WIN_HEIGHT
)
1401 || (primary_win_info
->generic
.type
!= CMD_WIN
1402 && new_height
<= (tui_term_height () - 2)
1403 && new_height
>= MIN_WIN_HEIGHT
));
1405 { /* Check the total height. */
1406 struct tui_win_info
*win_info
;
1408 if (primary_win_info
== TUI_CMD_WIN
)
1409 win_info
= tui_source_windows ()[0];
1411 win_info
= TUI_CMD_WIN
;
1413 (win_info
->generic
.height
+ diff
)) <= tui_term_height ());
1418 int cur_total_height
, total_height
, min_height
= 0;
1419 struct tui_win_info
*first_win
;
1420 struct tui_win_info
*second_win
;
1422 if (cur_layout
== SRC_DISASSEM_COMMAND
)
1424 first_win
= TUI_SRC_WIN
;
1425 second_win
= TUI_DISASM_WIN
;
1429 first_win
= TUI_DATA_WIN
;
1430 second_win
= tui_source_windows ()[0];
1432 /* We could simply add all the heights to obtain the same
1433 result but below is more explicit since we subtract 1 for
1434 the line that the first and second windows share, and add
1435 one for the locator. */
1436 total_height
= cur_total_height
=
1437 (first_win
->generic
.height
+ second_win
->generic
.height
- 1)
1438 + TUI_CMD_WIN
->generic
.height
+ 1; /* Locator. */
1439 if (primary_win_info
== TUI_CMD_WIN
)
1441 /* Locator included since first & second win share a line. */
1442 ok
= ((first_win
->generic
.height
+
1443 second_win
->generic
.height
+ diff
) >=
1444 (MIN_WIN_HEIGHT
* 2)
1445 && new_height
>= MIN_CMD_WIN_HEIGHT
);
1448 total_height
= new_height
+
1449 (first_win
->generic
.height
+
1450 second_win
->generic
.height
+ diff
);
1451 min_height
= MIN_CMD_WIN_HEIGHT
;
1456 min_height
= MIN_WIN_HEIGHT
;
1458 /* First see if we can increase/decrease the command
1459 window. And make sure that the command window is at
1461 ok
= ((TUI_CMD_WIN
->generic
.height
+ diff
) > 0);
1463 { /* Looks like we have to increase/decrease one of
1464 the other windows. */
1465 if (primary_win_info
== first_win
)
1466 ok
= (second_win
->generic
.height
+ diff
) >= min_height
;
1468 ok
= (first_win
->generic
.height
+ diff
) >= min_height
;
1472 if (primary_win_info
== first_win
)
1473 total_height
= new_height
+
1474 second_win
->generic
.height
+
1475 TUI_CMD_WIN
->generic
.height
+ diff
;
1477 total_height
= new_height
+
1478 first_win
->generic
.height
+
1479 TUI_CMD_WIN
->generic
.height
+ diff
;
1482 /* Now make sure that the proposed total height doesn't
1483 exceed the old total height. */
1485 ok
= (new_height
>= min_height
1486 && total_height
<= cur_total_height
);
1495 parse_scrolling_args (const char *arg
,
1496 struct tui_win_info
**win_to_scroll
,
1501 *win_to_scroll
= tui_win_with_focus ();
1503 /* First set up the default window to scroll, in case there is no
1509 /* Process the number of lines to scroll. */
1510 std::string copy
= arg
;
1512 if (isdigit (*buf_ptr
))
1517 buf_ptr
= strchr (buf_ptr
, ' ');
1518 if (buf_ptr
!= NULL
)
1520 *buf_ptr
= (char) 0;
1522 *num_to_scroll
= atoi (num_str
);
1525 else if (num_to_scroll
)
1526 *num_to_scroll
= atoi (num_str
);
1529 /* Process the window name if one is specified. */
1530 if (buf_ptr
!= NULL
)
1534 if (*buf_ptr
== ' ')
1535 while (*(++buf_ptr
) == ' ')
1538 if (*buf_ptr
!= (char) 0)
1540 /* Validate the window name. */
1541 for (char *p
= buf_ptr
; *p
!= '\0'; p
++)
1549 *win_to_scroll
= tui_partial_win_by_name (wname
);
1551 if (*win_to_scroll
== NULL
1552 || !(*win_to_scroll
)->generic
.is_visible
)
1553 error (_("Invalid window specified. \n\
1554 The window name specified must be valid and visible.\n"));
1555 else if (*win_to_scroll
== TUI_CMD_WIN
)
1556 *win_to_scroll
= tui_source_windows ()[0];
1561 /* Function to initialize gdb commands, for tui window
1565 _initialize_tui_win (void)
1567 static struct cmd_list_element
*tui_setlist
;
1568 static struct cmd_list_element
*tui_showlist
;
1569 struct cmd_list_element
*cmd
;
1571 /* Define the classes of commands.
1572 They will appear in the help list in the reverse of this order. */
1573 add_prefix_cmd ("tui", class_tui
, set_tui_cmd
,
1574 _("TUI configuration variables"),
1575 &tui_setlist
, "set tui ",
1576 0 /* allow-unknown */, &setlist
);
1577 add_prefix_cmd ("tui", class_tui
, show_tui_cmd
,
1578 _("TUI configuration variables"),
1579 &tui_showlist
, "show tui ",
1580 0 /* allow-unknown */, &showlist
);
1582 add_com ("refresh", class_tui
, tui_refresh_all_command
,
1583 _("Refresh the terminal display."));
1585 cmd
= add_com ("tabset", class_tui
, tui_set_tab_width_command
, _("\
1586 Set the width (in characters) of tab stops.\n\
1588 deprecate_cmd (cmd
, "set tui tab-width");
1590 cmd
= add_com ("winheight", class_tui
, tui_set_win_height_command
, _("\
1591 Set or modify the height of a specified window.\n"
1593 "Window names are:\n\
1594 src : the source window\n\
1595 cmd : the command window\n\
1596 asm : the disassembly window\n\
1597 regs : the register display"));
1598 add_com_alias ("wh", "winheight", class_tui
, 0);
1599 set_cmd_completer (cmd
, winheight_completer
);
1600 add_info ("win", tui_all_windows_info
,
1601 _("List of all displayed windows."));
1602 cmd
= add_com ("focus", class_tui
, tui_set_focus_command
, _("\
1603 Set focus to named window or next/prev window.\n"
1605 "Valid Window names are:\n\
1606 src : the source window\n\
1607 asm : the disassembly window\n\
1608 regs : the register display\n\
1609 cmd : the command window"));
1610 add_com_alias ("fs", "focus", class_tui
, 0);
1611 set_cmd_completer (cmd
, focus_completer
);
1612 add_com ("+", class_tui
, tui_scroll_forward_command
, _("\
1613 Scroll window forward.\n\
1614 Usage: + [WIN] [N]"));
1615 add_com ("-", class_tui
, tui_scroll_backward_command
, _("\
1616 Scroll window backward.\n\
1617 Usage: - [WIN] [N]"));
1618 add_com ("<", class_tui
, tui_scroll_left_command
, _("\
1619 Scroll window text to the left.\n\
1620 Usage: < [WIN] [N]"));
1621 add_com (">", class_tui
, tui_scroll_right_command
, _("\
1622 Scroll window text to the right.\n\
1623 Usage: > [WIN] [N]"));
1625 /* Define the tui control variables. */
1626 add_setshow_enum_cmd ("border-kind", no_class
, tui_border_kind_enums
,
1627 &tui_border_kind
, _("\
1628 Set the kind of border for TUI windows."), _("\
1629 Show the kind of border for TUI windows."), _("\
1630 This variable controls the border of TUI windows:\n\
1631 space use a white space\n\
1632 ascii use ascii characters + - | for the border\n\
1633 acs use the Alternate Character Set"),
1635 show_tui_border_kind
,
1636 &tui_setlist
, &tui_showlist
);
1638 add_setshow_enum_cmd ("border-mode", no_class
, tui_border_mode_enums
,
1639 &tui_border_mode
, _("\
1640 Set the attribute mode to use for the TUI window borders."), _("\
1641 Show the attribute mode to use for the TUI window borders."), _("\
1642 This variable controls the attributes to use for the window borders:\n\
1643 normal normal display\n\
1644 standout use highlight mode of terminal\n\
1645 reverse use reverse video mode\n\
1646 half use half bright\n\
1647 half-standout use half bright and standout mode\n\
1648 bold use extra bright or bold\n\
1649 bold-standout use extra bright or bold with standout mode"),
1651 show_tui_border_mode
,
1652 &tui_setlist
, &tui_showlist
);
1654 add_setshow_enum_cmd ("active-border-mode", no_class
, tui_border_mode_enums
,
1655 &tui_active_border_mode
, _("\
1656 Set the attribute mode to use for the active TUI window border."), _("\
1657 Show the attribute mode to use for the active TUI window border."), _("\
1658 This variable controls the attributes to use for the active window border:\n\
1659 normal normal display\n\
1660 standout use highlight mode of terminal\n\
1661 reverse use reverse video mode\n\
1662 half use half bright\n\
1663 half-standout use half bright and standout mode\n\
1664 bold use extra bright or bold\n\
1665 bold-standout use extra bright or bold with standout mode"),
1667 show_tui_active_border_mode
,
1668 &tui_setlist
, &tui_showlist
);
1670 add_setshow_zuinteger_cmd ("tab-width", no_class
,
1671 &internal_tab_width
, _("\
1672 Set the tab width, in characters, for the TUI."), _("\
1673 Show the tab witdh, in characters, for the TUI"), _("\
1674 This variable controls how many spaces are used to display a tab character."),
1675 tui_set_tab_width
, tui_show_tab_width
,
1676 &tui_setlist
, &tui_showlist
);