📄 readln.c
字号:
static char *
BookmarkCompletionFunction(const char *text, int state)
{
char *cp;
size_t textlen;
int i, matches;
if ((gBookmarkTable == NULL) || (state >= gNumBookmarks))
return (NULL);
textlen = strlen(text);
if (textlen == 0) {
cp = StrDup(gBookmarkTable[state].bookmarkName);
} else {
cp = NULL;
for (i=0, matches=0; i<gNumBookmarks; i++) {
if (ISTRNCMP(gBookmarkTable[i].bookmarkName, text, textlen) == 0) {
if (matches >= state) {
cp = StrDup(gBookmarkTable[i].bookmarkName);
break;
}
matches++;
}
}
}
return cp;
} /* BookmarkCompletionFunction */
static char *
CommandCompletionFunction(const char *text, int state)
{
char *cp;
size_t textlen;
int i, matches;
CommandPtr cmdp;
textlen = strlen(text);
if (textlen == 0) {
cp = NULL;
} else {
cp = NULL;
for (i=0, matches=0; ; i++) {
cmdp = GetCommandByIndex(i);
if (cmdp == kNoCommand)
break;
if (ISTRNCMP(cmdp->name, text, textlen) == 0) {
if (matches >= state) {
cp = StrDup(cmdp->name);
break;
}
matches++;
}
}
}
return cp;
} /* CommandCompletionFunction */
static char *
PrefOptCompletionFunction(const char *text, int state)
{
char *cp;
size_t textlen;
int i, matches;
if (state >= gNumPrefOpts)
return (NULL);
textlen = strlen(text);
if (textlen == 0) {
cp = StrDup(gPrefOpts[state].varname);
} else {
cp = NULL;
for (i=0, matches=0; i<gNumPrefOpts; i++) {
if (ISTRNCMP(gPrefOpts[i].varname, text, textlen) == 0) {
if (matches >= state) {
cp = StrDup(gPrefOpts[i].varname);
break;
}
matches++;
}
}
}
return cp;
} /* PrefOptCompletionFunction */
void
ReCacheBookmarks(void)
{
(void) LoadBookmarkTable();
}
static int
HaveCommandNameOnly(char *cmdstart)
{
char *cp;
for (cp = cmdstart; *cp != '\0'; cp++) {
if (isspace((int) *cp))
return (0); /* At least one argument in progress. */
}
return (1);
} /* HaveCommandNameOnly */
static char *
CompletionFunction(const char *text, int state)
{
char *cp;
char *cmdstart;
ArgvInfo ai;
int bUsed;
CommandPtr cmdp;
static int flags;
if (state == 0) {
flags = -1;
cmdstart = FindStartOfCurrentCommand();
if (cmdstart == NULL)
return NULL;
if (HaveCommandNameOnly(cmdstart)) {
flags = -2; /* special case */
cp = CommandCompletionFunction(text, state);
return cp;
}
(void) memset(&ai, 0, sizeof(ai));
bUsed = MakeArgv(cmdstart, &ai.cargc, ai.cargv,
(int) (sizeof(ai.cargv) / sizeof(char *)),
ai.argbuf, sizeof(ai.argbuf),
ai.noglobargv, 1);
if (bUsed <= 0)
return NULL;
if (ai.cargc == 0)
return NULL;
cmdp = GetCommandByName(ai.cargv[0], 0);
if (cmdp == kAmbiguousCommand) {
return NULL;
} else if (cmdp == kNoCommand) {
return NULL;
}
flags = cmdp->flags;
}
if (flags == (-2)) {
cp = CommandCompletionFunction(text, state);
return cp;
}
if (flags < 0)
return NULL;
if ((flags & (kCompleteLocalFile|kCompleteLocalDir)) != 0) {
cp = gl_local_filename_completion_proc(text, state);
return cp;
} else if ((flags & kCompleteRemoteFile) != 0) {
gl_filename_quoting_desired = 1;
cp = RemoteFileCompletionFunction(text, state);
return cp;
} else if ((flags & kCompleteRemoteDir) != 0) {
gl_filename_quoting_desired = 1;
cp = RemoteDirCompletionFunction(text, state);
return cp;
} else if ((flags & kCompleteBookmark) != 0) {
cp = BookmarkCompletionFunction(text, state);
return cp;
} else if ((flags & kCompletePrefOpt) != 0) {
cp = PrefOptCompletionFunction(text, state);
return cp;
}
return NULL;
} /* CompletionFunction */
void
LoadHistory(void)
{
char pathName[256];
if (gOurDirectoryPath[0] == '\0')
return;
(void) OurDirectoryPath(pathName, sizeof(pathName), kHistoryFileName);
gl_histloadfile(pathName);
} /* LoadHistory */
static size_t
Vt100VisibleStrlen(const char *src)
{
const char *cp;
size_t esc;
for (esc = 0, cp = src; *cp != '\0'; cp++) {
if (*cp == '\033')
esc++;
}
/* The VT100 escape codes we use are all in the form "\033[7m"
* These aren't visible, so subtract them from the count.
*/
return ((size_t) (cp - src) - (esc * 4));
} /* Vt100VisibleStrlen */
/* Save the commands they typed in a history file, then they can use
* readline to go through them again next time.
*/
void
SaveHistory(void)
{
char pathName[256];
if (gOurDirectoryPath[0] == '\0')
return; /* Don't create in root directory. */
(void) OurDirectoryPath(pathName, sizeof(pathName), kHistoryFileName);
gl_strlen = Vt100VisibleStrlen;
gl_histsavefile(pathName);
(void) chmod(pathName, 00600);
} /* SaveHistory */
void
InitReadline(void)
{
gl_completion_proc = CompletionFunction;
gl_setwidth(gScreenColumns);
LoadHistory();
ReCacheBookmarks();
} /* InitReadline */
char *
Readline(char *prompt)
{
char *linecopy, *line, *cp;
char lbuf[256];
if (gIsTTYr) {
line = getline(prompt);
} else {
line = fgets(lbuf, sizeof(lbuf) - 1, stdin);
if (line != NULL) {
cp = line + strlen(line) - 1;
if (*cp == '\n')
*cp = '\0';
}
}
if (line != NULL) {
if (line[0] == '\0')
return NULL; /* EOF */
linecopy = StrDup(line);
line = linecopy;
}
return (line);
} /* Readline */
void
AddHistory(char *line)
{
gl_histadd(line);
} /* AddHistory */
void
DisposeReadline(void)
{
SaveHistory();
} /* DisposeReadline */
/*VARARGS*/
void
SetXtermTitle(const char *const fmt, ...)
{
va_list ap;
char buf[256];
if ((gXtermTitle != 0) && (gMaySetXtermTitle != 0)) {
if ((fmt == NULL) || (ISTRCMP(fmt, "RESTORE") == 0)) {
#if (defined(WIN32) || defined(_WINDOWS)) && defined(_CONSOLE)
STRNCPY(buf, gSavedConsoleTitle);
#else
STRNCPY(buf, gTerm);
#endif
} else if (ISTRCMP(fmt, "DEFAULT") == 0) {
(void) Strncpy(buf, gVersion + 5, 12);
} else {
va_start(ap, fmt);
#ifdef HAVE_VSNPRINTF
(void) vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
buf[sizeof(buf) - 1] = '\0';
#else
(void) vsprintf(buf, fmt, ap);
#endif
va_end(ap);
}
if (buf[0] != '\0') {
#if (defined(WIN32) || defined(_WINDOWS)) && defined(_CONSOLE)
SetConsoleTitle(buf);
#else
if (strcmp(gCurXtermTitleStr, buf) != 0) {
fprintf(stderr, "\033]0;%s\007", buf);
STRNCPY(gCurXtermTitleStr, buf);
}
#endif
}
}
} /* SetXtermTitle */
void
PrintStartupBanner(void)
{
char v[80], *cp;
char vdate[32];
/* Print selected information from the version ID. */
vdate[0] = '\0';
(void) STRNCPY(v, gVersion + 5);
cp = strchr(v, ',');
if (cp != NULL) {
*cp = '\0';
cp[-5] = '\0';
(void) STRNCPY(vdate, " (");
(void) STRNCAT(vdate, v + 16);
(void) STRNCAT(vdate, ", ");
(void) STRNCAT(vdate, cp - 4);
(void) STRNCAT(vdate, ")");
}
#if defined(BETA) && (BETA > 0)
(void) fprintf(stdout, "%s%.11s beta %d%s%s by Mike Gleason (ncftp@ncftp.com).\n",
tcap_boldface,
gVersion + 5,
BETA,
tcap_normal,
vdate
);
#else
(void) fprintf(stdout, "%s%.11s%s%s by Mike Gleason (ncftp@ncftp.com).\n",
tcap_boldface,
gVersion + 5,
tcap_normal,
vdate
);
#endif
(void) fflush(stdout);
} /* PrintStartupBanner */
/* Print the command shell's prompt. */
void
MakePrompt(char *dst, size_t dsize)
{
char acwd[64];
# ifdef HAVE_SNPRINTF
if (gConn.loggedIn != 0) {
AbbrevStr(acwd, gRemoteCWD, 25, 0);
snprintf(dst, dsize, "%sncftp%s %s %s>%s ",
tcap_boldface, tcap_normal, acwd,
tcap_boldface, tcap_normal);
} else {
snprintf(dst, dsize, "%sncftp%s> ",
tcap_boldface, tcap_normal);
}
# else /* HAVE_SNPRINTF */
(void) Strncpy(dst, tcap_boldface, dsize);
(void) Strncat(dst, "ncftp", dsize);
(void) Strncat(dst, tcap_normal, dsize);
if (gConn.loggedIn != 0) {
AbbrevStr(acwd, gRemoteCWD, 25, 0);
(void) Strncat(dst, " ", dsize);
(void) Strncat(dst, acwd, dsize);
(void) Strncat(dst, " ", dsize);
}
(void) Strncat(dst, tcap_boldface, dsize);
(void) Strncat(dst, ">", dsize);
(void) Strncat(dst, tcap_normal, dsize);
(void) Strncat(dst, " ", dsize);
# endif /* HAVE_SNPRINTF */
} /* MakePrompt */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -