aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-09 03:41:56 +0000
committer_ov4 <ov4@ov4.org>2026-10-09 03:41:56 +0000
commitc47cfb32f4ca9ed7bbb360053d90f1fb52a95708 (patch)
tree0d186530cbccb6f14f5230da1ad145b4c98aeac0
parentd29590546054feabff2d7e559665811d1d28f538 (diff)
add line editor history
-rw-r--r--include/history.h4
-rw-r--r--include/line/cursor.h4
-rw-r--r--include/line/mode.h2
-rw-r--r--include/line/type.h2
-rw-r--r--module-test/line_test.cc24
-rw-r--r--src/history.cc5
-rw-r--r--src/line/cursor.cc77
-rw-r--r--src/line/mode.cc15
8 files changed, 110 insertions, 23 deletions
diff --git a/include/history.h b/include/history.h
index 77ab9ed..a4966e2 100644
--- a/include/history.h
+++ b/include/history.h
@@ -8,7 +8,11 @@ namespace ov4
inline std::vector<std::string> history_vec;
+inline size_t history_index;
+
void add_history(const std::string &s);
void clear_history();
+std::size_t get_last_index();
+
}
diff --git a/include/line/cursor.h b/include/line/cursor.h
index 032269d..217f5f2 100644
--- a/include/line/cursor.h
+++ b/include/line/cursor.h
@@ -38,5 +38,9 @@ void update_window_size();
void move_cursor(T_cursor_movement_direction d);
+void switch_history(T_cursor_movement_direction d);
+
+void reset_editor();
+
}
diff --git a/include/line/mode.h b/include/line/mode.h
index d080fc3..417dd3a 100644
--- a/include/line/mode.h
+++ b/include/line/mode.h
@@ -20,4 +20,6 @@ void clear_below();
std::string readline();
+void editor_exit(int code);
+
}
diff --git a/include/line/type.h b/include/line/type.h
index b85a81c..321e18d 100644
--- a/include/line/type.h
+++ b/include/line/type.h
@@ -13,6 +13,8 @@ enum class T_cursor_movement_direction
{
LEFT,
RIGHT,
+ UP,
+ DOWN,
};
} \ No newline at end of file
diff --git a/module-test/line_test.cc b/module-test/line_test.cc
index ea149ff..2ad6f32 100644
--- a/module-test/line_test.cc
+++ b/module-test/line_test.cc
@@ -5,6 +5,7 @@
src/line/mode.cc \
src/line/cursor.cc \
src/line/getter.cc \
+ src/history.cc \
-std=c++26 -Iinclude -Ithird_party/magic_enum/include \
-O0 -ggdb3 -fno-omit-frame-pointer -fno-inline -D_GLIBCXX_ASSERTIONS \
-o module-test/line_test.out
@@ -26,15 +27,18 @@ using namespace ov4;
int main()
{
- print("shell $ ");
- enable_raw();
- T_position pos = get_cursor_position();
- cursor_row = pos.row;
- cursor_col = pos.col;
- prompt_pos = cursor_col;
- string s = readline();
- disable_raw();
- cout << "\n\n\n\n" << endl;
- cout << s << endl;
+ while (true)
+ {
+ print("shell $ ");
+ enable_raw();
+ T_position pos = get_cursor_position();
+ cursor_row = pos.row;
+ cursor_col = pos.col;
+ prompt_pos = cursor_col;
+ string s = readline();
+ disable_raw();
+ cout << "\n\n\n\n" << endl;
+ cout << s << endl;
+ }
return 0;
}
diff --git a/src/history.cc b/src/history.cc
index 79f0ee2..3e976ce 100644
--- a/src/history.cc
+++ b/src/history.cc
@@ -14,5 +14,10 @@ void clear_history()
{
history_vec.clear();
}
+
+size_t get_last_index()
+{
+ return history_vec.size() - 1;
+}
}
diff --git a/src/line/cursor.cc b/src/line/cursor.cc
index 42b1685..bd2567e 100644
--- a/src/line/cursor.cc
+++ b/src/line/cursor.cc
@@ -10,6 +10,8 @@
#include <sys/ioctl.h>
#include "line/getter.h"
+#include "history.h"
+#include "line/mode.h"
using namespace std;
@@ -45,16 +47,12 @@ void move_cursor(char c)
{
switch (c)
{
- // case 'A':
- // print("\x1b[A");
- // fflush(stdout);
- // cursor_row--;
- // break;
- // case 'B':
- // print("\x1b[B");
- // fflush(stdout);
- // cursor_row++;
- // break;
+ case 'A':
+ switch_history(T_cursor_movement_direction::UP);
+ break;
+ case 'B':
+ switch_history(T_cursor_movement_direction::DOWN);
+ break;
case 'C':
// if (get_cursor_real_pos() < line_end_pos)
// {
@@ -82,6 +80,9 @@ void move_cursor(char c)
void cursor_input_char(char c)
{
+ // if receives any input
+ // it should move to the latest history
+ history_index = get_last_index();
// normal input
if (c != '\b')
{
@@ -115,7 +116,7 @@ void update_window_size()
{
winsize ws;
if (ioctl(1, TIOCGWINSZ, &ws) == -1)
- exit(-1); // TODO: fix
+ editor_exit(-1); // TODO: fix
window_size_row = ws.ws_row;
window_size_col = ws.ws_col;
@@ -167,8 +168,60 @@ void move_cursor(T_cursor_movement_direction d)
break;
default:
- exit(-1); // TODO: fix
+ editor_exit(-1); // TODO: fix
+ }
+}
+
+void switch_history(T_cursor_movement_direction d)
+{
+ switch (d)
+ {
+ case T_cursor_movement_direction::UP:
+ if (history_index == 0)
+ {
+ print("\a"); fflush(stdout);
+ }
+ else
+ {
+ history_index--;
+ reset_editor();
+ line_buffer = history_vec[history_index];
+ // move to the "start" of the zone
+ // should skip prompt zone
+ print("\r"); fflush(stdout);
+ print("\x1b[{}C", prompt_pos-1); fflush(stdout);
+ print_override(line_buffer);
+ }
+ break;
+
+ case T_cursor_movement_direction::DOWN:
+ if (history_index == get_last_index())
+ {
+ print("\a"); fflush(stdout);
+ }
+ else
+ {
+ history_index++;
+ reset_editor();
+ line_buffer = history_vec[history_index];
+ // move to the "start" of the zone
+ // should skip prompt zone
+ print("\r"); fflush(stdout);
+ print("\x1b[{}C", prompt_pos-1); fflush(stdout);
+ print_override(line_buffer);
+ }
+ break;
+
+ default:
+ editor_exit(-1); // TODO: fix
}
}
+void reset_editor()
+{
+ line_buffer = "";
+ buffer_index_cursor = 0;
+ _buffer_index_display_begin = 0;
+}
+
}
diff --git a/src/line/mode.cc b/src/line/mode.cc
index e8024fa..dc9291d 100644
--- a/src/line/mode.cc
+++ b/src/line/mode.cc
@@ -7,6 +7,7 @@
#include "line/cursor.h"
#include "line/getter.h"
+#include "history.h"
using namespace std;
@@ -70,13 +71,16 @@ void clear_below()
string readline()
{
update_window_size();
+ history_vec.push_back("");
+ history_index = get_last_index();
+ reset_editor();
T_position pos = get_cursor_position();
prompt_pos = pos.col;
char c;
while (read(STDIN_FILENO, &c, 1) == 1)
{
- if (c == 'Q') break;
+ if (c == 'Q') editor_exit(-1); // TODO: remove
else if (c == 'C')
{
clear_below();
@@ -92,6 +96,7 @@ string readline()
if (c == 13) // \n
{
//print("line: {}\r\n", line_buffer);
+ history_vec[get_last_index()] = line_buffer;
return line_buffer;
}
@@ -117,8 +122,16 @@ string readline()
print_override(line_buffer);
}
}
+
+ history_vec[get_last_index()] = line_buffer;
return line_buffer;
}
+void editor_exit(int code)
+{
+ disable_raw();
+ exit(code);
+}
+
}