/*************************************************************************
* This program is copyright (C) 1985, 1986 by Jonathan Payne. It is *
* provided to you without charge for use only on a licensed Unix *
* system. You may copy JOVE provided that this notice is included with *
* the copy. You may not sell copies of this program or versions *
* modified for use on microcomputer systems, unless the copies are *
* included with a Unix system distribution and the source is provided. *
*************************************************************************/
private Line
*CurAskPtr
= 0; /* points at some line in mini-buffer */
private Buffer
*AskBuffer
= 0; /* Askbuffer points to actual structure */
/* The way the mini-buffer works is this: The first line of the mini-buffer
is where the user does his stuff. The rest of the buffer contains
strings that the user often wants to use, for instance, file names, or
common search strings, etc. If he types C-N or C-P while in ask(), we
bump the point up or down a line and extract the contents (we make sure
is somewhere in the mini-buffer). */
AskBuffer
= do_select((Window
*) 0, "Minibuf");
AskBuffer
->b_type
= B_SCRATCH
;
/* Add a string to the mini-buffer. */
register Buffer
*saveb
= curbuf
;
real_ask(delim
, d_proc
, def
, prompt
)
data_obj
*push_cmd
= LastCmd
;
if (!inlist(AskBuffer
->b_first
, CurAskPtr
))
prompt_len
= strlen(prompt
);
ToFirst(); /* Beginning of buffer. */
if (InJoverc
) { /* this is a kludge */
cont
: s_mess("%s%s", prompt
, linebuf
);
Asking
= curchar
+ prompt_len
;
if ((c
== EOF
) || index(delim
, c
)) {
if (d_proc
== 0 || (*d_proc
)(c
) == 0)
int n
= (c
== CTL(P
) ? -exp
: exp
);
CurAskPtr
= next_line(CurAskPtr
, n
);
if (CurAskPtr
== curbuf
->b_first
&& CurAskPtr
->l_next
!= 0)
CurAskPtr
= CurAskPtr
->l_next
;
(void) ltobuf(CurAskPtr
, linebuf
);
if (curline
!= curbuf
->b_first
) {
curline
= curbuf
->b_first
; /* with whatever is in linebuf */
no_typed
= (linebuf
[0] == '\0');
strcpy(Minibuf
, linebuf
);
InAsk
= Asking
= Interactive
= 0;
format(prompt
, sizeof prompt
, fmt
, ap
);
ans
= real_ask("\r\n", (int (*)()) 0, def
, prompt
);
if (ans
== 0) { /* Typed nothing. */
complain("[No default]");
do_ask(delim
, d_proc
, def
, fmt
, va_alist
)
format(prompt
, sizeof prompt
, fmt
, ap
);
return real_ask(delim
, d_proc
, def
, prompt
);
static char *fc_filebase
;
char BadExtensions
[128] = ".o";
bad_extension(name
, bads
)
int namelen
= strlen(name
),
if (ip
= index(bads
, ' '))
ip
= bads
+ strlen(bads
);
if ((ext_len
= ip
- bads
) == 0)
if ((ext_len
< namelen
) &&
(strcmp(&name
[namelen
- ext_len
], bads
) == 0))
} while ((bads
= ip
+ 1), !stop
);
int len
= strlen(fc_filebase
);
(strncmp(file
, fc_filebase
, strlen(fc_filebase
)) == 0));
PathParse(name
, filebuf
);
return ((stat(filebuf
, &stbuf
) != -1) &&
(stbuf
.st_mode
& S_IFDIR
) == S_IFDIR
);
the_same
= TRUE
, /* After filling in, are we the same
as when we were called? */
is_ntdir
; /* Is Newly Typed Directory name */
for (i
= 0; i
< n
; i
++) {
strcpy(bads
, BadExtensions
);
/* bad_extension() is destructive */
if (bad_extension(dir_vec
[i
], bads
))
numcomp(dir_vec
[lastmatch
], dir_vec
[i
]));
minmatch
= strlen(dir_vec
[i
]);
/* Ugh. Beware--this is hard to get right in a reasonable
manner. Please excuse this code--it's past my bedtime. */
if (minmatch
> strlen(fc_filebase
)) {
null_ncpy(fc_filebase
, dir_vec
[lastmatch
], minmatch
);
is_ntdir
= ((numfound
== 1) &&
(linebuf
[curchar
- 1] != '/') &&
if (the_same
&& !is_ntdir
) {
add_mess(n
== 1 ? " [Unique]" : " [Ambiguous]");
/* called from do_ask() when one of "\r\n ?" is typed. Does the right
thing, depending on which. */
return 0; /* tells ask to return now */
if ((fc_filebase
= rindex(linebuf
, '/')) != 0) {
null_ncpy(tmp
, linebuf
, (++fc_filebase
- linebuf
));
if ((nentries
= scandir(dir
, &dir_vec
, f_match
, alphacomp
)) == -1) {
add_mess(" [Unknown directory: %s]", dir
);
fill_in(dir_vec
, nentries
);
TOstart("Completion", FALSE
); /* false means newline only on request */
Typeout("(! means file will not be chosen unless typed explicitly)");
Typeout("Possible completions (in %s):", dir
);
for (i
= 0; i
< nentries
; i
++)
maxlen
= max(strlen(dir_vec
[i
]), maxlen
);
maxlen
+= 4; /* pad each column with at least 4 spaces */
ncols
= (CO
- 2) / maxlen
;
linespercol
= 1 + (nentries
/ ncols
);
for (lines
= 0; lines
< linespercol
; lines
++) {
for (col
= 0; col
< ncols
; col
++) {
which
= (col
* linespercol
) + lines
;
strcpy(bads
, BadExtensions
);
isbad
= bad_extension(dir_vec
[which
], bads
);
Typeout("%s%-*s", isbad
? "!" : NullStr
,
maxlen
- isbad
, dir_vec
[which
]);
freedir(&dir_vec
, nentries
);
*pretty_name
= pr_name(def
);
if (def
!= 0 && *def
!= '\0')
sprintf(prompt
, ": %f (default %s) ", pretty_name
);
sprintf(prompt
, ProcFmt
);
ans
= real_ask("\r\n ?", f_complete
, pretty_name
, prompt
);
if (ans
== 0 && (ans
= pretty_name
) == 0)
complain("[No default file name]");
ans
= ask(pretty_name
, prompt
);