Added backward and forward navigation in the REPL to navigate within a typed string.
This commit is contained in:
parent
ff155b6a31
commit
c8d3fbea51
2 changed files with 41 additions and 18 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
project(fun VERSION 0.5.0 LANGUAGES C)
|
project(fun VERSION 0.5.1 LANGUAGES C)
|
||||||
|
|
||||||
set(CMAKE_C_STANDARD 11)
|
set(CMAKE_C_STANDARD 11)
|
||||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
|
|
|
||||||
57
src/fun.c
57
src/fun.c
|
|
@ -299,15 +299,20 @@ static int read_line_edit(char *out, size_t out_cap, const char *prompt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
size_t pos = 0; /* cursor position in [0..len] */
|
||||||
int hist_pos = rl_count; /* rl_count means "editing current input", 0..rl_count-1 indexes history entries */
|
int hist_pos = rl_count; /* rl_count means "editing current input", 0..rl_count-1 indexes history entries */
|
||||||
char saved_current[4096];
|
char saved_current[4096];
|
||||||
int has_saved = 0;
|
int has_saved = 0;
|
||||||
|
|
||||||
#define RL_REDRAW() do { \
|
#define RL_REDRAW_POS() do { \
|
||||||
fputc('\r', stdout); \
|
fputc('\r', stdout); \
|
||||||
if (prompt) fputs(prompt, stdout); \
|
if (prompt) fputs(prompt, stdout); \
|
||||||
fwrite(out, 1, len, stdout); \
|
fwrite(out, 1, len, stdout); \
|
||||||
fputs("\x1b[K", stdout); \
|
fputs("\x1b[K", stdout); \
|
||||||
|
if (pos < len) { \
|
||||||
|
size_t back = (size_t)(len - pos); \
|
||||||
|
if (back > 0) fprintf(stdout, "\x1b[%zuD", back); \
|
||||||
|
} \
|
||||||
fflush(stdout); \
|
fflush(stdout); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
|
@ -346,7 +351,8 @@ static int read_line_edit(char *out, size_t out_cap, const char *prompt) {
|
||||||
memcpy(out, h, hl);
|
memcpy(out, h, hl);
|
||||||
out[hl] = '\0';
|
out[hl] = '\0';
|
||||||
len = hl;
|
len = hl;
|
||||||
RL_REDRAW();
|
pos = len;
|
||||||
|
RL_REDRAW_POS();
|
||||||
} else {
|
} else {
|
||||||
fputc('\a', stdout); fflush(stdout);
|
fputc('\a', stdout); fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
@ -372,42 +378,59 @@ static int read_line_edit(char *out, size_t out_cap, const char *prompt) {
|
||||||
out[hl] = '\0';
|
out[hl] = '\0';
|
||||||
len = hl;
|
len = hl;
|
||||||
}
|
}
|
||||||
RL_REDRAW();
|
pos = len;
|
||||||
|
RL_REDRAW_POS();
|
||||||
} else {
|
} else {
|
||||||
fputc('\a', stdout); fflush(stdout);
|
fputc('\a', stdout); fflush(stdout);
|
||||||
}
|
}
|
||||||
|
} else if (c2 == 'C') { /* Right */
|
||||||
|
if (pos < len) { pos++; fputs("\x1b[C", stdout); fflush(stdout); }
|
||||||
|
else { fputc('\a', stdout); fflush(stdout); }
|
||||||
|
} else if (c2 == 'D') { /* Left */
|
||||||
|
if (pos > 0) { pos--; fputs("\x1b[D", stdout); fflush(stdout); }
|
||||||
|
else { fputc('\a', stdout); fflush(stdout); }
|
||||||
} else {
|
} else {
|
||||||
/* ignore other CSI sequences */
|
/* ignore other CSI sequences */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (ch == 127 || ch == 8) {
|
} else if (ch == 127 || ch == 8) {
|
||||||
/* backspace */
|
/* backspace: delete char left of cursor */
|
||||||
if (len > 0) {
|
if (pos > 0) {
|
||||||
|
/* shift tail left */
|
||||||
|
memmove(out + pos - 1, out + pos, len - pos);
|
||||||
len--;
|
len--;
|
||||||
|
pos--;
|
||||||
out[len] = '\0';
|
out[len] = '\0';
|
||||||
/* efficient backspace */
|
RL_REDRAW_POS();
|
||||||
fputs("\b \b", stdout);
|
|
||||||
fflush(stdout);
|
|
||||||
} else {
|
} else {
|
||||||
fputc('\a', stdout);
|
fputc('\a', stdout);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
} else if (ch == '\t') {
|
} else if (ch == '\t') {
|
||||||
/* only attempt completion for ':load ' */
|
/* only attempt completion for ':load ' when at end of line */
|
||||||
out[len] = '\0';
|
if (pos != len) {
|
||||||
size_t newlen = len;
|
fputc('\a', stdout);
|
||||||
if (complete_load_path(out, &newlen)) {
|
fflush(stdout);
|
||||||
len = newlen;
|
} else {
|
||||||
|
out[len] = '\0';
|
||||||
|
size_t newlen = len;
|
||||||
|
if (complete_load_path(out, &newlen)) {
|
||||||
|
len = newlen;
|
||||||
|
pos = len;
|
||||||
|
}
|
||||||
|
RL_REDRAW_POS();
|
||||||
}
|
}
|
||||||
RL_REDRAW();
|
|
||||||
} else if (ch >= 32 && ch <= 126) {
|
} else if (ch >= 32 && ch <= 126) {
|
||||||
if (len + 1 < out_cap) {
|
if (len + 1 < out_cap) {
|
||||||
out[len++] = (char)ch;
|
/* insert at cursor */
|
||||||
|
memmove(out + pos + 1, out + pos, len - pos);
|
||||||
|
out[pos] = (char)ch;
|
||||||
|
len++;
|
||||||
|
pos++;
|
||||||
out[len] = '\0';
|
out[len] = '\0';
|
||||||
fputc(ch, stdout);
|
|
||||||
fflush(stdout);
|
|
||||||
/* when typing after navigating history, we are editing current line; reset hist_pos to end */
|
/* when typing after navigating history, we are editing current line; reset hist_pos to end */
|
||||||
hist_pos = rl_count;
|
hist_pos = rl_count;
|
||||||
|
RL_REDRAW_POS();
|
||||||
} else {
|
} else {
|
||||||
fputc('\a', stdout);
|
fputc('\a', stdout);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue