Changes in uspace/app/edit/edit.c [8190e63:00413c5c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/edit/edit.c
r8190e63 r00413c5c 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 … … 98 93 static bool done; 99 94 static pane_t pane; 100 static bool cursor_visible;101 95 102 96 static int scr_rows, scr_columns; … … 107 101 #define ED_INFTY 65536 108 102 109 /** Maximum filename length that can be entered. */110 #define INFNAME_MAX_LEN 128111 112 static void cursor_show(void);113 static void cursor_hide(void);114 static void cursor_setvis(bool visible);115 116 103 static void key_handle_unmod(console_event_t const *ev); 117 104 static void key_handle_ctrl(console_event_t const *ev); 118 static void key_handle_shift(console_event_t const *ev);119 static void key_handle_movement(unsigned int key, bool shift);120 121 105 static int file_save(char const *fname); 122 static void file_save_as(void);123 106 static int file_insert(char *fname); 124 107 static int file_save_range(char const *fname, spt_t const *spos, 125 108 spt_t const *epos); 126 static char *filename_prompt(char const *prompt, char const *init_value);127 static char *range_get_str(spt_t const *spos, spt_t const *epos);128 129 109 static void pane_text_display(void); 130 110 static void pane_row_display(void); … … 132 112 static void pane_status_display(void); 133 113 static void pane_caret_display(void); 134 135 114 static void insert_char(wchar_t c); 136 115 static void delete_char_before(void); … … 138 117 static void caret_update(void); 139 118 static void caret_move(int drow, int dcolumn, enum dir_spec align_dir); 140 141 static bool selection_active(void);142 static void selection_sel_all(void);143 static void selection_get_points(spt_t *pa, spt_t *pb);144 static void selection_delete(void);145 static void selection_copy(void);146 static void insert_clipboard_data(void);147 148 119 static void pt_get_sof(spt_t *pt); 149 120 static void pt_get_eof(spt_t *pt); 150 static int tag_cmp(tag_t const *a, tag_t const *b);151 static int spt_cmp(spt_t const *a, spt_t const *b);152 static int coord_cmp(coord_t const *a, coord_t const *b);153 154 121 static void status_display(char const *str); 155 122 … … 183 150 184 151 if (argc == 2) { 185 doc.file_name = str_dup(argv[1]);152 doc.file_name = argv[1]; 186 153 } else if (argc > 1) { 187 154 printf("Invalid arguments.\n"); 188 155 return -2; 189 156 } else { 190 doc.file_name = NULL;157 doc.file_name = "/edit.txt"; 191 158 } 192 159 193 160 new_file = false; 194 161 195 if ( doc.file_name == NULL ||file_insert(doc.file_name) != EOK)162 if (file_insert(doc.file_name) != EOK) 196 163 new_file = true; 197 164 … … 199 166 caret_move(-ED_INFTY, -ED_INFTY, dir_before); 200 167 201 /* Place selection start tag. */202 tag_get_pt(&pane.caret_pos, &pt);203 sheet_place_tag(&doc.sh, &pt, &pane.sel_start);204 205 168 /* Initial display */ 206 cursor_visible = true;207 208 cursor_hide();209 169 console_clear(con); 210 170 pane_text_display(); 211 171 pane_status_display(); 212 if (new_file && doc.file_name != NULL)213 status_display("File not found. Startingempty file.");172 if (new_file) 173 status_display("File not found. Created empty file."); 214 174 pane_caret_display(); 215 cursor_show(); 175 216 176 217 177 done = false; … … 224 184 /* Handle key press. */ 225 185 if (((ev.mods & KM_ALT) == 0) && 226 ((ev.mods & KM_SHIFT) == 0) &&227 186 (ev.mods & KM_CTRL) != 0) { 228 187 key_handle_ctrl(&ev); 229 } else if (((ev.mods & KM_ALT) == 0) && 230 ((ev.mods & KM_CTRL) == 0) && 231 (ev.mods & KM_SHIFT) != 0) { 232 key_handle_shift(&ev); 233 } else if ((ev.mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0) { 188 } else if ((ev.mods & (KM_CTRL | KM_ALT)) == 0) { 234 189 key_handle_unmod(&ev); 235 190 } … … 237 192 238 193 /* Redraw as necessary. */ 239 240 cursor_hide();241 194 242 195 if (pane.rflags & REDRAW_TEXT) … … 248 201 if (pane.rflags & REDRAW_CARET) 249 202 pane_caret_display(); 250 251 cursor_show(); 203 252 204 } 253 205 … … 255 207 256 208 return 0; 257 }258 259 static void cursor_show(void)260 {261 cursor_setvis(true);262 }263 264 static void cursor_hide(void)265 {266 cursor_setvis(false);267 }268 269 static void cursor_setvis(bool visible)270 {271 if (cursor_visible != visible) {272 console_cursor_visibility(con, visible);273 cursor_visible = visible;274 }275 209 } 276 210 … … 280 214 switch (ev->key) { 281 215 case KC_ENTER: 282 selection_delete();283 216 insert_char('\n'); 284 217 caret_update(); 285 218 break; 286 219 case KC_LEFT: 220 caret_move(0, -1, dir_before); 221 break; 287 222 case KC_RIGHT: 223 caret_move(0, 0, dir_after); 224 break; 288 225 case KC_UP: 226 caret_move(-1, 0, dir_before); 227 break; 289 228 case KC_DOWN: 229 caret_move(+1, 0, dir_before); 230 break; 290 231 case KC_HOME: 232 caret_move(0, -ED_INFTY, dir_before); 233 break; 291 234 case KC_END: 235 caret_move(0, +ED_INFTY, dir_before); 236 break; 292 237 case KC_PAGE_UP: 238 caret_move(-pane.rows, 0, dir_before); 239 break; 293 240 case KC_PAGE_DOWN: 294 key_handle_movement(ev->key, false);241 caret_move(+pane.rows, 0, dir_before); 295 242 break; 296 243 case KC_BACKSPACE: 297 if (selection_active()) 298 selection_delete(); 299 else 300 delete_char_before(); 244 delete_char_before(); 301 245 caret_update(); 302 246 break; 303 247 case KC_DELETE: 304 if (selection_active()) 305 selection_delete(); 306 else 307 delete_char_after(); 248 delete_char_after(); 308 249 caret_update(); 309 250 break; 310 251 default: 311 252 if (ev->c >= 32 || ev->c == '\t') { 312 selection_delete();313 253 insert_char(ev->c); 314 254 caret_update(); … … 318 258 } 319 259 320 /** Handle Shift-key combination. */321 static void key_handle_shift(console_event_t const *ev)322 {323 switch (ev->key) {324 case KC_LEFT:325 case KC_RIGHT:326 case KC_UP:327 case KC_DOWN:328 case KC_HOME:329 case KC_END:330 case KC_PAGE_UP:331 case KC_PAGE_DOWN:332 key_handle_movement(ev->key, true);333 break;334 default:335 if (ev->c >= 32 || ev->c == '\t') {336 selection_delete();337 insert_char(ev->c);338 caret_update();339 }340 break;341 }342 }343 344 260 /** Handle Ctrl-key combination. */ 345 261 static void key_handle_ctrl(console_event_t const *ev) … … 350 266 break; 351 267 case KC_S: 352 if (doc.file_name != NULL) 353 file_save(doc.file_name); 354 else 355 file_save_as(); 356 break; 357 case KC_E: 358 file_save_as(); 359 break; 360 case KC_C: 361 selection_copy(); 362 break; 363 case KC_V: 364 selection_delete(); 365 insert_clipboard_data(); 366 pane.rflags |= REDRAW_TEXT; 367 caret_update(); 368 break; 369 case KC_X: 370 selection_copy(); 371 selection_delete(); 372 pane.rflags |= REDRAW_TEXT; 373 caret_update(); 374 break; 375 case KC_A: 376 selection_sel_all(); 268 (void) file_save(doc.file_name); 377 269 break; 378 270 default: … … 381 273 } 382 274 383 static void key_handle_movement(unsigned int key, bool select)384 {385 spt_t pt;386 spt_t caret_pt;387 coord_t c_old, c_new;388 bool had_sel;389 390 /* Check if we had selection before. */391 tag_get_pt(&pane.caret_pos, &caret_pt);392 tag_get_pt(&pane.sel_start, &pt);393 had_sel = !spt_equal(&caret_pt, &pt);394 395 switch (key) {396 case KC_LEFT:397 caret_move(0, -1, dir_before);398 break;399 case KC_RIGHT:400 caret_move(0, 0, dir_after);401 break;402 case KC_UP:403 caret_move(-1, 0, dir_before);404 break;405 case KC_DOWN:406 caret_move(+1, 0, dir_before);407 break;408 case KC_HOME:409 caret_move(0, -ED_INFTY, dir_before);410 break;411 case KC_END:412 caret_move(0, +ED_INFTY, dir_before);413 break;414 case KC_PAGE_UP:415 caret_move(-pane.rows, 0, dir_before);416 break;417 case KC_PAGE_DOWN:418 caret_move(+pane.rows, 0, dir_before);419 break;420 default:421 break;422 }423 424 if (select == false) {425 /* Move sel_start to the same point as caret. */426 sheet_remove_tag(&doc.sh, &pane.sel_start);427 tag_get_pt(&pane.caret_pos, &pt);428 sheet_place_tag(&doc.sh, &pt, &pane.sel_start);429 }430 431 if (select) {432 tag_get_pt(&pane.caret_pos, &pt);433 spt_get_coord(&caret_pt, &c_old);434 spt_get_coord(&pt, &c_new);435 436 if (c_old.row == c_new.row)437 pane.rflags |= REDRAW_ROW;438 else439 pane.rflags |= REDRAW_TEXT;440 441 } else if (had_sel == true) {442 /* Redraw because text was unselected. */443 pane.rflags |= REDRAW_TEXT;444 }445 }446 275 447 276 /** Save the document. */ … … 456 285 457 286 rc = file_save_range(fname, &sp, &ep); 458 459 switch (rc) { 460 case EINVAL: 461 status_display("Error opening file!"); 462 break; 463 case EIO: 464 status_display("Error writing data!"); 465 break; 466 default: 467 status_display("File saved."); 468 break; 469 } 287 status_display("File saved."); 470 288 471 289 return rc; 472 }473 474 /** Change document name and save. */475 static void file_save_as(void)476 {477 char *old_fname, *fname;478 int rc;479 480 old_fname = (doc.file_name != NULL) ? doc.file_name : "";481 fname = filename_prompt("Save As", old_fname);482 if (fname == NULL) {483 status_display("Save cancelled.");484 return;485 }486 487 rc = file_save(fname);488 if (rc != EOK)489 return;490 491 if (doc.file_name != NULL)492 free(doc.file_name);493 doc.file_name = fname;494 }495 496 /** Ask for a file name. */497 static char *filename_prompt(char const *prompt, char const *init_value)498 {499 console_event_t ev;500 char *str;501 wchar_t buffer[INFNAME_MAX_LEN + 1];502 int max_len;503 int nc;504 bool done;505 506 asprintf(&str, "%s: %s", prompt, init_value);507 status_display(str);508 console_goto(con, 1 + str_length(str), scr_rows - 1);509 free(str);510 511 console_set_color(con, COLOR_WHITE, COLOR_BLACK, 0);512 513 max_len = min(INFNAME_MAX_LEN, scr_columns - 4 - str_length(prompt));514 str_to_wstr(buffer, max_len + 1, init_value);515 nc = wstr_length(buffer);516 done = false;517 518 while (!done) {519 console_get_event(con, &ev);520 521 if (ev.type == KEY_PRESS) {522 /* Handle key press. */523 if (((ev.mods & KM_ALT) == 0) &&524 (ev.mods & KM_CTRL) != 0) {525 ;526 } else if ((ev.mods & (KM_CTRL | KM_ALT)) == 0) {527 switch (ev.key) {528 case KC_ESCAPE:529 return NULL;530 case KC_BACKSPACE:531 if (nc > 0) {532 putchar('\b');533 fflush(stdout);534 --nc;535 }536 break;537 case KC_ENTER:538 done = true;539 break;540 default:541 if (ev.c >= 32 && nc < max_len) {542 putchar(ev.c);543 fflush(stdout);544 buffer[nc++] = ev.c;545 }546 break;547 }548 }549 }550 }551 552 buffer[nc] = '\0';553 str = wstr_to_astr(buffer);554 555 console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);556 557 return str;558 290 } 559 291 … … 627 359 } while (!spt_equal(&bep, epos)); 628 360 629 if (fclose(f) != EOK) 630 return EIO; 361 fclose(f); 631 362 632 363 return EOK; 633 }634 635 /** Return contents of range as a new string. */636 static char *range_get_str(spt_t const *spos, spt_t const *epos)637 {638 char *buf;639 spt_t sp, bep;640 size_t bytes;641 size_t buf_size, bpos;642 643 buf_size = 1;644 645 buf = malloc(buf_size);646 if (buf == NULL)647 return NULL;648 649 bpos = 0;650 sp = *spos;651 652 while (true) {653 sheet_copy_out(&doc.sh, &sp, epos, &buf[bpos], buf_size - bpos,654 &bep);655 bytes = str_size(&buf[bpos]);656 bpos += bytes;657 sp = bep;658 659 if (spt_equal(&bep, epos))660 break;661 662 buf_size *= 2;663 buf = realloc(buf, buf_size);664 if (buf == NULL)665 return NULL;666 }667 668 return buf;669 364 } 670 365 … … 713 408 { 714 409 int i, j, fill; 715 spt_t rb, re, dep , pt;410 spt_t rb, re, dep; 716 411 coord_t rbc, rec; 717 412 char row_buf[ROW_BUF_SIZE]; … … 719 414 size_t pos, size; 720 415 unsigned s_column; 721 coord_t csel_start, csel_end, ctmp;722 723 /* Determine selection start and end. */724 725 tag_get_pt(&pane.sel_start, &pt);726 spt_get_coord(&pt, &csel_start);727 728 tag_get_pt(&pane.caret_pos, &pt);729 spt_get_coord(&pt, &csel_end);730 731 if (coord_cmp(&csel_start, &csel_end) > 0) {732 ctmp = csel_start;733 csel_start = csel_end;734 csel_end = ctmp;735 }736 416 737 417 /* Draw rows from the sheet. */ … … 754 434 /* Display text from the buffer. */ 755 435 756 if (coord_cmp(&csel_start, &rbc) <= 0 &&757 coord_cmp(&rbc, &csel_end) < 0) {758 fflush(stdout);759 console_set_color(con, COLOR_BLACK, COLOR_RED, 0);760 fflush(stdout);761 }762 763 436 console_goto(con, 0, i); 764 437 size = str_size(row_buf); 765 438 pos = 0; 766 s_column = pane.sh_column;439 s_column = 1; 767 440 while (pos < size) { 768 if (csel_start.row == rbc.row && csel_start.column == s_column) {769 fflush(stdout);770 console_set_color(con, COLOR_BLACK, COLOR_RED, 0);771 fflush(stdout);772 }773 774 if (csel_end.row == rbc.row && csel_end.column == s_column) {775 fflush(stdout);776 console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);777 fflush(stdout);778 }779 780 441 c = str_decode(row_buf, &pos, size); 781 442 if (c != '\t') { … … 792 453 } 793 454 794 if (csel_end.row == rbc.row && csel_end.column == s_column) {795 fflush(stdout);796 console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);797 fflush(stdout);798 }799 800 455 /* Fill until the end of display area. */ 801 456 … … 808 463 putchar(' '); 809 464 fflush(stdout); 810 console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);811 465 } 812 466 … … 819 473 spt_t caret_pt; 820 474 coord_t coord; 821 char *fname;822 475 int n; 823 476 … … 825 478 spt_get_coord(&caret_pt, &coord); 826 479 827 fname = (doc.file_name != NULL) ? doc.file_name : "<unnamed>";828 829 480 console_goto(con, 0, scr_rows - 1); 830 481 console_set_color(con, COLOR_WHITE, COLOR_BLACK, 0); 831 n = printf(" %d, %d: File '%s'. Ctrl- Q Quit Ctrl-S Save "832 "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); 833 484 printf("%*s", scr_columns - 1 - n, ""); 834 485 fflush(stdout); … … 997 648 } 998 649 999 /** Check for non-empty selection. */1000 static bool selection_active(void)1001 {1002 return (tag_cmp(&pane.caret_pos, &pane.sel_start) != 0);1003 }1004 1005 static void selection_get_points(spt_t *pa, spt_t *pb)1006 {1007 spt_t pt;1008 1009 tag_get_pt(&pane.sel_start, pa);1010 tag_get_pt(&pane.caret_pos, pb);1011 1012 if (spt_cmp(pa, pb) > 0) {1013 pt = *pa;1014 *pa = *pb;1015 *pb = pt;1016 }1017 }1018 1019 /** Delete selected text. */1020 static void selection_delete(void)1021 {1022 spt_t pa, pb;1023 coord_t ca, cb;1024 int rel;1025 1026 tag_get_pt(&pane.sel_start, &pa);1027 tag_get_pt(&pane.caret_pos, &pb);1028 spt_get_coord(&pa, &ca);1029 spt_get_coord(&pb, &cb);1030 rel = coord_cmp(&ca, &cb);1031 1032 if (rel == 0)1033 return;1034 1035 if (rel < 0)1036 sheet_delete(&doc.sh, &pa, &pb);1037 else1038 sheet_delete(&doc.sh, &pb, &pa);1039 1040 if (ca.row == cb.row)1041 pane.rflags |= REDRAW_ROW;1042 else1043 pane.rflags |= REDRAW_TEXT;1044 }1045 1046 static void selection_sel_all(void)1047 {1048 spt_t spt, ept;1049 1050 pt_get_sof(&spt);1051 pt_get_eof(&ept);1052 sheet_remove_tag(&doc.sh, &pane.sel_start);1053 sheet_place_tag(&doc.sh, &spt, &pane.sel_start);1054 sheet_remove_tag(&doc.sh, &pane.caret_pos);1055 sheet_place_tag(&doc.sh, &ept, &pane.caret_pos);1056 1057 pane.rflags |= REDRAW_TEXT;1058 caret_update();1059 }1060 1061 static void selection_copy(void)1062 {1063 spt_t pa, pb;1064 char *str;1065 1066 selection_get_points(&pa, &pb);1067 str = range_get_str(&pa, &pb);1068 if (str == NULL || clipboard_put_str(str) != EOK) {1069 status_display("Copying to clipboard failed!");1070 }1071 free(str);1072 }1073 1074 static void insert_clipboard_data(void)1075 {1076 char *str;1077 size_t off;1078 wchar_t c;1079 int rc;1080 1081 rc = clipboard_get_str(&str);1082 if (rc != EOK || str == NULL)1083 return;1084 1085 off = 0;1086 1087 while (true) {1088 c = str_decode(str, &off, STR_NO_LIMIT);1089 if (c == '\0')1090 break;1091 1092 insert_char(c);1093 }1094 1095 free(str);1096 }1097 650 1098 651 /** Get start-of-file s-point. */ … … 1116 669 1117 670 sheet_get_cell_pt(&doc.sh, &coord, dir_after, pt); 1118 }1119 1120 /** Compare tags. */1121 static int tag_cmp(tag_t const *a, tag_t const *b)1122 {1123 spt_t pa, pb;1124 1125 tag_get_pt(a, &pa);1126 tag_get_pt(b, &pb);1127 1128 return spt_cmp(&pa, &pb);1129 }1130 1131 /** Compare s-points. */1132 static int spt_cmp(spt_t const *a, spt_t const *b)1133 {1134 coord_t ca, cb;1135 1136 spt_get_coord(a, &ca);1137 spt_get_coord(b, &cb);1138 1139 return coord_cmp(&ca, &cb);1140 }1141 1142 /** Compare coordinats. */1143 static int coord_cmp(coord_t const *a, coord_t const *b)1144 {1145 if (a->row - b->row != 0)1146 return a->row - b->row;1147 1148 return a->column - b->column;1149 671 } 1150 672
Note:
See TracChangeset
for help on using the changeset viewer.