Changes in uspace/app/edit/edit.c [cd82bb1:743e17b] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/edit/edit.c
rcd82bb1 r743e17b 36 36 37 37 #include <stdio.h> 38 #include <stdlib.h>39 38 #include <sys/types.h> 40 39 #include <vfs/vfs.h> … … 45 44 #include <align.h> 46 45 #include <macros.h> 47 #include <clipboard.h>48 46 #include <bool.h> 49 47 … … 75 73 tag_t caret_pos; 76 74 77 /** Start of selection */78 tag_t sel_start;79 80 75 /** 81 76 * Ideal column where the caret should try to get. This is used … … 106 101 #define ED_INFTY 65536 107 102 108 /** Maximum filename length that can be entered. */109 #define INFNAME_MAX_LEN 128110 111 103 static void key_handle_unmod(console_event_t const *ev); 112 104 static void key_handle_ctrl(console_event_t const *ev); 113 static void key_handle_shift(console_event_t const *ev);114 static void key_handle_movement(unsigned int key, bool shift);115 116 105 static int file_save(char const *fname); 117 static void file_save_as(void);118 106 static int file_insert(char *fname); 119 107 static int file_save_range(char const *fname, spt_t const *spos, 120 108 spt_t const *epos); 121 static char *filename_prompt(char const *prompt, char const *init_value);122 static char *range_get_str(spt_t const *spos, spt_t const *epos);123 124 109 static void pane_text_display(void); 125 110 static void pane_row_display(void); … … 127 112 static void pane_status_display(void); 128 113 static void pane_caret_display(void); 129 130 114 static void insert_char(wchar_t c); 131 115 static void delete_char_before(void); … … 133 117 static void caret_update(void); 134 118 static void caret_move(int drow, int dcolumn, enum dir_spec align_dir); 135 136 static bool selection_active(void);137 static void selection_sel_all(void);138 static void selection_get_points(spt_t *pa, spt_t *pb);139 static void selection_delete(void);140 static void selection_copy(void);141 static void insert_clipboard_data(void);142 143 119 static void pt_get_sof(spt_t *pt); 144 120 static void pt_get_eof(spt_t *pt); 145 static int tag_cmp(tag_t const *a, tag_t const *b);146 static int spt_cmp(spt_t const *a, spt_t const *b);147 static int coord_cmp(coord_t const *a, coord_t const *b);148 149 121 static void status_display(char const *str); 150 122 … … 178 150 179 151 if (argc == 2) { 180 doc.file_name = str_dup(argv[1]);152 doc.file_name = argv[1]; 181 153 } else if (argc > 1) { 182 154 printf("Invalid arguments.\n"); 183 155 return -2; 184 156 } else { 185 doc.file_name = NULL;157 doc.file_name = "/edit.txt"; 186 158 } 187 159 188 160 new_file = false; 189 161 190 if ( doc.file_name == NULL ||file_insert(doc.file_name) != EOK)162 if (file_insert(doc.file_name) != EOK) 191 163 new_file = true; 192 164 193 165 /* Move to beginning of file. */ 194 166 caret_move(-ED_INFTY, -ED_INFTY, dir_before); 195 196 /* Place selection start tag. */197 tag_get_pt(&pane.caret_pos, &pt);198 sheet_place_tag(&doc.sh, &pt, &pane.sel_start);199 167 200 168 /* Initial display */ … … 202 170 pane_text_display(); 203 171 pane_status_display(); 204 if (new_file && doc.file_name != NULL)205 status_display("File not found. Startingempty file.");172 if (new_file) 173 status_display("File not found. Created empty file."); 206 174 pane_caret_display(); 207 175 … … 216 184 /* Handle key press. */ 217 185 if (((ev.mods & KM_ALT) == 0) && 218 ((ev.mods & KM_SHIFT) == 0) &&219 186 (ev.mods & KM_CTRL) != 0) { 220 187 key_handle_ctrl(&ev); 221 } else if (((ev.mods & KM_ALT) == 0) && 222 ((ev.mods & KM_CTRL) == 0) && 223 (ev.mods & KM_SHIFT) != 0) { 224 key_handle_shift(&ev); 225 } else if ((ev.mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0) { 188 } else if ((ev.mods & (KM_CTRL | KM_ALT)) == 0) { 226 189 key_handle_unmod(&ev); 227 190 } … … 238 201 if (pane.rflags & REDRAW_CARET) 239 202 pane_caret_display(); 203 240 204 } 241 205 … … 250 214 switch (ev->key) { 251 215 case KC_ENTER: 252 selection_delete();253 216 insert_char('\n'); 254 217 caret_update(); 255 218 break; 256 219 case KC_LEFT: 220 caret_move(0, -1, dir_before); 221 break; 257 222 case KC_RIGHT: 223 caret_move(0, 0, dir_after); 224 break; 258 225 case KC_UP: 226 caret_move(-1, 0, dir_before); 227 break; 259 228 case KC_DOWN: 229 caret_move(+1, 0, dir_before); 230 break; 260 231 case KC_HOME: 232 caret_move(0, -ED_INFTY, dir_before); 233 break; 261 234 case KC_END: 235 caret_move(0, +ED_INFTY, dir_before); 236 break; 262 237 case KC_PAGE_UP: 238 caret_move(-pane.rows, 0, dir_before); 239 break; 263 240 case KC_PAGE_DOWN: 264 key_handle_movement(ev->key, false);241 caret_move(+pane.rows, 0, dir_before); 265 242 break; 266 243 case KC_BACKSPACE: 267 if (selection_active()) 268 selection_delete(); 269 else 270 delete_char_before(); 244 delete_char_before(); 271 245 caret_update(); 272 246 break; 273 247 case KC_DELETE: 274 if (selection_active()) 275 selection_delete(); 276 else 277 delete_char_after(); 248 delete_char_after(); 278 249 caret_update(); 279 250 break; 280 251 default: 281 252 if (ev->c >= 32 || ev->c == '\t') { 282 selection_delete();283 253 insert_char(ev->c); 284 254 caret_update(); … … 288 258 } 289 259 290 /** Handle Shift-key combination. */291 static void key_handle_shift(console_event_t const *ev)292 {293 switch (ev->key) {294 case KC_LEFT:295 case KC_RIGHT:296 case KC_UP:297 case KC_DOWN:298 case KC_HOME:299 case KC_END:300 case KC_PAGE_UP:301 case KC_PAGE_DOWN:302 key_handle_movement(ev->key, true);303 break;304 default:305 if (ev->c >= 32 || ev->c == '\t') {306 selection_delete();307 insert_char(ev->c);308 caret_update();309 }310 break;311 }312 }313 314 260 /** Handle Ctrl-key combination. */ 315 261 static void key_handle_ctrl(console_event_t const *ev) … … 320 266 break; 321 267 case KC_S: 322 if (doc.file_name != NULL) 323 file_save(doc.file_name); 324 else 325 file_save_as(); 326 break; 327 case KC_E: 328 file_save_as(); 329 break; 330 case KC_C: 331 selection_copy(); 332 break; 333 case KC_V: 334 selection_delete(); 335 insert_clipboard_data(); 336 pane.rflags |= REDRAW_TEXT; 337 caret_update(); 338 break; 339 case KC_X: 340 selection_copy(); 341 selection_delete(); 342 pane.rflags |= REDRAW_TEXT; 343 caret_update(); 344 break; 345 case KC_A: 346 selection_sel_all(); 268 (void) file_save(doc.file_name); 347 269 break; 348 270 default: … … 351 273 } 352 274 353 static void key_handle_movement(unsigned int key, bool select)354 {355 spt_t pt;356 spt_t caret_pt;357 coord_t c_old, c_new;358 bool had_sel;359 360 /* Check if we had selection before. */361 tag_get_pt(&pane.caret_pos, &caret_pt);362 tag_get_pt(&pane.sel_start, &pt);363 had_sel = !spt_equal(&caret_pt, &pt);364 365 switch (key) {366 case KC_LEFT:367 caret_move(0, -1, dir_before);368 break;369 case KC_RIGHT:370 caret_move(0, 0, dir_after);371 break;372 case KC_UP:373 caret_move(-1, 0, dir_before);374 break;375 case KC_DOWN:376 caret_move(+1, 0, dir_before);377 break;378 case KC_HOME:379 caret_move(0, -ED_INFTY, dir_before);380 break;381 case KC_END:382 caret_move(0, +ED_INFTY, dir_before);383 break;384 case KC_PAGE_UP:385 caret_move(-pane.rows, 0, dir_before);386 break;387 case KC_PAGE_DOWN:388 caret_move(+pane.rows, 0, dir_before);389 break;390 default:391 break;392 }393 394 if (select == false) {395 /* Move sel_start to the same point as caret. */396 sheet_remove_tag(&doc.sh, &pane.sel_start);397 tag_get_pt(&pane.caret_pos, &pt);398 sheet_place_tag(&doc.sh, &pt, &pane.sel_start);399 }400 401 if (select) {402 tag_get_pt(&pane.caret_pos, &pt);403 spt_get_coord(&caret_pt, &c_old);404 spt_get_coord(&pt, &c_new);405 406 if (c_old.row == c_new.row)407 pane.rflags |= REDRAW_ROW;408 else409 pane.rflags |= REDRAW_TEXT;410 411 } else if (had_sel == true) {412 /* Redraw because text was unselected. */413 pane.rflags |= REDRAW_TEXT;414 }415 }416 275 417 276 /** Save the document. */ … … 426 285 427 286 rc = file_save_range(fname, &sp, &ep); 428 429 switch (rc) { 430 case EINVAL: 431 status_display("Error opening file!"); 432 break; 433 case EIO: 434 status_display("Error writing data!"); 435 break; 436 default: 437 status_display("File saved."); 438 break; 439 } 287 status_display("File saved."); 440 288 441 289 return rc; 442 }443 444 /** Change document name and save. */445 static void file_save_as(void)446 {447 char *old_fname, *fname;448 int rc;449 450 old_fname = (doc.file_name != NULL) ? doc.file_name : "";451 fname = filename_prompt("Save As", old_fname);452 if (fname == NULL) {453 status_display("Save cancelled.");454 return;455 }456 457 rc = file_save(fname);458 if (rc != EOK)459 return;460 461 if (doc.file_name != NULL)462 free(doc.file_name);463 doc.file_name = fname;464 }465 466 /** Ask for a file name. */467 static char *filename_prompt(char const *prompt, char const *init_value)468 {469 console_event_t ev;470 char *str;471 wchar_t buffer[INFNAME_MAX_LEN + 1];472 int max_len;473 int nc;474 bool done;475 476 asprintf(&str, "%s: %s", prompt, init_value);477 status_display(str);478 console_goto(con, 1 + str_length(str), scr_rows - 1);479 free(str);480 481 console_set_color(con, COLOR_WHITE, COLOR_BLACK, 0);482 483 max_len = min(INFNAME_MAX_LEN, scr_columns - 4 - str_length(prompt));484 str_to_wstr(buffer, max_len + 1, init_value);485 nc = wstr_length(buffer);486 done = false;487 488 while (!done) {489 console_get_event(con, &ev);490 491 if (ev.type == KEY_PRESS) {492 /* Handle key press. */493 if (((ev.mods & KM_ALT) == 0) &&494 (ev.mods & KM_CTRL) != 0) {495 ;496 } else if ((ev.mods & (KM_CTRL | KM_ALT)) == 0) {497 switch (ev.key) {498 case KC_ESCAPE:499 return NULL;500 case KC_BACKSPACE:501 if (nc > 0) {502 putchar('\b');503 fflush(stdout);504 --nc;505 }506 break;507 case KC_ENTER:508 done = true;509 break;510 default:511 if (ev.c >= 32 && nc < max_len) {512 putchar(ev.c);513 fflush(stdout);514 buffer[nc++] = ev.c;515 }516 break;517 }518 }519 }520 }521 522 buffer[nc] = '\0';523 str = wstr_to_astr(buffer);524 525 console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);526 527 return str;528 290 } 529 291 … … 597 359 } while (!spt_equal(&bep, epos)); 598 360 599 if (fclose(f) != EOK) 600 return EIO; 361 fclose(f); 601 362 602 363 return EOK; 603 }604 605 /** Return contents of range as a new string. */606 static char *range_get_str(spt_t const *spos, spt_t const *epos)607 {608 char *buf;609 spt_t sp, bep;610 size_t bytes;611 size_t buf_size, bpos;612 613 buf_size = 1;614 615 buf = malloc(buf_size);616 if (buf == NULL)617 return NULL;618 619 bpos = 0;620 sp = *spos;621 622 while (true) {623 sheet_copy_out(&doc.sh, &sp, epos, &buf[bpos], buf_size - bpos,624 &bep);625 bytes = str_size(&buf[bpos]);626 bpos += bytes;627 sp = bep;628 629 if (spt_equal(&bep, epos))630 break;631 632 buf_size *= 2;633 buf = realloc(buf, buf_size);634 if (buf == NULL)635 return NULL;636 }637 638 return buf;639 364 } 640 365 … … 683 408 { 684 409 int i, j, fill; 685 spt_t rb, re, dep , pt;410 spt_t rb, re, dep; 686 411 coord_t rbc, rec; 687 412 char row_buf[ROW_BUF_SIZE]; … … 689 414 size_t pos, size; 690 415 unsigned s_column; 691 coord_t csel_start, csel_end, ctmp;692 693 /* Determine selection start and end. */694 695 tag_get_pt(&pane.sel_start, &pt);696 spt_get_coord(&pt, &csel_start);697 698 tag_get_pt(&pane.caret_pos, &pt);699 spt_get_coord(&pt, &csel_end);700 701 if (coord_cmp(&csel_start, &csel_end) > 0) {702 ctmp = csel_start;703 csel_start = csel_end;704 csel_end = ctmp;705 }706 416 707 417 /* Draw rows from the sheet. */ … … 724 434 /* Display text from the buffer. */ 725 435 726 if (coord_cmp(&csel_start, &rbc) <= 0 &&727 coord_cmp(&rbc, &csel_end) < 0) {728 fflush(stdout);729 console_set_color(con, COLOR_BLACK, COLOR_RED, 0);730 fflush(stdout);731 }732 733 436 console_goto(con, 0, i); 734 437 size = str_size(row_buf); 735 438 pos = 0; 736 s_column = pane.sh_column;439 s_column = 1; 737 440 while (pos < size) { 738 if (csel_start.row == rbc.row && csel_start.column == s_column) {739 fflush(stdout);740 console_set_color(con, COLOR_BLACK, COLOR_RED, 0);741 fflush(stdout);742 }743 744 if (csel_end.row == rbc.row && csel_end.column == s_column) {745 fflush(stdout);746 console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);747 fflush(stdout);748 }749 750 441 c = str_decode(row_buf, &pos, size); 751 442 if (c != '\t') { … … 762 453 } 763 454 764 if (csel_end.row == rbc.row && csel_end.column == s_column) {765 fflush(stdout);766 console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);767 fflush(stdout);768 }769 770 455 /* Fill until the end of display area. */ 771 456 … … 778 463 putchar(' '); 779 464 fflush(stdout); 780 console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);781 465 } 782 466 … … 789 473 spt_t caret_pt; 790 474 coord_t coord; 791 char *fname;792 475 int n; 793 476 … … 795 478 spt_get_coord(&caret_pt, &coord); 796 479 797 fname = (doc.file_name != NULL) ? doc.file_name : "<unnamed>";798 799 480 console_goto(con, 0, scr_rows - 1); 800 481 console_set_color(con, COLOR_WHITE, COLOR_BLACK, 0); 801 n = printf(" %d, %d: File '%s'. Ctrl- Q Quit Ctrl-S Save "802 "Ctrl-E Save As", coord.row, coord.column, fname);482 n = printf(" %d, %d: File '%s'. Ctrl-S Save Ctrl-Q Quit", 483 coord.row, coord.column, doc.file_name); 803 484 printf("%*s", scr_columns - 1 - n, ""); 804 485 fflush(stdout); … … 967 648 } 968 649 969 /** Check for non-empty selection. */970 static bool selection_active(void)971 {972 return (tag_cmp(&pane.caret_pos, &pane.sel_start) != 0);973 }974 975 static void selection_get_points(spt_t *pa, spt_t *pb)976 {977 spt_t pt;978 979 tag_get_pt(&pane.sel_start, pa);980 tag_get_pt(&pane.caret_pos, pb);981 982 if (spt_cmp(pa, pb) > 0) {983 pt = *pa;984 *pa = *pb;985 *pb = pt;986 }987 }988 989 /** Delete selected text. */990 static void selection_delete(void)991 {992 spt_t pa, pb;993 coord_t ca, cb;994 int rel;995 996 tag_get_pt(&pane.sel_start, &pa);997 tag_get_pt(&pane.caret_pos, &pb);998 spt_get_coord(&pa, &ca);999 spt_get_coord(&pb, &cb);1000 rel = coord_cmp(&ca, &cb);1001 1002 if (rel == 0)1003 return;1004 1005 if (rel < 0)1006 sheet_delete(&doc.sh, &pa, &pb);1007 else1008 sheet_delete(&doc.sh, &pb, &pa);1009 1010 if (ca.row == cb.row)1011 pane.rflags |= REDRAW_ROW;1012 else1013 pane.rflags |= REDRAW_TEXT;1014 }1015 1016 static void selection_sel_all(void)1017 {1018 spt_t spt, ept;1019 1020 pt_get_sof(&spt);1021 pt_get_eof(&ept);1022 sheet_remove_tag(&doc.sh, &pane.sel_start);1023 sheet_place_tag(&doc.sh, &spt, &pane.sel_start);1024 sheet_remove_tag(&doc.sh, &pane.caret_pos);1025 sheet_place_tag(&doc.sh, &ept, &pane.caret_pos);1026 1027 pane.rflags |= REDRAW_TEXT;1028 caret_update();1029 }1030 1031 static void selection_copy(void)1032 {1033 spt_t pa, pb;1034 char *str;1035 1036 selection_get_points(&pa, &pb);1037 str = range_get_str(&pa, &pb);1038 if (str == NULL || clipboard_put_str(str) != EOK) {1039 status_display("Copying to clipboard failed!");1040 }1041 free(str);1042 }1043 1044 static void insert_clipboard_data(void)1045 {1046 char *str;1047 size_t off;1048 wchar_t c;1049 int rc;1050 1051 rc = clipboard_get_str(&str);1052 if (rc != EOK || str == NULL)1053 return;1054 1055 off = 0;1056 1057 while (true) {1058 c = str_decode(str, &off, STR_NO_LIMIT);1059 if (c == '\0')1060 break;1061 1062 insert_char(c);1063 }1064 1065 free(str);1066 }1067 650 1068 651 /** Get start-of-file s-point. */ … … 1082 665 1083 666 sheet_get_num_rows(&doc.sh, &num_rows); 1084 coord.row = num_rows + 1;667 coord.row = num_rows; 1085 668 coord.column = 1; 1086 669 1087 670 sheet_get_cell_pt(&doc.sh, &coord, dir_after, pt); 1088 }1089 1090 /** Compare tags. */1091 static int tag_cmp(tag_t const *a, tag_t const *b)1092 {1093 spt_t pa, pb;1094 1095 tag_get_pt(a, &pa);1096 tag_get_pt(b, &pb);1097 1098 return spt_cmp(&pa, &pb);1099 }1100 1101 /** Compare s-points. */1102 static int spt_cmp(spt_t const *a, spt_t const *b)1103 {1104 coord_t ca, cb;1105 1106 spt_get_coord(a, &ca);1107 spt_get_coord(b, &cb);1108 1109 return coord_cmp(&ca, &cb);1110 }1111 1112 /** Compare coordinats. */1113 static int coord_cmp(coord_t const *a, coord_t const *b)1114 {1115 if (a->row - b->row != 0)1116 return a->row - b->row;1117 1118 return a->column - b->column;1119 671 } 1120 672
Note:
See TracChangeset
for help on using the changeset viewer.