~kiwec/ke

ref: 842396976984e3cbd83251296dd90a46b9d53b3c ke/src/Line.cc -rw-r--r-- 3.2 KiB
84239697 — Wolf Clément Downgrade to C++17, avoid stdlib 3 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#include "Line.h"
#include "Buffer.h"
#include "Document.h"
#include "Editor.h"
#include "Gutter.h"
#include <math.h>

void Line::calc_size() {
  if(m_doc == nullptr) {
    m_size = 0;
    return;
  }
  
	auto ptr = begin();
	for(m_size = 0; ptr[m_size] != L'\n' && ptr[m_size] != L'\0'; m_size++);
}

void Line::clear_syntax() {
	for(auto ptr = syntax(); *ptr != L'\n' && *ptr != L'\0'; ptr++) {
		*ptr = 15;
	}
}

void Line::erase(uint start, uint size) {
	m_doc->erase(m_start + start, size);
}

void Line::erase_next() {
	if(is_last()) return;
	m_doc->erase(m_start + m_size, next().m_size + 1);
}

void Line::erase_prev() {
	if(is_first()) return;
	m_doc->erase(m_start - prev().m_size, prev().m_size + 1);
}

wchar_t Line::operator[](uint pos) const {
	return begin()[pos];
}

wchar_t* Line::begin() const {
	return &(*m_doc)[m_start];
}

wchar_t* Line::end() const {
	return begin() + m_size;
}

Line Line::next() const {
	assert(!is_last());

	return Line(m_doc, m_start + m_size + 1, m_number + 1);
}

Line Line::prev() const {
	assert(!is_first());

	// Edge case : first line is empty and we are the second line
	if(m_start == 1) {
		return Line(m_doc, 0, m_number - 1);
	}

	uint offset = 2;
	auto ptr = begin();
	for(; m_start - offset > 0 && *(ptr - offset) != L'\n'; offset++);
	return Line(m_doc, m_start - offset, m_number - 1);
}

Line Line::make_next() {
	m_doc->insert(L"\n", 1, m_start + m_size);
	return Line(m_doc, m_start + m_size + 1, m_number + 1);
}

int Line::get_current_indentation() const {
	uint indent = 0;
	while(indent < length() && operator[](indent) == L'\t') {
		indent++;
	}
	return indent;
}

int Line::get_next_indentation() const {
	if(length() == 0) return 0;
	if(operator[](length() - 1) == '{') return get_current_indentation() + 1;
	return get_current_indentation();
}

bool Line::is_first() const {
	return m_number == 1;
}

bool Line::is_last() const {
	return m_number == m_doc->get_nb_lines();
}

void Line::insert(wchar_t c, uint pos) {
	m_doc->insert(&c, 1, m_start + pos);
}

void Line::insert(wchar_t* str, uint size, uint pos) {
	m_doc->insert(str, size, m_start + pos);
}

void Line::print(uint x, uint y, uint bg) const {
	printFrom(0, x, y, bg);
}

void Line::printFrom(uint start, uint x, uint y, uint bg) const {
	uint c = 0;
	uint8_t syntax_color;
	auto text = begin();
	for(uint i = 0; i < length(); i++) {
		syntax_color = syntax()[i];

		if(text[i] == L'\t') {
			if(c >= start) {
				for(uint j = 0; j < 4; j++) {
					tb_change_cell(x + c + j - start, y, ' ', syntax_color, bg);
				}
			}
			c += 4;
		}
		else {
			if(c >= start) {
				tb_change_cell(x + c - start, y, text[i], syntax_color, bg);
			}
			c++;
		}
	}
}

uint Line::height(Buffer& buf) const {
	double bufWidth = (double)(buf.max_line_width());
	double w = (double)width() + 1.f;
	return ceil(w / bufWidth);
}

syntax_t* Line::syntax() const {
	return &m_doc->syntax()[m_start];
}

std::unique_ptr<wchar_t[]> Line::text_copy() const {
	std::unique_ptr<wchar_t[]> copy(new wchar_t[m_size + 1]);
	memcpy(copy.get(), begin(), m_size);
	copy[m_size] = L'\0';
	return copy;
}

uint Line::width() const {
	return width(length());
}

uint Line::width(uint pos) const {
	uint x = 0;
	for(uint i = 0; i < pos; i++) {
		if(begin()[i] == L'\t') {
			x += 4;
		}
		else {
			x++;
		}
	}

	return x;
}