summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-18 14:47:46 +0000
committer_ov4 <ov4@ov4.org>2026-10-18 14:47:46 +0000
commitcd55aa462b112896240ab736bf60035fdb30ca2d (patch)
tree4446cee1af4ba561e46b1587f96bb61aecedceb2
parentc8479ceff6aea37def538c902324c68930947f21 (diff)
adapt line editor
-rw-r--r--include/eval.h2
-rw-r--r--include/line/line_editor.h69
-rw-r--r--src/eval/eval.cc3
-rw-r--r--src/line/cursor.cc23
-rw-r--r--src/line/getter.cc14
-rw-r--r--src/line/input.cc8
-rw-r--r--src/line/mode.cc4
-rw-r--r--src/main.cc48
8 files changed, 108 insertions, 63 deletions
diff --git a/include/eval.h b/include/eval.h
index 5ccecf4..6268403 100644
--- a/include/eval.h
+++ b/include/eval.h
@@ -22,7 +22,7 @@ inline T_pipe T_pipe_not_pipe;
int eval_exe(const std::string &s, bool is_async);
int eval_exe(const std::string &s, bool is_async, const T_lexer *lexer_instance, size_t i, const T_pipe &pi = T_pipe_not_pipe);
int eval_tree_cd(size_t i, const T_lexer &lexer_instance, bool inside_subshell, T_pipe pi = T_pipe_not_pipe);
-void eval(char *cmdline);
+void eval(const std::string &s);
void eval_err(int err);
}
diff --git a/include/line/line_editor.h b/include/line/line_editor.h
new file mode 100644
index 0000000..a97b09c
--- /dev/null
+++ b/include/line/line_editor.h
@@ -0,0 +1,69 @@
+#pragma once
+
+#include <termios.h>
+#include <string>
+
+#include "line/type.h"
+
+namespace ov4
+{
+
+// mode
+inline termios attr;
+inline bool raw_enabled = false;
+
+void disable_raw();
+void enable_raw();
+void editor_exit(int code);
+
+class T_line_editor
+{
+public:
+ // cursor
+
+ // 1-based
+ int cursor_row = 1;
+ int cursor_col = 1;
+ int prompt_pos = 1;
+ int window_size_row = 24;
+ int window_size_col = 80;
+
+ // 0-based index
+ int buffer_index_cursor = 0;
+ // index [begin, end] is displayed
+ // NB: CLOSE interval
+ int _buffer_index_display_begin = 0;
+ //int buffer_index_display_end;
+
+ std::string line_buffer;
+
+ void print_override(const std::string &s);
+ void move_cursor(char c);
+ void cursor_input_char(char c);
+ void update_window_size();
+ void move_cursor(T_cursor_movement_direction d);
+ void switch_history(T_cursor_movement_direction d);
+ void reset_editor();
+ void cursor_skip_prompt();
+ void check_window_update();
+
+
+ // getter
+ bool windows_size_changed = false;
+
+ int get_terminal_pos_cursor();
+ int get_buffer_index_display_begin();
+ int get_buffer_index_display_end();
+ int get_terminal_pos_line_end();
+
+ //void update_line_end_pos();
+
+ T_position get_cursor_position();
+
+
+ // input
+ void clear_below();
+ std::string readline();
+};
+
+} \ No newline at end of file
diff --git a/src/eval/eval.cc b/src/eval/eval.cc
index 1551d1a..82ba710 100644
--- a/src/eval/eval.cc
+++ b/src/eval/eval.cc
@@ -37,9 +37,8 @@ namespace ov4
* background children don't receive SIGINT (SIGTSTP) from the kernel
* when we type ctrl-c (ctrl-z) at the keyboard.
*/
-void eval(char *raw_input)
+void eval(const string &s)
{
- string s = raw_input;
T_lexer lexer_instance;
try
diff --git a/src/line/cursor.cc b/src/line/cursor.cc
index a273843..81454ae 100644
--- a/src/line/cursor.cc
+++ b/src/line/cursor.cc
@@ -1,4 +1,4 @@
-#include "line/cursor.h"
+#include "line/line_editor.h"
#include <print>
#include <iostream>
@@ -9,17 +9,14 @@
#include <termios.h>
#include <sys/ioctl.h>
-#include "line/getter.h"
#include "history.h"
-#include "line/mode.h"
-#include "line/input.h"
using namespace std;
namespace ov4
{
-void print_override(const std::string &s)
+void T_line_editor::print_override(const std::string &s)
{
check_window_update();
@@ -43,7 +40,7 @@ void print_override(const std::string &s)
print("\x1b" "8"); fflush(stdout);
}
-void move_cursor(char c)
+void T_line_editor::move_cursor(char c)
{
check_window_update();
@@ -66,7 +63,7 @@ void move_cursor(char c)
}
}
-void cursor_input_char(char c)
+void T_line_editor::cursor_input_char(char c)
{
check_window_update();
@@ -97,7 +94,7 @@ void cursor_input_char(char c)
-void update_window_size()
+void T_line_editor::update_window_size()
{
winsize ws;
if (ioctl(1, TIOCGWINSZ, &ws) == -1)
@@ -107,7 +104,7 @@ void update_window_size()
window_size_col = ws.ws_col;
}
-void move_cursor(T_cursor_movement_direction d)
+void T_line_editor::move_cursor(T_cursor_movement_direction d)
{
check_window_update();
@@ -171,7 +168,7 @@ void move_cursor(T_cursor_movement_direction d)
}
}
-void switch_history(T_cursor_movement_direction d)
+void T_line_editor::switch_history(T_cursor_movement_direction d)
{
check_window_update();
@@ -210,7 +207,7 @@ void switch_history(T_cursor_movement_direction d)
}
}
-void reset_editor()
+void T_line_editor::reset_editor()
{
line_buffer = "";
buffer_index_cursor = 0;
@@ -218,14 +215,14 @@ void reset_editor()
cursor_skip_prompt();
}
-void cursor_skip_prompt()
+void T_line_editor::cursor_skip_prompt()
{
// move to the "start" of the zone
// should skip prompt zone
print("\r\x1b[{}C", prompt_pos-1); fflush(stdout);
}
-void check_window_update()
+void T_line_editor::check_window_update()
{
if (windows_size_changed)
{
diff --git a/src/line/getter.cc b/src/line/getter.cc
index f396ce1..432ddca 100644
--- a/src/line/getter.cc
+++ b/src/line/getter.cc
@@ -1,4 +1,4 @@
-#include "line/getter.h"
+#include "line/line_editor.h"
#include <cstdio>
#include <string>
@@ -8,39 +8,37 @@
#include <unistd.h>
#include <cmath>
-#include "line/cursor.h"
-
using namespace std;
namespace ov4
{
-int get_terminal_pos_cursor()
+int T_line_editor::get_terminal_pos_cursor()
{
return prompt_pos + (buffer_index_cursor - get_buffer_index_display_begin()) + 1;
}
-int get_buffer_index_display_begin()
+int T_line_editor::get_buffer_index_display_begin()
{
return _buffer_index_display_begin;
}
-int get_buffer_index_display_end()
+int T_line_editor::get_buffer_index_display_end()
{
int max_possible_end = get_buffer_index_display_begin() + line_buffer.size() - 1;
int window_possible_end = get_buffer_index_display_begin() + (window_size_col - prompt_pos) -1;
return min(max_possible_end, window_possible_end);
}
-int get_terminal_pos_line_end()
+int T_line_editor::get_terminal_pos_line_end()
{
int possible = prompt_pos + line_buffer.size();
return min(possible, window_size_col);
}
-T_position get_cursor_position()
+T_position T_line_editor::get_cursor_position()
{
char c;
string buffer;
diff --git a/src/line/input.cc b/src/line/input.cc
index cc5a62b..b7dbc23 100644
--- a/src/line/input.cc
+++ b/src/line/input.cc
@@ -1,24 +1,22 @@
-#include "line/input.h"
+#include "line/line_editor.h"
#include <print>
#include <string>
#include <unistd.h>
-#include "line/cursor.h"
#include "history.h"
-#include "line/getter.h"
using namespace std;
namespace ov4
{
-void clear_below()
+void T_line_editor::clear_below()
{
print("\x1b[0J");
}
-string readline()
+string T_line_editor::readline()
{
update_window_size();
history_vec.push_back("");
diff --git a/src/line/mode.cc b/src/line/mode.cc
index 208465b..626557c 100644
--- a/src/line/mode.cc
+++ b/src/line/mode.cc
@@ -1,12 +1,10 @@
-#include "line/mode.h"
+#include "line/line_editor.h"
#include <unistd.h>
#include <stdlib.h>
#include <iostream>
#include <print>
-#include "line/cursor.h"
-#include "line/getter.h"
#include "history.h"
#include "signal_handler.h"
diff --git a/src/main.cc b/src/main.cc
index 07a3f1a..55f669a 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -13,6 +13,7 @@
#include "all.h"
#include "test.h"
+#include "line/line_editor.h"
using namespace std;
using namespace ov4;
@@ -38,22 +39,6 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] char **argv)
exe_option(argv);
- // while ((c = getopt(argc, argv, "hvp")) != EOF) {
- // switch (c) {
- // case 'h': /* print help message */
- // usage();
- // break;
- // case 'v': /* emit additional diagnostic info */
- // verbose = true;
- // break;
- // case 'p': /* don't print a prompt */
- // emit_prompt = 0; /* handy for automatic testing */
- // break;
- // default:
- // usage();
- // }
- // }
-
/* Initialize the job list */
@@ -62,24 +47,25 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] char **argv)
/* Execute the shell's read/eval loop */
while (1) {
- /* Read command line */
- print_prompt();
+ /* Read command line */
+ print_prompt();
- if ((fgets(cmdline, MAXLINE, stdin) == NULL) && ferror(stdin))
- app_error("fgets error");
- if (feof(stdin)) { /* End of file (ctrl-d) */
- fflush(stdout);
- exit(0);
- }
+ T_line_editor line_editor_instance;
+ enable_raw();
+ T_position pos = line_editor_instance.get_cursor_position();
+ line_editor_instance.cursor_row = pos.row;
+ line_editor_instance.cursor_col = pos.col;
+ line_editor_instance.prompt_pos = line_editor_instance.cursor_col;
+ string s = line_editor_instance.readline();
+ disable_raw();
+ cout << "\n\n\n\n" << endl;
+ cout << s << endl;
+ if (s == "quit")
+ break;
+ eval(s.c_str());
- /* Evaluate the command line */
- // trim \n
- if(cmdline[strlen(cmdline)-1] == '\n')
- cmdline[strlen(cmdline)-1] = '\0';
- eval(cmdline);
- fflush(stdout);
- fflush(stdout);
+ fflush(stdout);
}
exit(0); /* control never reaches here */