2
* Copyright (C) 1984-2000 Mark Nudelman
4
* You may distribute under the terms of either the GNU General Public
5
* License or the Less License, as specified in the README file.
7
* For more information about less, or for information on how to
8
* contact the author, see the README file.
13
* Functions which manipulate the command buffer.
14
* Used only by command() and related functions.
22
static char cmdbuf[CMDBUF_SIZE]; /* Buffer for holding a multi-char command */
23
static int cmd_col; /* Current column of the cursor */
24
static int prompt_col; /* Column of cursor just after prompt */
25
static char *cp; /* Pointer into cmdbuf */
26
static int cmd_offset; /* Index into cmdbuf of first displayed char */
27
static int literal; /* Next input char should not be interpreted */
29
#if TAB_COMPLETE_FILENAME
30
static int cmd_complete();
32
* These variables are statics used by cmd_complete.
34
static int in_completion = 0;
36
static char *tk_original;
37
static char *tk_ipoint;
38
static char *tk_trial;
39
static struct textlist tk_tlist;
42
static int cmd_left();
43
static int cmd_right();
45
#if SPACES_IN_FILENAMES
46
public char openquote = '"';
47
public char closequote = '"';
52
* A mlist structure represents a command history.
58
struct mlist *curr_mp;
63
* These are the various command histories that exist.
65
struct mlist mlist_search =
66
{ &mlist_search, &mlist_search, &mlist_search, NULL };
67
public void constant *ml_search = (void *) &mlist_search;
69
struct mlist mlist_examine =
70
{ &mlist_examine, &mlist_examine, &mlist_examine, NULL };
71
public void constant *ml_examine = (void *) &mlist_examine;
73
#if SHELL_ESCAPE || PIPEC
74
struct mlist mlist_shell =
75
{ &mlist_shell, &mlist_shell, &mlist_shell, NULL };
76
public void constant *ml_shell = (void *) &mlist_shell;
79
#else /* CMD_HISTORY */
81
/* If CMD_HISTORY is off, these are just flags. */
82
public void constant *ml_search = (void *)1;
83
public void constant *ml_examine = (void *)2;
84
#if SHELL_ESCAPE || PIPEC
85
public void constant *ml_shell = (void *)3;
88
#endif /* CMD_HISTORY */
91
* History for the current command.
93
static struct mlist *curr_mlist = NULL;
94
static int curr_cmdflags;
98
* Reset command buffer (to empty).
111
* Clear command line on display.
117
cmd_col = prompt_col = 0;
121
* Display a string, usually as a prompt for input into the command buffer.
128
cmd_col += strlen(s);
129
prompt_col += strlen(s);
133
* How many characters are in the command buffer?
138
return (strlen(cmdbuf));
142
* Repaint the line from cp onwards.
143
* Then position the cursor just after the char old_cp (a pointer into cmdbuf).
152
* Repaint the line from the current position.
155
for ( ; *cp != '\0'; cp++)
158
if (cmd_col + (int)strlen(p) >= sc_width)
161
cmd_col += strlen(p);
165
* Back up the cursor to the correct position.
172
* Put the cursor at "home" (just after the prompt),
173
* and set cp to the corresponding char in cmdbuf.
178
while (cmd_col > prompt_col)
184
cp = &cmdbuf[cmd_offset];
188
* Shift the cmdbuf display left a half-screen.
198
* Start at the first displayed char, count how far to the
199
* right we'd have to move to reach the center of the screen.
201
s = cmdbuf + cmd_offset;
203
while (cols < (sc_width - prompt_col) / 2 && *s != '\0')
204
cols += strlen(prchar(*s++));
206
cmd_offset = s - cmdbuf;
209
cmd_repaint(save_cp);
213
* Shift the cmdbuf display right a half-screen.
224
* Start at the first displayed char, count how far to the
225
* left we'd have to move to traverse a half-screen width
226
* of displayed characters.
228
s = cmdbuf + cmd_offset;
230
while (cols < (sc_width - prompt_col) / 2 && s > cmdbuf)
236
cmd_offset = s - cmdbuf;
239
cmd_repaint(save_cp);
243
* Move cursor right one character.
253
* Already at the end of the line.
258
if (cmd_col + (int)strlen(p) >= sc_width)
260
else if (cmd_col + (int)strlen(p) == sc_width - 1 && cp[1] != '\0')
264
cmd_col += strlen(p);
269
* Move cursor left one character.
278
/* Already at the beginning of the line */
282
if (cmd_col < prompt_col + (int)strlen(p))
285
cmd_col -= strlen(p);
292
* Insert a char into the command buffer, at the current position.
300
if (strlen(cmdbuf) >= sizeof(cmdbuf)-2)
303
* No room in the command buffer for another char.
310
* Insert the character into the buffer.
312
for (s = &cmdbuf[strlen(cmdbuf)]; s >= cp; s--)
316
* Reprint the tail of the line from the inserted char.
324
* Backspace in the command buffer.
325
* Delete the char to the left of the cursor.
335
* Backspace past beginning of the buffer:
336
* this usually means abort the command.
341
* Move cursor left (to the char being erased).
345
* Remove the char from the buffer (shift the buffer left).
347
for (s = cp; *s != '\0'; s++)
350
* Repaint the buffer after the erased char.
355
* We say that erasing the entire command string causes us
356
* to abort the current command, if CF_QUIT_ON_ERASE is set.
358
if ((curr_cmdflags & CF_QUIT_ON_ERASE) && cp == cmdbuf && *cp == '\0')
364
* Delete the char under the cursor.
372
* At end of string; there is no char under the cursor.
377
* Move right, then use cmd_erase.
385
* Delete the "word" to the left of the cursor.
390
if (cp > cmdbuf && cp[-1] == ' ')
393
* If the char left of cursor is a space,
394
* erase all the spaces left of cursor (to the first non-space).
396
while (cp > cmdbuf && cp[-1] == ' ')
401
* If the char left of cursor is not a space,
402
* erase all the nonspaces left of cursor (the whole "word").
404
while (cp > cmdbuf && cp[-1] != ' ')
411
* Delete the "word" under the cursor.
419
* If the char under the cursor is a space,
420
* delete it and all the spaces right of cursor.
427
* If the char under the cursor is not a space,
428
* delete it and all nonspaces right of cursor (the whole word).
430
while (*cp != ' ' && *cp != '\0')
437
* Delete all chars in the command buffer.
442
if (cmdbuf[0] == '\0')
445
* Buffer is already empty; abort the current command.
455
* We say that erasing the entire command string causes us
456
* to abort the current command, if CF_QUIT_ON_ERASE is set.
458
if (curr_cmdflags & CF_QUIT_ON_ERASE)
464
* Select an mlist structure to be the current command history.
467
set_mlist(mlist, cmdflags)
471
curr_mlist = (struct mlist *) mlist;
472
curr_cmdflags = cmdflags;
477
* Move up or down in the currently selected command history list.
485
if (curr_mlist == NULL)
488
* The current command has no history list.
496
* Move curr_mp to the next/prev entry.
499
curr_mlist->curr_mp = curr_mlist->curr_mp->prev;
501
curr_mlist->curr_mp = curr_mlist->curr_mp->next;
503
* Copy the entry into cmdbuf and echo it on the screen.
505
s = curr_mlist->curr_mp->string;
508
for (cp = cmdbuf; *s != '\0'; s++)
519
* Add a string to a history list.
522
cmd_addhist(mlist, cmd)
530
* Don't save a trivial command.
532
if (strlen(cmd) == 0)
535
* Don't save if a duplicate of a command which is already
537
* But select the one already in the history to be current.
539
for (ml = mlist->next; ml != mlist; ml = ml->next)
541
if (strcmp(ml->string, cmd) == 0)
547
* Did not find command in history.
548
* Save the command and put it at the end of the history list.
550
ml = (struct mlist *) ecalloc(1, sizeof(struct mlist));
551
ml->string = save(cmd);
553
ml->prev = mlist->prev;
554
mlist->prev->next = ml;
558
* Point to the cmd just after the just-accepted command.
559
* Thus, an UPARROW will always retrieve the previous command.
561
mlist->curr_mp = ml->next;
566
* Accept the command in the command buffer.
567
* Add it to the currently selected history list.
574
* Nothing to do if there is no currently selected history list.
576
if (curr_mlist == NULL)
578
cmd_addhist(curr_mlist, cmdbuf);
583
* Try to perform a line-edit function on the command buffer,
584
* using a specified char as a line-editing command.
586
* CC_PASS The char does not invoke a line edit function.
587
* CC_OK Line edit function done.
588
* CC_QUIT The char requests the current command to be aborted.
597
#if TAB_COMPLETE_FILENAME
598
#define not_in_completion() in_completion = 0
600
#define not_in_completion()
604
* See if the char is indeed a line-editing command.
608
if (curr_mlist == NULL)
610
* No current history; don't accept history manipulation cmds.
612
flags |= EC_NOHISTORY;
614
#if TAB_COMPLETE_FILENAME
615
if (curr_mlist == ml_search)
617
* In a search command; don't accept file-completion cmds.
619
flags |= EC_NOCOMPLETE;
622
action = editchar(c, flags);
628
return (cmd_right());
634
while (*cp != '\0' && *cp != ' ')
641
while (cp > cmdbuf && cp[-1] == ' ')
643
while (cp > cmdbuf && cp[-1] != ' ')
662
return (cmd_erase());
668
return (cmd_werase());
671
return (cmd_delete());
674
return (cmd_wdelete());
682
return (cmd_updown(action));
684
#if TAB_COMPLETE_FILENAME
688
return (cmd_complete(action));
698
#if TAB_COMPLETE_FILENAME
700
* Insert a string into the command buffer, at the current position.
709
for (s = str; *s != '\0'; s++)
711
action = cmd_ichar(*s);
722
* Find the beginning and end of the "current" word.
723
* This is the word which the cursor (cp) is inside or at the end of.
724
* Return pointer to the beginning of the word and put the
725
* cursor at the end of the word.
731
#if SPACES_IN_FILENAMES
733
int delim_quoted = 0;
735
char *esc = get_meta_escape();
736
int esclen = strlen(esc);
740
* Move cursor to end of word.
742
if (*cp != ' ' && *cp != '\0')
745
* Cursor is on a nonspace.
746
* Move cursor right to the next space.
748
while (*cp != ' ' && *cp != '\0')
750
} else if (cp > cmdbuf && cp[-1] != ' ')
753
* Cursor is on a space, and char to the left is a nonspace.
754
* We're already at the end of the word.
761
* Cursor is on a space and char to the left is a space.
762
* Huh? There's no word here.
768
* Find the beginning of the word which the cursor is in.
772
#if SPACES_IN_FILENAMES
774
* If we have an unbalanced quote (that is, an open quote
775
* without a corresponding close quote), we return everything
776
* from the open quote, including spaces.
778
for (word = cmdbuf; word < cp; word++)
783
for (p = cmdbuf; p < cp; p++)
788
} else if (esclen > 0 && p + esclen < cp &&
789
strncmp(p, esc, esclen) == 0)
793
} else if (delim_quoted)
795
if (*p == closequote)
797
} else /* (!delim_quoted) */
810
* Set things up to enter completion mode.
811
* Expand the word under the cursor into a list of filenames
812
* which start with that word, and set tk_text to that list.
821
* Get rid of any previous tk_text.
829
* Find the original (uncompleted) word in the command buffer.
831
word = delimit_word();
835
* Set the insertion point to the point in the command buffer
836
* where the original (uncompleted) word now sits.
840
* Save the original (uncompleted) word
842
if (tk_original != NULL)
844
tk_original = (char *) ecalloc(cp-word+1, sizeof(char));
845
strncpy(tk_original, word, cp-word);
847
* Get the expanded filename.
848
* This may result in a single filename, or
849
* a blank-separated list of filenames.
853
if (*word != openquote)
855
tk_text = fcomplete(word);
858
char *qword = shell_quote(word+1);
860
tk_text = fcomplete(word+1);
863
tk_text = fcomplete(qword);
871
* Return the next word in the current completion list.
874
next_compl(action, prev)
881
return (forw_textlist(&tk_tlist, prev));
883
return (back_textlist(&tk_tlist, prev));
890
* Complete the filename before (or under) the cursor.
891
* cmd_complete may be called multiple times. The global in_completion
892
* remembers whether this call is the first time (create the list),
893
* or a subsequent time (step thru the list).
901
if (!in_completion || action == EC_EXPAND)
904
* Expand the word under the cursor and
905
* use the first word in the expansion
906
* (or the entire expansion if we're doing EC_EXPAND).
914
if (action == EC_EXPAND)
917
* Use the whole list.
923
* Use the first filename in the list.
926
init_textlist(&tk_tlist, tk_text);
927
tk_trial = next_compl(action, (char*)NULL);
932
* We already have a completion list.
933
* Use the next/previous filename from the list.
935
tk_trial = next_compl(action, tk_trial);
939
* Remove the original word, or the previous trial completion.
941
while (cp > tk_ipoint)
944
if (tk_trial == NULL)
947
* There are no more trial completions.
948
* Insert the original (uncompleted) filename.
951
if (cmd_istr(tk_original) != CC_OK)
956
* Insert trial completion.
958
if (cmd_istr(tk_trial) != CC_OK)
961
* If it is a directory, append a slash.
963
if (is_dir(tk_trial))
965
if (cp > cmdbuf && cp[-1] == closequote)
967
s = lgetenv("LESSSEPARATOR");
970
if (cmd_istr(s) != CC_OK)
983
#endif /* TAB_COMPLETE_FILENAME */
986
* Process a single character of a multi-character command, such as
987
* a number, or the pattern of a search command.
989
* CC_OK The char was accepted.
990
* CC_QUIT The char requests the command to be aborted.
991
* CC_ERROR The char could not be accepted due to an error.
1002
* Insert the char, even if it is a line-editing char.
1005
return (cmd_ichar(c));
1009
* See if it is a special line-editing character.
1013
action = cmd_edit(c);
1025
* Insert the char into the command buffer.
1027
return (cmd_ichar(c));
1031
* Return the number currently in the command buffer.
1036
return (atoi(cmdbuf));
1040
* Return a pointer to the command buffer.