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