forked from hughbarney/femto
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcomplete.c
More file actions
111 lines (95 loc) · 3.13 KB
/
Copy pathcomplete.c
File metadata and controls
111 lines (95 loc) · 3.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/* complete.c, Atto Emacs, Hugh Barney, Public Domain, 2016 */
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <curses.h>
#include "femto.h"
#include "window.h"
#include "undo.h"
#include "buffer.h"
#include "key.h"
#include "display.h"
/** getfilename() - basic filename completion, based on code in uemacs/PK
*
* @param prompt .. Prompt to display in the message line.
* @param buf .. Pointer to char buffer where returned filename is left.
* @param nbuf .. Size of buf.
*
* @returns: false if aborted by user, true otherwise.
*
* buf can be a wildcard string which is used for TAB-completions.
* Note that the wildcard is overwritten by the first TAB and not
* available for a second round.
* This is due to simplifying code by not using a tempfile.
*
*/
char sys_command[PATH_MAX];
bool getfilename(char *prompt, char *buf, int nbuf)
{
int wpos, cpos = strlen(buf); /* current character position in string */
int key = 0, c;
bool didtry = false, iswild = false;
FILE *fp = NULL;
for (;;) {
didtry = didtry && (key == 0x09); /* Was last command tab-completion? */
display_prompt_and_response(prompt, buf);
key = getch(); /* get a character from the user */
switch(key) {
case 0x07: /* ctrl-g, abort */
case 0x0a: /* cr, lf */
case 0x0d:
if (fp != NULL) pclose(fp);
debug("getfilename(): quitting\n");
return (key != 0x07);
case 0x7f: /* del, erase */
case 0x08: /* backspace */
if (cpos == 0) continue;
buf[--cpos] = '\0';
break;
case 0x15: /* C-u kill */
cpos = 0;
buf[0] = '\0';
break;
case 0x09: /* TAB, complete file name */
/* scan backwards for a wild card and set iswild */
iswild=false;
for (wpos = strlen(buf); wpos; wpos--)
if ((iswild = (buf[wpos-1] == '*' || buf[wpos-1] == '?')))
break;
/* first time retrieval */
if (!didtry) {
strcpy(sys_command, "ls -1Adp ");
strcat(sys_command, buf);
if (!iswild)
strcat(sys_command, "*");
strcat(sys_command, " 2>/dev/null");
if (fp != NULL) pclose(fp);
fp = popen(sys_command, "r");
if (fp == NULL)
fatal("getfilename(): failed to get directory listing\n");
}
cpos = 0;
/* copy next filename into buf */
while ((c = getc(fp)) != EOF && c != '\n')
if (cpos < nbuf - 1 && c != '*')
buf[cpos++] = c;
buf[cpos] = '\0';
didtry = (c == EOF) ? false : true;
break;
default:
if (cpos < nbuf - 1) {
buf[cpos++] = key;
buf[cpos] = '\0';
}
break;
}
debug("getfilename(): key processed: '%c', %u\n", key, key);
}
}
/*
* Local Variables:
* c-file-style: "k&r"
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/