Code Cleanup + Ctrl+D fix + Ctrl+L clears screen

- Removed some code duplication
- Ctrl+D is fixed and now works as it should (exit if user didn't
write anything, ignore otherwise)
- Ctrl+L clears the terminal screen
This commit is contained in:
Aleksandr Lebedev 2026-04-21 15:43:51 +02:00
parent ca08c9e3e5
commit 527199c23d

90
main.c
View file

@ -48,10 +48,11 @@ void* ccalloc(size_t size, size_t n)
} }
static constexpr size_t max_line = 1024; static constexpr size_t max_line = 1024;
static char string_buffer[max_line];
char* __readline_file(FILE* stream) char* __readline_file(FILE* stream)
{ {
if(fgets(string_buffer, max_line, stream) == NULL) static char buffer[max_line];
if(fgets(buffer, sizeof(buffer), stream) == NULL)
{ {
if(ferror(stream)) if(ferror(stream))
{ {
@ -62,13 +63,13 @@ char* __readline_file(FILE* stream)
return NULL; return NULL;
} }
size_t length = strlen(string_buffer); size_t length = strlen(buffer);
//Remove trailing \n //Remove trailing \n
if (length > 0 && string_buffer[length - 1] == '\n') if (length > 0 && buffer[length - 1] == '\n')
{ {
string_buffer[length - 1] = '\0'; buffer[length - 1] = '\0';
} }
return string_buffer; return buffer;
} }
static struct termios orig_termios; static struct termios orig_termios;
@ -139,24 +140,9 @@ size_t utf8_display_width(const char *buf, size_t len)
while (i < len) { while (i < len) {
unsigned char c = buf[i]; unsigned char c = buf[i];
i += utf8_char_len(c);
if ((c & 0x80) == 0) {
i += 1;
width += 1; width += 1;
} }
else if ((c & 0xE0) == 0xC0) {
i += 2;
width += 1;
}
else if ((c & 0xF0) == 0xE0) {
i += 3;
width += 1;
}
else {
i += 4;
width += 1;
}
}
return width; return width;
} }
@ -180,24 +166,9 @@ size_t visible_width(const char *s)
} }
unsigned char c = s[i]; unsigned char c = s[i];
i += utf8_char_len(c);
if ((c & 0x80) == 0) {
i += 1;
width += 1; width += 1;
} }
else if ((c & 0xE0) == 0xC0) {
i += 2;
width += 1;
}
else if ((c & 0xF0) == 0xE0) {
i += 3;
width += 1;
}
else {
i += 4;
width += 1;
}
}
return width; return width;
} }
@ -205,7 +176,7 @@ size_t visible_width(const char *s)
char* __readline_interactive(char* prompt) char* __readline_interactive(char* prompt)
{ {
enable_raw_mode(); enable_raw_mode();
static char buffer[max_length]; static char buffer[max_line];
size_t cursor = 0; size_t cursor = 0;
size_t len = 0; size_t len = 0;
ssize_t swrite(int fd, const char* str) ssize_t swrite(int fd, const char* str)
@ -282,6 +253,19 @@ char* __readline_interactive(char* prompt)
} }
} }
} }
else if (utf8[0] == 0x04) //CTRL + D
{
if(len == 0)
{
disable_raw_mode();
return NULL;
}
}
else if (utf8[0] == 0x0C) //CTRL + L
{
swrite(1, "\x1b[2J"); // clear screen
swrite(1, "\x1b[H"); // cursor home
}
else { else {
if(len < sizeof(buffer)) if(len < sizeof(buffer))
{ {
@ -866,7 +850,7 @@ int execute_pipeline(struct pipeline* pl, int capture, char** out)
if(strcmp(cmd_name, "cd") == 0) if(strcmp(cmd_name, "cd") == 0)
{ {
char* path = cmd->argv[1] ? cmd->argv[1] : getenv("HOME"); char* path = cmd->argv[1] ? cmd->argv[1] : get_home();
if (cd(path) < 0) if (cd(path) < 0)
{ {
char err_buf[max_length] = {0}; char err_buf[max_length] = {0};
@ -923,43 +907,43 @@ int execute_pipeline(struct pipeline* pl, int capture, char** out)
return WEXITSTATUS(status); return WEXITSTATUS(status);
} }
char username_buf[max_env_var_length] = {0};
char* get_user() char* get_user()
{ {
static char buf[max_env_var_length] = {0};
char* result = getenv("USER"); char* result = getenv("USER");
if(!result) if(!result)
{ {
return "UNKNOWN"; return "UNKNOWN";
} }
size_t length = min_size_t(sizeof(username_buf), strlen(result) + 1); size_t length = min_size_t(sizeof(buf), strlen(result) + 1);
memcpy(username_buf, result, length); memcpy(buf, result, length);
return username_buf; return buf;
} }
char home_buf[max_length] = {0};
char* get_home() char* get_home()
{ {
static char buf[max_length] = {0};
char* result = getenv("HOME"); char* result = getenv("HOME");
if(!result) if(!result)
{ {
return "UNKNOWN_HOME_PATH"; return "UNKNOWN_HOME_PATH";
} }
size_t length = min_size_t(sizeof(home_buf), strlen(result) + 1); size_t length = min_size_t(sizeof(buf), strlen(result) + 1);
memcpy(home_buf, result, length); memcpy(buf, result, length);
return home_buf; return buf;
} }
char pwd_buf[max_length] = {0};
char* get_pwd() char* get_pwd()
{ {
static char buf[max_length] = {0};
char* result = getenv("PWD"); char* result = getenv("PWD");
if(!result) if(!result)
{ {
return "UNKNOWN"; return "UNKNOWN";
} }
size_t length = min_size_t(sizeof(pwd_buf), strlen(result) + 1); size_t length = min_size_t(sizeof(buf), strlen(result) + 1);
memcpy(pwd_buf, result, length); memcpy(buf, result, length);
return pwd_buf; return buf;
} }
char* prettify_pwd(char* pwd) char* prettify_pwd(char* pwd)
@ -988,9 +972,9 @@ char* prettify_pwd(char* pwd)
return pwd; return pwd;
} }
char prompt_buf[max_length] = {0};
char* generate_ps1_prompt() char* generate_ps1_prompt()
{ {
static char prompt_buf[max_length] = {0};
char env_buf[max_env_var_length] = {0}; char env_buf[max_env_var_length] = {0};
char* ps1 = getenv("PS1"); char* ps1 = getenv("PS1");
if(!ps1) if(!ps1)