aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar BanceDev 2024-09-06 14:37:03 -0400
committerGravatar BanceDev 2024-09-06 14:37:03 -0400
commitd864cde4fa8236e85f610d2b9e22d944af6c8780 (patch)
tree8c13802b489e6b55828f5ac730837a942b7a9945 /src
parentcleaned up syntax (diff)
fixed inability to move cursor between lines
Diffstat (limited to 'src')
-rw-r--r--src/lush.c79
1 files changed, 61 insertions, 18 deletions
diff --git a/src/lush.c b/src/lush.c
index 1574b3c..aa1b90f 100644
--- a/src/lush.c
+++ b/src/lush.c
@@ -157,7 +157,7 @@ static int get_terminal_width() {
return w.ws_col;
}
-static void reprint_buffer(char *buffer, int *pos, int history_pos) {
+static char *get_prompt() {
char *username = getenv("USER");
char device_name[256];
gethostname(device_name, sizeof(device_name));
@@ -183,13 +183,16 @@ static void reprint_buffer(char *buffer, int *pos, int history_pos) {
snprintf(prompt, prompt_len, "[%s@%s:%s]", username, device_name,
prompt_cwd);
+ free(cwd);
+ return prompt;
+}
+
+static void reprint_buffer(char *buffer, int *last_lines, int *pos,
+ int history_pos) {
+ char *prompt = get_prompt();
int width = get_terminal_width();
- int num_lines = ((strlen(buffer) + strlen(prompt) + 1) / width) + 1;
- for (int i = 0; i < num_lines; i++) {
- printf("\r\033[K");
- if (i > 0)
- printf("\033[A");
- }
+
+ // handle history before doing calculations
if (history_pos >= 0) {
char *history_line = lush_get_past_command(history_pos);
strncpy(buffer, history_line, BUFFER_SIZE);
@@ -198,13 +201,34 @@ static void reprint_buffer(char *buffer, int *pos, int history_pos) {
buffer[strlen(buffer) - 1] = '\0';
*pos = strlen(buffer);
}
+
+ int num_lines = ((strlen(buffer) + strlen(prompt) + 1) / width) + 1;
+ int cursor_pos = (strlen(prompt) + *pos + 1) % width;
+ int cursor_line = (strlen(prompt) + *pos + 1) / width + 1;
+ // move cursor down if it is up a number of lines first
+ if (num_lines - cursor_line > 0) {
+ printf("\033[%dB", num_lines - cursor_line);
+ }
+ for (int i = 0; i < *last_lines; i++) {
+ printf("\r\033[K");
+ if (i > 0)
+ printf("\033[A");
+ }
+ *last_lines = num_lines;
+
// ensure line is cleared before printing
printf("\r\033[K");
printf("%s ", prompt);
printf("%s ", buffer);
- printf("\033[%ldD", strlen(buffer) - *pos + 1);
- free(cwd);
+ // move cursor up and to the right to be in correct position
+ if (cursor_pos > 0)
+ printf("\r\033[%dC", cursor_pos);
+ else
+ printf("\r");
+ if (num_lines > 1 && (num_lines - cursor_line) > 0)
+ printf("\033[%dA", num_lines - cursor_line);
+
free(prompt);
}
@@ -213,6 +237,8 @@ char *lush_read_line() {
char *buffer = (char *)calloc(BUFFER_SIZE, sizeof(char));
int pos = 0;
int history_pos = -1;
+ int last_lines = 1;
+ char last_command;
int c;
// init buffer and make raw mode
@@ -225,29 +251,44 @@ char *lush_read_line() {
getchar(); // skip [
switch (getchar()) {
case 'A': // up arrow
- reprint_buffer(buffer, &pos, ++history_pos);
+ reprint_buffer(buffer, &last_lines, &pos, ++history_pos);
break;
case 'B': // down arrow
- reprint_buffer(buffer, &pos, --history_pos);
+ reprint_buffer(buffer, &last_lines, &pos, --history_pos);
if (history_pos < 0)
history_pos = 0;
break;
case 'C': // right arrow
+ {
+ int width = get_terminal_width();
+ char *prompt = get_prompt();
+ if ((strlen(prompt) + pos) % width == width - 2) {
+ printf("\033[B");
+ }
if (pos < strlen(buffer)) {
pos++;
// if modifying text reset history
history_pos = -1;
- reprint_buffer(buffer, &pos, history_pos);
+ reprint_buffer(buffer, &last_lines, &pos, history_pos);
}
- break;
+ free(prompt);
+ } break;
case 'D': // left arrow
+ {
+ int width = get_terminal_width();
+ char *prompt = get_prompt();
+ if ((strlen(prompt) + pos) % width == width - 1) {
+ printf("\033[A");
+ }
+
if (pos > 0) {
pos--;
// if modifying text reset history
history_pos = -1;
- reprint_buffer(buffer, &pos, history_pos);
+ reprint_buffer(buffer, &last_lines, &pos, history_pos);
}
- break;
+ free(prompt);
+ } break;
case '3': // delete
if (getchar() == '~') {
if (pos < strlen(buffer)) {
@@ -255,7 +296,7 @@ char *lush_read_line() {
strlen(&buffer[pos + 1]) + 1);
// if modifying text reset history
history_pos = -1;
- reprint_buffer(buffer, &pos, history_pos);
+ reprint_buffer(buffer, &last_lines, &pos, history_pos);
}
}
break;
@@ -269,11 +310,13 @@ char *lush_read_line() {
pos--;
// if modifying text reset history
history_pos = -1;
- reprint_buffer(buffer, &pos, history_pos);
+ reprint_buffer(buffer, &last_lines, &pos, history_pos);
}
} else if (c == '\n') {
// if modifying text reset history
history_pos = -1;
+ pos = strlen(buffer);
+ reprint_buffer(buffer, &last_lines, &pos, history_pos);
break; // submit the command
} else {
if (pos < BUFFER_SIZE - 1) {
@@ -285,7 +328,7 @@ char *lush_read_line() {
// if modifying text reset history
history_pos = -1;
- reprint_buffer(buffer, &pos, history_pos);
+ reprint_buffer(buffer, &last_lines, &pos, history_pos);
}
}
}