-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patheditorOperations.c
More file actions
159 lines (134 loc) · 4.4 KB
/
editorOperations.c
File metadata and controls
159 lines (134 loc) · 4.4 KB
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
#include "marisa.h"
extern editorConfig E;
/* static void markRegionForward (int); */
/* static void unMarkRegionForward (int); */
/* static void markRegionBackwards (int); */
/* static void unMarkRegionBackwards (int); */
void
editorInsertChar (int c)
{
if (FRAME->cy == BUFFER->numrows)
{
bufferInsertRow(BUFFER->numrows, L"", 0);
}
bufferRowInsertChar(&BUFFER->row[FRAME->cy], FRAME->cx, c);
FRAME->cx++;
}
void
editorInsertNewline (void)
{
if (FRAME->cx == 0)
{
bufferInsertRow(FRAME->cy, L"", 0);
}
else
{
erow *row = &BUFFER->row[FRAME->cy];
bufferInsertRow(FRAME->cy + 1, &row->chars[FRAME->cx], row->size - FRAME->cx);
row = &BUFFER->row[FRAME->cy]; /* need to reassign after bufferInsertRow */
row->size = FRAME->cx;
row->chars[row->size] = L'\0';
bufferUpdateRow(row);
}
FRAME->cy++;
FRAME->cx = 0;
}
void
editorDelChar (void)
{
if (FRAME->cy == BUFFER->numrows) return;
if (FRAME->cx == 0 && FRAME->cy == 0) return;
erow *row = &BUFFER->row[FRAME->cy];
if (FRAME->cx > 0)
{
bufferRowDelChar (row, FRAME->cx - 1);
FRAME->cx--;
}
else
{
FRAME->cx = BUFFER->row[FRAME->cy - 1].size;
bufferRowAppendString (&BUFFER->row[FRAME->cy - 1], row->chars, row->size);
bufferDelRow (FRAME->cy);
FRAME->cy--;
}
}
/* TODO: highlight does not work well with wide characters */
/* TODO: Breaks when selection starts in the middle of a word */
/*
* Every motion during mark-mode refreshes the screen with a section of the text highlighted
* Every motion produces a coordinate to anywhere on the screen
* We find the x-offset and y-offset of each action
* We need to keep track of the previous coordinates (in case we need to unmark)
* Once mark-mode is activated, we need to keep track of the anchors
*
*
* We need to do 2 passes on the screen
* 1. Refresh screen line by line from the top (0, 0)
* 2. Back from the top, top to the coordinate of the last mark command
* Start moving character by character and mark the region until you get to the mark end coordinate
*
* No need for an unmark function because the screen gets refreshed every command
*
*
* Variables to keep track of:
* anchorX/Y: to know where mark-mode started. will ALWAYS be the beginning or end of a selection block
* prevX/Y: to know where the previous mark-mode move ended
* currX/Y: to know where the current mark-mode move will end
* Screen min-point / max-point: to know the minimum and maximum coordinates the user can mark without scrolling
*/
void
editorMarkRegion (void)
{
int anchorX = FRAME->cx, anchorRX = FRAME->rx, anchorY = FRAME->cy;
editorSetStatusMessage(L"Marking time");
editorDrawMessageBar();
cursor_set_color_rgb(MARK_CURSOR);
/* move back to the text window */
wmove(FRAME->frame, anchorY, anchorRX);
#define MARK_CHAR(y, x) mvwchgat(FRAME->frame, y, x, 1, A_REVERSE, TEXTWINDOW_COLOR, NULL)
wint_t c;
while ((wget_wch(FRAME->frame, &c) != ERR) && (c != CTRL_KEY('q')))
{
editorProcessKeypressMark(c);
editorRefreshScreen();
int currX = FRAME->rx, currY = FRAME->cy;
if (currY == anchorY)
{
int beg = anchorRX < currX ? anchorRX: currX;
int end = currX > anchorRX ? currX : anchorRX;
for (int i = beg; i <= end; i++)
MARK_CHAR(currY - FRAME->rowoff, i - FRAME->coloff);
}
else if (currY > anchorY)
{
for (int i = anchorRX; i < BUFFER->row[anchorY].rsize; i++)
MARK_CHAR(anchorY - FRAME->rowoff, i - FRAME->coloff);
for (int i = anchorY + 1; i < currY; i++)
for (int j = 0; j < BUFFER->row[i].rsize; j++)
MARK_CHAR(i - FRAME->rowoff, j - FRAME->coloff);
for (int i = 0; i <= currX; i++)
MARK_CHAR(currY - FRAME->rowoff, i - FRAME->coloff);
}
else {
for (int i = anchorRX; i >= 0; i--)
MARK_CHAR(anchorY - FRAME->rowoff, i - FRAME->coloff);
for (int i = currY + 1; i < anchorY; i++)
for (int j = 0; j < BUFFER->row[i].rsize; j++)
MARK_CHAR(i - FRAME->rowoff, j - FRAME->coloff);
for (int i = currX; i <= BUFFER->row[currY].rsize; i++)
MARK_CHAR(currY - FRAME->rowoff, i - FRAME->coloff);
}
wrefresh(FRAME->frame);
}
#undef MARK_CHAR
cursor_set_color_rgb(NORMAL_CURSOR);
editorSetStatusMessage(L"Marking time done");
editorDrawMessageBar();
E.regionMarked[0] = anchorY;
E.regionMarked[1] = anchorX;
E.regionMarked[2] = FRAME->cy;
E.regionMarked[3] = FRAME->cx;
/* TODO: this is terrible erognomics for the user */
if (wget_wch(FRAME->frame, &c) != ERR)
editorProcessMarkActions(c);
}