history navigation by !!
This commit is contained in:
parent
9b27891d43
commit
0a8d3ca51c
5 changed files with 181 additions and 118 deletions
18
commands.c
18
commands.c
|
@ -6,11 +6,12 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include "commands.h"
|
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "history.h"
|
#include "history.h"
|
||||||
#include "rush.h"
|
#include "rush.h"
|
||||||
|
|
||||||
|
int execute(char **args);
|
||||||
|
|
||||||
// Function declarations for builtin commands
|
// Function declarations for builtin commands
|
||||||
int cd(char **args);
|
int cd(char **args);
|
||||||
int help(char **args);
|
int help(char **args);
|
||||||
|
@ -81,7 +82,7 @@ int quit(char **args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int history(char **args) {
|
int history(char **args) {
|
||||||
char **history = get_all_history();
|
char **history = get_all_history(true);
|
||||||
|
|
||||||
for (int i = 0; history[i] != NULL; ++i) {
|
for (int i = 0; history[i] != NULL; ++i) {
|
||||||
printf("%s\n", history[i]);
|
printf("%s\n", history[i]);
|
||||||
|
@ -158,17 +159,24 @@ int execute(char **args) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
save_command_history(args); // save command to history file
|
||||||
|
|
||||||
// prioritize builtin commands
|
// prioritize builtin commands
|
||||||
for (int i = 0; i < num_builtins(); i++) {
|
for (int i = 0; i < num_builtins(); i++) {
|
||||||
if (strcmp(args[0], builtin_cmds[i]) == 0) {
|
if (strcmp(args[0], builtin_cmds[i]) == 0) {
|
||||||
return (*builtin_func[i])(args);
|
return (*builtin_func[i])(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
while (*args) {
|
|
||||||
|
|
||||||
|
int num_arg = 0;
|
||||||
|
|
||||||
|
while (*args != NULL) {
|
||||||
|
num_arg++; // count number of args
|
||||||
|
args++;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
args -= num_arg;
|
||||||
|
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
int status;
|
int status;
|
||||||
|
|
73
history.c
73
history.c
|
@ -1,9 +1,11 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <linux/limits.h>
|
#include <linux/limits.h>
|
||||||
|
|
||||||
|
#include "history.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
|
|
||||||
FILE *history_file;
|
FILE *history_file;
|
||||||
|
@ -45,36 +47,26 @@ void check_history_file() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_command_history(char *command) {
|
void save_command_history(char **args) {
|
||||||
history_file = fopen(histfile_path, "a+");
|
history_file = fopen(histfile_path, "a+");
|
||||||
if (history_file == NULL) {
|
if (history_file == NULL) {
|
||||||
fprintf(stderr, "rush: Error opening history file\n");
|
fprintf(stderr, "rush: Error opening history file\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
int cmd_len = strlen(command);
|
char cmd[RL_BUFSIZE];
|
||||||
command[cmd_len] = '\n'; // put new line feed to split commands
|
cmd[0] = '\0';
|
||||||
|
for (int i = 0; args[i] != NULL; ++i) {
|
||||||
|
strcat(cmd, args[i]);
|
||||||
|
strcat(cmd, " ");
|
||||||
|
}
|
||||||
|
int cmd_len = strlen(cmd);
|
||||||
|
cmd[cmd_len] = '\n'; // put new line feed to split commands
|
||||||
// ptr to first obj, size of each obj, number of obj, file ptr
|
// ptr to first obj, size of each obj, number of obj, file ptr
|
||||||
fwrite(command, sizeof(char), cmd_len + 1, history_file);
|
fwrite(cmd, sizeof(char), cmd_len + 1, history_file);
|
||||||
fclose(history_file);
|
fclose(history_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *read_command(int direction) {
|
char *read_command(int direction) {
|
||||||
history_file = fopen(histfile_path, "rb"); // read binary mode
|
|
||||||
if (history_file == NULL) {
|
|
||||||
fprintf(stderr, "rush: Error opening history file\n");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
// normal bufsize is 1024, we serach for 1025 bytes for new line feed
|
|
||||||
int search_len = RL_BUFSIZE + 1;
|
|
||||||
char search[search_len];
|
|
||||||
fseek(history_file, -search_len, SEEK_END); // go back 1025 characters from end of file
|
|
||||||
int count = fread(search, 1, search_len - 1, history_file); // try to read 1025 characters from file, returning count number of bytes
|
|
||||||
search[count] = '\0';
|
|
||||||
char *last_nlf = strrchr(search, '\n'); // locate last occurence of \n in a searching string
|
|
||||||
if (last_nlf == NULL) {
|
|
||||||
// no history
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (direction == 1) { // up
|
if (direction == 1) { // up
|
||||||
cmd_count++;
|
cmd_count++;
|
||||||
} else { // down
|
} else { // down
|
||||||
|
@ -84,24 +76,18 @@ char *read_command(int direction) {
|
||||||
cmd_count--;
|
cmd_count--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < cmd_count; i++) {
|
char **history = get_all_history(false);
|
||||||
search[last_nlf - search] = '\0'; // terminate string earlier to find second last \n, search points to first char and last_nlf is last \n, difference is the index of \n
|
int num_history = 0;
|
||||||
last_nlf = strrchr(search, '\n'); // call strrchr 2 times to get second last new line feed in search string as every life is new line feed
|
while (*history != NULL) {
|
||||||
if ((last_nlf - search) == (strchr(search, '\n') - search)) {
|
num_history++;
|
||||||
// check if the first \n is the last \n we searching for, if yes it is first command
|
history++;
|
||||||
cmd_count--;
|
|
||||||
search[last_nlf - search] = '\0'; // terminate string earlier to find second last \n, search points to first char and last_nlf is last \n, difference is the index of \n
|
|
||||||
char *first_cmd = malloc(sizeof(char) * (last_nlf - search) + 1);
|
|
||||||
if (first_cmd == NULL) {
|
|
||||||
fprintf(stderr, "rush: Error allocating memory\n");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
strcpy(first_cmd, search);
|
if (cmd_count > num_history) {
|
||||||
return first_cmd;
|
cmd_count = num_history;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
history -= num_history;
|
||||||
fclose(history_file);
|
return history[num_history - cmd_count];
|
||||||
return last_nlf + 1; // return the string from the new line feed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int is_duplicate(char **history, int line_count, char *line) {
|
int is_duplicate(char **history, int line_count, char *line) {
|
||||||
|
@ -113,7 +99,7 @@ int is_duplicate(char **history, int line_count, char *line) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char **get_all_history() {
|
char **get_all_history(bool check) {
|
||||||
history_file = fopen(histfile_path, "r");
|
history_file = fopen(histfile_path, "r");
|
||||||
if (history_file == NULL) {
|
if (history_file == NULL) {
|
||||||
fprintf(stderr, "rush: Error opening history file\n");
|
fprintf(stderr, "rush: Error opening history file\n");
|
||||||
|
@ -130,6 +116,7 @@ char **get_all_history() {
|
||||||
|
|
||||||
while (fgets(buffer, sizeof(buffer), history_file) != NULL) {
|
while (fgets(buffer, sizeof(buffer), history_file) != NULL) {
|
||||||
buffer[strcspn(buffer, "\n")] = '\0';
|
buffer[strcspn(buffer, "\n")] = '\0';
|
||||||
|
if (check) {
|
||||||
if (!is_duplicate(history, line_count, buffer)) {
|
if (!is_duplicate(history, line_count, buffer)) {
|
||||||
history[line_count] = strdup(buffer);
|
history[line_count] = strdup(buffer);
|
||||||
if (history[line_count] == NULL) {
|
if (history[line_count] == NULL) {
|
||||||
|
@ -142,6 +129,18 @@ char **get_all_history() {
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
history[line_count] = strdup(buffer);
|
||||||
|
if (history[line_count] == NULL) {
|
||||||
|
fprintf(stderr, "Error allocating memory\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
line_count++;
|
||||||
|
if (line_count >= MAX_HISTORY) {
|
||||||
|
fprintf(stderr, "Maximum number of lines reached.\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(history_file);
|
fclose(history_file);
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#ifndef HISTORY_H_
|
#ifndef HISTORY_H_
|
||||||
#define HISTORY_H_
|
#define HISTORY_H_
|
||||||
|
|
||||||
void save_command_history(char *command);
|
void save_command_history(char **args);
|
||||||
void check_history_file();
|
void check_history_file();
|
||||||
char *read_command(int direction);
|
char *read_command(int direction);
|
||||||
char **get_all_history();
|
char **get_all_history(bool check);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
348
rush.c
348
rush.c
|
@ -69,7 +69,7 @@ char **setup_path_variable() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool find_command(char **paths, char *command) {
|
bool find_command(char **paths, char *command) {
|
||||||
if (strcmp(command, "") == 0) {
|
if (strncmp(command, "", 1) == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
while (*paths != NULL) {
|
while (*paths != NULL) {
|
||||||
|
@ -97,147 +97,11 @@ void shiftright(int chars) {
|
||||||
printf("\033[%dC", chars);
|
printf("\033[%dC", chars);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *readline(char **paths) {
|
void clearline() {
|
||||||
int bufsize = RL_BUFSIZE;
|
|
||||||
int position = 0;
|
|
||||||
char *buffer = malloc(sizeof(char) * bufsize);
|
|
||||||
|
|
||||||
bool moved = false;
|
|
||||||
bool backspaced = false;
|
|
||||||
bool navigated = false;
|
|
||||||
bool insertatmiddle = false;
|
|
||||||
if (!buffer) {
|
|
||||||
fprintf(stderr, "rush: Error allocating memory\n");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer[0] = '\0';
|
|
||||||
while (1) {
|
|
||||||
int c = getchar(); // read a character
|
|
||||||
int buf_len = strlen(buffer);
|
|
||||||
|
|
||||||
// check each character user has input
|
|
||||||
switch (c) {
|
|
||||||
case EOF:
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
case 10: {
|
|
||||||
// enter/new line feed
|
|
||||||
if (buf_len == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
buffer[buf_len] = '\0';
|
|
||||||
// clear all characters after the command
|
|
||||||
for (int start = buf_len + 1; buffer[start] != '\0'; start++) {
|
|
||||||
buffer[start] = '\0';
|
|
||||||
}
|
|
||||||
printf("\n"); // give space for response
|
|
||||||
save_command_history(buffer);
|
|
||||||
position = 0;
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
case 127: // backspace
|
|
||||||
if (buf_len >= 1) {
|
|
||||||
position--;
|
|
||||||
for (int i = position; i < buf_len; i++) {
|
|
||||||
// shift the buffer
|
|
||||||
buffer[i] = buffer[i + 1];
|
|
||||||
}
|
|
||||||
backspaced = true;
|
|
||||||
moved = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 27: // arrow keys comes at three characters, 27, 91, then 65-68
|
|
||||||
if (getchar() == 91) {
|
|
||||||
int arrow_key = getchar();
|
|
||||||
if (arrow_key == 65) { // up
|
|
||||||
// read history file and fill prompt with latest command
|
|
||||||
char *last_command = read_command(1);
|
|
||||||
if (last_command != NULL) {
|
|
||||||
strcpy(buffer, last_command);
|
|
||||||
navigated = true;
|
|
||||||
}
|
|
||||||
moved = false;
|
|
||||||
break;
|
|
||||||
} else if (arrow_key == 66) { // down
|
|
||||||
char *last_command = read_command(0);
|
|
||||||
if (last_command != NULL) {
|
|
||||||
strcpy(buffer, last_command);
|
|
||||||
navigated = true;
|
|
||||||
}
|
|
||||||
moved = false;
|
|
||||||
break;
|
|
||||||
} else if (arrow_key == 67) { // right
|
|
||||||
if (position < buf_len) {
|
|
||||||
shiftright(1);
|
|
||||||
position++;
|
|
||||||
}
|
|
||||||
moved = true;
|
|
||||||
break;
|
|
||||||
} else if (arrow_key == 68) { // left
|
|
||||||
if (position >= 1) {
|
|
||||||
shiftleft(1);
|
|
||||||
position--;
|
|
||||||
}
|
|
||||||
moved = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if (c > 31 && c < 127) {
|
|
||||||
if (position == buf_len) {
|
|
||||||
// Append character to the end of the buffer
|
|
||||||
buffer[buf_len] = c;
|
|
||||||
buffer[buf_len + 1] = '\0';
|
|
||||||
moved = false;
|
|
||||||
navigated = false;
|
|
||||||
} else {
|
|
||||||
// Insert character at the current position
|
|
||||||
memmove(&buffer[position + 1], &buffer[position], buf_len - position + 1);
|
|
||||||
buffer[position] = c;
|
|
||||||
shiftright(1);
|
|
||||||
insertatmiddle = true;
|
|
||||||
}
|
|
||||||
position++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (navigated && buf_len >= 1) {
|
|
||||||
if (position != 0) {
|
|
||||||
shiftleft(buf_len); // move cursor to the beginning
|
|
||||||
printf("\033[K"); // clear line to the right of cursor
|
printf("\033[K"); // clear line to the right of cursor
|
||||||
}
|
}
|
||||||
}
|
|
||||||
buf_len = strlen(buffer);
|
void highlight(char *buffer, char **paths) {
|
||||||
if (moved) {
|
|
||||||
moved = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!navigated) {
|
|
||||||
if (position != buf_len) {
|
|
||||||
// not at normal place
|
|
||||||
if (backspaced) {
|
|
||||||
shiftleft(position + 1);
|
|
||||||
} else {
|
|
||||||
shiftleft(position); // move cursor to the beginning
|
|
||||||
}
|
|
||||||
} else if (buf_len > 1) {
|
|
||||||
if (backspaced) {
|
|
||||||
shiftleft(buf_len + 1); // move cursor to the beginning
|
|
||||||
} else {
|
|
||||||
shiftleft(buf_len - 1); // move cursor to the beginning
|
|
||||||
}
|
|
||||||
} else if (buf_len == 1) {
|
|
||||||
if (backspaced) {
|
|
||||||
shiftleft(2);
|
|
||||||
}
|
|
||||||
} else if (buf_len == 0) {
|
|
||||||
if (backspaced) {
|
|
||||||
shiftleft(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("\033[K"); // clear line to the right of cursor
|
|
||||||
} else {
|
|
||||||
navigated = false;
|
|
||||||
}
|
|
||||||
char *cmd_part = strchr(buffer, ' ');
|
char *cmd_part = strchr(buffer, ' ');
|
||||||
char *command_without_arg = NULL;
|
char *command_without_arg = NULL;
|
||||||
int cmd_len = 0;
|
int cmd_len = 0;
|
||||||
|
@ -281,6 +145,186 @@ char *readline(char **paths) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(command_without_arg);
|
free(command_without_arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *readline(char **paths) {
|
||||||
|
int bufsize = RL_BUFSIZE;
|
||||||
|
int position = 0;
|
||||||
|
char *buffer = malloc(sizeof(char) * bufsize);
|
||||||
|
|
||||||
|
bool moved = false;
|
||||||
|
bool backspaced = false;
|
||||||
|
bool navigated = false;
|
||||||
|
bool insertatmiddle = false;
|
||||||
|
bool replaced = false;
|
||||||
|
if (!buffer) {
|
||||||
|
fprintf(stderr, "rush: Error allocating memory\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[0] = '\0';
|
||||||
|
while (1) {
|
||||||
|
int c = getchar(); // read a character
|
||||||
|
int buf_len = strlen(buffer);
|
||||||
|
|
||||||
|
// check each character user has input
|
||||||
|
switch (c) {
|
||||||
|
case EOF:
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
case 10: {
|
||||||
|
// enter/new line feed
|
||||||
|
if (buf_len == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// check if command includes !!
|
||||||
|
if (strstr(buffer, "!!") != NULL) {
|
||||||
|
char *last_command = read_command(1);
|
||||||
|
if (last_command != NULL) {
|
||||||
|
// replace !! with the last command
|
||||||
|
char *replace = strstr(buffer, "!!");
|
||||||
|
int replace_len = strlen(replace);
|
||||||
|
int last_command_len = strlen(last_command);
|
||||||
|
int buffer_len = strlen(buffer);
|
||||||
|
if (last_command_len > replace_len) {
|
||||||
|
buffer = realloc(buffer, buffer_len + last_command_len - replace_len + 1);
|
||||||
|
if (!buffer) {
|
||||||
|
fprintf(stderr, "rush: Error allocating memory\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memmove(replace + last_command_len, replace + replace_len, buffer_len - (replace - buffer) - replace_len + 1);
|
||||||
|
memcpy(replace, last_command, last_command_len);
|
||||||
|
position += last_command_len - replace_len;
|
||||||
|
shiftright(last_command_len - replace_len);
|
||||||
|
replaced = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buffer[buf_len] = '\0';
|
||||||
|
// clear all characters after the command
|
||||||
|
for (int start = buf_len + 1; buffer[start] != '\0'; start++) {
|
||||||
|
buffer[start] = '\0';
|
||||||
|
}
|
||||||
|
printf("\n"); // give space for response
|
||||||
|
position = 0;
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 127: // backspace
|
||||||
|
if (buf_len >= 1) {
|
||||||
|
position--;
|
||||||
|
for (int i = position; i < buf_len; i++) {
|
||||||
|
// shift the buffer
|
||||||
|
buffer[i] = buffer[i + 1];
|
||||||
|
}
|
||||||
|
backspaced = true;
|
||||||
|
moved = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 27: // arrow keys comes at three characters, 27, 91, then 65-68
|
||||||
|
if (getchar() == 91) {
|
||||||
|
int arrow_key = getchar();
|
||||||
|
if (arrow_key == 65) { // up
|
||||||
|
// read history file and fill prompt with latest command
|
||||||
|
char *last_command = read_command(1);
|
||||||
|
if (last_command != NULL) {
|
||||||
|
strcpy(buffer, last_command);
|
||||||
|
}
|
||||||
|
navigated = true;
|
||||||
|
moved = false;
|
||||||
|
break;
|
||||||
|
} else if (arrow_key == 66) { // down
|
||||||
|
char *last_command = read_command(0);
|
||||||
|
if (last_command != NULL) {
|
||||||
|
strcpy(buffer, last_command);
|
||||||
|
}
|
||||||
|
navigated = true;
|
||||||
|
moved = false;
|
||||||
|
break;
|
||||||
|
} else if (arrow_key == 67) { // right
|
||||||
|
if (position < buf_len) {
|
||||||
|
shiftright(1);
|
||||||
|
position++;
|
||||||
|
}
|
||||||
|
moved = true;
|
||||||
|
break;
|
||||||
|
} else if (arrow_key == 68) { // left
|
||||||
|
if (position >= 1) {
|
||||||
|
shiftleft(1);
|
||||||
|
position--;
|
||||||
|
}
|
||||||
|
moved = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if (c > 31 && c < 127) {
|
||||||
|
if (position == buf_len) {
|
||||||
|
// Append character to the end of the buffer
|
||||||
|
buffer[buf_len] = c;
|
||||||
|
buffer[buf_len + 1] = '\0';
|
||||||
|
moved = false;
|
||||||
|
navigated = false;
|
||||||
|
} else {
|
||||||
|
// Insert character at the current position
|
||||||
|
memmove(&buffer[position + 1], &buffer[position], buf_len - position + 1);
|
||||||
|
buffer[position] = c;
|
||||||
|
shiftright(1);
|
||||||
|
insertatmiddle = true;
|
||||||
|
}
|
||||||
|
position++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf_len = strlen(buffer);
|
||||||
|
|
||||||
|
if (replaced) {
|
||||||
|
shiftleft(buf_len);
|
||||||
|
clearline();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (navigated && buf_len >= 1) {
|
||||||
|
if (position > 0) {
|
||||||
|
shiftleft(position); // move cursor to the beginning
|
||||||
|
clearline();
|
||||||
|
}
|
||||||
|
position = buf_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moved) {
|
||||||
|
moved = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!navigated && !replaced) {
|
||||||
|
if (position != buf_len) {
|
||||||
|
// not at normal place
|
||||||
|
if (backspaced) {
|
||||||
|
shiftleft(position + 1);
|
||||||
|
} else {
|
||||||
|
shiftleft(position); // move cursor to the beginning
|
||||||
|
}
|
||||||
|
} else if (buf_len > 1) {
|
||||||
|
if (backspaced) {
|
||||||
|
shiftleft(buf_len + 1); // move cursor to the beginning
|
||||||
|
} else {
|
||||||
|
shiftleft(buf_len - 1); // move cursor to the beginning
|
||||||
|
}
|
||||||
|
} else if (buf_len == 1) {
|
||||||
|
if (backspaced) {
|
||||||
|
shiftleft(2);
|
||||||
|
}
|
||||||
|
} else if (buf_len == 0) {
|
||||||
|
if (backspaced) {
|
||||||
|
shiftleft(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clearline();
|
||||||
|
} else {
|
||||||
|
navigated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
highlight(buffer, paths);
|
||||||
|
|
||||||
if (backspaced) {
|
if (backspaced) {
|
||||||
if (buf_len != position) {
|
if (buf_len != position) {
|
||||||
|
@ -291,8 +335,11 @@ char *readline(char **paths) {
|
||||||
if (insertatmiddle) {
|
if (insertatmiddle) {
|
||||||
shiftleft(buf_len - position); // move cursor back to where it was
|
shiftleft(buf_len - position); // move cursor back to where it was
|
||||||
insertatmiddle = false;
|
insertatmiddle = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if (replaced) {
|
||||||
|
replaced = false;
|
||||||
|
}
|
||||||
|
|
||||||
// If we have exceeded the buffer, reallocate.
|
// If we have exceeded the buffer, reallocate.
|
||||||
if ((buf_len + 1) >= bufsize) {
|
if ((buf_len + 1) >= bufsize) {
|
||||||
bufsize += RL_BUFSIZE;
|
bufsize += RL_BUFSIZE;
|
||||||
|
@ -332,15 +379,23 @@ char **argsplit(char *line) {
|
||||||
|
|
||||||
token = strtok(NULL, TOK_DELIM);
|
token = strtok(NULL, TOK_DELIM);
|
||||||
}
|
}
|
||||||
// makes ls and diff have color without user typing it
|
|
||||||
if (strcmp(tokens[0], "ls") == 0 || strcmp(tokens[0], "diff") == 0) {
|
|
||||||
tokens[position] = "--color=auto";
|
|
||||||
}
|
|
||||||
position++;
|
|
||||||
tokens[position] = NULL;
|
tokens[position] = NULL;
|
||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char **modifyargs(char **args) {
|
||||||
|
int num_arg = 0;
|
||||||
|
|
||||||
|
// makes ls and diff have color without user typing it
|
||||||
|
if (strncmp(args[0], "ls", 2) == 0 || strncmp(args[0], "diff", 4) == 0) {
|
||||||
|
args[num_arg] = "--color=auto";
|
||||||
|
num_arg++;
|
||||||
|
args[num_arg] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
// continously prompt for command and execute it
|
// continously prompt for command and execute it
|
||||||
void command_loop(char **paths) {
|
void command_loop(char **paths) {
|
||||||
char *line;
|
char *line;
|
||||||
|
@ -371,6 +426,7 @@ void command_loop(char **paths) {
|
||||||
|
|
||||||
line = readline(paths);
|
line = readline(paths);
|
||||||
args = argsplit(line);
|
args = argsplit(line);
|
||||||
|
args = modifyargs(args);
|
||||||
status = execute(args);
|
status = execute(args);
|
||||||
|
|
||||||
free(line);
|
free(line);
|
||||||
|
|
Loading…
Reference in a new issue