Home | History | Annotate | Line # | Download | only in dist
      1  1.6  simonb /*	$NetBSD: opttbl.c,v 1.6 2023/10/06 07:29:42 simonb Exp $	*/
      2  1.1    tron 
      3  1.1    tron /*
      4  1.5  simonb  * Copyright (C) 1984-2023  Mark Nudelman
      5  1.1    tron  *
      6  1.1    tron  * You may distribute under the terms of either the GNU General Public
      7  1.1    tron  * License or the Less License, as specified in the README file.
      8  1.1    tron  *
      9  1.4    tron  * For more information, see the README file.
     10  1.1    tron  */
     11  1.1    tron 
     12  1.1    tron 
     13  1.1    tron /*
     14  1.1    tron  * The option table.
     15  1.1    tron  */
     16  1.1    tron 
     17  1.1    tron #include "less.h"
     18  1.1    tron #include "option.h"
     19  1.1    tron 
     20  1.1    tron /*
     21  1.1    tron  * Variables controlled by command line options.
     22  1.1    tron  */
     23  1.6  simonb public int quiet;               /* Should we suppress the audible bell? */
     24  1.6  simonb public int no_vbell;            /* Should we suppress the visual bell? */
     25  1.6  simonb public int how_search;          /* Where should forward searches start? */
     26  1.6  simonb public int top_scroll;          /* Repaint screen from top?
     27  1.6  simonb                                    (alternative is scroll from bottom) */
     28  1.6  simonb public int pr_type;             /* Type of prompt (short, medium, long) */
     29  1.6  simonb public int bs_mode;             /* How to process backspaces */
     30  1.6  simonb public int know_dumb;           /* Don't complain about dumb terminals */
     31  1.6  simonb public int quit_at_eof;         /* Quit after hitting end of file twice */
     32  1.6  simonb public int quit_if_one_screen;  /* Quit if EOF on first screen */
     33  1.6  simonb public int be_helpful;          /* more(1) style -d */
     34  1.6  simonb public int squeeze;             /* Squeeze multiple blank lines into one */
     35  1.6  simonb public int tabstop;             /* Tab settings */
     36  1.6  simonb public int back_scroll;         /* Repaint screen on backwards movement */
     37  1.6  simonb public int forw_scroll;         /* Repaint screen on forward movement */
     38  1.6  simonb public int caseless;            /* Do "caseless" searches */
     39  1.6  simonb public int linenums;            /* Use line numbers */
     40  1.6  simonb public int autobuf;             /* Automatically allocate buffers as needed */
     41  1.6  simonb public int bufspace;            /* Max buffer space per file (K) */
     42  1.6  simonb public int ctldisp;             /* Send control chars to screen untranslated */
     43  1.6  simonb public int force_open;          /* Open the file even if not regular file */
     44  1.6  simonb public int swindow;             /* Size of scrolling window */
     45  1.6  simonb public int jump_sline;          /* Screen line of "jump target" */
     46  1.1    tron public long jump_sline_fraction = -1;
     47  1.1    tron public long shift_count_fraction = -1;
     48  1.5  simonb public int chopline;            /* Truncate displayed lines at screen width */
     49  1.5  simonb public int wordwrap;            /* Wrap lines at space */
     50  1.5  simonb public int no_init;             /* Disable sending ti/te termcap strings */
     51  1.5  simonb public int no_keypad;           /* Disable sending ks/ke termcap strings */
     52  1.1    tron public int twiddle;             /* Show tildes after EOF */
     53  1.5  simonb public int show_attn;           /* Hilite first unread line */
     54  1.5  simonb public int shift_count;         /* Number of positions to shift horizontally */
     55  1.5  simonb public int status_col;          /* Display a status column */
     56  1.5  simonb public int use_lessopen;        /* Use the LESSOPEN filter */
     57  1.5  simonb public int quit_on_intr;        /* Quit on interrupt */
     58  1.5  simonb public int follow_mode;         /* F cmd Follows file desc or file name? */
     59  1.5  simonb public int oldbot;              /* Old bottom of screen behavior {{REMOVE}} */
     60  1.5  simonb public int opt_use_backslash;   /* Use backslash escaping in option parsing */
     61  1.5  simonb public char rscroll_char;       /* Char which marks chopped lines with -S */
     62  1.5  simonb public int rscroll_attr;        /* Attribute of rscroll_char */
     63  1.5  simonb public int no_hist_dups;        /* Remove dups from history list */
     64  1.5  simonb public int mousecap;            /* Allow mouse for scrolling */
     65  1.5  simonb public int wheel_lines;         /* Number of lines to scroll on mouse wheel scroll */
     66  1.5  simonb public int perma_marks;         /* Save marks in history file */
     67  1.5  simonb public int linenum_width;       /* Width of line numbers */
     68  1.5  simonb public int status_col_width;    /* Width of status column */
     69  1.5  simonb public int incr_search;         /* Incremental search */
     70  1.5  simonb public int use_color;           /* Use UI color */
     71  1.5  simonb public int want_filesize;       /* Scan to EOF if necessary to get file size */
     72  1.5  simonb public int status_line;         /* Highlight entire marked lines */
     73  1.5  simonb public int header_lines;        /* Freeze header lines at top of screen */
     74  1.5  simonb public int header_cols;         /* Freeze header columns at left of screen */
     75  1.5  simonb public int nonum_headers;       /* Don't give headers line numbers */
     76  1.5  simonb public int nosearch_headers;    /* Don't search in header lines or columns */
     77  1.5  simonb public int redraw_on_quit;      /* Redraw last screen after term deinit */
     78  1.5  simonb public int def_search_type;     /* */
     79  1.5  simonb public int exit_F_on_close;     /* Exit F command when input closes */
     80  1.5  simonb public int modelines;           /* Lines to read looking for modelines */
     81  1.5  simonb public int show_preproc_error;  /* Display msg when preproc exits with error */
     82  1.5  simonb public int proc_backspace;      /* Special handling of backspace */
     83  1.5  simonb public int proc_tab;            /* Special handling of tab */
     84  1.5  simonb public int proc_return;         /* Special handling of carriage return */
     85  1.5  simonb public char intr_char = CONTROL('X'); /* Char to interrupt reads */
     86  1.1    tron #if HILITE_SEARCH
     87  1.5  simonb public int hilite_search;       /* Highlight matched search patterns? */
     88  1.1    tron #endif
     89  1.1    tron 
     90  1.5  simonb public int less_is_more = 0;    /* Make compatible with POSIX more */
     91  1.1    tron 
     92  1.1    tron /*
     93  1.1    tron  * Long option names.
     94  1.1    tron  */
     95  1.1    tron static struct optname a_optname      = { "search-skip-screen",   NULL };
     96  1.1    tron static struct optname b_optname      = { "buffers",              NULL };
     97  1.1    tron static struct optname B__optname     = { "auto-buffers",         NULL };
     98  1.1    tron static struct optname c_optname      = { "clear-screen",         NULL };
     99  1.1    tron static struct optname d_optname      = { "dumb",                 NULL };
    100  1.1    tron static struct optname D__optname     = { "color",                NULL };
    101  1.1    tron static struct optname e_optname      = { "quit-at-eof",          NULL };
    102  1.1    tron static struct optname f_optname      = { "force",                NULL };
    103  1.1    tron static struct optname F__optname     = { "quit-if-one-screen",   NULL };
    104  1.1    tron #if HILITE_SEARCH
    105  1.1    tron static struct optname g_optname      = { "hilite-search",        NULL };
    106  1.1    tron #endif
    107  1.1    tron static struct optname h_optname      = { "max-back-scroll",      NULL };
    108  1.1    tron static struct optname i_optname      = { "ignore-case",          NULL };
    109  1.1    tron static struct optname j_optname      = { "jump-target",          NULL };
    110  1.1    tron static struct optname J__optname     = { "status-column",        NULL };
    111  1.1    tron #if USERFILE
    112  1.1    tron static struct optname k_optname      = { "lesskey-file",         NULL };
    113  1.5  simonb #if HAVE_LESSKEYSRC
    114  1.5  simonb static struct optname ks_optname     = { "lesskey-src",          NULL };
    115  1.5  simonb #endif /* HAVE_LESSKEYSRC */
    116  1.1    tron #endif
    117  1.1    tron static struct optname K__optname     = { "quit-on-intr",         NULL };
    118  1.1    tron static struct optname L__optname     = { "no-lessopen",          NULL };
    119  1.1    tron static struct optname m_optname      = { "long-prompt",          NULL };
    120  1.1    tron static struct optname n_optname      = { "line-numbers",         NULL };
    121  1.1    tron #if LOGFILE
    122  1.1    tron static struct optname o_optname      = { "log-file",             NULL };
    123  1.1    tron static struct optname O__optname     = { "LOG-FILE",             NULL };
    124  1.1    tron #endif
    125  1.1    tron static struct optname p_optname      = { "pattern",              NULL };
    126  1.1    tron static struct optname P__optname     = { "prompt",               NULL };
    127  1.1    tron static struct optname q2_optname     = { "silent",               NULL };
    128  1.1    tron static struct optname q_optname      = { "quiet",                &q2_optname };
    129  1.1    tron static struct optname r_optname      = { "raw-control-chars",    NULL };
    130  1.1    tron static struct optname s_optname      = { "squeeze-blank-lines",  NULL };
    131  1.1    tron static struct optname S__optname     = { "chop-long-lines",      NULL };
    132  1.1    tron #if TAGS
    133  1.1    tron static struct optname t_optname      = { "tag",                  NULL };
    134  1.1    tron static struct optname T__optname     = { "tag-file",             NULL };
    135  1.1    tron #endif
    136  1.1    tron static struct optname u_optname      = { "underline-special",    NULL };
    137  1.1    tron static struct optname V__optname     = { "version",              NULL };
    138  1.1    tron static struct optname w_optname      = { "hilite-unread",        NULL };
    139  1.1    tron static struct optname x_optname      = { "tabs",                 NULL };
    140  1.1    tron static struct optname X__optname     = { "no-init",              NULL };
    141  1.1    tron static struct optname y_optname      = { "max-forw-scroll",      NULL };
    142  1.1    tron static struct optname z_optname      = { "window",               NULL };
    143  1.1    tron static struct optname quote_optname  = { "quotes",               NULL };
    144  1.1    tron static struct optname tilde_optname  = { "tilde",                NULL };
    145  1.1    tron static struct optname query_optname  = { "help",                 NULL };
    146  1.1    tron static struct optname pound_optname  = { "shift",                NULL };
    147  1.1    tron static struct optname keypad_optname = { "no-keypad",            NULL };
    148  1.1    tron static struct optname oldbot_optname = { "old-bot",              NULL };
    149  1.1    tron static struct optname follow_optname = { "follow-name",          NULL };
    150  1.4    tron static struct optname use_backslash_optname = { "use-backslash", NULL };
    151  1.5  simonb static struct optname rscroll_optname = { "rscroll", NULL };
    152  1.5  simonb static struct optname nohistdups_optname = { "no-histdups",      NULL };
    153  1.5  simonb static struct optname mousecap_optname = { "mouse",              NULL };
    154  1.5  simonb static struct optname wheel_lines_optname = { "wheel-lines",     NULL };
    155  1.5  simonb static struct optname perma_marks_optname = { "save-marks",      NULL };
    156  1.5  simonb static struct optname linenum_width_optname = { "line-num-width", NULL };
    157  1.5  simonb static struct optname status_col_width_optname = { "status-col-width", NULL };
    158  1.5  simonb static struct optname incr_search_optname = { "incsearch",       NULL };
    159  1.5  simonb static struct optname use_color_optname = { "use-color",         NULL };
    160  1.5  simonb static struct optname want_filesize_optname = { "file-size",     NULL };
    161  1.5  simonb static struct optname status_line_optname = { "status-line",     NULL };
    162  1.5  simonb static struct optname header_optname = { "header",               NULL };
    163  1.5  simonb static struct optname nonum_headers_optname = { "no-number-headers", NULL };
    164  1.5  simonb static struct optname nosearch_headers_optname = { "no-search-headers", NULL };
    165  1.5  simonb static struct optname redraw_on_quit_optname = { "redraw-on-quit", NULL };
    166  1.5  simonb static struct optname search_type_optname = { "search-options", NULL };
    167  1.5  simonb static struct optname exit_F_on_close_optname = { "exit-follow-on-close", NULL };
    168  1.5  simonb static struct optname modelines_optname = { "modelines", NULL };
    169  1.5  simonb static struct optname no_vbell_optname = { "no-vbell", NULL };
    170  1.5  simonb static struct optname intr_optname = { "intr", NULL };
    171  1.5  simonb static struct optname wordwrap_optname = { "wordwrap", NULL };
    172  1.5  simonb static struct optname show_preproc_error_optname = { "show-preproc-errors", NULL };
    173  1.5  simonb static struct optname proc_backspace_optname = { "proc-backspace", NULL };
    174  1.5  simonb static struct optname proc_tab_optname = { "proc-tab", NULL };
    175  1.5  simonb static struct optname proc_return_optname = { "proc-return", NULL };
    176  1.5  simonb #if LESSTEST
    177  1.5  simonb static struct optname ttyin_name_optname = { "tty",              NULL };
    178  1.5  simonb #endif /*LESSTEST*/
    179  1.1    tron 
    180  1.1    tron 
    181  1.1    tron /*
    182  1.1    tron  * Table of all options and their semantics.
    183  1.1    tron  *
    184  1.1    tron  * For BOOL and TRIPLE options, odesc[0], odesc[1], odesc[2] are
    185  1.1    tron  * the description of the option when set to 0, 1 or 2, respectively.
    186  1.1    tron  * For NUMBER options, odesc[0] is the prompt to use when entering
    187  1.1    tron  * a new value, and odesc[1] is the description, which should contain
    188  1.1    tron  * one %d which is replaced by the value of the number.
    189  1.1    tron  * For STRING options, odesc[0] is the prompt to use when entering
    190  1.1    tron  * a new value, and odesc[1], if not NULL, is the set of characters
    191  1.1    tron  * that are valid in the string.
    192  1.1    tron  */
    193  1.1    tron static struct loption option[] =
    194  1.1    tron {
    195  1.1    tron 	{ 'a', &a_optname,
    196  1.1    tron 		TRIPLE, OPT_ONPLUS, &how_search, NULL,
    197  1.1    tron 		{
    198  1.1    tron 			"Search includes displayed screen",
    199  1.1    tron 			"Search skips displayed screen",
    200  1.1    tron 			"Search includes all of displayed screen"
    201  1.1    tron 		}
    202  1.1    tron 	},
    203  1.1    tron 
    204  1.1    tron 	{ 'b', &b_optname,
    205  1.1    tron 		NUMBER|INIT_HANDLER, 64, &bufspace, opt_b,
    206  1.1    tron 		{
    207  1.1    tron 			"Max buffer space per file (K): ",
    208  1.1    tron 			"Max buffer space per file: %dK",
    209  1.1    tron 			NULL
    210  1.1    tron 		}
    211  1.1    tron 	},
    212  1.1    tron 	{ 'B', &B__optname,
    213  1.1    tron 		BOOL, OPT_ON, &autobuf, NULL,
    214  1.1    tron 		{
    215  1.1    tron 			"Don't automatically allocate buffers",
    216  1.1    tron 			"Automatically allocate buffers when needed",
    217  1.1    tron 			NULL
    218  1.1    tron 		}
    219  1.1    tron 	},
    220  1.1    tron 	{ 'c', &c_optname,
    221  1.1    tron 		TRIPLE, OPT_OFF, &top_scroll, NULL,
    222  1.1    tron 		{
    223  1.1    tron 			"Repaint by scrolling from bottom of screen",
    224  1.1    tron 			"Repaint by painting from top of screen",
    225  1.1    tron 			"Repaint by painting from top of screen"
    226  1.1    tron 		}
    227  1.1    tron 	},
    228  1.3    tron #if 1
    229  1.1    tron 	{ 'd', &d_optname,
    230  1.3    tron 		BOOL, OPT_OFF, &be_helpful, NULL,
    231  1.3    tron 		{ "Be less helpful in prompts",
    232  1.3    tron 		"Be helpful in prompts",
    233  1.3    tron 		NULL }
    234  1.3    tron 	},
    235  1.3    tron #endif
    236  1.3    tron 	{ -1, &d_optname,
    237  1.1    tron 		BOOL|NO_TOGGLE, OPT_OFF, &know_dumb, NULL,
    238  1.1    tron 		{
    239  1.1    tron 			"Assume intelligent terminal",
    240  1.1    tron 			"Assume dumb terminal",
    241  1.1    tron 			NULL
    242  1.1    tron 		}
    243  1.1    tron 	},
    244  1.1    tron 	{ 'D', &D__optname,
    245  1.1    tron 		STRING|REPAINT|NO_QUERY, 0, NULL, opt_D,
    246  1.1    tron 		{
    247  1.1    tron 			"color desc: ",
    248  1.5  simonb 			NULL,
    249  1.1    tron 			NULL
    250  1.1    tron 		}
    251  1.1    tron 	},
    252  1.1    tron 	{ 'e', &e_optname,
    253  1.1    tron 		TRIPLE, OPT_OFF, &quit_at_eof, NULL,
    254  1.1    tron 		{
    255  1.1    tron 			"Don't quit at end-of-file",
    256  1.1    tron 			"Quit at end-of-file",
    257  1.1    tron 			"Quit immediately at end-of-file"
    258  1.1    tron 		}
    259  1.1    tron 	},
    260  1.1    tron 	{ 'f', &f_optname,
    261  1.1    tron 		BOOL, OPT_OFF, &force_open, NULL,
    262  1.1    tron 		{
    263  1.1    tron 			"Open only regular files",
    264  1.1    tron 			"Open even non-regular files",
    265  1.1    tron 			NULL
    266  1.1    tron 		}
    267  1.1    tron 	},
    268  1.1    tron 	{ 'F', &F__optname,
    269  1.1    tron 		BOOL, OPT_OFF, &quit_if_one_screen, NULL,
    270  1.1    tron 		{
    271  1.1    tron 			"Don't quit if end-of-file on first screen",
    272  1.1    tron 			"Quit if end-of-file on first screen",
    273  1.1    tron 			NULL
    274  1.1    tron 		}
    275  1.1    tron 	},
    276  1.1    tron #if HILITE_SEARCH
    277  1.1    tron 	{ 'g', &g_optname,
    278  1.1    tron 		TRIPLE|HL_REPAINT, OPT_ONPLUS, &hilite_search, NULL,
    279  1.1    tron 		{
    280  1.1    tron 			"Don't highlight search matches",
    281  1.1    tron 			"Highlight matches for previous search only",
    282  1.1    tron 			"Highlight all matches for previous search pattern",
    283  1.1    tron 		}
    284  1.1    tron 	},
    285  1.1    tron #endif
    286  1.1    tron 	{ 'h', &h_optname,
    287  1.1    tron 		NUMBER, -1, &back_scroll, NULL,
    288  1.1    tron 		{
    289  1.1    tron 			"Backwards scroll limit: ",
    290  1.1    tron 			"Backwards scroll limit is %d lines",
    291  1.1    tron 			NULL
    292  1.1    tron 		}
    293  1.1    tron 	},
    294  1.1    tron 	{ 'i', &i_optname,
    295  1.1    tron 		TRIPLE|HL_REPAINT, OPT_OFF, &caseless, opt_i,
    296  1.1    tron 		{
    297  1.1    tron 			"Case is significant in searches",
    298  1.1    tron 			"Ignore case in searches",
    299  1.1    tron 			"Ignore case in searches and in patterns"
    300  1.1    tron 		}
    301  1.1    tron 	},
    302  1.1    tron 	{ 'j', &j_optname,
    303  1.1    tron 		STRING, 0, NULL, opt_j,
    304  1.1    tron 		{
    305  1.1    tron 			"Target line: ",
    306  1.1    tron 			"0123456789.-",
    307  1.1    tron 			NULL
    308  1.1    tron 		}
    309  1.1    tron 	},
    310  1.1    tron 	{ 'J', &J__optname,
    311  1.1    tron 		BOOL|REPAINT, OPT_OFF, &status_col, NULL,
    312  1.1    tron 		{
    313  1.1    tron 			"Don't display a status column",
    314  1.1    tron 			"Display a status column",
    315  1.1    tron 			NULL
    316  1.1    tron 		}
    317  1.1    tron 	},
    318  1.1    tron #if USERFILE
    319  1.1    tron 	{ 'k', &k_optname,
    320  1.1    tron 		STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_k,
    321  1.1    tron 		{ NULL, NULL, NULL }
    322  1.1    tron 	},
    323  1.5  simonb #if HAVE_LESSKEYSRC
    324  1.5  simonb 	{ OLETTER_NONE, &ks_optname,
    325  1.5  simonb 		STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_ks,
    326  1.5  simonb 		{ NULL, NULL, NULL }
    327  1.5  simonb 	},
    328  1.5  simonb #endif /* HAVE_LESSKEYSRC */
    329  1.1    tron #endif
    330  1.1    tron 	{ 'K', &K__optname,
    331  1.1    tron 		BOOL, OPT_OFF, &quit_on_intr, NULL,
    332  1.1    tron 		{
    333  1.1    tron 			"Interrupt (ctrl-C) returns to prompt",
    334  1.1    tron 			"Interrupt (ctrl-C) exits less",
    335  1.1    tron 			NULL
    336  1.1    tron 		}
    337  1.1    tron 	},
    338  1.1    tron 	{ 'L', &L__optname,
    339  1.1    tron 		BOOL, OPT_ON, &use_lessopen, NULL,
    340  1.1    tron 		{
    341  1.1    tron 			"Don't use the LESSOPEN filter",
    342  1.1    tron 			"Use the LESSOPEN filter",
    343  1.1    tron 			NULL
    344  1.1    tron 		}
    345  1.1    tron 	},
    346  1.1    tron 	{ 'm', &m_optname,
    347  1.1    tron 		TRIPLE, OPT_OFF, &pr_type, NULL,
    348  1.1    tron 		{
    349  1.1    tron 			"Short prompt",
    350  1.1    tron 			"Medium prompt",
    351  1.1    tron 			"Long prompt"
    352  1.1    tron 		}
    353  1.1    tron 	},
    354  1.1    tron 	{ 'n', &n_optname,
    355  1.1    tron 		TRIPLE|REPAINT, OPT_ON, &linenums, NULL,
    356  1.1    tron 		{
    357  1.1    tron 			"Don't use line numbers",
    358  1.1    tron 			"Use line numbers",
    359  1.1    tron 			"Constantly display line numbers"
    360  1.1    tron 		}
    361  1.1    tron 	},
    362  1.1    tron #if LOGFILE
    363  1.1    tron 	{ 'o', &o_optname,
    364  1.1    tron 		STRING, 0, NULL, opt_o,
    365  1.1    tron 		{ "log file: ", NULL, NULL }
    366  1.1    tron 	},
    367  1.1    tron 	{ 'O', &O__optname,
    368  1.1    tron 		STRING, 0, NULL, opt__O,
    369  1.1    tron 		{ "Log file: ", NULL, NULL }
    370  1.1    tron 	},
    371  1.1    tron #endif
    372  1.1    tron 	{ 'p', &p_optname,
    373  1.1    tron 		STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_p,
    374  1.1    tron 		{ NULL, NULL, NULL }
    375  1.1    tron 	},
    376  1.1    tron 	{ 'P', &P__optname,
    377  1.1    tron 		STRING, 0, NULL, opt__P,
    378  1.1    tron 		{ "prompt: ", NULL, NULL }
    379  1.1    tron 	},
    380  1.1    tron 	{ 'q', &q_optname,
    381  1.1    tron 		TRIPLE, OPT_OFF, &quiet, NULL,
    382  1.1    tron 		{
    383  1.1    tron 			"Ring the bell for errors AND at eof/bof",
    384  1.1    tron 			"Ring the bell for errors but not at eof/bof",
    385  1.1    tron 			"Never ring the bell"
    386  1.1    tron 		}
    387  1.1    tron 	},
    388  1.1    tron 	{ 'r', &r_optname,
    389  1.1    tron 		TRIPLE|REPAINT, OPT_OFF, &ctldisp, NULL,
    390  1.1    tron 		{
    391  1.1    tron 			"Display control characters as ^X",
    392  1.5  simonb 			"Display control characters directly (not recommended)",
    393  1.5  simonb 			"Display ANSI sequences directly, other control characters as ^X"
    394  1.1    tron 		}
    395  1.1    tron 	},
    396  1.1    tron 	{ 's', &s_optname,
    397  1.1    tron 		BOOL|REPAINT, OPT_OFF, &squeeze, NULL,
    398  1.1    tron 		{
    399  1.1    tron 			"Display all blank lines",
    400  1.1    tron 			"Squeeze multiple blank lines",
    401  1.1    tron 			NULL
    402  1.1    tron 		}
    403  1.1    tron 	},
    404  1.1    tron 	{ 'S', &S__optname,
    405  1.1    tron 		BOOL|REPAINT, OPT_OFF, &chopline, NULL,
    406  1.1    tron 		{
    407  1.1    tron 			"Fold long lines",
    408  1.1    tron 			"Chop long lines",
    409  1.1    tron 			NULL
    410  1.1    tron 		}
    411  1.1    tron 	},
    412  1.1    tron #if TAGS
    413  1.1    tron 	{ 't', &t_optname,
    414  1.1    tron 		STRING|NO_QUERY, 0, NULL, opt_t,
    415  1.1    tron 		{ "tag: ", NULL, NULL }
    416  1.1    tron 	},
    417  1.1    tron 	{ 'T', &T__optname,
    418  1.1    tron 		STRING, 0, NULL, opt__T,
    419  1.1    tron 		{ "tags file: ", NULL, NULL }
    420  1.1    tron 	},
    421  1.1    tron #endif
    422  1.1    tron 	{ 'u', &u_optname,
    423  1.5  simonb 		TRIPLE|REPAINT|HL_REPAINT, OPT_OFF, &bs_mode, NULL,
    424  1.1    tron 		{
    425  1.1    tron 			"Display underlined text in underline mode",
    426  1.1    tron 			"Backspaces cause overstrike",
    427  1.1    tron 			"Print backspace as ^H"
    428  1.1    tron 		}
    429  1.1    tron 	},
    430  1.1    tron 	{ 'V', &V__optname,
    431  1.1    tron 		NOVAR, 0, NULL, opt__V,
    432  1.1    tron 		{ NULL, NULL, NULL }
    433  1.1    tron 	},
    434  1.1    tron 	{ 'w', &w_optname,
    435  1.1    tron 		TRIPLE|REPAINT, OPT_OFF, &show_attn, NULL,
    436  1.1    tron 		{
    437  1.1    tron 			"Don't highlight first unread line",
    438  1.1    tron 			"Highlight first unread line after forward-screen",
    439  1.1    tron 			"Highlight first unread line after any forward movement",
    440  1.1    tron 		}
    441  1.1    tron 	},
    442  1.1    tron 	{ 'x', &x_optname,
    443  1.1    tron 		STRING|REPAINT, 0, NULL, opt_x,
    444  1.1    tron 		{
    445  1.1    tron 			"Tab stops: ",
    446  1.1    tron 			"0123456789,",
    447  1.1    tron 			NULL
    448  1.1    tron 		}
    449  1.1    tron 	},
    450  1.1    tron 	{ 'X', &X__optname,
    451  1.1    tron 		BOOL|NO_TOGGLE, OPT_OFF, &no_init, NULL,
    452  1.1    tron 		{
    453  1.1    tron 			"Send init/deinit strings to terminal",
    454  1.1    tron 			"Don't use init/deinit strings",
    455  1.1    tron 			NULL
    456  1.1    tron 		}
    457  1.1    tron 	},
    458  1.1    tron 	{ 'y', &y_optname,
    459  1.1    tron 		NUMBER, -1, &forw_scroll, NULL,
    460  1.1    tron 		{
    461  1.1    tron 			"Forward scroll limit: ",
    462  1.1    tron 			"Forward scroll limit is %d lines",
    463  1.1    tron 			NULL
    464  1.1    tron 		}
    465  1.1    tron 	},
    466  1.1    tron 	{ 'z', &z_optname,
    467  1.1    tron 		NUMBER, -1, &swindow, NULL,
    468  1.1    tron 		{
    469  1.1    tron 			"Scroll window size: ",
    470  1.1    tron 			"Scroll window size is %d lines",
    471  1.1    tron 			NULL
    472  1.1    tron 		}
    473  1.1    tron 	},
    474  1.1    tron 	{ '"', &quote_optname,
    475  1.1    tron 		STRING, 0, NULL, opt_quote,
    476  1.1    tron 		{ "quotes: ", NULL, NULL }
    477  1.1    tron 	},
    478  1.1    tron 	{ '~', &tilde_optname,
    479  1.1    tron 		BOOL|REPAINT, OPT_ON, &twiddle, NULL,
    480  1.1    tron 		{
    481  1.1    tron 			"Don't show tildes after end of file",
    482  1.1    tron 			"Show tildes after end of file",
    483  1.1    tron 			NULL
    484  1.1    tron 		}
    485  1.1    tron 	},
    486  1.1    tron 	{ '?', &query_optname,
    487  1.1    tron 		NOVAR, 0, NULL, opt_query,
    488  1.1    tron 		{ NULL, NULL, NULL }
    489  1.1    tron 	},
    490  1.1    tron 	{ '#', &pound_optname,
    491  1.1    tron 		STRING, 0, NULL, opt_shift,
    492  1.1    tron 		{
    493  1.1    tron 			"Horizontal shift: ",
    494  1.1    tron 			"0123456789.",
    495  1.1    tron 			NULL
    496  1.1    tron 		}
    497  1.1    tron 	},
    498  1.1    tron 	{ OLETTER_NONE, &keypad_optname,
    499  1.1    tron 		BOOL|NO_TOGGLE, OPT_OFF, &no_keypad, NULL,
    500  1.1    tron 		{
    501  1.1    tron 			"Use keypad mode",
    502  1.1    tron 			"Don't use keypad mode",
    503  1.1    tron 			NULL
    504  1.1    tron 		}
    505  1.1    tron 	},
    506  1.1    tron 	{ OLETTER_NONE, &oldbot_optname,
    507  1.1    tron 		BOOL, OPT_OFF, &oldbot, NULL,
    508  1.1    tron 		{
    509  1.1    tron 			"Use new bottom of screen behavior",
    510  1.1    tron 			"Use old bottom of screen behavior",
    511  1.1    tron 			NULL
    512  1.1    tron 		}
    513  1.1    tron 	},
    514  1.1    tron 	{ OLETTER_NONE, &follow_optname,
    515  1.1    tron 		BOOL, FOLLOW_DESC, &follow_mode, NULL,
    516  1.1    tron 		{
    517  1.1    tron 			"F command follows file descriptor",
    518  1.1    tron 			"F command follows file name",
    519  1.1    tron 			NULL
    520  1.1    tron 		}
    521  1.1    tron 	},
    522  1.4    tron 	{ OLETTER_NONE, &use_backslash_optname,
    523  1.4    tron 		BOOL, OPT_OFF, &opt_use_backslash, NULL,
    524  1.4    tron 		{
    525  1.4    tron 			"Use backslash escaping in command line parameters",
    526  1.4    tron 			"Don't use backslash escaping in command line parameters",
    527  1.4    tron 			NULL
    528  1.4    tron 		}
    529  1.4    tron 	},
    530  1.5  simonb 	{ OLETTER_NONE, &rscroll_optname,
    531  1.5  simonb 		STRING|REPAINT|INIT_HANDLER, 0, NULL, opt_rscroll,
    532  1.5  simonb 		{ "rscroll character: ", NULL, NULL }
    533  1.5  simonb 	},
    534  1.5  simonb 	{ OLETTER_NONE, &nohistdups_optname,
    535  1.5  simonb 		BOOL, OPT_OFF, &no_hist_dups, NULL,
    536  1.5  simonb 		{
    537  1.5  simonb 			"Allow duplicates in history list",
    538  1.5  simonb 			"Remove duplicates from history list",
    539  1.5  simonb 			NULL
    540  1.5  simonb 		}
    541  1.5  simonb 	},
    542  1.5  simonb 	{ OLETTER_NONE, &mousecap_optname,
    543  1.5  simonb 		TRIPLE, OPT_OFF, &mousecap, opt_mousecap,
    544  1.5  simonb 		{
    545  1.5  simonb 			"Ignore mouse input",
    546  1.5  simonb 			"Use the mouse for scrolling",
    547  1.5  simonb 			"Use the mouse for scrolling (reverse)"
    548  1.5  simonb 		}
    549  1.5  simonb 	},
    550  1.5  simonb 	{ OLETTER_NONE, &wheel_lines_optname,
    551  1.5  simonb 		NUMBER|INIT_HANDLER, 0, &wheel_lines, opt_wheel_lines,
    552  1.5  simonb 		{
    553  1.5  simonb 			"Lines to scroll on mouse wheel: ",
    554  1.5  simonb 			"Scroll %d line(s) on mouse wheel",
    555  1.5  simonb 			NULL
    556  1.5  simonb 		}
    557  1.5  simonb 	},
    558  1.5  simonb 	{ OLETTER_NONE, &perma_marks_optname,
    559  1.5  simonb 		BOOL, OPT_OFF, &perma_marks, NULL,
    560  1.5  simonb 		{
    561  1.5  simonb 			"Don't save marks in history file",
    562  1.5  simonb 			"Save marks in history file",
    563  1.5  simonb 			NULL
    564  1.5  simonb 		}
    565  1.5  simonb 	},
    566  1.5  simonb 	{ OLETTER_NONE, &linenum_width_optname,
    567  1.5  simonb 		NUMBER|REPAINT, MIN_LINENUM_WIDTH, &linenum_width, opt_linenum_width,
    568  1.5  simonb 		{
    569  1.5  simonb 			"Line number width: ",
    570  1.5  simonb 			"Line number width is %d chars",
    571  1.5  simonb 			NULL
    572  1.5  simonb 		}
    573  1.5  simonb 	},
    574  1.5  simonb 	{ OLETTER_NONE, &status_col_width_optname,
    575  1.5  simonb 		NUMBER|REPAINT, 2, &status_col_width, opt_status_col_width,
    576  1.5  simonb 		{
    577  1.5  simonb 			"Status column width: ",
    578  1.5  simonb 			"Status column width is %d chars",
    579  1.5  simonb 			NULL
    580  1.5  simonb 		}
    581  1.5  simonb 	},
    582  1.5  simonb 	{ OLETTER_NONE, &incr_search_optname,
    583  1.5  simonb 		BOOL, OPT_OFF, &incr_search, NULL,
    584  1.5  simonb 		{
    585  1.5  simonb 			"Incremental search is off",
    586  1.5  simonb 			"Incremental search is on",
    587  1.5  simonb 			NULL
    588  1.5  simonb 		}
    589  1.5  simonb 	},
    590  1.5  simonb 	{ OLETTER_NONE, &use_color_optname,
    591  1.5  simonb 		BOOL|REPAINT, OPT_OFF, &use_color, NULL,
    592  1.5  simonb 		{
    593  1.5  simonb 			"Don't use color",
    594  1.5  simonb 			"Use color",
    595  1.5  simonb 			NULL
    596  1.5  simonb 		}
    597  1.5  simonb 	},
    598  1.5  simonb 	{ OLETTER_NONE, &want_filesize_optname,
    599  1.5  simonb 		BOOL|REPAINT, OPT_OFF, &want_filesize, opt_filesize,
    600  1.5  simonb 		{
    601  1.5  simonb 			"Don't get size of each file",
    602  1.5  simonb 			"Get size of each file",
    603  1.5  simonb 			NULL
    604  1.5  simonb 		}
    605  1.5  simonb 	},
    606  1.5  simonb 	{ OLETTER_NONE, &status_line_optname,
    607  1.5  simonb 		BOOL|REPAINT, OPT_OFF, &status_line, NULL,
    608  1.5  simonb 		{
    609  1.5  simonb 			"Don't color each line with its status column color",
    610  1.5  simonb 			"Color each line with its status column color",
    611  1.5  simonb 			NULL
    612  1.5  simonb 		}
    613  1.5  simonb 	},
    614  1.5  simonb 	{ OLETTER_NONE, &header_optname,
    615  1.5  simonb 		STRING|REPAINT, 0, NULL, opt_header,
    616  1.5  simonb 		{
    617  1.5  simonb 			"Header lines: ",
    618  1.5  simonb 			NULL,
    619  1.5  simonb 			NULL
    620  1.5  simonb 		}
    621  1.5  simonb 	},
    622  1.5  simonb 	{ OLETTER_NONE, &nonum_headers_optname,
    623  1.5  simonb 		BOOL|REPAINT, 0, &nonum_headers, NULL,
    624  1.5  simonb 		{
    625  1.5  simonb 			"Number header lines",
    626  1.5  simonb 			"Don't number header lines",
    627  1.5  simonb 			NULL
    628  1.5  simonb 		}
    629  1.5  simonb 	},
    630  1.5  simonb 	{ OLETTER_NONE, &nosearch_headers_optname,
    631  1.5  simonb 		BOOL|HL_REPAINT, 0, &nosearch_headers, NULL,
    632  1.5  simonb 		{
    633  1.5  simonb 			"Search includes header lines",
    634  1.5  simonb 			"Search does not include header lines",
    635  1.5  simonb 			NULL
    636  1.5  simonb 		}
    637  1.5  simonb 	},
    638  1.5  simonb 	{ OLETTER_NONE, &redraw_on_quit_optname,
    639  1.5  simonb 		BOOL, OPT_OFF, &redraw_on_quit, NULL,
    640  1.5  simonb 		{
    641  1.5  simonb 			"Don't redraw screen when quitting",
    642  1.5  simonb 			"Redraw last screen when quitting",
    643  1.5  simonb 			NULL
    644  1.5  simonb 		}
    645  1.5  simonb 	},
    646  1.5  simonb 	{ OLETTER_NONE, &search_type_optname,
    647  1.5  simonb 		STRING, 0, NULL, opt_search_type,
    648  1.5  simonb 		{
    649  1.5  simonb 			"Search options: ",
    650  1.5  simonb 			NULL,
    651  1.5  simonb 			NULL
    652  1.5  simonb 		}
    653  1.5  simonb 	},
    654  1.5  simonb 	{ OLETTER_NONE, &exit_F_on_close_optname,
    655  1.5  simonb 		BOOL, OPT_OFF, &exit_F_on_close, NULL,
    656  1.5  simonb 		{
    657  1.5  simonb 			"Don't exit F command when input closes",
    658  1.5  simonb 			"Exit F command when input closes",
    659  1.5  simonb 			NULL
    660  1.5  simonb 		}
    661  1.5  simonb 	},
    662  1.5  simonb 	{ OLETTER_NONE, &no_vbell_optname,
    663  1.5  simonb 		BOOL, OPT_OFF, &no_vbell, NULL,
    664  1.5  simonb 		{
    665  1.5  simonb 			"Display visual bell",
    666  1.5  simonb 			"Don't display visual bell",
    667  1.5  simonb 			NULL
    668  1.5  simonb 		}
    669  1.5  simonb 	},
    670  1.5  simonb 	{ OLETTER_NONE, &modelines_optname,
    671  1.5  simonb 		NUMBER, 0, &modelines, NULL,
    672  1.5  simonb 		{
    673  1.5  simonb 			"Lines to read looking for modelines: ",
    674  1.5  simonb 			"Read %d lines looking for modelines",
    675  1.5  simonb 			NULL
    676  1.5  simonb 		}
    677  1.5  simonb 	},
    678  1.5  simonb 	{ OLETTER_NONE, &intr_optname,
    679  1.5  simonb 		STRING, 0, NULL, opt_intr,
    680  1.5  simonb 		{ "interrupt character: ", NULL, NULL }
    681  1.5  simonb 	},
    682  1.5  simonb 	{ OLETTER_NONE, &wordwrap_optname,
    683  1.5  simonb 		BOOL|REPAINT, OPT_OFF, &wordwrap, NULL,
    684  1.5  simonb 		{
    685  1.5  simonb 			"Wrap lines at any character",
    686  1.5  simonb 			"Wrap lines at spaces",
    687  1.5  simonb 			NULL
    688  1.5  simonb 		}
    689  1.5  simonb 	},
    690  1.5  simonb 	{ OLETTER_NONE, &show_preproc_error_optname,
    691  1.5  simonb 		BOOL, OPT_OFF, &show_preproc_error, NULL,
    692  1.5  simonb 		{
    693  1.5  simonb 			"Don't show error message if preprocessor fails",
    694  1.5  simonb 			"Show error message if preprocessor fails",
    695  1.5  simonb 			NULL
    696  1.5  simonb 		}
    697  1.5  simonb 	},
    698  1.5  simonb 	{ OLETTER_NONE, &proc_backspace_optname,
    699  1.5  simonb 		TRIPLE|REPAINT|HL_REPAINT, OPT_OFF, &proc_backspace, NULL,
    700  1.5  simonb 		{
    701  1.5  simonb 			"Backspace handling is specified by the -U option",
    702  1.5  simonb 			"Display underline text in underline mode",
    703  1.5  simonb 			"Print backspaces as ^H"
    704  1.5  simonb 		}
    705  1.5  simonb 	},
    706  1.5  simonb 	{ OLETTER_NONE, &proc_tab_optname,
    707  1.5  simonb 		TRIPLE|REPAINT|HL_REPAINT, OPT_OFF, &proc_tab, NULL,
    708  1.5  simonb 		{
    709  1.5  simonb 			"Tab handling is specified by the -U option",
    710  1.5  simonb 			"Expand tabs to spaces",
    711  1.5  simonb 			"Print tabs as ^I"
    712  1.5  simonb 		}
    713  1.5  simonb 	},
    714  1.5  simonb 	{ OLETTER_NONE, &proc_return_optname,
    715  1.5  simonb 		TRIPLE|REPAINT|HL_REPAINT, OPT_OFF, &proc_return, NULL,
    716  1.5  simonb 		{
    717  1.5  simonb 			"Carriage return handling is specified by the -U option",
    718  1.5  simonb 			"Delete carriage return before newline",
    719  1.5  simonb 			"Print carriage return as ^M"
    720  1.5  simonb 		}
    721  1.5  simonb 	},
    722  1.5  simonb #if LESSTEST
    723  1.5  simonb 	{ OLETTER_NONE, &ttyin_name_optname,
    724  1.5  simonb 		STRING|NO_TOGGLE, 0, NULL, opt_ttyin_name,
    725  1.5  simonb 		{
    726  1.5  simonb 			NULL,
    727  1.5  simonb 			NULL,
    728  1.5  simonb 			NULL
    729  1.5  simonb 		}
    730  1.5  simonb 	},
    731  1.5  simonb #endif /*LESSTEST*/
    732  1.1    tron 	{ '\0', NULL, NOVAR, 0, NULL, NULL, { NULL, NULL, NULL } }
    733  1.1    tron };
    734  1.1    tron 
    735  1.1    tron 
    736  1.1    tron /*
    737  1.1    tron  * Initialize each option to its default value.
    738  1.1    tron  */
    739  1.5  simonb public void init_option(void)
    740  1.1    tron {
    741  1.5  simonb 	struct loption *o;
    742  1.1    tron 	char *p;
    743  1.1    tron 
    744  1.1    tron 	p = lgetenv("LESS_IS_MORE");
    745  1.5  simonb 	if (!isnullenv(p))
    746  1.1    tron 		less_is_more = 1;
    747  1.1    tron 
    748  1.1    tron 	for (o = option;  o->oletter != '\0';  o++)
    749  1.1    tron 	{
    750  1.1    tron 		/*
    751  1.1    tron 		 * Set each variable to its default.
    752  1.1    tron 		 */
    753  1.1    tron 		if (o->ovar != NULL)
    754  1.1    tron 			*(o->ovar) = o->odefault;
    755  1.1    tron 		if (o->otype & INIT_HANDLER)
    756  1.1    tron 			(*(o->ofunc))(INIT, (char *) NULL);
    757  1.1    tron 	}
    758  1.1    tron }
    759  1.1    tron 
    760  1.1    tron /*
    761  1.1    tron  * Find an option in the option table, given its option letter.
    762  1.1    tron  */
    763  1.5  simonb public struct loption * findopt(int c)
    764  1.1    tron {
    765  1.5  simonb 	struct loption *o;
    766  1.1    tron 
    767  1.1    tron 	for (o = option;  o->oletter != '\0';  o++)
    768  1.1    tron 	{
    769  1.1    tron 		if (o->oletter == c)
    770  1.1    tron 			return (o);
    771  1.1    tron 		if ((o->otype & TRIPLE) && ASCII_TO_UPPER(o->oletter) == c)
    772  1.1    tron 			return (o);
    773  1.1    tron 	}
    774  1.1    tron 	return (NULL);
    775  1.1    tron }
    776  1.1    tron 
    777  1.1    tron /*
    778  1.1    tron  *
    779  1.1    tron  */
    780  1.5  simonb static int is_optchar(char c)
    781  1.1    tron {
    782  1.1    tron 	if (ASCII_IS_UPPER(c))
    783  1.1    tron 		return 1;
    784  1.1    tron 	if (ASCII_IS_LOWER(c))
    785  1.1    tron 		return 1;
    786  1.1    tron 	if (c == '-')
    787  1.1    tron 		return 1;
    788  1.1    tron 	return 0;
    789  1.1    tron }
    790  1.1    tron 
    791  1.1    tron /*
    792  1.1    tron  * Find an option in the option table, given its option name.
    793  1.1    tron  * p_optname is the (possibly partial) name to look for, and
    794  1.1    tron  * is updated to point after the matched name.
    795  1.1    tron  * p_oname if non-NULL is set to point to the full option name.
    796  1.1    tron  */
    797  1.5  simonb public struct loption * findopt_name(char **p_optname, char **p_oname, int *p_err)
    798  1.1    tron {
    799  1.1    tron 	char *optname = *p_optname;
    800  1.5  simonb 	struct loption *o;
    801  1.5  simonb 	struct optname *oname;
    802  1.5  simonb 	int len;
    803  1.1    tron 	int uppercase;
    804  1.1    tron 	struct loption *maxo = NULL;
    805  1.1    tron 	struct optname *maxoname = NULL;
    806  1.1    tron 	int maxlen = 0;
    807  1.1    tron 	int ambig = 0;
    808  1.1    tron 	int exact = 0;
    809  1.1    tron 
    810  1.1    tron 	/*
    811  1.1    tron 	 * Check all options.
    812  1.1    tron 	 */
    813  1.1    tron 	for (o = option;  o->oletter != '\0';  o++)
    814  1.1    tron 	{
    815  1.1    tron 		/*
    816  1.1    tron 		 * Check all names for this option.
    817  1.1    tron 		 */
    818  1.1    tron 		for (oname = o->onames;  oname != NULL;  oname = oname->onext)
    819  1.1    tron 		{
    820  1.1    tron 			/*
    821  1.1    tron 			 * Try normal match first (uppercase == 0),
    822  1.1    tron 			 * then, then if it's a TRIPLE option,
    823  1.1    tron 			 * try uppercase match (uppercase == 1).
    824  1.1    tron 			 */
    825  1.1    tron 			for (uppercase = 0;  uppercase <= 1;  uppercase++)
    826  1.1    tron 			{
    827  1.1    tron 				len = sprefix(optname, oname->oname, uppercase);
    828  1.1    tron 				if (len <= 0 || is_optchar(optname[len]))
    829  1.1    tron 				{
    830  1.1    tron 					/*
    831  1.1    tron 					 * We didn't use all of the option name.
    832  1.1    tron 					 */
    833  1.1    tron 					continue;
    834  1.1    tron 				}
    835  1.1    tron 				if (!exact && len == maxlen)
    836  1.1    tron 					/*
    837  1.1    tron 					 * Already had a partial match,
    838  1.1    tron 					 * and now there's another one that
    839  1.1    tron 					 * matches the same length.
    840  1.1    tron 					 */
    841  1.1    tron 					ambig = 1;
    842  1.1    tron 				else if (len > maxlen)
    843  1.1    tron 				{
    844  1.1    tron 					/*
    845  1.1    tron 					 * Found a better match than
    846  1.1    tron 					 * the one we had.
    847  1.1    tron 					 */
    848  1.1    tron 					maxo = o;
    849  1.1    tron 					maxoname = oname;
    850  1.1    tron 					maxlen = len;
    851  1.1    tron 					ambig = 0;
    852  1.1    tron 					exact = (len == (int)strlen(oname->oname));
    853  1.1    tron 				}
    854  1.1    tron 				if (!(o->otype & TRIPLE))
    855  1.1    tron 					break;
    856  1.1    tron 			}
    857  1.1    tron 		}
    858  1.1    tron 	}
    859  1.1    tron 	if (ambig)
    860  1.1    tron 	{
    861  1.1    tron 		/*
    862  1.1    tron 		 * Name matched more than one option.
    863  1.1    tron 		 */
    864  1.1    tron 		if (p_err != NULL)
    865  1.1    tron 			*p_err = OPT_AMBIG;
    866  1.1    tron 		return (NULL);
    867  1.1    tron 	}
    868  1.1    tron 	*p_optname = optname + maxlen;
    869  1.1    tron 	if (p_oname != NULL)
    870  1.1    tron 		*p_oname = maxoname == NULL ? NULL : maxoname->oname;
    871  1.1    tron 	return (maxo);
    872  1.1    tron }
    873