Skip to content

Commit

Permalink
更新shell和readline
Browse files Browse the repository at this point in the history
  • Loading branch information
min0911Y committed Nov 10, 2024
1 parent a97b0f0 commit d188015
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 67 deletions.
87 changes: 44 additions & 43 deletions include/pl_readline.h
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
#pragma once
#include <libc.h>
#include <data-structure.h>
#include <libc.h>

#define PL_READLINE_KEY_UP 0xff00
#define PL_READLINE_KEY_DOWN 0xff01
#define PL_READLINE_KEY_LEFT 0xff02
#define PL_READLINE_KEY_RIGHT 0xff03
#define PL_READLINE_KEY_ENTER '\n'
#define PL_READLINE_KEY_TAB '\t'
#define PL_READLINE_KEY_UP 0xff00
#define PL_READLINE_KEY_DOWN 0xff01
#define PL_READLINE_KEY_LEFT 0xff02
#define PL_READLINE_KEY_RIGHT 0xff03
#define PL_READLINE_KEY_ENTER '\n'
#define PL_READLINE_KEY_TAB '\t'
#define PL_READLINE_KEY_CTRL_A 0x01
#define PL_READLINE_KEY_CTRL_C 0x03
#define PL_READLINE_KEY_BACKSPACE '\b'
#define _SELF pl_readline_t self
#define PL_READLINE_SUCCESS 0
#define PL_READLINE_FAILED -1
#define PL_READLINE_NOT_FINISHED 1
#define _SELF pl_readline_t self
#define PL_READLINE_SUCCESS 0
#define PL_READLINE_FAILED -1
#define PL_READLINE_NOT_FINISHED 1

typedef struct pl_readline_word {
char *word; // 词组
Expand All @@ -22,53 +24,52 @@ typedef struct pl_readline_word {
如abc 则必须输入"ab"然后按tab,才会有可能有"abc"
如果是“qwe ab”则不会补全"qwe abc",除非first为false.
*/
bool first;
bool first;

char sep; // 分隔符
} pl_readline_word;

typedef struct pl_readline_words {
int len; // 词组数量
int max_len; // 词组最大数量
pl_readline_word *words; // 词组列表
} * pl_readline_words_t;
int len; // 词组数量
int max_len; // 词组最大数量
pl_readline_word *words; // 词组列表
} *pl_readline_words_t;

typedef struct pl_readline {
int (*pl_readline_hal_getch)(); // 输入函数
void (*pl_readline_hal_putch)(int ch); // 输出函数
void (*pl_readline_hal_flush)(); // 刷新函数
void (*pl_readline_get_words)(char *buf,
void (*pl_readline_get_words)(char *buf,
pl_readline_words_t words); // 获取词组列表
list_t history; // 历史记录列表
} * pl_readline_t;
list_t history; // 历史记录列表
} *pl_readline_t;
typedef struct pl_readline_runtime {
char *buffer; // 输入缓冲区
int p; // 输入缓冲区指针
int length; // 输入缓冲区长度(已经输入的字符数)
int history_idx; // 历史记录指针
char *prompt; // 提示符
size_t len; // 缓冲区最大长度
char *input_buf; // 输入缓冲区(补全的前缀)
int input_buf_ptr; // 输入缓冲区(补全的前缀)指针
bool intellisense_mode; // 智能补全模式
char *intellisense_word; // 智能补全词组
char *buffer; // 输入缓冲区
int p; // 输入缓冲区指针
int length; // 输入缓冲区长度(已经输入的字符数)
int history_idx; // 历史记录指针
char *prompt; // 提示符
size_t maxlen; // 缓冲区最大长度
char *input_buf; // 输入缓冲区(补全的前缀)
int input_buf_ptr; // 输入缓冲区(补全的前缀)指针
bool intellisense_mode; // 智能补全模式
char *intellisense_word; // 智能补全词组
} pl_readline_runtime;

