Skip to content

Commit

Permalink
Move code from src/misc.c to src/{case,delete,join,selection}.c
Browse files Browse the repository at this point in the history
  • Loading branch information
craigbarnes committed Jan 9, 2025
1 parent bff60a2 commit 8b174b1
Show file tree
Hide file tree
Showing 20 changed files with 407 additions and 377 deletions.
4 changes: 3 additions & 1 deletion docs/TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,11 @@ Testing/Debugging
* `handle_exec()`
* `spawn_compiler()`
* `dump_buffer()`
* `src/case.c`
* `src/cmdline.c`
* `src/erase.c`
* `src/load-save.c`
* `src/misc.c`
* `src/selection.c`
* `src/show.c`
* `src/tag.c`
* `src/view.c`
Expand Down
12 changes: 6 additions & 6 deletions mk/build.mk
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ terminal_objects := $(call prefix-obj, build/terminal/, \
query rxvt style terminal )

editor_objects := $(call prefix-obj, build/, \
bind block block-iter bookmark buffer change cmdline commands \
compat compiler completion config convert copy ctags edit editor \
encoding error exec file-history file-option filetype frame history \
indent insert load-save lock main misc mode move msg options regexp \
replace search selection shift show signals spawn status tag vars \
view window wrap \
bind block block-iter bookmark buffer case change cmdline commands \
compat compiler completion config convert copy ctags delete edit \
editor encoding error exec file-history file-option filetype frame \
history indent insert join load-save lock main mode move msg options \
regexp replace search selection shift show signals spawn status tag \
vars view window wrap \
$(addprefix ui-, cmdline prompt status tabbar view window) ui ) \
$(command_objects) \
$(editorconfig_objects) \
Expand Down
2 changes: 1 addition & 1 deletion src/bookmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
#include "bookmark.h"
#include "buffer.h"
#include "editor.h"
#include "misc.h"
#include "move.h"
#include "search.h"
#include "selection.h"
#include "util/debug.h"

FileLocation *get_current_file_location(const View *v)
Expand Down
72 changes: 72 additions & 0 deletions src/case.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include <stdbool.h>
#include <stdlib.h>
#include "case.h"
#include "block-iter.h"
#include "change.h"
#include "selection.h"
#include "util/debug.h"
#include "util/string.h"
#include "util/unicode.h"
#include "util/utf8.h"

void change_case(View *view, char mode)
{
bool was_selecting = false;
bool move = true;
size_t text_len;
if (view->selection) {
SelectionInfo info = init_selection(view);
view->cursor = info.si;
text_len = info.eo - info.so;
unselect(view);
was_selecting = true;
move = !info.swapped;
} else {
CodePoint u;
if (!block_iter_get_char(&view->cursor, &u)) {
return;
}
text_len = u_char_size(u);
}

String dst = string_new(text_len);
char *src = block_iter_get_bytes(&view->cursor, text_len);
size_t i = 0;
switch (mode) {
case 'l':
while (i < text_len) {
CodePoint u = u_to_lower(u_get_char(src, text_len, &i));
string_append_codepoint(&dst, u);
}
break;
case 'u':
while (i < text_len) {
CodePoint u = u_to_upper(u_get_char(src, text_len, &i));
string_append_codepoint(&dst, u);
}
break;
case 't':
while (i < text_len) {
CodePoint u = u_get_char(src, text_len, &i);
u = u_is_upper(u) ? u_to_lower(u) : u_to_upper(u);
string_append_codepoint(&dst, u);
}
break;
default:
BUG("unhandled case mode");
}

buffer_replace_bytes(view, text_len, dst.buffer, dst.len);
free(src);

if (move && dst.len > 0) {
size_t skip = dst.len;
if (was_selecting) {
// Move cursor back to where it was
u_prev_char(dst.buffer, &skip);
}
block_iter_skip_bytes(&view->cursor, skip);
}

string_free(&dst);
}
9 changes: 9 additions & 0 deletions src/case.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef CASE_H
#define CASE_H

#include "util/macros.h"
#include "view.h"

void change_case(View *view, char mode) NONNULL_ARGS;

#endif
4 changes: 3 additions & 1 deletion src/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "bind.h"
#include "bookmark.h"
#include "buffer.h"
#include "case.h"
#include "change.h"
#include "cmdline.h"
#include "command/alias.h"
Expand All @@ -19,6 +20,7 @@
#include "config.h"
#include "convert.h"
#include "copy.h"
#include "delete.h"
#include "editor.h"
#include "encoding.h"
#include "error.h"
Expand All @@ -28,9 +30,9 @@
#include "frame.h"
#include "history.h"
#include "insert.h"
#include "join.h"
#include "load-save.h"
#include "lock.h"
#include "misc.h"
#include "mode.h"
#include "move.h"
#include "msg.h"
Expand Down
1 change: 0 additions & 1 deletion src/copy.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include "block-iter.h"
#include "change.h"
#include "insert.h"
#include "misc.h"
#include "move.h"
#include "selection.h"
#include "util/debug.h"
Expand Down
88 changes: 88 additions & 0 deletions src/delete.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include <stdlib.h>
#include <string.h>
#include "delete.h"
#include "buffer.h"
#include "change.h"
#include "indent.h"
#include "options.h"
#include "selection.h"
#include "util/debug.h"
#include "util/string.h"
#include "util/string-view.h"
#include "util/utf8.h"

