Changeset 1e58e1b in mainline
- Timestamp:
- 2012-08-17T11:33:15Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2f136e4
- Parents:
- 87c0a45 (diff), 7feb86e6 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace/app/edit
- Files:
-
- 3 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/edit/Makefile
r87c0a45 r1e58e1b 33 33 SOURCES = \ 34 34 edit.c \ 35 sheet.c 35 sheet.c \ 36 search.c 36 37 37 38 include $(USPACE_PREFIX)/Makefile.common -
uspace/app/edit/edit.c
r87c0a45 r1e58e1b 1 1 /* 2 2 * Copyright (c) 2009 Jiri Svoboda 3 * Copyright (c) 2012 Martin Sucha 3 4 * All rights reserved. 4 5 * … … 49 50 50 51 #include "sheet.h" 52 #include "search.h" 51 53 52 54 enum redraw_flags { … … 83 85 */ 84 86 int ideal_column; 87 88 char *previous_search; 85 89 } pane_t; 86 90 … … 140 144 static void delete_char_after(void); 141 145 static void caret_update(void); 142 static void caret_move(int drow, int dcolumn, enum dir_spec align_dir); 143 static void caret_move_word_left(void); 144 static void caret_move_word_right(void); 145 static void caret_move_to_line(int row); 146 static void caret_move_relative(int drow, int dcolumn, enum dir_spec align_dir, bool select); 147 static void caret_move_absolute(int row, int column, enum dir_spec align_dir, bool select); 148 static void caret_move(spt_t spt, bool select, bool update_ideal_column); 149 static void caret_move_word_left(bool select); 150 static void caret_move_word_right(bool select); 146 151 static void caret_go_to_line_ask(void); 147 152 … … 149 154 static void selection_sel_all(void); 150 155 static void selection_sel_range(spt_t pa, spt_t pb); 151 static void selection_sel_prev_word(void);152 static void selection_sel_next_word(void);153 156 static void selection_get_points(spt_t *pa, spt_t *pb); 154 157 static void selection_delete(void); 155 158 static void selection_copy(void); 156 159 static void insert_clipboard_data(void); 160 161 static void search(void); 162 static void search_forward(char *pattern); 163 static void search_repeat(void); 157 164 158 165 static void pt_get_sof(spt_t *pt); … … 163 170 static bool pt_is_delimiter(spt_t *pt); 164 171 static bool pt_is_punctuation(spt_t *pt); 172 static spt_t pt_find_word_left(spt_t spt); 173 static spt_t pt_find_word_left(spt_t spt); 174 165 175 static int tag_cmp(tag_t const *a, tag_t const *b); 166 176 static int spt_cmp(spt_t const *a, spt_t const *b); … … 173 183 { 174 184 kbd_event_t ev; 175 coord_t coord;176 185 bool new_file; 177 186 int rc; 178 179 spt_t pt;180 187 181 188 con = console_init(stdin, stdout); … … 197 204 198 205 /* Place caret at the beginning of file. */ 199 coord.row = coord.column = 1;200 sheet_get_cell_pt(doc.sh, &coord, dir_before, &pt);201 sheet_place_tag(doc.sh, & pt, &pane.caret_pos);202 pane.ideal_column = coord.column;206 spt_t sof; 207 pt_get_sof(&sof); 208 sheet_place_tag(doc.sh, &sof, &pane.caret_pos); 209 pane.ideal_column = 1; 203 210 204 211 if (argc == 2) { … … 216 223 new_file = true; 217 224 225 /* Place selection start tag. */ 226 sheet_place_tag(doc.sh, &sof, &pane.sel_start); 227 218 228 /* Move to beginning of file. */ 219 caret_move(-ED_INFTY, -ED_INFTY, dir_before); 220 221 /* Place selection start tag. */ 222 tag_get_pt(&pane.caret_pos, &pt); 223 sheet_place_tag(doc.sh, &pt, &pane.sel_start); 229 pt_get_sof(&sof); 230 caret_move(sof, true, true); 224 231 225 232 /* Initial display */ … … 400 407 selection_sel_all(); 401 408 break; 402 case KC_W:403 if (selection_active())404 break;405 selection_sel_prev_word();406 selection_delete();407 break;408 409 case KC_RIGHT: 409 caret_move_word_right( );410 caret_move_word_right(false); 410 411 break; 411 412 case KC_LEFT: 412 caret_move_word_left( );413 caret_move_word_left(false); 413 414 break; 414 415 case KC_L: 415 416 caret_go_to_line_ask(); 416 417 break; 418 case KC_F: 419 search(); 420 break; 421 case KC_N: 422 search_repeat(); 423 break; 417 424 default: 418 425 break; … … 424 431 switch(ev->key) { 425 432 case KC_LEFT: 426 selection_sel_prev_word();433 caret_move_word_left(true); 427 434 break; 428 435 case KC_RIGHT: 429 selection_sel_next_word();436 caret_move_word_right(true); 430 437 break; 431 438 default: … … 435 442 436 443 /** Move caret while preserving or resetting selection. */ 437 static void caret_movement(int drow, int dcolumn, enum dir_spec align_dir, 438 bool select) 439 { 440 spt_t pt; 441 spt_t caret_pt; 444 static void caret_move(spt_t new_caret_pt, bool select, bool update_ideal_column) 445 { 446 spt_t old_caret_pt, old_sel_pt; 442 447 coord_t c_old, c_new; 443 448 bool had_sel; 444 449 445 450 /* Check if we had selection before. */ 446 tag_get_pt(&pane.caret_pos, &caret_pt); 447 tag_get_pt(&pane.sel_start, &pt); 448 had_sel = !spt_equal(&caret_pt, &pt); 449 450 caret_move(drow, dcolumn, align_dir); 451 tag_get_pt(&pane.caret_pos, &old_caret_pt); 452 tag_get_pt(&pane.sel_start, &old_sel_pt); 453 had_sel = !spt_equal(&old_caret_pt, &old_sel_pt); 454 455 /* Place tag of the caret */ 456 sheet_remove_tag(doc.sh, &pane.caret_pos); 457 sheet_place_tag(doc.sh, &new_caret_pt, &pane.caret_pos); 451 458 452 459 if (select == false) { 453 460 /* Move sel_start to the same point as caret. */ 454 461 sheet_remove_tag(doc.sh, &pane.sel_start); 455 tag_get_pt(&pane.caret_pos, &pt);456 sheet_place_tag(doc.sh, &pt, &pane.sel_start);457 } 458 462 sheet_place_tag(doc.sh, &new_caret_pt, &pane.sel_start); 463 } 464 465 spt_get_coord(&new_caret_pt, &c_new); 459 466 if (select) { 460 tag_get_pt(&pane.caret_pos, &pt); 461 spt_get_coord(&caret_pt, &c_old); 462 spt_get_coord(&pt, &c_new); 467 spt_get_coord(&old_caret_pt, &c_old); 463 468 464 469 if (c_old.row == c_new.row) … … 471 476 pane.rflags |= REDRAW_TEXT; 472 477 } 478 479 if (update_ideal_column) 480 pane.ideal_column = c_new.column; 481 482 caret_update(); 473 483 } 474 484 … … 477 487 switch (key) { 478 488 case KC_LEFT: 479 caret_move ment(0, -1, dir_before, select);489 caret_move_relative(0, -1, dir_before, select); 480 490 break; 481 491 case KC_RIGHT: 482 caret_move ment(0, 0, dir_after, select);492 caret_move_relative(0, 0, dir_after, select); 483 493 break; 484 494 case KC_UP: 485 caret_move ment(-1, 0, dir_before, select);495 caret_move_relative(-1, 0, dir_before, select); 486 496 break; 487 497 case KC_DOWN: 488 caret_move ment(+1, 0, dir_before, select);498 caret_move_relative(+1, 0, dir_before, select); 489 499 break; 490 500 case KC_HOME: 491 caret_move ment(0, -ED_INFTY, dir_before, select);501 caret_move_relative(0, -ED_INFTY, dir_after, select); 492 502 break; 493 503 case KC_END: 494 caret_move ment(0, +ED_INFTY, dir_before, select);504 caret_move_relative(0, +ED_INFTY, dir_before, select); 495 505 break; 496 506 case KC_PAGE_UP: 497 caret_move ment(-pane.rows, 0, dir_before, select);507 caret_move_relative(-pane.rows, 0, dir_before, select); 498 508 break; 499 509 case KC_PAGE_DOWN: 500 caret_move ment(+pane.rows, 0, dir_before, select);510 caret_move_relative(+pane.rows, 0, dir_before, select); 501 511 break; 502 512 default: … … 1012 1022 } 1013 1023 1014 /** Change the caret position.1024 /** Relatively move caret position. 1015 1025 * 1016 1026 * Moves caret relatively to the current position. Looking at the first … … 1018 1028 * to a new character cell, and thus a new character. Then we either go to the 1019 1029 * point before the the character or after it, depending on @a align_dir. 1030 * 1031 * @param select true if the selection tag should stay where it is 1020 1032 */ 1021 static void caret_move(int drow, int dcolumn, enum dir_spec align_dir) 1033 static void caret_move_relative(int drow, int dcolumn, enum dir_spec align_dir, 1034 bool select) 1022 1035 { 1023 1036 spt_t pt; … … 1055 1068 */ 1056 1069 sheet_get_cell_pt(doc.sh, &coord, align_dir, &pt); 1057 sheet_remove_tag(doc.sh, &pane.caret_pos);1058 sheet_place_tag(doc.sh, &pt, &pane.caret_pos);1059 1070 1060 1071 /* For non-vertical movement set the new value for @c ideal_column. */ 1061 if (!pure_vertical) { 1062 spt_get_coord(&pt, &coord); 1063 pane.ideal_column = coord.column; 1064 } 1065 1066 caret_update(); 1067 } 1068 1069 static void caret_move_word_left(void) 1070 { 1072 caret_move(pt, select, !pure_vertical); 1073 } 1074 1075 /** Absolutely move caret position. 1076 * 1077 * Moves caret to a specified position. We get to a new character cell, and 1078 * thus a new character. Then we either go to the point before the the character 1079 * or after it, depending on @a align_dir. 1080 * 1081 * @param select true if the selection tag should stay where it is 1082 */ 1083 static void caret_move_absolute(int row, int column, enum dir_spec align_dir, 1084 bool select) 1085 { 1086 coord_t coord; 1087 coord.row = row; 1088 coord.column = column; 1089 1071 1090 spt_t pt; 1072 1091 sheet_get_cell_pt(doc.sh, &coord, align_dir, &pt); 1092 1093 caret_move(pt, select, true); 1094 } 1095 1096 /** Find beginning of a word to the left of spt */ 1097 static spt_t pt_find_word_left(spt_t spt) 1098 { 1073 1099 do { 1074 caret_move(0, -1, dir_before); 1075 1076 tag_get_pt(&pane.caret_pos, &pt); 1077 1078 sheet_remove_tag(doc.sh, &pane.sel_start); 1079 sheet_place_tag(doc.sh, &pt, &pane.sel_start); 1080 } while (!pt_is_word_beginning(&pt)); 1081 1082 pane.rflags |= REDRAW_TEXT; 1083 } 1084 1085 static void caret_move_word_right(void) 1100 spt_prev_char(spt, &spt); 1101 } while (!pt_is_word_beginning(&spt)); 1102 return spt; 1103 } 1104 1105 /** Find beginning of a word to the right of spt */ 1106 static spt_t pt_find_word_right(spt_t spt) 1107 { 1108 do { 1109 spt_next_char(spt, &spt); 1110 } while (!pt_is_word_beginning(&spt)); 1111 return spt; 1112 } 1113 1114 static void caret_move_word_left(bool select) 1086 1115 { 1087 1116 spt_t pt; 1088 1089 do { 1090 caret_move(0, 0, dir_after); 1091 1092 tag_get_pt(&pane.caret_pos, &pt); 1093 1094 sheet_remove_tag(doc.sh, &pane.sel_start); 1095 sheet_place_tag(doc.sh, &pt, &pane.sel_start); 1096 } while (!pt_is_word_beginning(&pt)); 1097 1098 pane.rflags |= REDRAW_TEXT; 1099 } 1100 1101 /** Change the caret position to a beginning of a given line 1102 */ 1103 static void caret_move_to_line(int row) 1117 tag_get_pt(&pane.caret_pos, &pt); 1118 spt_t word_left = pt_find_word_left(pt); 1119 caret_move(word_left, select, true); 1120 } 1121 1122 static void caret_move_word_right(bool select) 1104 1123 { 1105 1124 spt_t pt; 1106 coord_t coord;1107 1108 1125 tag_get_pt(&pane.caret_pos, &pt); 1109 spt_get_coord(&pt, &coord); 1110 1111 caret_movement(row - coord.row, 0, dir_before, false); 1126 spt_t word_right = pt_find_word_right(pt); 1127 caret_move(word_right, select, true); 1112 1128 } 1113 1129 … … 1126 1142 int line = strtol(sline, &endptr, 10); 1127 1143 if (*endptr != '\0') { 1144 free(sline); 1128 1145 status_display("Invalid number entered."); 1129 1146 return; 1130 1147 } 1131 1132 caret_move_to_line(line); 1133 } 1134 1148 free(sline); 1149 1150 caret_move_absolute(line, pane.ideal_column, dir_before, false); 1151 } 1152 1153 /* Search operations */ 1154 static int search_spt_producer(void *data, wchar_t *ret) 1155 { 1156 assert(data != NULL); 1157 assert(ret != NULL); 1158 spt_t *spt = data; 1159 *ret = spt_next_char(*spt, spt); 1160 return EOK; 1161 } 1162 1163 static int search_spt_mark(void *data, void **mark) 1164 { 1165 assert(data != NULL); 1166 assert(mark != NULL); 1167 spt_t *spt = data; 1168 spt_t *new = calloc(1, sizeof(spt_t)); 1169 *mark = new; 1170 if (new == NULL) 1171 return ENOMEM; 1172 *new = *spt; 1173 return EOK; 1174 } 1175 1176 static void search_spt_mark_free(void *data) 1177 { 1178 free(data); 1179 } 1180 1181 static search_ops_t search_spt_ops = { 1182 .equals = char_exact_equals, 1183 .producer = search_spt_producer, 1184 .mark = search_spt_mark, 1185 .mark_free = search_spt_mark_free, 1186 }; 1187 1188 /** Ask for line and go to it. */ 1189 static void search(void) 1190 { 1191 char *pattern; 1192 1193 const char *default_value = ""; 1194 if (pane.previous_search) 1195 default_value = pane.previous_search; 1196 1197 pattern = prompt("Search for", default_value); 1198 if (pattern == NULL) { 1199 status_display("Search cancelled."); 1200 return; 1201 } 1202 1203 if (pane.previous_search) 1204 free(pane.previous_search); 1205 pane.previous_search = pattern; 1206 1207 search_forward(pattern); 1208 } 1209 1210 static void search_repeat(void) 1211 { 1212 if (pane.previous_search == NULL) { 1213 status_display("No previous search to repeat."); 1214 return; 1215 } 1216 1217 search_forward(pane.previous_search); 1218 } 1219 1220 static void search_forward(char *pattern) 1221 { 1222 status_display("Searching..."); 1223 1224 spt_t sp, producer_pos; 1225 tag_get_pt(&pane.caret_pos, &sp); 1226 1227 /* Start searching on the position after caret */ 1228 spt_next_char(sp, &sp); 1229 producer_pos = sp; 1230 1231 search_t *search = search_init(pattern, &producer_pos, search_spt_ops); 1232 if (search == NULL) { 1233 status_display("Failed initializing search."); 1234 return; 1235 } 1236 1237 match_t match; 1238 int rc = search_next_match(search, &match); 1239 if (rc != EOK) { 1240 status_display("Failed searching."); 1241 search_fini(search); 1242 } 1243 1244 if (match.end) { 1245 status_display("Match found."); 1246 assert(match.end != NULL); 1247 spt_t *end = match.end; 1248 caret_move(*end, false, true); 1249 while (match.length > 0) { 1250 match.length--; 1251 spt_prev_char(*end, end); 1252 } 1253 caret_move(*end, true, true); 1254 free(end); 1255 } 1256 else { 1257 status_display("Not found."); 1258 } 1259 1260 search_fini(search); 1261 } 1135 1262 1136 1263 /** Check for non-empty selection. */ … … 1202 1329 pane.rflags |= REDRAW_TEXT; 1203 1330 caret_update(); 1204 }1205 1206 /** Add the previous word to the selection */1207 static void selection_sel_prev_word(void)1208 {1209 spt_t cpt, wpt, spt, ept;1210 1211 selection_get_points(&spt, &ept);1212 1213 tag_get_pt(&pane.caret_pos, &cpt);1214 caret_move_word_left();1215 tag_get_pt(&pane.caret_pos, &wpt);1216 1217 if (spt_cmp(&spt, &cpt) == 0)1218 selection_sel_range(ept, wpt);1219 else1220 selection_sel_range(spt, wpt);1221 }1222 1223 /** Add the next word to the selection */1224 static void selection_sel_next_word(void)1225 {1226 spt_t cpt, wpt, spt, ept;1227 1228 selection_get_points(&spt, &ept);1229 1230 tag_get_pt(&pane.caret_pos, &cpt);1231 caret_move_word_right();1232 tag_get_pt(&pane.caret_pos, &wpt);1233 1234 if (spt_cmp(&ept, &cpt) == 0)1235 selection_sel_range(spt, wpt);1236 else1237 selection_sel_range(ept, wpt);1238 1331 } 1239 1332 -
uspace/app/edit/sheet.c
r87c0a45 r1e58e1b 323 323 } 324 324 325 /** Get a character at spt and return next spt */ 326 wchar_t spt_next_char(spt_t spt, spt_t *next) 327 { 328 wchar_t ch = str_decode(spt.sh->data, &spt.b_off, spt.sh->text_size); 329 if (next) 330 *next = spt; 331 return ch; 332 } 333 334 wchar_t spt_prev_char(spt_t spt, spt_t *prev) 335 { 336 wchar_t ch = str_decode_reverse(spt.sh->data, &spt.b_off, spt.sh->text_size); 337 if (prev) 338 *prev = spt; 339 return ch; 340 } 341 325 342 /** Place a tag on the specified s-point. */ 326 343 void sheet_place_tag(sheet_t *sh, spt_t const *pt, tag_t *tag) -
uspace/app/edit/sheet.h
r87c0a45 r1e58e1b 101 101 extern void spt_get_coord(spt_t const *, coord_t *); 102 102 extern bool spt_equal(spt_t const *, spt_t const *); 103 extern wchar_t spt_next_char(spt_t, spt_t *); 104 extern wchar_t spt_prev_char(spt_t, spt_t *); 103 105 104 106 extern void sheet_place_tag(sheet_t *, spt_t const *, tag_t *);
Note:
See TracChangeset
for help on using the changeset viewer.