138
139
static void delete_char_after(void);
139
140
static void caret_update(void);
140
141
static void caret_move(int drow, int dcolumn, enum dir_spec align_dir);
142
static void caret_move_word_left(void);
143
static void caret_move_word_right(void);
142
145
static bool selection_active(void);
143
146
static void selection_sel_all(void);
147
static void selection_sel_range(spt_t pa, spt_t pb);
148
static void selection_sel_prev_word(void);
149
static void selection_sel_next_word(void);
144
150
static void selection_get_points(spt_t *pa, spt_t *pb);
145
151
static void selection_delete(void);
146
152
static void selection_copy(void);
149
155
static void pt_get_sof(spt_t *pt);
150
156
static void pt_get_eof(spt_t *pt);
157
static void pt_get_sol(spt_t *cpt, spt_t *spt);
158
static void pt_get_eol(spt_t *cpt, spt_t *ept);
159
static bool pt_is_word_beginning(spt_t *pt);
160
static bool pt_is_delimiter(spt_t *pt);
161
static bool pt_is_punctuation(spt_t *pt);
151
162
static int tag_cmp(tag_t const *a, tag_t const *b);
152
163
static int spt_cmp(spt_t const *a, spt_t const *b);
153
164
static int coord_cmp(coord_t const *a, coord_t const *b);
970
1011
/* Clamp coordinates. */
971
1012
if (drow < 0 && coord.row < 1) coord.row = 1;
972
if (dcolumn < 0 && coord.column < 1) coord.column = 1;
1013
if (dcolumn < 0 && coord.column < 1) {
1018
sheet_get_row_width(&doc.sh, coord.row, &coord.column);
974
1022
sheet_get_num_rows(&doc.sh, &num_rows);
975
1023
if (coord.row > num_rows) coord.row = num_rows;
1048
static void caret_move_word_left(void)
1053
caret_move(0, -1, dir_before);
1055
tag_get_pt(&pane.caret_pos, &pt);
1057
sheet_remove_tag(&doc.sh, &pane.sel_start);
1058
sheet_place_tag(&doc.sh, &pt, &pane.sel_start);
1059
} while (!pt_is_word_beginning(&pt));
1061
pane.rflags |= REDRAW_TEXT;
1064
static void caret_move_word_right(void)
1069
caret_move(0, 0, dir_after);
1071
tag_get_pt(&pane.caret_pos, &pt);
1073
sheet_remove_tag(&doc.sh, &pane.sel_start);
1074
sheet_place_tag(&doc.sh, &pt, &pane.sel_start);
1075
} while (!pt_is_word_beginning(&pt));
1077
pane.rflags |= REDRAW_TEXT;
1000
1080
/** Check for non-empty selection. */
1001
1081
static bool selection_active(void)
1044
1124
pane.rflags |= REDRAW_TEXT;
1127
/** Select all text in the editor */
1047
1128
static void selection_sel_all(void)
1049
1130
spt_t spt, ept;
1051
1132
pt_get_sof(&spt);
1052
1133
pt_get_eof(&ept);
1135
selection_sel_range(spt, ept);
1138
/** Select select all text in a given range with the given direction */
1139
static void selection_sel_range(spt_t pa, spt_t pb)
1053
1141
sheet_remove_tag(&doc.sh, &pane.sel_start);
1054
sheet_place_tag(&doc.sh, &spt, &pane.sel_start);
1142
sheet_place_tag(&doc.sh, &pa, &pane.sel_start);
1055
1143
sheet_remove_tag(&doc.sh, &pane.caret_pos);
1056
sheet_place_tag(&doc.sh, &ept, &pane.caret_pos);
1144
sheet_place_tag(&doc.sh, &pb, &pane.caret_pos);
1058
1146
pane.rflags |= REDRAW_TEXT;
1059
1147
caret_update();
1150
/** Add the previous word to the selection */
1151
static void selection_sel_prev_word(void)
1153
spt_t cpt, wpt, spt, ept;
1155
selection_get_points(&spt, &ept);
1157
tag_get_pt(&pane.caret_pos, &cpt);
1158
caret_move_word_left();
1159
tag_get_pt(&pane.caret_pos, &wpt);
1161
if (spt_cmp(&spt, &cpt) == 0)
1162
selection_sel_range(ept, wpt);
1164
selection_sel_range(spt, wpt);
1167
/** Add the next word to the selection */
1168
static void selection_sel_next_word(void)
1170
spt_t cpt, wpt, spt, ept;
1172
selection_get_points(&spt, &ept);
1174
tag_get_pt(&pane.caret_pos, &cpt);
1175
caret_move_word_right();
1176
tag_get_pt(&pane.caret_pos, &wpt);
1178
if (spt_cmp(&ept, &cpt) == 0)
1179
selection_sel_range(spt, wpt);
1181
selection_sel_range(ept, wpt);
1062
1184
static void selection_copy(void)
1118
1240
sheet_get_cell_pt(&doc.sh, &coord, dir_after, pt);
1243
/** Get start-of-line s-point for given s-point cpt */
1244
static void pt_get_sol(spt_t *cpt, spt_t *spt)
1248
spt_get_coord(cpt, &coord);
1251
sheet_get_cell_pt(&doc.sh, &coord, dir_before, spt);
1254
/** Get end-of-line s-point for given s-point cpt */
1255
static void pt_get_eol(spt_t *cpt, spt_t *ept)
1260
spt_get_coord(cpt, &coord);
1261
sheet_get_row_width(&doc.sh, coord.row, &row_width);
1262
coord.column = row_width - 1;
1264
sheet_get_cell_pt(&doc.sh, &coord, dir_after, ept);
1267
/** Check whether the spt is at a beginning of a word */
1268
static bool pt_is_word_beginning(spt_t *pt)
1270
spt_t lp, sfp, efp, slp, elp;
1275
pt_get_sol(pt, &slp);
1276
pt_get_eol(pt, &elp);
1278
/* the spt is at the beginning or end of the file or line */
1279
if ((spt_cmp(&sfp, pt) == 0) || (spt_cmp(&efp, pt) == 0)
1280
|| (spt_cmp(&slp, pt) == 0) || (spt_cmp(&elp, pt) == 0))
1283
/* the spt is a delimiter */
1284
if (pt_is_delimiter(pt))
1287
spt_get_coord(pt, &coord);
1290
sheet_get_cell_pt(&doc.sh, &coord, dir_before, &lp);
1292
return pt_is_delimiter(&lp)
1293
|| (pt_is_punctuation(pt) && !pt_is_punctuation(&lp))
1294
|| (pt_is_punctuation(&lp) && !pt_is_punctuation(pt));
1297
static wchar_t get_first_wchar(const char *str)
1300
return str_decode(str, &offset, str_size(str));
1303
static bool pt_is_delimiter(spt_t *pt)
1309
spt_get_coord(pt, &coord);
1312
sheet_get_cell_pt(&doc.sh, &coord, dir_after, &rp);
1314
ch = range_get_str(pt, &rp);
1318
wchar_t first_char = get_first_wchar(ch);
1319
switch(first_char) {
1329
static bool pt_is_punctuation(spt_t *pt)
1335
spt_get_coord(pt, &coord);
1338
sheet_get_cell_pt(&doc.sh, &coord, dir_after, &rp);
1340
ch = range_get_str(pt, &rp);
1344
wchar_t first_char = get_first_wchar(ch);
1345
switch(first_char) {
1121
1367
/** Compare tags. */
1122
1368
static int tag_cmp(tag_t const *a, tag_t const *b)