Line | Branch | Exec | Source |
---|---|---|---|
1 | #include "join.h" | ||
2 | #include "block-iter.h" | ||
3 | #include "change.h" | ||
4 | #include "selection.h" | ||
5 | #include "util/debug.h" | ||
6 | #include "util/unicode.h" | ||
7 | |||
8 | 4 | static void join_selection(View *view, const char *delim, size_t delim_len) | |
9 | { | ||
10 | 4 | size_t count = prepare_selection(view); | |
11 | 4 | BlockIter bi = view->cursor; | |
12 | 4 | size_t ws_len = 0; | |
13 | 4 | size_t join = 0; | |
14 | 4 | CodePoint ch = 0; | |
15 | 4 | unselect(view); | |
16 | 4 | begin_change_chain(); | |
17 | |||
18 |
2/2✓ Branch 0 (17→6) taken 20 times.
✓ Branch 1 (17→18) taken 4 times.
|
24 | while (count > 0) { |
19 |
2/2✓ Branch 0 (6→7) taken 14 times.
✓ Branch 1 (6→8) taken 6 times.
|
20 | if (!ws_len) { |
20 | 14 | view->cursor = bi; | |
21 | } | ||
22 | |||
23 | 20 | size_t n = block_iter_next_char(&bi, &ch); | |
24 | 20 | count -= MIN(n, count); | |
25 |
2/2✓ Branch 0 (9→10) taken 10 times.
✓ Branch 1 (9→11) taken 10 times.
|
20 | if (ch == '\n' || ch == '\t' || ch == ' ') { |
26 | 10 | join += (ch == '\n'); | |
27 | 10 | ws_len++; | |
28 | 10 | continue; | |
29 | } | ||
30 | |||
31 |
2/2✓ Branch 0 (11→12) taken 6 times.
✓ Branch 1 (11→16) taken 4 times.
|
10 | if (join) { |
32 | 6 | buffer_replace_bytes(view, ws_len, delim, delim_len); | |
33 | // Skip the delimiter we inserted and the char we read last | ||
34 | 6 | block_iter_skip_bytes(&view->cursor, delim_len); | |
35 | 6 | block_iter_next_char(&view->cursor, &ch); | |
36 | 6 | bi = view->cursor; | |
37 | } | ||
38 | |||
39 | ws_len = 0; | ||
40 | join = 0; | ||
41 | } | ||
42 | |||
43 |
2/4✓ Branch 0 (18→19) taken 4 times.
✗ Branch 1 (18→25) not taken.
✓ Branch 2 (19→20) taken 4 times.
✗ Branch 3 (19→21) not taken.
|
4 | if (join && ch == '\n') { |
44 | // Don't replace last newline at end of selection | ||
45 | 4 | join--; | |
46 | 4 | ws_len--; | |
47 | } | ||
48 | |||
49 |
1/2✗ Branch 0 (21→22) not taken.
✓ Branch 1 (21→25) taken 4 times.
|
4 | if (join) { |
50 | ✗ | size_t ins_len = (ch == '\n') ? 0 : delim_len; // Don't add delim, if at eol | |
51 | ✗ | buffer_replace_bytes(view, ws_len, delim, ins_len); | |
52 | } | ||
53 | |||
54 | 4 | end_change_chain(view); | |
55 | 4 | } | |
56 | |||
57 | 16 | void join_lines(View *view, const char *delim, size_t delim_len) | |
58 | { | ||
59 |
2/2✓ Branch 0 (2→3) taken 4 times.
✓ Branch 1 (2→4) taken 12 times.
|
16 | if (view->selection) { |
60 | 4 | join_selection(view, delim, delim_len); | |
61 | 14 | return; | |
62 | } | ||
63 | |||
64 | // Create an iterator and position it at the beginning of the next line | ||
65 | // (or return early, if there is no next line) | ||
66 | 12 | BlockIter next = view->cursor; | |
67 |
3/4✓ Branch 0 (5→6) taken 6 times.
✓ Branch 1 (5→19) taken 6 times.
✓ Branch 2 (6→7) taken 6 times.
✗ Branch 3 (6→19) not taken.
|
12 | if (!block_iter_next_line(&next) || block_iter_is_eof(&next)) { |
68 | return; | ||
69 | } | ||
70 | |||
71 | // Create a second iterator and position it at the end of the current line | ||
72 | 6 | BlockIter eol = next; | |
73 | 6 | CodePoint u; | |
74 | 6 | size_t nbytes = block_iter_prev_char(&eol, &u); | |
75 | 6 | BUG_ON(nbytes != 1); | |
76 | 6 | BUG_ON(u != '\n'); | |
77 | |||
78 | // Skip over trailing whitespace at the end of the current line | ||
79 | 6 | size_t del_count = 1 + block_iter_skip_blanks_bwd(&eol); | |
80 | |||
81 | // Skip over leading whitespace at the start of the next line | ||
82 | 6 | del_count += block_iter_skip_blanks_fwd(&next); | |
83 | |||
84 | // Move the cursor to the join position | ||
85 | 6 | view->cursor = eol; | |
86 | |||
87 |
2/2✓ Branch 0 (14→15) taken 3 times.
✓ Branch 1 (14→16) taken 3 times.
|
6 | if (block_iter_is_bol(&next)) { |
88 | // If the next line is empty (or whitespace only) just discard | ||
89 | // it, by deleting the newline and any whitespace | ||
90 | 3 | buffer_delete_bytes(view, del_count); | |
91 | } else { | ||
92 | // Otherwise, join the current and next lines together, by | ||
93 | // replacing the newline/whitespace with the delimiter string | ||
94 | 3 | buffer_replace_bytes(view, del_count, delim, delim_len); | |
95 | } | ||
96 | } | ||
97 |