--- lbbs/src/editor.c 2025/06/15 13:40:52 1.23 +++ lbbs/src/editor.c 2025/06/27 10:14:47 1.32 @@ -14,19 +14,16 @@ * * ***************************************************************************/ -#include "editor.h" #include "bbs.h" +#include "common.h" +#include "editor.h" #include "io.h" #include "log.h" -#include "common.h" -#include "str_process.h" #include "memory_pool.h" +#include "str_process.h" #include -#include -#include - -#define _POSIX_C_SOURCE 200809L #include +#include #define EDITOR_ESC_DISPLAY_STR "\033[32m*\033[m" #define EDITOR_MEM_POOL_LINE_PER_CHUNK 1000 @@ -96,7 +93,7 @@ EDITOR_DATA *editor_data_load(const char return NULL; } - p_editor_data->display_line_total = split_data_lines(p_data, SCREEN_COLS, line_offsets, MAX_EDITOR_DATA_LINES + 1); + p_editor_data->display_line_total = split_data_lines(p_data, SCREEN_COLS, line_offsets, MAX_EDITOR_DATA_LINES + 1, 0); for (i = 0; i < p_editor_data->display_line_total; i++) { @@ -138,7 +135,7 @@ EDITOR_DATA *editor_data_load(const char p_data_line[current_data_line_length] = '\0'; } - bzero(p_editor_data->p_display_lines + p_editor_data->display_line_total, MAX_EDITOR_DATA_LINES - (size_t)p_editor_data->display_line_total); + memset(p_editor_data->p_display_lines + p_editor_data->display_line_total, 0, MAX_EDITOR_DATA_LINES - (size_t)p_editor_data->display_line_total); return p_editor_data; } @@ -216,7 +213,7 @@ int editor_data_insert(EDITOR_DATA *p_ed long last_display_line; // of data line long line_offsets[MAX_EDITOR_DATA_LINE_LENGTH + 1]; long split_line_total; - long i, j; + long i; int len; int eol; int display_len; @@ -281,8 +278,11 @@ int editor_data_insert(EDITOR_DATA *p_ed { if (p_editor_data->display_line_total >= MAX_EDITOR_DATA_LINES) { - // log_error("Split line error, display_line_total(%ld) reach limit(%d)\n", - // p_editor_data->display_line_total, MAX_EDITOR_DATA_LINES); +#ifdef _DEBUG + log_error("Split line error, display_line_total(%ld) reach limit(%d)\n", + p_editor_data->display_line_total, MAX_EDITOR_DATA_LINES); +#endif + return -2; } @@ -362,7 +362,7 @@ int editor_data_insert(EDITOR_DATA *p_ed } // Split current data line since beginning of current display line - split_line_total = split_data_lines(p_data_line, SCREEN_COLS, line_offsets, split_line_total); + split_line_total = split_data_lines(p_data_line, SCREEN_COLS, line_offsets, split_line_total, 0); for (i = 0; i < split_line_total; i++) { @@ -371,11 +371,14 @@ int editor_data_insert(EDITOR_DATA *p_ed // Insert blank display line after last_display_line if (p_editor_data->display_line_total >= MAX_EDITOR_DATA_LINES) { - // log_error("display_line_total over limit %d >= %d\n", p_editor_data->display_line_total, MAX_EDITOR_DATA_LINES); +#ifdef _DEBUG + log_error("display_line_total over limit %d >= %d\n", p_editor_data->display_line_total, MAX_EDITOR_DATA_LINES); +#endif + // Terminate prior display line with \n, to avoid error on cleanup if (display_line + i - 1 >= 0 && p_editor_data->display_line_lengths[display_line + i - 1] > 0) { - len = split_line(p_editor_data->p_display_lines[display_line + i - 1], SCREEN_COLS - 1, &eol, &display_len); + len = split_line(p_editor_data->p_display_lines[display_line + i - 1], SCREEN_COLS - 1, &eol, &display_len, 0); p_editor_data->p_display_lines[display_line + i - 1][len] = '\n'; p_editor_data->p_display_lines[display_line + i - 1][len + 1] = '\0'; p_editor_data->display_line_lengths[display_line + i - 1] = len + 1; @@ -386,12 +389,23 @@ int editor_data_insert(EDITOR_DATA *p_ed } break; } - for (j = p_editor_data->display_line_total; j > last_display_line + 1; j--) - { - p_editor_data->p_display_lines[j] = p_editor_data->p_display_lines[j - 1]; - p_editor_data->display_line_lengths[j] = p_editor_data->display_line_lengths[j - 1]; - } + + // for (j = p_editor_data->display_line_total; j > last_display_line + 1; j--) + // { + // p_editor_data->p_display_lines[j] = p_editor_data->p_display_lines[j - 1]; + // p_editor_data->display_line_lengths[j] = p_editor_data->display_line_lengths[j - 1]; + // } + memmove(p_editor_data->p_display_lines + last_display_line + 2, + p_editor_data->p_display_lines + last_display_line + 1, + (size_t)(p_editor_data->display_line_total - last_display_line - 1) * + sizeof(p_editor_data->p_display_lines[last_display_line + 1])); + memmove(p_editor_data->display_line_lengths + last_display_line + 2, + p_editor_data->display_line_lengths + last_display_line + 1, + (size_t)(p_editor_data->display_line_total - last_display_line - 1) * + sizeof(p_editor_data->display_line_lengths[last_display_line + 1])); + last_display_line++; + *p_last_updated_line = p_editor_data->display_line_total; (p_editor_data->display_line_total)++; } @@ -422,7 +436,7 @@ int editor_data_insert(EDITOR_DATA *p_ed // Prevent the last display line from being over-length if (p_editor_data->display_line_total == MAX_EDITOR_DATA_LINES) { - len = split_line(p_editor_data->p_display_lines[p_editor_data->display_line_total - 1], SCREEN_COLS - 1, &eol, &display_len); + len = split_line(p_editor_data->p_display_lines[p_editor_data->display_line_total - 1], SCREEN_COLS - 1, &eol, &display_len, 0); p_editor_data->p_display_lines[p_editor_data->display_line_total - 1][len] = '\0'; p_editor_data->display_line_lengths[p_editor_data->display_line_total - 1] = len; if (*p_display_line + 1 >= p_editor_data->display_line_total) @@ -564,7 +578,7 @@ int editor_data_delete(EDITOR_DATA *p_ed split_line_total = last_display_line - display_line + 2; // Split current data line since beginning of current display line - split_line_total = split_data_lines(p_data_line, SCREEN_COLS, line_offsets, split_line_total); + split_line_total = split_data_lines(p_data_line, SCREEN_COLS, line_offsets, split_line_total, 0); for (i = 0; i < split_line_total; i++) { @@ -586,11 +600,19 @@ int editor_data_delete(EDITOR_DATA *p_ed if (*p_last_updated_line < last_display_line) { // Remove redundant display line after last_display_line - for (j = last_display_line + 1; j < p_editor_data->display_line_total; j++) - { - p_editor_data->p_display_lines[j - (last_display_line - *p_last_updated_line)] = p_editor_data->p_display_lines[j]; - p_editor_data->display_line_lengths[j - (last_display_line - *p_last_updated_line)] = p_editor_data->display_line_lengths[j]; - } + // for (j = last_display_line + 1; j < p_editor_data->display_line_total; j++) + // { + // p_editor_data->p_display_lines[j - (last_display_line - *p_last_updated_line)] = p_editor_data->p_display_lines[j]; + // p_editor_data->display_line_lengths[j - (last_display_line - *p_last_updated_line)] = p_editor_data->display_line_lengths[j]; + // } + memmove(p_editor_data->p_display_lines + *p_last_updated_line + 1, + p_editor_data->p_display_lines + last_display_line + 1, + (size_t)(p_editor_data->display_line_total - last_display_line - 1) * + sizeof(p_editor_data->p_display_lines[last_display_line + 1])); + memmove(p_editor_data->display_line_lengths + *p_last_updated_line + 1, + p_editor_data->display_line_lengths + last_display_line + 1, + (size_t)(p_editor_data->display_line_total - last_display_line - 1) * + sizeof(p_editor_data->display_line_lengths[last_display_line + 1])); j = p_editor_data->display_line_total; (p_editor_data->display_line_total) -= (last_display_line - *p_last_updated_line); @@ -609,7 +631,10 @@ static int editor_display_key_handler(in { case 0: // Set msg snprintf(p_ctx->msg, sizeof(p_ctx->msg), - "| 退出[\033[32mCtrl-W\033[33m] | 帮助[\033[32mh\033[33m] |"); + "| 退出[\033[32mCtrl-W\033[33m] |"); + break; + case KEY_CSI: + *p_key = KEY_ESC; break; } @@ -663,10 +688,10 @@ int editor_display(EDITOR_DATA *p_editor "%s", row_pos, col_pos, ctx.line_cursor, p_editor_data->display_line_total, - key_insert ? "插入" : "改写", + key_insert ? "插入" : "替换", ctx.msg); - len = split_line(buffer, SCREEN_COLS, &eol, &display_len); + len = split_line(buffer, SCREEN_COLS, &eol, &display_len, 1); for (; display_len < SCREEN_COLS; display_len++) { buffer[len++] = ' '; @@ -680,12 +705,11 @@ int editor_display(EDITOR_DATA *p_editor moveto((int)row_pos, (int)col_pos); iflush(); + str_len = 0; input_ok = 0; + ch = igetch_t(MAX_DELAY_TIME); while (!SYS_server_exit && !input_ok) { - ch = igetch_t(MAX_DELAY_TIME); - input_ok = 1; - // extended key handler if (editor_display_key_handler(&ch, &ctx) != 0) { @@ -706,18 +730,21 @@ int editor_display(EDITOR_DATA *p_editor if ((ch >= 32 && ch < 127) || (ch > 127 && ch <= 255 && str_len == 2) || // Printable character or GBK ch == CR || ch == KEY_ESC) // Special character { + BBS_last_access_tm = time(NULL); + if (str_len == 0) // ch >= 32 && ch < 127 { input_str[0] = (char)ch; str_len = 1; } - last_updated_line = line_current; display_line_in = line_current - output_current_row + row_pos; offset_in = col_pos - 1; display_line_out = display_line_in; offset_out = offset_in; + last_updated_line = display_line_in; + if (!key_insert) // overwrite { if (editor_data_delete(p_editor_data, &display_line_out, &offset_out, @@ -764,16 +791,29 @@ int editor_display(EDITOR_DATA *p_editor col_pos = offset_out + 1; // Set col_pos to accurate pos } + if (display_line_out != display_line_in) // Output on line change + { + break; + } + + ch = igetch(0); + if (ch == KEY_NULL || ch == KEY_TIMEOUT) // Output if no futher input + { + break; + } + str_len = 0; continue; } else if (ch == KEY_DEL || ch == BACKSPACE) // Del { + BBS_last_access_tm = time(NULL); + if (ch == BACKSPACE) { if (line_current - output_current_row + row_pos <= 0 && col_pos <= 1) // Forbidden { - input_ok = 0; + ch = igetch_t(MAX_DELAY_TIME); continue; } @@ -832,10 +872,22 @@ int editor_display(EDITOR_DATA *p_editor clrline(output_current_row, output_end_row); } + if (display_line_out != display_line_in) // Output on line change + { + break; + } + + ch = igetch(0); + if (ch == KEY_NULL || ch == KEY_TIMEOUT) // Output if no futher input + { + break; + } + str_len = 0; continue; } + input_ok = 1; switch (ch) { case KEY_NULL: @@ -1032,12 +1084,14 @@ int editor_display(EDITOR_DATA *p_editor break; } - BBS_last_access_tm = time(0); + BBS_last_access_tm = time(NULL); if (input_ok) { break; } + + ch = igetch_t(MAX_DELAY_TIME); } continue;