diff options
Diffstat (limited to 'examples/dte/shift.c')
| -rw-r--r-- | examples/dte/shift.c | 147 |
1 files changed, 0 insertions, 147 deletions
diff --git a/examples/dte/shift.c b/examples/dte/shift.c deleted file mode 100644 index 6276d3c..0000000 --- a/examples/dte/shift.c +++ /dev/null | |||
| @@ -1,147 +0,0 @@ | |||
| 1 | #include <stddef.h> | ||
| 2 | #include <stdlib.h> | ||
| 3 | #include <string.h> | ||
| 4 | #include "shift.h" | ||
| 5 | #include "block-iter.h" | ||
| 6 | #include "buffer.h" | ||
| 7 | #include "change.h" | ||
| 8 | #include "indent.h" | ||
| 9 | #include "move.h" | ||
| 10 | #include "options.h" | ||
| 11 | #include "selection.h" | ||
| 12 | #include "util/debug.h" | ||
| 13 | #include "util/macros.h" | ||
| 14 | #include "util/xmalloc.h" | ||
| 15 | |||
| 16 | static char *alloc_indent(const LocalOptions *options, size_t count, size_t *sizep) | ||
| 17 | { | ||
| 18 | bool use_spaces = use_spaces_for_indent(options); | ||
| 19 | size_t size = use_spaces ? count * options->indent_width : count; | ||
| 20 | *sizep = size; | ||
| 21 | return memset(xmalloc(size), use_spaces ? ' ' : '\t', size); | ||
| 22 | } | ||
| 23 | |||
| 24 | static void shift_right(View *view, size_t nr_lines, size_t count) | ||
| 25 | { | ||
| 26 | const LocalOptions *options = &view->buffer->options; | ||
| 27 | size_t indent_size; | ||
| 28 | char *indent = alloc_indent(options, count, &indent_size); | ||
| 29 | |||
| 30 | for (size_t i = 0; true; ) { | ||
| 31 | StringView line; | ||
| 32 | fetch_this_line(&view->cursor, &line); | ||
| 33 | IndentInfo info = get_indent_info(options, &line); | ||
| 34 | if (info.wsonly) { | ||
| 35 | if (info.bytes) { | ||
| 36 | // Remove indentation | ||
| 37 | buffer_delete_bytes(view, info.bytes); | ||
| 38 | } | ||
| 39 | } else if (info.sane) { | ||
| 40 | // Insert whitespace | ||
| 41 | buffer_insert_bytes(view, indent, indent_size); | ||
| 42 | } else { | ||
| 43 | // Replace whole indentation with sane one | ||
| 44 | size_t size; | ||
| 45 | char *buf = alloc_indent(options, info.level + count, &size); | ||
| 46 | buffer_replace_bytes(view, info.bytes, buf, size); | ||
| 47 | free(buf); | ||
| 48 | } | ||
| 49 | if (++i == nr_lines) { | ||
| 50 | break; | ||
| 51 | } | ||
| 52 | block_iter_eat_line(&view->cursor); | ||
| 53 | } | ||
| 54 | |||
| 55 | free(indent); | ||
| 56 | } | ||
| 57 | |||
| 58 | static void shift_left(View *view, size_t nr_lines, size_t count) | ||
| 59 | { | ||
| 60 | const LocalOptions *options = &view->buffer->options; | ||
| 61 | const size_t indent_width = options->indent_width; | ||
| 62 | const bool space_indent = use_spaces_for_indent(options); | ||
| 63 | |||
| 64 | for (size_t i = 0; true; ) { | ||
| 65 | StringView line; | ||
| 66 | fetch_this_line(&view->cursor, &line); | ||
| 67 | IndentInfo info = get_indent_info(options, &line); | ||
| 68 | if (info.wsonly) { | ||
| 69 | if (info.bytes) { | ||
| 70 | // Remove indentation | ||
| 71 | buffer_delete_bytes(view, info.bytes); | ||
| 72 | } | ||
| 73 | } else if (info.level && info.sane) { | ||
| 74 | size_t n = MIN(count, info.level); | ||
| 75 | if (space_indent) { | ||
| 76 | n *= indent_width; | ||
| 77 | } | ||
| 78 | buffer_delete_bytes(view, n); | ||
| 79 | } else if (info.bytes) { | ||
| 80 | // Replace whole indentation with sane one | ||
| 81 | if (info.level > count) { | ||
| 82 | size_t size; | ||
| 83 | char *buf = alloc_indent(options, info.level - count, &size); | ||
| 84 | buffer_replace_bytes(view, info.bytes, buf, size); | ||
| 85 | free(buf); | ||
| 86 | } else { | ||
| 87 | buffer_delete_bytes(view, info.bytes); | ||
| 88 | } | ||
| 89 | } | ||
| 90 | if (++i == nr_lines) { | ||
| 91 | break; | ||
| 92 | } | ||
| 93 | block_iter_eat_line(&view->cursor); | ||
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | static void do_shift_lines(View *view, int count, size_t nr_lines) | ||
| 98 | { | ||
| 99 | begin_change_chain(); | ||
| 100 | block_iter_bol(&view->cursor); | ||
| 101 | if (count > 0) { | ||
| 102 | shift_right(view, nr_lines, count); | ||
| 103 | } else { | ||
| 104 | shift_left(view, nr_lines, -count); | ||
| 105 | } | ||
| 106 | end_change_chain(view); | ||
| 107 | } | ||
| 108 | |||
| 109 | void shift_lines(View *view, int count) | ||
| 110 | { | ||
| 111 | unsigned int width = view->buffer->options.indent_width; | ||
| 112 | BUG_ON(width > INDENT_WIDTH_MAX); | ||
| 113 | BUG_ON(count == 0); | ||
| 114 | |||
| 115 | long x = view_get_preferred_x(view) + (count * width); | ||
| 116 | x = MAX(x, 0); | ||
| 117 | |||
| 118 | if (view->selection == SELECT_NONE) { | ||
| 119 | do_shift_lines(view, count, 1); | ||
| 120 | goto out; | ||
| 121 | } | ||
| 122 | |||
| 123 | SelectionInfo info; | ||
| 124 | view->selection = SELECT_LINES; | ||
| 125 | init_selection(view, &info); | ||
| 126 | view->cursor = info.si; | ||
| 127 | size_t nr_lines = get_nr_selected_lines(&info); | ||
| 128 | do_shift_lines(view, count, nr_lines); | ||
| 129 | if (info.swapped) { | ||
| 130 | // Cursor should be at beginning of selection | ||
| 131 | block_iter_bol(&view->cursor); | ||
| 132 | view->sel_so = block_iter_get_offset(&view->cursor); | ||
| 133 | while (--nr_lines) { | ||
| 134 | block_iter_prev_line(&view->cursor); | ||
| 135 | } | ||
| 136 | } else { | ||
| 137 | BlockIter save = view->cursor; | ||
| 138 | while (--nr_lines) { | ||
| 139 | block_iter_prev_line(&view->cursor); | ||
| 140 | } | ||
| 141 | view->sel_so = block_iter_get_offset(&view->cursor); | ||
| 142 | view->cursor = save; | ||
| 143 | } | ||
| 144 | |||
| 145 | out: | ||
| 146 | move_to_preferred_x(view, x); | ||
| 147 | } | ||
