чување 41a84a2eb048a0098057a9f1c3fbcd6a7f7313ed
родитељ be581e70af14ca984fec684cf1ca1a9c92b5b757
Аутор: Страхиња Радић <contact@strahinja.org>
Датум: Wed, 23 Feb 2022 21:31:45 +0100
Add overwrite mode; new key: Z -> write_file
Signed-off-by: Страхиња Радић <contact@strahinja.org>
Diffstat:
измењених датотека: 8, додавања: 63(+), брисања: 18(-)
diff --git a/TODO b/TODO
@@ -1,19 +1,19 @@
TODO
====
- [ ] Reassign C-I (clash with inserting tab!)
+ [x] Reassign C-I (clash with inserting tab!)
- [ ] When updating first_shown_column in insert_line, set it to (maxy - 2) / 2
+ [/] When updating first_shown_column in insert_line, set it to (maxy - 2) / 2
[x] Copy/paste?
- [ ] Overwrite mode
+ [x] Overwrite mode
[ ] Investigate DrawState.first_shown_column
[ ] Add vi V
- [ ] Add Z as vi-like shortcut for C-S
+ [x] Add Z as vi-like shortcut for C-S
< > Search?
diff --git a/config.def.h b/config.def.h
@@ -81,6 +81,7 @@ int paste_from_paste(struct DrawState* state);
int reread_or_callback(struct DrawState* state);
int show_go_to_line(struct DrawState* state);
int show_help(struct DrawState* state);
+int toggle_overwrite(struct DrawState* state);
int toggle_selection(struct DrawState* state);
int write_file(struct DrawState* state);
int yank_to_paste(struct DrawState* state);
@@ -141,6 +142,8 @@ static const struct Key global_keys[] = {
{ .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_INSERT },
+ .callback = toggle_overwrite },
{ .ev = { .key = TB_KEY_PGDN }, .callback = move_page_down },
{ .ev = { .key = TB_KEY_PGUP }, .callback = move_page_up }
};
@@ -185,6 +188,8 @@ static const struct Key insert_keys[] = {
.callback = enter_command_mode },
{ .ev = { .key = TB_KEY_ENTER },
.callback = insert_line },
+ { .ev = { .key = TB_KEY_INSERT },
+ .callback = toggle_overwrite },
{ .ev = { .key = TB_KEY_SPACE },
.callback = insert_space },
{ .ev = { .key = TB_KEY_TAB }, .callback = insert_tab }
@@ -208,10 +213,13 @@ static const struct Key command_keys[] = {
{ .ev = { .ch = 'M' }, .callback = move_screen_middle },
{ .ev = { .ch = 'P' }, .callback = paste_from_paste },
{ .ev = { .ch = 'q' }, .callback = exit_program },
+ { .ev = { .ch = 'R' }, .callback = toggle_overwrite },
+ { .ev = { .ch = 'r' }, .callback = reread_or_callback },
{ .ev = { .ch = 'v' }, .callback = toggle_selection },
{ .ev = { .ch = 'W' }, .callback = move_prev_word },
{ .ev = { .ch = 'w' }, .callback = move_next_word },
- { .ev = { .ch = 'y' }, .callback = yank_to_paste }
+ { .ev = { .ch = 'y' }, .callback = yank_to_paste },
+ { .ev = { .ch = 'Z' }, .callback = write_file }
};
/* clang-format on */
#endif /* SLED_C_GLOBALS */
diff --git a/config.h b/config.h
@@ -81,6 +81,7 @@ int paste_from_paste(struct DrawState* state);
int reread_or_callback(struct DrawState* state);
int show_go_to_line(struct DrawState* state);
int show_help(struct DrawState* state);
+int toggle_overwrite(struct DrawState* state);
int toggle_selection(struct DrawState* state);
int write_file(struct DrawState* state);
int yank_to_paste(struct DrawState* state);
@@ -141,6 +142,8 @@ static const struct Key global_keys[] = {
{ .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_INSERT },
+ .callback = toggle_overwrite },
{ .ev = { .key = TB_KEY_PGDN }, .callback = move_page_down },
{ .ev = { .key = TB_KEY_PGUP }, .callback = move_page_up }
};
@@ -185,6 +188,8 @@ static const struct Key insert_keys[] = {
.callback = enter_command_mode },
{ .ev = { .key = TB_KEY_ENTER },
.callback = insert_line },
+ { .ev = { .key = TB_KEY_INSERT },
+ .callback = toggle_overwrite },
{ .ev = { .key = TB_KEY_SPACE },
.callback = insert_space },
{ .ev = { .key = TB_KEY_TAB }, .callback = insert_tab }
@@ -208,10 +213,13 @@ static const struct Key command_keys[] = {
{ .ev = { .ch = 'M' }, .callback = move_screen_middle },
{ .ev = { .ch = 'P' }, .callback = paste_from_paste },
{ .ev = { .ch = 'q' }, .callback = exit_program },
+ { .ev = { .ch = 'R' }, .callback = toggle_overwrite },
+ { .ev = { .ch = 'r' }, .callback = reread_or_callback },
{ .ev = { .ch = 'v' }, .callback = toggle_selection },
{ .ev = { .ch = 'W' }, .callback = move_prev_word },
{ .ev = { .ch = 'w' }, .callback = move_next_word },
- { .ev = { .ch = 'y' }, .callback = yank_to_paste }
+ { .ev = { .ch = 'y' }, .callback = yank_to_paste },
+ { .ev = { .ch = 'Z' }, .callback = write_file }
};
/* clang-format on */
#endif /* SLED_C_GLOBALS */
diff --git a/draw.c b/draw.c
@@ -23,6 +23,7 @@ static const char* help[] = {
"C-\\ - Switch command <-> insert mode",
"Home or C-A - Go to start of line",
"End or C-E - Go to end of line",
+ "Insert - Toggle overwrite mode",
"C-L - Show Go to line dialog",
"C-O - Reread (reopen) file",
"C-Q - Quit",
@@ -40,6 +41,7 @@ const char* mode_labels[] = {
[COMMAND_MODE] = "COMMAND",
[HELP_MODE] = "HELP",
[INSERT_MODE] = "INSERT",
+ [OVERWRITE_MODE] = "OVERWRITE",
[PROMPT_MODE] = "PROMPT",
[SELECTION_MODE] = "SELECTION"
};
@@ -121,6 +123,7 @@ init_drawstate(struct DrawState* state, char* error, char* action,
state->dirty = 0;
state->in_prompt = 0;
state->in_command_mode = 0;
+ state->in_overwrite_mode = 0;
state->in_selection_mode = 0;
state->show_help = 0;
state->show_input_dialog = 0;
@@ -167,6 +170,8 @@ format_mode(char* result, size_t result_size, const char* format,
mode_label = mode_labels[PROMPT_MODE];
else if (state->in_selection_mode)
mode_label = mode_labels[SELECTION_MODE];
+ else if (state->in_overwrite_mode)
+ mode_label = mode_labels[OVERWRITE_MODE];
else if (state->in_command_mode)
mode_label = mode_labels[COMMAND_MODE];
else
diff --git a/draw.h b/draw.h
@@ -60,6 +60,7 @@ struct DrawState {
int dirty;
int in_prompt;
int in_command_mode;
+ int in_overwrite_mode;
int in_selection_mode;
int show_help;
int show_input_dialog;
diff --git a/sled.1.in b/sled.1.in
@@ -61,7 +61,7 @@ is a simple text editor with a terminal UI.
.
.LP
.B sled
-has three modes of operation. The initial mode which is active on startup is the
+has four modes of operation. The initial mode which is active on startup is the
.BR "insert mode" .
It behaves like one would expect from a \[lq]normal\[rq] text editor: most
characters are self-inserting, arrow keys and backspace/delete work as expected,
@@ -70,7 +70,10 @@ and so on.
behaves more like
.BR vi (1):
characters like \fCh\fP, \fCj\fP, \fCk\fP, \fCl\fP no longer insert themselves
-but execute commands (in this case movement commands). Last, in
+but execute commands (in this case movement commands).
+.B Overwrite mode
+is the same as insert mode, except that newly inserted characters replace the
+existing ones instead of being inserted among them. Last, in
.BR "selection mode" ,
moving around the file extends the selection, and most commands that alter text
instead delete the selection and exit selection mode.
@@ -94,6 +97,7 @@ _
\fCC-C\fP@Yank to paste buffer
\fCDelete\fP@Erase character under cursor
\fCEnd\fP or \fCC-E\fP@Go to end of line
+\fCInsert\fP@Toggle overwrite
\fCPgDown\fP or \fCC-F\fP@Go to next page
\fCC-K\fP@Erase to end of line
\fCC-L\fP@Show Go to line dialog
@@ -111,9 +115,13 @@ _
.
.LP
In
-.BR "insert mode" ,
+.B insert mode
+and
+.BR "overwrite mode" ,
characters are self-inserting, and \fCEnter\fP inserts new line. All the global
-keys apply to insert mode as well.
+keys apply to insert mode as well. Entering overwrite mode switches back to
+insert mode when the overwrite mode is toggled off, even when the overwrite mode
+was entered from the command mode.
.
.LP
In
@@ -139,12 +147,15 @@ _
\fCL\fP@Go to last line on the screen
\fCl\fP@Go to next character
\fCM\fP@Go to middle line on the screen
-\fCp\fP@Paste from paste buffer
+\fCP\fP@Paste from paste buffer
\fCq\fP@Quit
+\fCR\fP@Toggle overwrite mode
+\fCr\fP@Reread (reopen) file
\fCv\fP@Toggle selection mode
\fCW\fP@Go to previous word
\fCw\fP@Go to next word
\fCy\fP@Yank to paste buffer
+\fCZ\fP@Write (save) file
.TE
.
.sp 1
diff --git a/sled.c b/sled.c
@@ -1047,13 +1047,15 @@ insert_char(struct DrawState* state, uint32_t ch)
len = buffer_line->length;
i = len + 1;
- while (i < MAXBUFLINE - 2 && i > state->column)
- {
- buffer_line->text[i] = buffer_line->text[i - 1];
- i--;
- }
+ if (!state->in_overwrite_mode)
+ while (i < MAXBUFLINE - 2 && i > state->column)
+ {
+ buffer_line->text[i] = buffer_line->text[i - 1];
+ i--;
+ }
buffer_line->text[state->column++] = ch;
- buffer_line->length++;
+ if (!state->in_overwrite_mode)
+ buffer_line->length++;
if (state->column == MAXBUFLINE)
state->column = MAXBUFLINE - 1;
state->display_column = display_length(state,
@@ -1263,7 +1265,7 @@ insert_line(struct DrawState* state)
= u32_strlen(state->buffer[state->row].text);
state->row++;
if (state->row > state->first_shown_row + (state->maxy - 2))
- state->first_shown_row = state->row - state->maxy + 2;
+ state->first_shown_row = state->row - (state->maxy - 2);
move_start(state);
state->dirty = 1;
return 0;
@@ -1641,6 +1643,15 @@ show_help(struct DrawState* state)
}
int
+toggle_overwrite(struct DrawState* state)
+{
+ state->in_overwrite_mode = !state->in_overwrite_mode;
+ if (state->in_overwrite_mode)
+ state->in_command_mode = 0;
+ return 0;
+}
+
+int
toggle_selection(struct DrawState* state)
{
state->in_selection_mode = !state->in_selection_mode;
diff --git a/util.h b/util.h
@@ -10,6 +10,7 @@ enum {
COMMAND_MODE,
HELP_MODE,
INSERT_MODE,
+ OVERWRITE_MODE,
PROMPT_MODE,
SELECTION_MODE
};