dte test coverage


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 50.0% high: ≥ 85.0%
Coverage Exec / Excl / Total
Lines: 97.4% 74 / 0 / 76
Functions: 100.0% 6 / 0 / 6
Branches: 70.0% 35 / 0 / 50

src/wrap.c
Line Branch Exec Source
1 #include <stdbool.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "wrap.h"
5 #include "buffer.h"
6 #include "indent.h"
7 #include "selection.h"
8 #include "util/string-view.h"
9 #include "util/string.h"
10 #include "util/unicode.h"
11 #include "util/utf8.h"
12
13 typedef struct {
14 String buf;
15 String indent;
16 size_t indent_width;
17 size_t cur_width;
18 size_t text_width;
19 } ParagraphFormatter;
20
21 60 static void add_word(ParagraphFormatter *pf, StringView word)
22 {
23 60 size_t i = 0;
24 60 size_t word_width = 0;
25
2/2
✓ Branch 5 → 3 taken 180 times.
✓ Branch 5 → 6 taken 60 times.
240 while (i < word.length) {
26 180 word_width += u_char_width(u_get_char(word.data, word.length, &i));
27 }
28
29
4/4
✓ Branch 6 → 7 taken 58 times.
✓ Branch 6 → 10 taken 2 times.
✓ Branch 7 → 8 taken 6 times.
✓ Branch 7 → 10 taken 52 times.
60 if (pf->cur_width && pf->cur_width + 1 + word_width > pf->text_width) {
30 6 string_append_byte(&pf->buf, '\n');
31 6 pf->cur_width = 0;
32 }
33
34
2/2
✓ Branch 10 → 11 taken 8 times.
✓ Branch 10 → 13 taken 52 times.
60 if (pf->cur_width == 0) {
35 8 string_append_string(&pf->buf, &pf->indent);
36 8 pf->cur_width = pf->indent_width;
37 } else {
38 52 string_append_byte(&pf->buf, ' ');
39 52 pf->cur_width++;
40 }
41
42 60 string_append_strview(&pf->buf, word);
43 60 pf->cur_width += word_width;
44 60 }
45
46 2 static bool is_long_comment_delim(StringView sv)
47 {
48 // TODO: make this configurable
49
2/4
✓ Branch 3 → 4 taken 2 times.
✗ Branch 3 → 7 not taken.
✓ Branch 5 → 6 taken 2 times.
✗ Branch 5 → 7 not taken.
2 return strview_equal_cstring(sv, "/*") || strview_equal_cstring(sv, "*/");
50 }
51
52 5 static bool is_paragraph_separator(StringView line)
53 {
54 5 strview_trim(&line);
55
3/4
✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 7 taken 3 times.
✓ Branch 5 → 6 taken 2 times.
✗ Branch 5 → 7 not taken.
5 return (line.length == 0) || is_long_comment_delim(line);
56 }
57
58 3 static bool in_paragraph (
59 StringView line,
60 size_t para_indent_width,
61 unsigned int tab_width
62 ) {
63 3 size_t w = get_indent_width(line, tab_width);
64
2/4
✓ Branch 3 → 4 taken 3 times.
✗ Branch 3 → 7 not taken.
✓ Branch 5 → 6 taken 3 times.
✗ Branch 5 → 7 not taken.
3 return (w == para_indent_width) && !is_paragraph_separator(line);
65 }
66
67 2 static size_t paragraph_size(View *view)
68 {
69 2 BlockIter bi = view->cursor;
70 2 block_iter_bol(&bi);
71 2 StringView line = block_iter_get_line(&bi);
72
1/2
✓ Branch 5 → 6 taken 2 times.
✗ Branch 5 → 21 not taken.
2 if (is_paragraph_separator(line)) {
73 // Not in paragraph
74 return 0;
75 }
76
77 2 unsigned int tab_width = view->buffer->options.tab_width;
78 2 size_t para_indent_width = get_indent_width(line, tab_width);
79
80 // Go to beginning of paragraph
81
2/2
✓ Branch 14 → 7 taken 1 time.
✓ Branch 14 → 15 taken 1 time.
2 while (block_iter_prev_line(&bi)) {
82 1 line = block_iter_get_line(&bi);
83
1/2
✓ Branch 9 → 10 taken 1 time.
✗ Branch 9 → 13 not taken.
1 if (!in_paragraph(line, para_indent_width, tab_width)) {
84 1 block_iter_eat_line(&bi);
85 1 break;
86 }
87 }
88 2 view->cursor = bi;
89
90 // Get size of paragraph
91 2 size_t size = 0;
92 2 do {
93 2 size_t bytes = block_iter_eat_line(&bi);
94
1/2
✓ Branch 17 → 18 taken 2 times.
✗ Branch 17 → 21 not taken.
2 if (!bytes) {
95 break;
96 }
97 2 size += bytes;
98 2 line = block_iter_get_line(&bi);
99
1/2
✗ Branch 20 → 16 not taken.
✓ Branch 20 → 21 taken 2 times.
2 } while (in_paragraph(line, para_indent_width, tab_width));
100 return size;
101 }
102
103 2 void wrap_paragraph(View *view, size_t text_width)
104 {
105
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 2 times.
2 if (view->selection) {
106 view->selection = SELECT_LINES;
107 }
108
109
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 2 times.
2 size_t len = view->selection ? prepare_selection(view) : paragraph_size(view);
110
1/2
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 2 times.
2 if (!len) {
111 return;
112 }
113
114 2 const LocalOptions *options = &view->buffer->options;
115 2 String sel = block_iter_get_bytes(view->cursor, len);
116 2 size_t indent_width = get_indent_width(strview_from_string(&sel), options->tab_width);
117
118 4 ParagraphFormatter pf = {
119 2 .buf = string_new(len + 64),
120 2 .indent = make_indent(options, indent_width),
121 .indent_width = indent_width,
122 .cur_width = 0,
123 .text_width = text_width
124 };
125
126 62 for (size_t i = 0; true; ) {
127
2/2
✓ Branch 20 → 14 taken 122 times.
✓ Branch 20 → 21 taken 2 times.
124 while (i < len) {
128 122 size_t tmp = i;
129
2/2
✓ Branch 15 → 16 taken 62 times.
✓ Branch 15 → 17 taken 60 times.
122 if (!u_is_breakable_whitespace(u_get_char(sel.buffer, len, &tmp))) {
130 break;
131 }
132 62 i = tmp;
133 }
134
2/2
✓ Branch 21 → 26 taken 60 times.
✓ Branch 21 → 29 taken 2 times.
62 if (i == len) {
135 break;
136 }
137
138 size_t start = i;
139
1/2
✓ Branch 26 → 22 taken 240 times.
✗ Branch 26 → 27 not taken.
240 while (i < len) {
140 240 size_t tmp = i;
141
2/2
✓ Branch 23 → 24 taken 180 times.
✓ Branch 23 → 25 taken 60 times.
240 if (u_is_breakable_whitespace(u_get_char(sel.buffer, len, &tmp))) {
142 break;
143 }
144 180 i = tmp;
145 }
146
147 60 add_word(&pf, strview_from_slice(sel.buffer, start, i));
148 }
149
150
1/2
✓ Branch 29 → 30 taken 2 times.
✗ Branch 29 → 31 not taken.
2 if (pf.buf.len) {
151 2 string_append_byte(&pf.buf, '\n');
152 }
153
154 2 buffer_replace_bytes(view, len, strview_from_string(&pf.buf));
155
156
1/2
✓ Branch 32 → 33 taken 2 times.
✗ Branch 32 → 34 not taken.
2 if (pf.buf.len) {
157 2 block_iter_skip_bytes(&view->cursor, pf.buf.len - 1);
158 }
159
160 2 string_free(&pf.buf);
161 2 string_free(&pf.indent);
162 2 string_free(&sel);
163 2 unselect(view);
164 }
165