чување f91aa7860c8e97ff54b4336b382e331de53ff1e0
родитељ 0bfda2400f710f300c58bb24f2a9bd882f53e5e5
Аутор: Страхиња Радић <contact@strahinja.org>
Датум: Mon, 14 Feb 2022 20:25:00 +0100
Reorganize key handler; add insert (default) and command mode (inverse vi)
Signed-off-by: Страхиња Радић <contact@strahinja.org>
Diffstat:
| M | README | | | 4 | ++-- |
| M | TODO | | | 2 | +- |
| M | config.def.h | | | 118 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- |
| M | config.h | | | 118 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- |
| M | draw.c | | | 41 | +++++++++++++++++++++++++++++------------ |
| M | draw.h | | | 8 | +++++++- |
| M | sled.c | | | 805 | +++++++++++++++++++++++++++++++++++-------------------------------------------- |
| M | util.h | | | 8 | ++++++++ |
измењених датотека: 8, додавања: 624(+), брисања: 480(-)
diff --git a/README b/README
@@ -14,13 +14,13 @@ A: A text editor's purpose should be to *edit* text files. For just *viewing*
Of course, one could argue that screen editors like vi already double as
text file viewers, but I think of displaying the contents of a writable file
- as separate from displaying the contents of a non-writable file.
+ as being separate from displaying the contents of a non-writable file.
If this bothers you, you can use something like the included shell script
sledv.
Q: Is editing multiple files planned?
-A: No, this is by design. You can edit multiple files at the same time by
+A: No, and this is by design. You can edit multiple files at the same time by
running multiple instances of sled. You can arrange them on screen through a
terminal multiplexer like GNU screen(1) or tmux(1), or just open several
terminal emulators like st(1) and have your window manager arrange their
diff --git a/TODO b/TODO
@@ -3,7 +3,7 @@
[~] Create a working base by migration from poe
- [ ] Implement "inverse vi mode"
+ [x] Implement "inverse vi mode"
Legend
diff --git a/config.def.h b/config.def.h
@@ -13,26 +13,130 @@
#define TITLE_FG TB_BLACK
#define TITLE_BG TB_WHITE
+int cancel_close(struct DrawState* state);
+int enter_command_mode(struct DrawState* state);
+int enter_insert_mode(struct DrawState* state);
+int erase_backwards(struct DrawState* state);
+int erase_forward(struct DrawState* state);
+int erase_to_end(struct DrawState* state);
+int erase_to_start(struct DrawState* state);
+int exit_program(struct DrawState* state);
+int insert_space(struct DrawState* state);
+int insert_tab(struct DrawState* state);
+int move_bottom(struct DrawState* state);
+int move_down(struct DrawState* state);
+int move_end(struct DrawState* state);
+int move_left(struct DrawState* state);
+int move_next_word(struct DrawState* state);
+int move_page_down(struct DrawState* state);
+int move_page_up(struct DrawState* state);
+int move_prev_word(struct DrawState* state);
+int move_right(struct DrawState* state);
+int move_start(struct DrawState* state);
+int move_top(struct DrawState* state);
+int move_up(struct DrawState* state);
+int show_help(struct DrawState* state);
+
+/* Always processed */
+static const struct Key top_level_keys[] = {
+ { .ev = { .key = TB_KEY_ESC }, .callback = cancel_close },
+ { .ev = { .key = TB_KEY_CTRL_Q },
+ .callback = exit_program }
+};
+
+/* Only when no dialog/prompt open */
+static const struct Key global_keys[] = {
+ { .ev = { .key = TB_KEY_ARROW_DOWN },
+ .callback = move_down },
+ { .ev = { .key = TB_KEY_ARROW_UP },
+ .callback = move_up },
+ { .ev = { .key = TB_KEY_ARROW_LEFT },
+ .callback = move_left },
+ { .ev = { .key = TB_KEY_ARROW_RIGHT },
+ .callback = move_right },
+ { .ev = { .key = TB_KEY_BACKSPACE },
+ .callback = erase_backwards },
+ { .ev = { .key = TB_KEY_BACKSPACE2 },
+ .callback = erase_backwards },
+ { .ev = { .key = TB_KEY_CTRL_A },
+ .callback = move_start },
+ { .ev = { .key = TB_KEY_CTRL_B },
+ .callback = move_page_up },
+ { .ev = { .key = TB_KEY_CTRL_E },
+ .callback = move_end },
+ { .ev = { .key = TB_KEY_CTRL_F },
+ .callback = move_page_down },
+ { .ev = { .key = TB_KEY_CTRL_K },
+ .callback = erase_to_end },
+ { .ev = { .key = TB_KEY_CTRL_R },
+ .callback = move_prev_word },
+ { .ev = { .key = TB_KEY_CTRL_T },
+ .callback = move_next_word },
+ { .ev = { .key = TB_KEY_CTRL_U },
+ .callback = erase_to_start },
+ { .ev = { .key = TB_KEY_DELETE },
+ .callback = erase_forward },
+ { .ev = { .key = TB_KEY_F1 }, .callback = show_help },
+ { .ev = { .key = TB_KEY_END }, .callback = move_end },
+ { .ev = { .key = TB_KEY_HOME }, .callback = move_start },
+ { .ev = { .key = TB_KEY_PGDN }, .callback = move_page_down },
+ { .ev = { .key = TB_KEY_PGUP }, .callback = move_page_up }
+};
+
+/* Only when in insert mode */
+static const struct Key insert_keys[] = {
+ { .ev = { .key = TB_KEY_CTRL_C },
+ .callback = enter_command_mode },
+ { .ev = { .key = TB_KEY_SPACE },
+ .callback = insert_space },
+ { .ev = { .key = TB_KEY_TAB },
+ .callback = insert_tab }
+};
+
+/* Only when in command mode */
+static const struct Key command_keys[] = {
+ { .ev = { .key = TB_KEY_CTRL_C },
+ .callback = enter_insert_mode },
+ { .ev = { .ch = '0' }, .callback = move_start },
+ { .ev = { .ch = '$' }, .callback = move_end },
+ { .ev = { .ch = 'g' }, .callback = move_top },
+ { .ev = { .ch = 'h' }, .callback = move_left },
+ { .ev = { .ch = 'j' }, .callback = move_down },
+ { .ev = { .ch = 'k' }, .callback = move_up },
+ { .ev = { .ch = 'l' }, .callback = move_right },
+ { .ev = { .ch = 'q' }, .callback = exit_program },
+ { .ev = { .ch = 'w' }, .callback = move_next_word },
+ { .ev = { .ch = 'G' }, .callback = move_bottom },
+ { .ev = { .ch = 'H' }, .callback = show_help },
+ { .ev = { .ch = 'W' }, .callback = move_prev_word }
+};
+
void format_filename(char* result, size_t result_size, const char* format,
const struct DrawState* state);
-
+void format_mode(char* result, size_t result_size, const char* format,
+ const struct DrawState* state);
void format_position(char* result, size_t result_size, const char* format,
const struct DrawState* state);
static const struct StatusSegment status_segments[] = {
{.format = "%s%s",
.callback = format_filename,
- .fg = TB_BLACK,
- .bg = TB_WHITE,
+ .fg = TB_WHITE,
+ .bg = TB_DEFAULT,
.alignment = LEFT},
+ { .format = "%s",
+ .callback = format_mode,
+ .fg = TB_YELLOW | TB_BOLD,
+ .bg = TB_DEFAULT,
+ .alignment = CENTER},
{.format = "%ld:%ld (%ld%%)",
.callback = format_position,
.fg = TB_WHITE | TB_BOLD,
- .bg = TB_BLUE,
+ .bg = TB_DEFAULT,
.alignment = CENTER},
- {.format = "H=HELP, q=QUIT",
+ {.format = "F1=HELP, C-Q=QUIT",
.callback = NULL,
- .fg = TB_BLACK,
- .bg = TB_WHITE,
+ .fg = TB_WHITE,
+ .bg = TB_DEFAULT,
.alignment = RIGHT},
};
diff --git a/config.h b/config.h
@@ -13,26 +13,130 @@
#define TITLE_FG TB_BLACK
#define TITLE_BG TB_WHITE
+int cancel_close(struct DrawState* state);
+int enter_command_mode(struct DrawState* state);
+int enter_insert_mode(struct DrawState* state);
+int erase_backwards(struct DrawState* state);
+int erase_forward(struct DrawState* state);
+int erase_to_end(struct DrawState* state);
+int erase_to_start(struct DrawState* state);
+int exit_program(struct DrawState* state);
+int insert_space(struct DrawState* state);
+int insert_tab(struct DrawState* state);
+int move_bottom(struct DrawState* state);
+int move_down(struct DrawState* state);
+int move_end(struct DrawState* state);
+int move_left(struct DrawState* state);
+int move_next_word(struct DrawState* state);
+int move_page_down(struct DrawState* state);
+int move_page_up(struct DrawState* state);
+int move_prev_word(struct DrawState* state);
+int move_right(struct DrawState* state);
+int move_start(struct DrawState* state);
+int move_top(struct DrawState* state);
+int move_up(struct DrawState* state);
+int show_help(struct DrawState* state);
+
+/* Always processed */
+static const struct Key top_level_keys[] = {
+ { .ev = { .key = TB_KEY_ESC }, .callback = cancel_close },
+ { .ev = { .key = TB_KEY_CTRL_Q },
+ .callback = exit_program }
+};
+
+/* Only when no dialog/prompt open */
+static const struct Key global_keys[] = {
+ { .ev = { .key = TB_KEY_ARROW_DOWN },
+ .callback = move_down },
+ { .ev = { .key = TB_KEY_ARROW_UP },
+ .callback = move_up },
+ { .ev = { .key = TB_KEY_ARROW_LEFT },
+ .callback = move_left },
+ { .ev = { .key = TB_KEY_ARROW_RIGHT },
+ .callback = move_right },
+ { .ev = { .key = TB_KEY_BACKSPACE },
+ .callback = erase_backwards },
+ { .ev = { .key = TB_KEY_BACKSPACE2 },
+ .callback = erase_backwards },
+ { .ev = { .key = TB_KEY_CTRL_A },
+ .callback = move_start },
+ { .ev = { .key = TB_KEY_CTRL_B },
+ .callback = move_page_up },
+ { .ev = { .key = TB_KEY_CTRL_E },
+ .callback = move_end },
+ { .ev = { .key = TB_KEY_CTRL_F },
+ .callback = move_page_down },
+ { .ev = { .key = TB_KEY_CTRL_K },
+ .callback = erase_to_end },
+ { .ev = { .key = TB_KEY_CTRL_R },
+ .callback = move_prev_word },
+ { .ev = { .key = TB_KEY_CTRL_T },
+ .callback = move_next_word },
+ { .ev = { .key = TB_KEY_CTRL_U },
+ .callback = erase_to_start },
+ { .ev = { .key = TB_KEY_DELETE },
+ .callback = erase_forward },
+ { .ev = { .key = TB_KEY_F1 }, .callback = show_help },
+ { .ev = { .key = TB_KEY_END }, .callback = move_end },
+ { .ev = { .key = TB_KEY_HOME }, .callback = move_start },
+ { .ev = { .key = TB_KEY_PGDN }, .callback = move_page_down },
+ { .ev = { .key = TB_KEY_PGUP }, .callback = move_page_up }
+};
+
+/* Only when in insert mode */
+static const struct Key insert_keys[] = {
+ { .ev = { .key = TB_KEY_CTRL_C },
+ .callback = enter_command_mode },
+ { .ev = { .key = TB_KEY_SPACE },
+ .callback = insert_space },
+ { .ev = { .key = TB_KEY_TAB },
+ .callback = insert_tab }
+};
+
+/* Only when in command mode */
+static const struct Key command_keys[] = {
+ { .ev = { .key = TB_KEY_CTRL_C },
+ .callback = enter_insert_mode },
+ { .ev = { .ch = '0' }, .callback = move_start },
+ { .ev = { .ch = '$' }, .callback = move_end },
+ { .ev = { .ch = 'g' }, .callback = move_top },
+ { .ev = { .ch = 'h' }, .callback = move_left },
+ { .ev = { .ch = 'j' }, .callback = move_down },
+ { .ev = { .ch = 'k' }, .callback = move_up },
+ { .ev = { .ch = 'l' }, .callback = move_right },
+ { .ev = { .ch = 'q' }, .callback = exit_program },
+ { .ev = { .ch = 'w' }, .callback = move_next_word },
+ { .ev = { .ch = 'G' }, .callback = move_bottom },
+ { .ev = { .ch = 'H' }, .callback = show_help },
+ { .ev = { .ch = 'W' }, .callback = move_prev_word }
+};
+
void format_filename(char* result, size_t result_size, const char* format,
const struct DrawState* state);
-
+void format_mode(char* result, size_t result_size, const char* format,
+ const struct DrawState* state);
void format_position(char* result, size_t result_size, const char* format,
const struct DrawState* state);
static const struct StatusSegment status_segments[] = {
{.format = "%s%s",
.callback = format_filename,
- .fg = TB_BLACK,
- .bg = TB_WHITE,
+ .fg = TB_WHITE,
+ .bg = TB_DEFAULT,
.alignment = LEFT},
+ { .format = "%s",
+ .callback = format_mode,
+ .fg = TB_YELLOW | TB_BOLD,
+ .bg = TB_DEFAULT,
+ .alignment = CENTER},
{.format = "%ld:%ld (%ld%%)",
.callback = format_position,
.fg = TB_WHITE | TB_BOLD,
- .bg = TB_BLUE,
+ .bg = TB_DEFAULT,
.alignment = CENTER},
- {.format = "H=HELP, q=QUIT",
+ {.format = "F1=HELP, C-Q=QUIT",
.callback = NULL,
- .fg = TB_BLACK,
- .bg = TB_WHITE,
+ .fg = TB_WHITE,
+ .bg = TB_DEFAULT,
.alignment = RIGHT},
};
diff --git a/draw.c b/draw.c
@@ -12,24 +12,40 @@
#include "version.h"
/* clang-format off */
-static const char* help_title = "Main view help";
+static const char* help_title = "sled help";
static const char* help[] = {
- "Esc - Close dialog, clear error",
- "H or F1 - Show this screen",
- "q or C-Q - Quit",
+ "Esc - Close dialog, clear error",
+ "F1 - Show this screen",
+ "C-C - Switch command <-> insert mode",
+ "Home or C-A - Go to start of line",
+ "PgUp or C-B - Go to previous page",
+ "PgDown or C-F - Go to next page",
+ "End or C-E - Go to end of line",
+ "C-Q - Quit",
+ "",
+ "Arrow keys work both in insert and command mode.",
+ "Some vi-like keys work in command mode.",
+ "",
"See the manual (man sled) for full help."};
-const char* errors[] = {
- [ERR_UNKNOWN_KEY] = "Unknown key (press H for help)",
- [ERR_EXIT_KEY] = "Press q or C-Q to quit",
- [ERR_DLG_OPEN] = "Press Esc to close dialog or q/C-Q to quit",
+const char* mode_labels[] = {
+ [UNKNOWN_MODE] = "UNKNOWN",
+ [COMMAND_MODE] = "COMMAND",
+ [HELP_MODE] = "HELP",
+ [INSERT_MODE] = "INSERT",
+ [PROMPT_MODE] = "PROMPT"
+};
+const char* errors[] = {
+ [ERR_UNKNOWN_KEY] = "Unknown key (press F1 for help)",
+ [ERR_EXIT_KEY] = "Press C-Q to quit",
+ [ERR_DLG_OPEN] = "Press Esc to close dialog or C-Q to quit",
[ERR_DLG_OPEN_QUIT] = "Press Esc to close dialog",
[ERR_CANT_ALLOC] = "Memory allocation failed",
[ERR_CANT_SAVE] = "File is not writeable",
[ERR_CANT_MOVE] = "Cannot move temporary file"};
-const char* program_name = "sled";
-const char* prompt_dirty = "File changed, save [y/n/ESC]?";
+const char* program_name = "sled";
+const char* prompt_dirty = "File changed, save [y/n/ESC]?";
const char* prompt_cancel_dirty = "Entry changed, save [y/n/ESC]?";
-const char* prompt_overwrite = "Not empty, overwrite? [y/n/ESC]?";
+const char* prompt_overwrite = "Not empty, overwrite? [y/n/ESC]?";
/* clang-format on */
void
@@ -77,6 +93,7 @@ init_drawstate(struct DrawState* state, char* error, char* filename,
state->running = 1;
state->dirty = 0;
state->in_prompt = 0;
+ state->in_command_mode = 0;
state->show_help = 0;
}
@@ -503,7 +520,7 @@ draw_status(const struct DrawState* state)
return NULL;
char buf[MAXBUFLINE];
- int seg_size = state->maxx / 3;
+ int seg_size = state->maxx / LEN(status_segments);
int current_start = 0;
const struct StatusSegment* pseg = status_segments;
diff --git a/draw.h b/draw.h
@@ -10,7 +10,7 @@
#define BORDER_VER ((uint32_t)L'\u2502')
#define BORDER_HOR ((uint32_t)L'\u2500')
-#define HELP_WIDTH 50
+#define HELP_WIDTH 60
#define HELP_HEIGHT 21
#define TAB_SIZE 8
@@ -43,11 +43,17 @@ struct DrawState {
int running;
int dirty;
int in_prompt;
+ int in_command_mode;
int show_help;
int maxx;
int maxy;
};
+struct Key {
+ struct tb_event ev;
+ int (*callback)(struct DrawState*);
+};
+
struct StatusSegment {
const char* format;
void (*callback)(char*, size_t, const char*, const struct DrawState*);
diff --git a/sled.c b/sled.c
@@ -36,6 +36,7 @@ enum {
};
extern const char* errors[];
+extern const char* mode_labels[];
extern const char* prompt_dirty;
extern const char* prompt_cancel_dirty;
extern const char* prompt_overwrite;
@@ -58,32 +59,6 @@ struct BufferLine* load_info(struct DrawState* state);
struct DrawState* load_msgstr(struct DrawState* state);
int load_file(struct DrawState* dstate, long* lineno, long* col);
int save_file(struct DrawState* state);
-void save_msgstr(struct DrawState* state);
-void cancel_msgstr(struct DrawState* state);
-void goto_msgid(struct DrawState* state, const size_t msgid_number);
-void show_edit(struct DrawState* state);
-void move_up(struct DrawState* state);
-void move_down(struct DrawState* state);
-void move_start(struct DrawState* state);
-void move_left(struct DrawState* state);
-void move_right(struct DrawState* state);
-void move_prev_word(struct DrawState* state);
-void move_next_word(struct DrawState* state);
-void erase_prev_word(struct DrawState* state);
-void move_end(struct DrawState* state);
-void move_list_up(struct DrawState* state);
-void move_list_down(struct DrawState* state);
-void move_list_start(struct DrawState* state);
-void move_list_end(struct DrawState* state);
-void move_list_page_up(struct DrawState* state);
-void move_list_page_down(struct DrawState* state);
-void next_plural(struct DrawState* state);
-void prev_plural(struct DrawState* state);
-void insert_char(struct DrawState* state, uint32_t ch);
-void erase_backwards(struct DrawState* state);
-void erase_forward(struct DrawState* state);
-void erase_to_start(struct DrawState* state);
-void erase_to_end(struct DrawState* state);
struct DrawState* insert_line(struct DrawState* state);
struct DrawState* join_lines(struct DrawState* state, size_t first_line,
int forward);
@@ -129,6 +104,25 @@ format_filename(char* result, size_t result_size, const char* format,
}
void
+format_mode(char* result, size_t result_size, const char* format,
+ const struct DrawState* state)
+{
+ const char* mode_label = mode_labels[UNKNOWN_MODE];
+ if (!result)
+ return;
+ if (state->show_help)
+ mode_label = mode_labels[HELP_MODE];
+ else if (state->in_prompt)
+ mode_label = mode_labels[PROMPT_MODE];
+ else if (state->in_command_mode)
+ mode_label = mode_labels[COMMAND_MODE];
+ else
+ mode_label = mode_labels[INSERT_MODE];
+
+ snprintf(result, result_size, format, mode_label);
+}
+
+void
format_position(char* result, size_t result_size, const char* format,
const struct DrawState* state)
{
@@ -178,10 +172,11 @@ cancel_callback(struct DrawState* state, struct tb_event* ev)
if (!state)
return;
- if (ev->ch == 'y')
+ /*if (ev->ch == 'y')
save_msgstr(state);
else
cancel_msgstr(state);
+ */
state->prompt_callback = NULL;
}
@@ -387,49 +382,6 @@ save_msgstr(struct DrawState* state)
*/
}
-void
-cancel_msgstr(struct DrawState* state)
-{
- if (!state->in_prompt && state->dirty)
- {
- state->in_prompt = 1;
- strcpy(state->prompt, prompt_cancel_dirty);
- state->prompt_callback = cancel_callback;
- return;
- }
-
- /*
- state->show_edit = 0;
- state->edit_info_focused = 0;
-
- for (size_t i = 0; i < state->input_rows_count; i++)
- free_bufferline(state->input_buffer + i);
- free(state->input_buffer);
- state->input_buffer = NULL;
- state->input_rows_count = 0;
- if (state->info_buffer)
- for (size_t i = 0; i < state->info_rows_count; i++)
- free_bufferline(state->info_buffer + i);
- free(state->info_buffer);
- state->info_buffer = NULL;
- state->info_rows_count = 0;
- state->dirty = state->dirty_before_edit;
- state->fuzzy_count = state->fuzzy_before_edit;
- switch (state->input_changed_fuzzy)
- {
- case SET:
- state->entries[state->msgid_number - 1].flags &= ~FL_FUZZY;
- break;
- case CLEARED:
- state->entries[state->msgid_number - 1].flags |= FL_FUZZY;
- break;
- default:;
- }
- state->input_changed_fuzzy = UNCHANGED;
-*/
- tb_set_cursor(TB_HIDE_CURSOR, TB_HIDE_CURSOR);
-}
-
struct DrawState*
paste_paste_buffer_to_input(struct DrawState* state)
{
@@ -520,7 +472,7 @@ paste_paste_buffer_to_input(struct DrawState* state)
return state;
}
-void
+int
move_up(struct DrawState* state)
{
if (state->row > 0)
@@ -544,9 +496,10 @@ move_up(struct DrawState* state)
= state->display_column - state->maxx + 1;
state->display_column = display_length(state,
state->buffer[state->row].text, state->column);
+ return 0;
}
-void
+int
move_down(struct DrawState* state)
{
if (state->row < state->rows_count - 1)
@@ -570,67 +523,65 @@ move_down(struct DrawState* state)
= state->display_column - state->maxx + 1;
state->display_column = display_length(state,
state->buffer[state->row].text, state->column);
+ return 0;
}
-void
+int
move_top(struct DrawState* state)
{
state->row = 0;
state->first_shown_row = 0;
-
- move_start(state);
+ return 0;
}
-void
+int
move_start(struct DrawState* state)
{
state->column = 0;
state->display_column = 0;
state->first_shown_column = 0;
+ return 0;
}
-void
+int
move_left(struct DrawState* state)
{
if (state->column == 0)
- return;
+ return 0;
- if (state->buffer[state->row].text[state->column - 1]
- == '\t')
+ if (state->buffer[state->row].text[state->column - 1] == '\t')
state->display_column = display_length(state,
- state->buffer[state->row].text,
- state->column - 1);
+ state->buffer[state->row].text, state->column - 1);
else
state->display_column--;
state->column--;
if (state->display_column < state->first_shown_column)
state->first_shown_column = state->display_column;
+ return 0;
}
-void
+int
move_right(struct DrawState* state)
{
size_t len = state->buffer[state->row].length;
if (state->column == len)
- return;
+ return 0;
- if (state->buffer[state->row].text[state->column]
- == '\t')
+ if (state->buffer[state->row].text[state->column] == '\t')
state->display_column = display_length(state,
- state->buffer[state->row].text,
- state->column + 1);
+ state->buffer[state->row].text, state->column + 1);
else
state->display_column++;
state->column++;
- if (state->display_column - state->first_shown_column
- > state->maxx - 1)
+ if (state->display_column - state->first_shown_column > state->maxx - 1)
state->first_shown_column
= state->display_column - state->maxx + 1;
+ return 0;
}
-void
+int
move_prev_word(struct DrawState* state)
{
int i = state->column;
@@ -644,15 +595,15 @@ move_prev_word(struct DrawState* state)
&& !u32_is_word_boundary(pline[i - 1], 0))
i--;
- state->column = i;
+ state->column = i;
state->display_column = display_length(state,
- state->buffer[state->row].text,
- state->column);
+ state->buffer[state->row].text, state->column);
if (state->display_column < state->first_shown_column)
state->first_shown_column = state->display_column;
+ return 0;
}
-void
+int
move_next_word(struct DrawState* state)
{
int i = state->column;
@@ -663,14 +614,13 @@ move_next_word(struct DrawState* state)
i++;
while (i < len && u32_is_word_boundary(pline[i], 0))
i++;
- state->column = i;
+ state->column = i;
state->display_column = display_length(state,
- state->buffer[state->row].text,
- state->column);
- if (state->display_column - state->first_shown_column
- > state->maxx - 1)
+ state->buffer[state->row].text, state->column);
+ if (state->display_column - state->first_shown_column > state->maxx - 1)
state->first_shown_column
= state->display_column - state->maxx + 1;
+ return 0;
}
void
@@ -712,17 +662,16 @@ erase_prev_word(struct DrawState* state)
*/
}
-void
+int
move_bottom(struct DrawState* state)
{
state->row = state->rows_count - 1;
state->first_shown_row
= state->row > state->maxy ? state->row - state->maxy + 2 : 0;
-
- move_start(state);
+ return 0;
}
-void
+int
move_end(struct DrawState* state)
{
size_t len = state->buffer[state->row].length;
@@ -736,60 +685,10 @@ move_end(struct DrawState* state)
state->first_shown_column = dlen - state->maxx + 4;
else
state->first_shown_column = 0;
+ return 0;
}
-void
-move_list_up(struct DrawState* state)
-{
- /*
- if (state->msgid_number > 1)
- {
- state->error[0] = 0;
- state->msgid_number--;
- if (state->msgid_number < state->first_shown_msgid)
- state->first_shown_msgid--;
- }
- */
-}
-
-void
-move_list_down(struct DrawState* state)
-{
- /*
- if (state->msgid_number < state->msgid_count)
- {
- state->error[0] = 0;
- state->msgid_number++;
- if (state->msgid_number - state->first_shown_msgid
- > state->maxy - 2)
- state->first_shown_msgid++;
- }
- */
-}
-
-void
-move_list_start(struct DrawState* state)
-{
- /*
- state->error[0] = 0;
- state->msgid_number = state->msgid_count > 0 ? 1 : 0;
- state->first_shown_msgid = state->msgid_number;
- */
-}
-
-void
-move_list_end(struct DrawState* state)
-{
- /*
- state->error[0] = 0;
- state->msgid_number = state->msgid_count;
- state->first_shown_msgid = state->msgid_count > 0
- ? MAX(1, state->msgid_number - (state->maxy - 2))
- : 0;
- */
-}
-
-void
+int
move_page_up(struct DrawState* state)
{
*state->error = 0;
@@ -801,9 +700,10 @@ move_page_up(struct DrawState* state)
}
else
move_top(state);
+ return 0;
}
-void
+int
move_page_down(struct DrawState* state)
{
*state->error = 0;
@@ -815,85 +715,67 @@ move_page_down(struct DrawState* state)
}
else
move_bottom(state);
+ return 0;
}
-void
-next_plural(struct DrawState* state)
-{
- /*
- if (state->edit_info_focused)
- return;
- struct PoEntry* current = &state->entries[state->msgid_number - 1];
- save_msgstr(state);
- if (state->msgstr_index + 1 < current->msgstr_count)
- state->msgstr_index++;
- show_edit(state);
- */
-}
-
-void
-prev_plural(struct DrawState* state)
-{
- /*
- if (state->edit_info_focused)
- return;
- save_msgstr(state);
- if (state->msgstr_index > 0)
- state->msgstr_index--;
- show_edit(state);
- */
-}
-
-void
+int
insert_char(struct DrawState* state, uint32_t ch)
{
- /*
- if (state->edit_info_focused)
- return;
- struct BufferLine* buffer_line = &state->input_buffer[state->input_row];
+ struct BufferLine* buffer_line = &state->buffer[state->row];
size_t len = buffer_line->length;
- if (state->input_column < MAXBUFLINE - 1)
+ if (state->column < MAXBUFLINE - 1)
{
size_t i = len + 1;
- int add_null = buffer_line->text[state->input_column] == 0;
- while (i < MAXBUFLINE - 2 && i > state->input_column)
+ int add_null = buffer_line->text[state->column] == 0;
+ while (i < MAXBUFLINE - 2 && i > state->column)
{
buffer_line->text[i] = buffer_line->text[i - 1];
i--;
}
- buffer_line->text[state->input_column++] = ch;
+ buffer_line->text[state->column++] = ch;
buffer_line->length++;
- if (state->input_column == MAXBUFLINE)
- state->input_column = MAXBUFLINE - 1;
- state->input_display_column = display_length(state,
- state->input_buffer[state->input_row].text,
- state->input_column);
- if (state->input_display_column -
- state->input_first_shown_column > state->edit_width - 4)
+ if (state->column == MAXBUFLINE)
+ state->column = MAXBUFLINE - 1;
+ state->display_column = display_length(state,
+ state->buffer[state->row].text,
+ state->column);
+ if (state->display_column -
+ state->first_shown_column > state->maxx - 1)
{
- state->input_first_shown_column
- = state->input_display_column
- - state->edit_width + 4;
- state->input_display_column = display_length(state,
- state->input_buffer[state->input_row].text,
- state->input_column);
+ state->first_shown_column
+ = state->display_column
+ - state->maxx + 1;
+ state->display_column = display_length(state,
+ state->buffer[state->row].text,
+ state->column);
}
if (add_null)
- buffer_line->text[state->input_column] = 0;
+ buffer_line->text[state->column] = 0;
}
state->dirty = 1;
- */
+ return 0;
}
-void
+int
+insert_space(struct DrawState* state)
+{
+ return insert_char(state, ' ');
+}
+
+int
+insert_tab(struct DrawState* state)
+{
+ return insert_char(state, '\t');
+}
+
+int
erase_backwards(struct DrawState* state)
{
- /*
- struct BufferLine* buffer_line = &state->input_buffer[state->input_row];
+ struct BufferLine* buffer_line = &state->buffer[state->row];
- if (state->input_column > 0)
+ if (state->column > 0)
{
- size_t i = state->input_column;
+ size_t i = state->column;
do
{
buffer_line->text[i - 1] = buffer_line->text[i];
@@ -901,43 +783,42 @@ erase_backwards(struct DrawState* state)
} while (buffer_line->text[i]);
buffer_line->text[i - 1] = 0;
buffer_line->length--;
- state->input_column--;
- if (state->input_first_shown_column > 0)
+ state->column--;
+ if (state->first_shown_column > 0)
{
const struct BufferLine* current_line
- = &state->input_buffer[state->input_row];
+ = &state->buffer[state->row];
if (display_length(state, current_line->text,
current_line->length)
- >= state->edit_width - 4)
- state->input_first_shown_column--;
+ >= state->maxx - 1)
+ state->first_shown_column--;
}
- state->input_display_column = display_length(state,
- state->input_buffer[state->input_row].text,
- state->input_column);
- if (state->input_display_column
- < state->input_first_shown_column)
- state->input_first_shown_column
- = state->input_display_column;
+ state->display_column = display_length(state,
+ state->buffer[state->row].text,
+ state->column);
+ if (state->display_column
+ < state->first_shown_column)
+ state->first_shown_column
+ = state->display_column;
state->dirty = 1;
}
- else if (state->input_row > 0)
+ else if (state->row > 0)
{
move_up(state);
move_end(state);
erase_forward(state);
}
- */
+ return 0;
}
-void
+int
erase_forward(struct DrawState* state)
{
- /*
- struct BufferLine* buffer_line = &state->input_buffer[state->input_row];
+ struct BufferLine* buffer_line = &state->buffer[state->row];
- if (buffer_line->text[state->input_column])
+ if (buffer_line->text[state->column])
{
- size_t i = state->input_column;
+ size_t i = state->column;
while (i < MAXBUFLINE - 2 && buffer_line->text[i + 1])
{
buffer_line->text[i] = buffer_line->text[i + 1];
@@ -947,99 +828,85 @@ erase_forward(struct DrawState* state)
buffer_line->length--;
state->dirty = 1;
}
- else if (state->input_row < state->input_rows_count - 1)
+ else if (state->row < state->rows_count - 1)
{
- if (!join_lines(state, state->input_row, 1))
+ if (!join_lines(state, state->row, 1))
{
strcpy(state->error, errors[ERR_CANT_ALLOC]);
state->running = 0;
}
}
- */
+ return 0;
}
-void
+int
erase_to_start(struct DrawState* state)
{
- /*
- if (state->edit_info_focused)
- {
- strcpy(state->error, errors[ERR_DLG_OPEN_QUIT]);
- return;
- }
-
- size_t i = state->input_column;
- struct BufferLine* buffer_line = &state->input_buffer[state->input_row];
+ size_t i = state->column;
+ struct BufferLine* buffer_line = &state->buffer[state->row];
size_t len = buffer_line->length;
do
{
- buffer_line->text[i - state->input_column]
+ buffer_line->text[i - state->column]
= buffer_line->text[i];
i++;
} while (buffer_line->text[i]);
- buffer_line->text[len - state->input_column] = 0;
- buffer_line->length = len - state->input_column;
+ buffer_line->text[len - state->column] = 0;
+ buffer_line->length = len - state->column;
move_start(state);
state->dirty = 1;
- */
+ return 0;
}
-void
+int
erase_to_end(struct DrawState* state)
{
- /*
- if (state->edit_info_focused)
- return;
- struct BufferLine* buffer_line = &state->input_buffer[state->input_row];
- buffer_line->text[state->input_column] = 0;
- buffer_line->length = state->input_column;
+ struct BufferLine* buffer_line = &state->buffer[state->row];
+ buffer_line->text[state->column] = 0;
+ buffer_line->length = state->column;
move_end(state);
state->dirty = 1;
- */
+ return 0;
}
struct DrawState*
insert_line(struct DrawState* state)
{
- /*
- if (state->edit_info_focused)
- return state;
- state->input_rows_count++;
- struct BufferLine* newbuf = realloc(state->input_buffer,
- state->input_rows_count * sizeof(struct BufferLine));
+ state->rows_count++;
+ struct BufferLine* newbuf = realloc(state->buffer,
+ state->rows_count * sizeof(struct BufferLine));
if (!newbuf)
return NULL;
- state->input_buffer = newbuf;
- init_bufferline(&state->input_buffer[state->input_rows_count - 1]);
+ state->buffer = newbuf;
+ init_bufferline(&state->buffer[state->rows_count - 1]);
uint32_t* newtext = calloc(MAXBUFLINE, sizeof(uint32_t));
if (!newtext)
return NULL;
- state->input_buffer[state->input_rows_count - 1].text = newtext;
- for (size_t i = state->input_rows_count - 1; i > state->input_row + 1;
+ state->buffer[state->rows_count - 1].text = newtext;
+ for (size_t i = state->rows_count - 1; i > state->row + 1;
i--)
{
- u32_strncpy(state->input_buffer[i].text,
- state->input_buffer[i - 1].text, MAXBUFLINE);
- state->input_buffer[i].length
- = state->input_buffer[i - 1].length;
+ u32_strncpy(state->buffer[i].text,
+ state->buffer[i - 1].text, MAXBUFLINE);
+ state->buffer[i].length
+ = state->buffer[i - 1].length;
}
- u32_strncpy(state->input_buffer[state->input_row + 1].text,
- state->input_buffer[state->input_row].text +
- state->input_column, MAXBUFLINE); state->input_buffer[state->input_row +
- 1].length = u32_strlen(state->input_buffer[state->input_row + 1].text);
- state->input_buffer[state->input_row].text[state->input_column] = 0;
- state->input_buffer[state->input_row].length
- = u32_strlen(state->input_buffer[state->input_row].text);
-
- state->input_row++;
- if (state->input_row
- > state->input_first_shown_row + (EDIT_HEIGHT - 3) / 2)
- state->input_first_shown_row
- = state->input_row - (EDIT_HEIGHT - 3) / 2;
+ u32_strncpy(state->buffer[state->row + 1].text,
+ state->buffer[state->row].text +
+ state->column, MAXBUFLINE); state->buffer[state->row +
+ 1].length = u32_strlen(state->buffer[state->row + 1].text);
+ state->buffer[state->row].text[state->column] = 0;
+ state->buffer[state->row].length
+ = u32_strlen(state->buffer[state->row].text);
+
+ state->row++;
+ if (state->row
+ > state->first_shown_row + (state->maxy - 1) / 2) // TODO
+ state->first_shown_row
+ = state->row - (state->maxy - 1) / 2;
move_start(state);
state->dirty = 1;
-*/
return state;
}
@@ -1049,40 +916,98 @@ join_lines(struct DrawState* state, size_t first_line, int forward)
if (!state)
return NULL;
- /*
- state->input_column = state->input_buffer[first_line].length;
- state->input_display_column = display_length(state,
- state->input_buffer[state->input_row].text,
- state->input_column);
- u32_strncat(state->input_buffer[first_line].text,
- state->input_buffer[first_line + 1].text, MAXBUFLINE);
- state->input_buffer[first_line].length
- = u32_strlen(state->input_buffer[first_line].text);
+ state->column = state->buffer[first_line].length;
+ state->display_column = display_length(state,
+ state->buffer[state->row].text,
+ state->column);
+ u32_strncat(state->buffer[first_line].text,
+ state->buffer[first_line + 1].text, MAXBUFLINE);
+ state->buffer[first_line].length
+ = u32_strlen(state->buffer[first_line].text);
if (!forward)
{
- state->input_row--;
- if (state->input_row < 0)
- state->input_row = 0;
+ state->row--;
+ if (state->row < 0)
+ state->row = 0;
}
- for (size_t i = first_line + 1; i < state->input_rows_count - 1; i++)
+ for (size_t i = first_line + 1; i < state->rows_count - 1; i++)
{
- u32_strncpy(state->input_buffer[i].text,
- state->input_buffer[i + 1].text, MAXBUFLINE);
- state->input_buffer[i].length
- = state->input_buffer[i + 1].length;
+ u32_strncpy(state->buffer[i].text,
+ state->buffer[i + 1].text, MAXBUFLINE);
+ state->buffer[i].length
+ = state->buffer[i + 1].length;
}
- free_bufferline(state->input_buffer + state->input_rows_count - 1);
- state->input_rows_count--;
- struct BufferLine* newbuf = realloc(state->input_buffer,
- state->input_rows_count * sizeof(struct BufferLine));
+ free_bufferline(state->buffer + state->rows_count - 1);
+ state->rows_count--;
+ struct BufferLine* newbuf = realloc(state->buffer,
+ state->rows_count * sizeof(struct BufferLine));
if (!newbuf)
return NULL;
- state->input_buffer = newbuf;
+ state->buffer = newbuf;
state->dirty = 1;
-*/
return state;
}
+int
+cancel_close(struct DrawState* state)
+{
+ if (!state)
+ return 1;
+
+ if (!*state->error && !state->in_prompt && !state->show_help)
+ strcpy(state->error, errors[ERR_EXIT_KEY]);
+ else
+ {
+ *state->error = 0;
+ *state->prompt = 0;
+ state->in_prompt = 0;
+ state->show_help = 0;
+ }
+
+ return 0;
+}
+
+int
+enter_command_mode(struct DrawState* state)
+{
+ if (!state)
+ return 1;
+ state->in_command_mode = 1;
+ return 0;
+}
+
+int
+enter_insert_mode(struct DrawState* state)
+{
+ if (!state)
+ return 1;
+ state->in_command_mode = 0;
+ return 0;
+}
+
+int
+exit_program(struct DrawState* state)
+{
+ if (state->dirty)
+ {
+ state->in_prompt = 1;
+ strcpy(state->prompt, prompt_dirty);
+ state->prompt_callback = quit_callback;
+ }
+ else
+ state->running = 0;
+ *state->error = 0;
+ return 0;
+}
+
+int
+show_help(struct DrawState* state)
+{
+ state->show_help = 1;
+ *state->error = 0;
+ return 0;
+}
+
void
handle_editbox_key_event(struct tb_event* ev, struct DrawState* state)
{
@@ -1117,17 +1042,10 @@ handle_editbox_key_event(struct tb_event* ev, struct DrawState* state)
move_right(state);
else if (ev->key == TB_KEY_ARROW_UP)
move_up(state);
- else if ((ev->key == TB_KEY_BACKSPACE || ev->key == TB_KEY_BACKSPACE2)
- /*&& !state->edit_info_focused*/)
- erase_backwards(state);
else if (ev->key == TB_KEY_CTRL_C)
; // yank_msgstr_to_paste_buffer(state);
else if (ev->key == TB_KEY_CTRL_K)
erase_to_end(state);
- else if (ev->key == TB_KEY_CTRL_N)
- next_plural(state);
- else if (ev->key == TB_KEY_CTRL_P)
- prev_plural(state);
else if (ev->key == TB_KEY_CTRL_Q)
strcpy(state->error, errors[ERR_DLG_OPEN_QUIT]);
else if (ev->key == TB_KEY_CTRL_R)
@@ -1144,8 +1062,6 @@ handle_editbox_key_event(struct tb_event* ev, struct DrawState* state)
erase_prev_word(state);
else if (ev->key == TB_KEY_CTRL_Z)
; // toggle_fuzzy(state);
- else if (ev->key == TB_KEY_DELETE /* && !state->edit_info_focused*/)
- erase_forward(state);
else if (ev->key == TB_KEY_END || ev->key == TB_KEY_CTRL_E)
move_end(state);
else if (ev->key == TB_KEY_ENTER)
@@ -1156,29 +1072,6 @@ handle_editbox_key_event(struct tb_event* ev, struct DrawState* state)
state->running = 0;
}
}
- else if (ev->key == TB_KEY_ESC)
- cancel_msgstr(state);
- else if (ev->key == TB_KEY_F5)
- ; // copy_msgid_to_input(state);
- else if (ev->key == TB_KEY_F6)
- // state->edit_info_focused = !state->edit_info_focused;
- ;
- else if (ev->key == TB_KEY_F8)
- ; // next_untranslated(state);
- else if (ev->key == TB_KEY_F9)
- ; // next_fuzzy(state);
- else if (ev->key == TB_KEY_HOME || ev->key == TB_KEY_CTRL_A)
- move_start(state);
- else if (ev->key == TB_KEY_PGDN || ev->key == TB_KEY_CTRL_F)
- ;//edit_page_down(state);
- else if (ev->key == TB_KEY_PGUP || ev->key == TB_KEY_CTRL_B)
- ;//edit_page_up(state);
- else if (ev->key == TB_KEY_SPACE)
- insert_char(state, ' ');
- else if (ev->key == TB_KEY_TAB)
- insert_char(state, '\t');
- else if (ev->ch != 0)
- insert_char(state, ev->ch);
}
void
@@ -1187,134 +1080,146 @@ handle_key_event(struct tb_event* ev, struct DrawState* state)
if (!state)
return;
- /*
- if (state->show_edit)
- handle_editbox_key_event(ev, state);
- else if (state->show_search)
- handle_search_key_event(ev, state);
- else */
-
- if (ev->key != TB_KEY_ARROW_DOWN && ev->key != TB_KEY_ARROW_UP
- && ev->ch != 'j' && ev->ch != 'k')
- state->saved_column = -1;
-
- if (ev->key == TB_KEY_ESC)
- {
- if (state->error[0])
- state->error[0] = 0;
- else if (state->in_prompt)
- {
- state->in_prompt = 0;
- state->prompt[0] = 0;
- return;
- }
- else if (state->show_help)
- state->show_help = 0;
- else
- strcpy(state->error, errors[ERR_EXIT_KEY]);
- }
- else if ((ev->ch == 'y' || ev->ch == 'n') && state->in_prompt)
+ if ((ev->ch == 'y' || ev->ch == 'n') && state->in_prompt)
{
if (state->prompt_callback)
state->prompt_callback(state, ev);
state->in_prompt = 0;
*state->prompt = 0;
+ return;
}
- else if (state->in_prompt)
+
+ /* Remember to also edit the following condition if you reassign motion
+ * keys */
+ if (ev->key != TB_KEY_ARROW_DOWN && ev->key != TB_KEY_ARROW_UP
+ && !(state->in_command_mode && strchr("jkgG", ev->ch)))
+ state->saved_column = -1;
+
+ for (int key = 0; key < LEN(top_level_keys); key++)
+ if ((top_level_keys[key].ev.key
+ && (top_level_keys[key].ev.key == ev->key))
+ || (top_level_keys[key].ev.ch
+ && (top_level_keys[key].ev.ch == ev->ch)))
+ if (top_level_keys[key].callback
+ && !top_level_keys[key].callback(state))
+ return;
+
+ if (state->in_prompt)
return;
- else if (ev->ch == 'q' || ev->key == TB_KEY_CTRL_Q)
+
+ if (state->show_help)
{
- if (state->dirty)
- {
- state->in_prompt = 1;
- strcpy(state->prompt, prompt_dirty);
- state->prompt_callback = quit_callback;
- }
- else
- state->running = 0;
- state->error[0] = 0;
- }
- else if (state->show_help)
strcpy(state->error, errors[ERR_DLG_OPEN]);
- else if (ev->key == TB_KEY_ARROW_DOWN || ev->ch == 'j')
- move_down(state);
- else if (ev->key == TB_KEY_ARROW_LEFT || ev->ch == 'h')
- move_left(state);
- else if (ev->key == TB_KEY_ARROW_RIGHT || ev->ch == 'l')
- move_right(state);
- else if (ev->key == TB_KEY_ARROW_UP || ev->ch == 'k')
- move_up(state);
- else if (ev->key == TB_KEY_CTRL_B || ev->key == TB_KEY_PGUP)
- move_page_up(state);
- else if (ev->key == TB_KEY_CTRL_F || ev->key == TB_KEY_PGDN)
- move_page_down(state);
- else if (ev->key == TB_KEY_CTRL_S || ev->ch == 'w')
+ return;
+ }
+
+ for (int key = 0; key < LEN(global_keys); key++)
+ if ((global_keys[key].ev.key
+ && (global_keys[key].ev.key == ev->key))
+ || (global_keys[key].ev.ch
+ && (global_keys[key].ev.ch == ev->ch)))
+ if (global_keys[key].callback
+ && !global_keys[key].callback(state))
+ return;
+
+ if (state->in_command_mode)
{
- if (!state->dirty)
- return;
- /*
- int result = save_file(state->entries, state->real_msgid_count,
- state->filename, state->nplurals);
- switch (result)
- {
- case SAVE_ERR_CANT_ALLOC:
- strcpy(state->error, errors[ERR_CANT_ALLOC]);
- state->running = 0;
- break;
- case SAVE_ERR_CANT_OPEN_FILE:
- strcpy(state->error, errors[ERR_CANT_SAVE]);
- state->running = 0;
- break;
- case SAVE_ERR_CANT_MOVE_FILE:
- strcpy(state->error, strerror(errno));
- state->running = 0;
- break;
- case SAVE_ERR_NONE:
- default:
- state->error[0] = 0;
- }
- */
- state->dirty = 0;
+ for (int key = 0; key < LEN(command_keys); key++)
+ if ((command_keys[key].ev.key
+ && (command_keys[key].ev.key == ev->key))
+ || (command_keys[key].ev.ch
+ && (command_keys[key].ev.ch == ev->ch)))
+ if (command_keys[key].callback
+ && !command_keys[key].callback(state))
+ return;
}
- else if (ev->key == TB_KEY_CTRL_Z || ev->ch == 'z')
- ; // toggle_fuzzy(state);
- else if (ev->ch == 'G')
- move_bottom(state);
- else if (ev->key == TB_KEY_END)
- move_end(state);
- else if (ev->key == TB_KEY_ENTER)
+ else
{
- /*
- if (state->msgid_count == 0)
- strcpy(state->error, errors[ERR_EMPTY_FILE]);
- else
+ for (int key = 0; key < LEN(insert_keys); key++)
+ if ((insert_keys[key].ev.key
+ && (insert_keys[key].ev.key == ev->key))
+ || (insert_keys[key].ev.ch
+ && (insert_keys[key].ev.ch == ev->ch)))
+ if (insert_keys[key].callback
+ && !insert_keys[key].callback(state))
+ return;
+ if (ev->ch)
{
- state->msgstr_index = 0;
- show_edit(state);
+ insert_char(state, ev->ch);
+ return;
}
- */
}
- else if (ev->key == TB_KEY_F1 || ev->ch == 'H')
+
+ strcpy(state->error, errors[ERR_UNKNOWN_KEY]);
+ /*
+else if (ev->key == TB_KEY_CTRL_B || ev->key == TB_KEY_PGUP)
+ move_page_up(state);
+else if (ev->key == TB_KEY_CTRL_F || ev->key == TB_KEY_PGDN)
+ move_page_down(state);
+else if (ev->key == TB_KEY_CTRL_S || ev->ch == 'w')
+{
+ if (!state->dirty)
+ return;
+ int result = save_file(state->entries, state->real_msgid_count,
+ state->filename, state->nplurals);
+ switch (result)
{
- state->show_help = 1;
- *state->error = 0;
+ case SAVE_ERR_CANT_ALLOC:
+ strcpy(state->error, errors[ERR_CANT_ALLOC]);
+ state->running = 0;
+ break;
+ case SAVE_ERR_CANT_OPEN_FILE:
+ strcpy(state->error, errors[ERR_CANT_SAVE]);
+ state->running = 0;
+ break;
+ case SAVE_ERR_CANT_MOVE_FILE:
+ strcpy(state->error, strerror(errno));
+ state->running = 0;
+ break;
+ case SAVE_ERR_NONE:
+ default:
+ state->error[0] = 0;
}
- else if (ev->key == TB_KEY_F3 || ev->ch == 'n')
- ; // next_match(state);
- else if (ev->key == TB_KEY_F4 || ev->ch == 'N')
- ; // prev_match(state);
- else if (ev->key == TB_KEY_F7 || ev->ch == '/')
- ; // show_search(state);
- else if (ev->key == TB_KEY_F8 || ev->ch == 'u')
- ; // next_untranslated(state);
- else if (ev->key == TB_KEY_F9 || ev->ch == 'f')
- ; // next_fuzzy(state);
- else if (ev->ch == 'g')
- move_top(state);
- else if (ev->key == TB_KEY_HOME)
- move_start(state);
+ state->dirty = 0;
+}
+else if (ev->key == TB_KEY_CTRL_Z || ev->ch == 'z')
+ ; // toggle_fuzzy(state);
+else if (ev->ch == 'G')
+ move_bottom(state);
+else if (ev->key == TB_KEY_END)
+ move_end(state);
+else if (ev->key == TB_KEY_ENTER)
+{
+ if (state->msgid_count == 0)
+ strcpy(state->error, errors[ERR_EMPTY_FILE]);
else
- strcpy(state->error, errors[ERR_UNKNOWN_KEY]);
+ {
+ state->msgstr_index = 0;
+ show_edit(state);
+ }
+}
+else if (ev->key == TB_KEY_F1 || ev->ch == 'H')
+{
+ state->show_help = 1;
+ *state->error = 0;
+}
+else if (ev->key == TB_KEY_F3 || ev->ch == 'n')
+ ; // next_match(state);
+else if (ev->key == TB_KEY_F4 || ev->ch == 'N')
+ ; // prev_match(state);
+else if (ev->key == TB_KEY_F7 || ev->ch == '/')
+ ; // show_search(state);
+else if (ev->key == TB_KEY_F8 || ev->ch == 'u')
+ ; // next_untranslated(state);
+else if (ev->key == TB_KEY_F9 || ev->ch == 'f')
+ ; // next_fuzzy(state);
+else if (ev->ch == 'g')
+ move_top(state);
+else if (ev->key == TB_KEY_HOME)
+ move_start(state);
+else
+ strcpy(state->error, errors[ERR_UNKNOWN_KEY]);
+ */
}
void
diff --git a/util.h b/util.h
@@ -6,6 +6,14 @@
#define MIN(a, b) ((a < b) ? a : b)
enum {
+ UNKNOWN_MODE,
+ COMMAND_MODE,
+ HELP_MODE,
+ INSERT_MODE,
+ PROMPT_MODE
+};
+
+enum {
ERR_UNKNOWN_KEY,
ERR_EXIT_KEY,
ERR_DLG_OPEN,