]>
diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/miscellany/less-177/lesskey.c
2 * lesskey [-o output] [input]
5 * If no input file is specified, standard input is used.
6 * If no output file is specified, $HOME/.less is used.
8 * The .less file is used to specify (to "less") user-defined
9 * key bindings. Basically any sequence of 1 to MAX_CMDLEN
10 * keystrokes may be bound to an existing less function.
12 * The input file is an ascii file consisting of a
13 * sequence of lines of the form:
14 * string <whitespace> action [chars] <newline>
16 * "string" is a sequence of command characters which form
17 * the new user-defined command. The command
19 * 1. The actual character itself.
20 * 2. A character preceded by ^ to specify a
21 * control character (e.g. ^X means control-X).
22 * 3. Any character (other than an octal digit) preceded by
23 * a \ to specify the character itself (characters which
24 * must be preceded by \ include ^, \, and whitespace.
25 * 4. A backslash followed by one to three octal digits
26 * to specify a character by its octal value.
27 * "action" is the name of a "less" action, from the table below.
28 * "chars" is an optional sequence of characters which is treated
29 * as keyboard input after the command is executed.
31 * Blank lines and lines which start with # are ignored.
34 * The output file is a non-ascii file, consisting of
35 * zero or more byte sequences of the form:
38 * string <0> <action|A_EXTRA> chars <0>
40 * "string" is the command string.
41 * "<0>" is one null byte.
42 * "<action>" is one byte containing the action code (the A_xxx value).
43 * If action is ORed with A_EXTRA, the action byte is followed
44 * by the null-terminated "chars" string.
51 char usertable
[MAX_USERCMD
];
59 "back-bracket", A_B_BRACKET
,
60 "back-line", A_B_LINE
,
61 "back-line-force", A_BF_LINE
,
62 "back-screen", A_B_SCREEN
,
63 "back-scroll", A_B_SCROLL
,
64 "back-search", A_B_SEARCH
,
65 "back-window", A_B_WINDOW
,
67 "display-flag", A_DISP_OPTION
,
68 "display-option", A_DISP_OPTION
,
71 "first-cmd", A_FIRSTCMD
,
72 "firstcmd", A_FIRSTCMD
,
73 "flush-repaint", A_FREPAINT
,
74 "forw-bracket", A_F_BRACKET
,
75 "forw-forever", A_F_FOREVER
,
76 "forw-line", A_F_LINE
,
77 "forw-line-force", A_FF_LINE
,
78 "forw-screen", A_F_SCREEN
,
79 "forw-scroll", A_F_SCROLL
,
80 "forw-search", A_F_SEARCH
,
81 "forw-window", A_F_WINDOW
,
83 "goto-line", A_GOLINE
,
84 "goto-mark", A_GOMARK
,
86 "index-file", A_INDEX_FILE
,
87 "invalid", A_UINVALID
,
88 "next-file", A_NEXT_FILE
,
89 "noaction", A_NOACTION
,
92 "prev-file", A_PREV_FILE
,
95 "repaint-flush", A_FREPAINT
,
96 "repeat-search", A_AGAIN_SEARCH
,
97 "repeat-search-all", A_T_AGAIN_SEARCH
,
98 "reverse-search", A_REVERSE_SEARCH
,
99 "reverse-search-all", A_T_REVERSE_SEARCH
,
100 "set-mark", A_SETMARK
,
103 "toggle-flag", A_OPT_TOGGLE
,
104 "toggle-option", A_OPT_TOGGLE
,
105 "version", A_VERSION
,
114 char *p
; /* {{ Can't be register since we use &p }} */
115 register char *up
; /* Pointer into usertable */
116 FILE *desc
; /* Description file (input) */
117 FILE *out
; /* Output file */
118 int linenum
; /* Line number in input file */
119 char *currcmd
; /* Start of current command string */
125 extern char *getenv();
128 * Process command line arguments.
131 while (--argc
> 0 && **(++argv
) == '-')
136 outfile
= &argv
[0][2];
137 if (*outfile
== '\0')
153 * Open the input file, or use standard input if none specified.
157 if ((desc
= fopen(*argv
, "r")) == NULL
)
166 * Read the input file, one line at a time.
167 * Each line consists of a command string,
168 * followed by white space, followed by an action name.
173 while (fgets(line
, sizeof(line
), desc
) != NULL
)
178 * Skip leading white space.
179 * Replace the final newline with a null byte.
180 * Ignore blank lines and comment lines.
183 while (*p
== ' ' || *p
== '\t')
185 for (i
= 0; p
[i
] != '\n' && p
[i
] != '\0'; i
++)
188 if (*p
== '#' || *p
== '\0')
192 * Parse the command string and store it in the usertable.
197 if (up
>= usertable
+ MAX_USERCMD
)
199 fprintf(stderr
, "too many commands, line %d\n",
203 if (up
>= currcmd
+ MAX_CMDLEN
)
205 fprintf(stderr
, "command too long on line %d\n",
213 } while (*p
!= ' ' && *p
!= '\t' && *p
!= '\0');
216 * Terminate the command string with a null byte.
221 * Skip white space between the command string
222 * and the action name.
223 * Terminate the action name with a null byte if it
224 * is followed by whitespace or a # comment.
228 fprintf(stderr
, "missing whitespace on line %d\n",
233 while (*p
== ' ' || *p
== '\t')
235 for (j
= 0; p
[j
] != ' ' && p
[j
] != '\t' &&
236 p
[j
] != '#' && p
[j
] != '\0'; j
++)
241 * Parse the action name and store it in the usertable.
243 for (i
= 0; cmdnames
[i
].cn_name
!= NULL
; i
++)
244 if (strcmp(cmdnames
[i
].cn_name
, p
) == 0)
246 if (cmdnames
[i
].cn_name
== NULL
)
248 fprintf(stderr
, "unknown action <%s> on line %d\n",
253 *up
++ = cmdnames
[i
].cn_action
;
256 * See if an extra string follows the action name.
258 for (j
= j
+1; p
[j
] == ' ' || p
[j
] == '\t'; j
++)
264 * OR the special value A_EXTRA into the action byte.
265 * Put the extra string after the action byte.
276 fprintf(stderr
, "%d errors; no output produced\n", errors
);
281 * Write the output file.
282 * If no output file was specified, use "$HOME/.less"
287 if (p
== NULL
|| *p
== '\0')
289 fprintf(stderr
, "cannot find $HOME - using current directory\n");
291 strcpy(line
, "_less");
293 strcpy(line
, ".less");
299 strcat(line
, "\\_less");
301 strcat(line
, "/.less");
306 if ((out
= fopen(outfile
, "w")) == NULL
)
309 fwrite((char *)usertable
, 1, up
-usertable
, out
);
314 * Parse one character of a string.
327 if (*++p
>= '0' && *p
<= '7')
330 * Parse an octal number.
335 ch
= 8*ch
+ (*p
- '0');
336 while (*++p
>= '0' && *p
<= '7' && ++i
< 3);
341 * Backslash followed by a char just means that char.
347 * Carat means CONTROL.
350 return (CONTROL(p
[1]));
358 fprintf(stderr
, "usage: lesskey [-o output] [input]\n");