aboutsummaryrefslogtreecommitdiff
path: root/examples/dte/shift.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/dte/shift.c')
-rw-r--r--examples/dte/shift.c147
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
16static 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
24static 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
58static 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
97static 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
109void 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
145out:
146 move_to_preferred_x(view, x);
147}