pl_readline_words_t pl_readline_word_maker_init();
pl_readline_t pl_readline_init(
int (*pl_readline_hal_getch)(), void (*pl_readline_hal_putch)(int ch),
void (*pl_readline_hal_flush)(),
void (*pl_readline_get_words)(char *buf, pl_readline_words_t words));
int pl_readline(_SELF, char *prompt, char *buffer, size_t len);
pl_readline_word pl_readline_intellisense(_SELF, pl_readline_runtime *rt,
pl_readline_words_t words);
void pl_readline_insert_char_and_view(_SELF, char ch, pl_readline_runtime *rt);
void pl_readline_insert_char(char *str, char ch, int idx);
int pl_readline_word_maker_add(char *word, pl_readline_words_t words,
bool is_first, char sep);
pl_readline_t pl_readline_init(int (*pl_readline_hal_getch)(),
void (*pl_readline_hal_putch)(int ch),
void (*pl_readline_hal_flush)(),
void (*pl_readline_get_words)(char *buf, pl_readline_words_t words));
int pl_readline(_SELF, char *prompt, char *buffer, size_t maxlen);
pl_readline_word pl_readline_intellisense(_SELF, pl_readline_runtime *rt,
pl_readline_words_t words);
void pl_readline_insert_char_and_view(_SELF, char ch, pl_readline_runtime *rt);
void pl_readline_insert_char(char *str, char ch, int idx);
int pl_readline_word_maker_add(char *word, pl_readline_words_t words, bool is_first, char sep);
void pl_readline_print(_SELF, char *str);
void pl_readline_intellisense_insert(_SELF, pl_readline_runtime *rt,
pl_readline_word words);
void pl_readline_intellisense_insert(_SELF, pl_readline_runtime *rt, pl_readline_word words);
void pl_readline_word_maker_destroy(pl_readline_words_t words);
void pl_readline_next_line(_SELF, pl_readline_runtime *rt);
int pl_readline_handle_key(_SELF, int ch, pl_readline_runtime *rt);
int pl_readline_handle_key(_SELF, int ch, pl_readline_runtime *rt);
void pl_readline_uninit(_SELF);
17 changes: 14 additions & 3 deletions src/kernel/task/shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ void shell() {
if (!strlen(ch)) continue;
if (strneq(ch, "cd ", 3)) {
char *s = ch + 3;
if (s[strlen(s) - 1] == '/') {
s[strlen(s) - 1] = '\0';
}
if (streq(s, ".")) continue;
if (streq(s, "..")) {
if (streq(s, "/")) continue;
Expand All @@ -180,10 +183,18 @@ void shell() {
if (strlen(path) == 0) strcpy(path, "/");
continue;
}
if (streq(path, "/"))
sprintf(path, "%s%s", path, s);
else
char *old = strdup(path);
if (streq(path, "/")) sprintf(path, "%s%s", path, s);
if (s[0] == '/') {
strcpy(path, s);
} else
sprintf(path, "%s/%s", path, s);
if (vfs_open(path) == null) {
printf("cd: %s: No such directory\n", s);
sprintf(path, "%s", old);
free(old);
continue;
}
} else if (streq(ch, "ls")) {
list_files(path);
} else if (streq(ch, "pcils")) {
Expand Down
64 changes: 43 additions & 21 deletions src/pl_readline/plreadln.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@

#include <pl_readline.h>

static int pl_readline_add_history(_SELF, char *line) {
if (strlen(line)) list_prepend(self->history, strdup(line));
int pl_readline_add_history(_SELF, char *line) {
list_prepend(self->history, strdup(line));
return PL_READLINE_SUCCESS;
}

int pl_readline_remove_history(_SELF) {
auto list = list_head(self->history);
if (list) list_delete_node_with(self->history, list, free);
return PL_READLINE_SUCCESS;
}

Expand All @@ -30,6 +36,7 @@ pl_readline_init(int (*pl_readline_hal_getch)(), void (*pl_readline_hal_putch)(i
plreadln->pl_readline_get_words = pl_readline_get_words;
// 设置history链表
plreadln->history = NULL;
pl_readline_add_history(plreadln, "");
return plreadln;
}
void pl_readline_uninit(_SELF) {
Expand All @@ -38,12 +45,12 @@ void pl_readline_uninit(_SELF) {
}
void pl_readline_insert_char(char *str, char ch, int idx) {
int len = strlen(str);
memmove(str + idx + 1, str + idx, len - idx);
if (len) memmove(str + idx + 1, str + idx, len - idx);
str[idx] = ch;
}
static void pl_readline_delete_char(char *str, int idx) {
int len = strlen(str);
memmove(str + idx, str + idx + 1, len - idx);
if (len) memmove(str + idx, str + idx + 1, len - idx);
str[len] = '\0';
}

Expand Down Expand Up @@ -83,14 +90,14 @@ static void pl_readline_handle_key_down_up(_SELF, pl_readline_runtime *rt, int n
self->pl_readline_hal_flush(); // 刷新输出缓冲区,在Linux下需要,否则会导致输入不显示
rt->p = 0; // 光标移动到最左边
rt->length = 0; // 清空缓冲区长度
memset(rt->buffer, 0, rt->len); // 清空缓冲区
memset(rt->buffer, 0, rt->maxlen); // 清空缓冲区
strcpy(rt->buffer, node->data);
pl_readline_print(self, rt->buffer); // 打印历史记录
rt->length = strlen(rt->buffer); // 更新缓冲区长度
rt->p = rt->length;

memset(rt->input_buf, 0, rt->len); // 清空输入缓冲区
rt->input_buf_ptr = 0; // 输入缓冲区指针置0
memset(rt->input_buf, 0, rt->maxlen); // 清空输入缓冲区
rt->input_buf_ptr = 0; // 输入缓冲区指针置0
// strcpy(rt->input_buf, node->data); // 复制历史记录到输入缓冲区
char *p = node->data;
while (*p) {
Expand Down Expand Up @@ -141,7 +148,7 @@ int pl_readline_handle_key(_SELF, int ch, pl_readline_runtime *rt) {
rt->intellisense_word = NULL;
}
}
if (rt->length >= rt->len) { // 输入的字符数超过最大长度
if (rt->length >= rt->maxlen) { // 输入的字符数超过最大长度
pl_readline_to_the_end(self, rt->length - rt->p);
self->pl_readline_hal_putch('\n');
rt->buffer[rt->length] = '\0';
Expand All @@ -151,9 +158,14 @@ int pl_readline_handle_key(_SELF, int ch, pl_readline_runtime *rt) {
switch (ch) {
case PL_READLINE_KEY_DOWN:
rt->history_idx--;
pl_readline_handle_key_down_up(self, rt, 1); // n = 1是为了的失败的时候还原
// n = 1是为了的失败的时候还原
pl_readline_handle_key_down_up(self, rt, 1);
break;
case PL_READLINE_KEY_UP: {
if (rt->history_idx == 0) {
pl_readline_remove_history(self);
pl_readline_add_history(self, rt->buffer);
}
rt->history_idx++;
// n = -1是为了的失败的时候还原
pl_readline_handle_key_down_up(self, rt, -1);
Expand All @@ -165,7 +177,7 @@ int pl_readline_handle_key(_SELF, int ch, pl_readline_runtime *rt) {
rt->p--;
pl_readline_print(self, "\e[D");
if (rt->buffer[rt->p] == ' ') {
memset(rt->input_buf, 0, rt->len);
memset(rt->input_buf, 0, rt->maxlen);
// 光标移动到前一个空格
int i = rt->p;
while (i && rt->buffer[i - 1] != ' ') {
Expand All @@ -190,7 +202,7 @@ int pl_readline_handle_key(_SELF, int ch, pl_readline_runtime *rt) {
rt->p++;
pl_readline_print(self, "\e[C");
if (rt->buffer[rt->p - 1] == ' ') {
memset(rt->input_buf, 0, rt->len);
memset(rt->input_buf, 0, rt->maxlen);
// 光标移动到前一个空格
int i = rt->p;
int j = i;
Expand All @@ -216,7 +228,7 @@ int pl_readline_handle_key(_SELF, int ch, pl_readline_runtime *rt) {
return PL_READLINE_NOT_FINISHED;
--rt->p;
if (rt->buffer[rt->p] == ' ') {
memset(rt->input_buf, 0, rt->len);
memset(rt->input_buf, 0, rt->maxlen);
// 光标移动到前一个空格
int i = rt->p;
while (i && rt->buffer[i - 1] != ' ') {
Expand Down Expand Up @@ -248,6 +260,7 @@ int pl_readline_handle_key(_SELF, int ch, pl_readline_runtime *rt) {
pl_readline_print(self, "\e[D");
pl_readline_print(self, rt->buffer + rt->p);
pl_readline_print(self, buf);

} else {
pl_readline_print(self, "\e[D \e[D");
}
Expand All @@ -256,7 +269,9 @@ int pl_readline_handle_key(_SELF, int ch, pl_readline_runtime *rt) {
pl_readline_to_the_end(self, rt->length - rt->p);
self->pl_readline_hal_putch('\n');
rt->buffer[rt->length] = '\0';
pl_readline_remove_history(self);
pl_readline_add_history(self, rt->buffer);
pl_readline_add_history(self, "");
return PL_READLINE_SUCCESS;
case PL_READLINE_KEY_TAB: { // 自动补全
pl_readline_words_t words = pl_readline_word_maker_init();
Expand All @@ -278,8 +293,16 @@ int pl_readline_handle_key(_SELF, int ch, pl_readline_runtime *rt) {
}
break;
}
case PL_READLINE_KEY_CTRL_A:
pl_readline_reset(self, rt->p, 0);
rt->p = 0;
break;
case PL_READLINE_KEY_CTRL_C:
rt->buffer[0] = '\0';
pl_readline_print(self, "^C\n");
return PL_READLINE_SUCCESS;
case ' ': {
memset(rt->input_buf, 0, rt->len);
memset(rt->input_buf, 0, rt->maxlen);
rt->input_buf_ptr = 0;
goto handle;
}
Expand All @@ -292,19 +315,18 @@ int pl_readline_handle_key(_SELF, int ch, pl_readline_runtime *rt) {
}
return PL_READLINE_NOT_FINISHED;
}

// 主体函数
int pl_readline(_SELF, char *prompt, char *buffer, size_t len) {
int pl_readline(_SELF, char *prompt, char *buffer, size_t maxlen) {
// 为了实现自动补全,需要将输入的字符保存到缓冲区中
char *input_buf = malloc(len + 1);
memset(input_buf, 0, len + 1);
char *input_buf = malloc(maxlen + 1);
memset(input_buf, 0, maxlen + 1);
int input_buf_ptr = 0;
assert(input_buf);
pl_readline_runtime rt = {buffer, 0, 0, -1, prompt, len, input_buf, 0, false, NULL};
pl_readline_runtime rt = {buffer, 0, 0, 0, prompt, maxlen, input_buf, 0, false, NULL};

// 清空缓冲区
memset(input_buf, 0, len + 1);
memset(buffer, 0, len);
memset(input_buf, 0, maxlen + 1);
memset(buffer, 0, maxlen);
// 打印提示符
pl_readline_print(self, prompt);
self->pl_readline_hal_flush(); // 刷新输出缓冲区,在Linux下需要,否则会导致输入不显示
Expand All @@ -317,4 +339,4 @@ int pl_readline(_SELF, char *prompt, char *buffer, size_t len) {
free(input_buf);
if (rt.intellisense_word) { free(rt.intellisense_word); }
return PL_READLINE_SUCCESS;
}
}

0 comments on commit d188015

Please sign in to comment.