void delete_ch(View *view)
{
size_t size = 0;
if (view->selection) {
size = prepare_selection(view);
unselect(view);
} else {
const LocalOptions *options = &view->buffer->options;
begin_change(CHANGE_MERGE_DELETE);
if (options->emulate_tab) {
size = get_indent_level_bytes_right(options, &view->cursor);
}
if (size == 0) {
BlockIter bi = view->cursor;
size = block_iter_next_column(&bi);
}
}
buffer_delete_bytes(view, size);
}

void erase(View *view)
{
size_t size = 0;
if (view->selection) {
size = prepare_selection(view);
unselect(view);
} else {
const LocalOptions *options = &view->buffer->options;
begin_change(CHANGE_MERGE_ERASE);
if (options->emulate_tab) {
size = get_indent_level_bytes_left(options, &view->cursor);
block_iter_back_bytes(&view->cursor, size);
}
if (size == 0) {
CodePoint u;
size = block_iter_prev_char(&view->cursor, &u);
}
}
buffer_erase_bytes(view, size);
}

void clear_lines(View *view, bool auto_indent)
{
char *indent = NULL;
if (auto_indent) {
BlockIter bi = view->cursor;
if (block_iter_prev_line(&bi) && block_iter_find_non_empty_line_bwd(&bi)) {
StringView line = block_iter_get_line(&bi);
indent = get_indent_for_next_line(&view->buffer->options, &line);
}
}

size_t del_count = 0;
if (view->selection) {
view->selection = SELECT_LINES;
del_count = prepare_selection(view);
unselect(view);
// Don't delete last newline
if (del_count) {
del_count--;
}
} else {
block_iter_eol(&view->cursor);
del_count = block_iter_bol(&view->cursor);
}

if (!indent && !del_count) {
return;
}

size_t ins_count = indent ? strlen(indent) : 0;
buffer_replace_bytes(view, del_count, indent, ins_count);
free(indent);
block_iter_skip_bytes(&view->cursor, ins_count);
}
12 changes: 12 additions & 0 deletions src/delete.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef DELETE_H
#define DELETE_H

#include <stdbool.h>
#include "util/macros.h"
#include "view.h"

void delete_ch(View *view) NONNULL_ARGS;
void erase(View *view) NONNULL_ARGS;
void clear_lines(View *view, bool auto_indent) NONNULL_ARGS;

#endif
1 change: 0 additions & 1 deletion src/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include "commands.h"
#include "ctags.h"
#include "error.h"
#include "misc.h"
#include "move.h"
#include "msg.h"
#include "selection.h"
Expand Down
1 change: 0 additions & 1 deletion src/insert.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include "buffer.h"
#include "change.h"
#include "indent.h"
#include "misc.h"
#include "options.h"
#include "selection.h"
#include "util/utf8.h"
Expand Down
96 changes: 96 additions & 0 deletions src/join.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#include "join.h"
#include "block-iter.h"
#include "change.h"
#include "selection.h"
#include "util/debug.h"
#include "util/unicode.h"

static void join_selection(View *view, const char *delim, size_t delim_len)
{
size_t count = prepare_selection(view);
BlockIter bi = view->cursor;
size_t ws_len = 0;
size_t join = 0;
CodePoint ch = 0;
unselect(view);
begin_change_chain();

while (count > 0) {
if (!ws_len) {
view->cursor = bi;
}

size_t n = block_iter_next_char(&bi, &ch);
count -= MIN(n, count);
if (ch == '\n' || ch == '\t' || ch == ' ') {
join += (ch == '\n');
ws_len++;
continue;
}

if (join) {
buffer_replace_bytes(view, ws_len, delim, delim_len);
// Skip the delimiter we inserted and the char we read last
block_iter_skip_bytes(&view->cursor, delim_len);
block_iter_next_char(&view->cursor, &ch);
bi = view->cursor;
}

ws_len = 0;
join = 0;
}

if (join && ch == '\n') {
// Don't replace last newline at end of selection
join--;
ws_len--;
}

if (join) {
size_t ins_len = (ch == '\n') ? 0 : delim_len; // Don't add delim, if at eol
buffer_replace_bytes(view, ws_len, delim, ins_len);
}

end_change_chain(view);
}

void join_lines(View *view, const char *delim, size_t delim_len)
{
if (view->selection) {
join_selection(view, delim, delim_len);
return;
}

// Create an iterator and position it at the beginning of the next line
// (or return early, if there is no next line)
BlockIter next = view->cursor;
if (!block_iter_next_line(&next) || block_iter_is_eof(&next)) {
return;
}

// Create a second iterator and position it at the end of the current line
BlockIter eol = next;
CodePoint u;
size_t nbytes = block_iter_prev_char(&eol, &u);
BUG_ON(nbytes != 1);
BUG_ON(u != '\n');

// Skip over trailing whitespace at the end of the current line
size_t del_count = 1 + block_iter_skip_blanks_bwd(&eol);

// Skip over leading whitespace at the start of the next line
del_count += block_iter_skip_blanks_fwd(&next);

// Move the cursor to the join position
view->cursor = eol;

if (block_iter_is_bol(&next)) {
// If the next line is empty (or whitespace only) just discard
// it, by deleting the newline and any whitespace
buffer_delete_bytes(view, del_count);
} else {
// Otherwise, join the current and next lines together, by
// replacing the newline/whitespace with the delimiter string
buffer_replace_bytes(view, del_count, delim, delim_len);
}
}
10 changes: 10 additions & 0 deletions src/join.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef JOIN_H
#define JOIN_H

#include <stddef.h>
#include "view.h"
#include "util/macros.h"

void join_lines(View *view, const char *delim, size_t delim_len) NONNULL_ARG(1);

#endif
Loading

0 comments on commit 8b174b1

Please sign in to comment.