Changes in uspace/app/edit/edit.c [cd82bb1:743e17b] in mainline


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/edit/edit.c

    rcd82bb1 r743e17b  
    3636
    3737#include <stdio.h>
    38 #include <stdlib.h>
    3938#include <sys/types.h>
    4039#include <vfs/vfs.h>
     
    4544#include <align.h>
    4645#include <macros.h>
    47 #include <clipboard.h>
    4846#include <bool.h>
    4947
     
    7573        tag_t caret_pos;
    7674
    77         /** Start of selection */
    78         tag_t sel_start;
    79 
    8075        /**
    8176         * Ideal column where the caret should try to get. This is used
     
    106101#define ED_INFTY 65536
    107102
    108 /** Maximum filename length that can be entered. */
    109 #define INFNAME_MAX_LEN 128
    110 
    111103static void key_handle_unmod(console_event_t const *ev);
    112104static 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 
    116105static int file_save(char const *fname);
    117 static void file_save_as(void);
    118106static int file_insert(char *fname);
    119107static int file_save_range(char const *fname, spt_t const *spos,
    120108    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 
    124109static void pane_text_display(void);
    125110static void pane_row_display(void);
     
    127112static void pane_status_display(void);
    128113static void pane_caret_display(void);
    129 
    130114static void insert_char(wchar_t c);
    131115static void delete_char_before(void);
     
    133117static void caret_update(void);
    134118static 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 
    143119static void pt_get_sof(spt_t *pt);
    144120static 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 
    149121static void status_display(char const *str);
    150122
     
    178150
    179151        if (argc == 2) {
    180                 doc.file_name = str_dup(argv[1]);
     152                doc.file_name = argv[1];
    181153        } else if (argc > 1) {
    182154                printf("Invalid arguments.\n");
    183155                return -2;
    184156        } else {
    185                 doc.file_name = NULL;
     157                doc.file_name = "/edit.txt";
    186158        }
    187159
    188160        new_file = false;
    189161
    190         if (doc.file_name == NULL || file_insert(doc.file_name) != EOK)
     162        if (file_insert(doc.file_name) != EOK)
    191163                new_file = true;
    192164
    193165        /* Move to beginning of file. */
    194166        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);
    199167
    200168        /* Initial display */
     
    202170        pane_text_display();
    203171        pane_status_display();
    204         if (new_file && doc.file_name != NULL)
    205                 status_display("File not found. Starting empty file.");
     172        if (new_file)
     173                status_display("File not found. Created empty file.");
    206174        pane_caret_display();
    207175
     
    216184                        /* Handle key press. */
    217185                        if (((ev.mods & KM_ALT) == 0) &&
    218                             ((ev.mods & KM_SHIFT) == 0) &&
    219186                             (ev.mods & KM_CTRL) != 0) {
    220187                                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) {
    226189                                key_handle_unmod(&ev);
    227190                        }
     
    238201                if (pane.rflags & REDRAW_CARET)
    239202                        pane_caret_display();
     203                       
    240204        }
    241205
     
    250214        switch (ev->key) {
    251215        case KC_ENTER:
    252                 selection_delete();
    253216                insert_char('\n');
    254217                caret_update();
    255218                break;
    256219        case KC_LEFT:
     220                caret_move(0, -1, dir_before);
     221                break;
    257222        case KC_RIGHT:
     223                caret_move(0, 0, dir_after);
     224                break;
    258225        case KC_UP:
     226                caret_move(-1, 0, dir_before);
     227                break;
    259228        case KC_DOWN:
     229                caret_move(+1, 0, dir_before);
     230                break;
    260231        case KC_HOME:
     232                caret_move(0, -ED_INFTY, dir_before);
     233                break;
    261234        case KC_END:
     235                caret_move(0, +ED_INFTY, dir_before);
     236                break;
    262237        case KC_PAGE_UP:
     238                caret_move(-pane.rows, 0, dir_before);
     239                break;
    263240        case KC_PAGE_DOWN:
    264                 key_handle_movement(ev->key, false);
     241                caret_move(+pane.rows, 0, dir_before);
    265242                break;
    266243        case KC_BACKSPACE:
    267                 if (selection_active())
    268                         selection_delete();
    269                 else
    270                         delete_char_before();
     244                delete_char_before();
    271245                caret_update();
    272246                break;
    273247        case KC_DELETE:
    274                 if (selection_active())
    275                         selection_delete();
    276                 else
    277                         delete_char_after();
     248                delete_char_after();
    278249                caret_update();
    279250                break;
    280251        default:
    281252                if (ev->c >= 32 || ev->c == '\t') {
    282                         selection_delete();
    283253                        insert_char(ev->c);
    284254                        caret_update();
     
    288258}
    289259
    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 
    314260/** Handle Ctrl-key combination. */
    315261static void key_handle_ctrl(console_event_t const *ev)
     
    320266                break;
    321267        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);
    347269                break;
    348270        default:
     
    351273}
    352274
    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                 else
    409                         pane.rflags |= REDRAW_TEXT;
    410 
    411         } else if (had_sel == true) {
    412                 /* Redraw because text was unselected. */
    413                 pane.rflags |= REDRAW_TEXT;
    414         }
    415 }
    416275
    417276/** Save the document. */
     
    426285
    427286        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.");
    440288
    441289        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;
    528290}
    529291
     
    597359        } while (!spt_equal(&bep, epos));
    598360
    599         if (fclose(f) != EOK)
    600                 return EIO;
     361        fclose(f);
    601362
    602363        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;
    639364}
    640365
     
    683408{
    684409        int i, j, fill;
    685         spt_t rb, re, dep, pt;
     410        spt_t rb, re, dep;
    686411        coord_t rbc, rec;
    687412        char row_buf[ROW_BUF_SIZE];
     
    689414        size_t pos, size;
    690415        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         }
    706416
    707417        /* Draw rows from the sheet. */
     
    724434                /* Display text from the buffer. */
    725435
    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 
    733436                console_goto(con, 0, i);
    734437                size = str_size(row_buf);
    735438                pos = 0;
    736                 s_column = pane.sh_column;
     439                s_column = 1;
    737440                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        
    750441                        c = str_decode(row_buf, &pos, size);
    751442                        if (c != '\t') {
     
    762453                }
    763454
    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 
    770455                /* Fill until the end of display area. */
    771456
     
    778463                        putchar(' ');
    779464                fflush(stdout);
    780                 console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
    781465        }
    782466
     
    789473        spt_t caret_pt;
    790474        coord_t coord;
    791         char *fname;
    792475        int n;
    793476
     
    795478        spt_get_coord(&caret_pt, &coord);
    796479
    797         fname = (doc.file_name != NULL) ? doc.file_name : "<unnamed>";
    798 
    799480        console_goto(con, 0, scr_rows - 1);
    800481        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);
    803484        printf("%*s", scr_columns - 1 - n, "");
    804485        fflush(stdout);
     
    967648}
    968649
    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         else
    1008                 sheet_delete(&doc.sh, &pb, &pa);
    1009 
    1010         if (ca.row == cb.row)
    1011                 pane.rflags |= REDRAW_ROW;
    1012         else
    1013                 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 }
    1067650
    1068651/** Get start-of-file s-point. */
     
    1082665
    1083666        sheet_get_num_rows(&doc.sh, &num_rows);
    1084         coord.row = num_rows + 1;
     667        coord.row = num_rows;
    1085668        coord.column = 1;
    1086669
    1087670        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;
    1119671}
    1120672
Note: See TracChangeset for help on using the changeset viewer.