Ignore:
File:
1 edited

Legend:

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

    rad78054 r8f6bffdd  
    11/*
    22 * Copyright (c) 2009 Jiri Svoboda
    3  * Copyright (c) 2012 Martin Sucha
    43 * All rights reserved.
    54 *
     
    5049
    5150#include "sheet.h"
    52 #include "search.h"
    5351
    5452enum redraw_flags {
     
    8583         */
    8684        int ideal_column;
    87        
    88         char *previous_search;
    89         bool previous_search_reverse;
    9085} pane_t;
    9186
     
    9691typedef struct {
    9792        char *file_name;
    98         sheet_t *sh;
     93        sheet_t sh;
    9994} doc_t;
    10095
     
    131126static int file_save_range(char const *fname, spt_t const *spos,
    132127    spt_t const *epos);
     128static char *filename_prompt(char const *prompt, char const *init_value);
    133129static char *range_get_str(spt_t const *spos, spt_t const *epos);
    134 
    135 static char *prompt(char const *prompt, char const *init_value);
    136130
    137131static void pane_text_display(void);
     
    145139static void delete_char_after(void);
    146140static void caret_update(void);
    147 static void caret_move_relative(int drow, int dcolumn, enum dir_spec align_dir, bool select);
    148 static void caret_move_absolute(int row, int column, enum dir_spec align_dir, bool select);
    149 static void caret_move(spt_t spt, bool select, bool update_ideal_column);
    150 static void caret_move_word_left(bool select);
    151 static void caret_move_word_right(bool select);
    152 static void caret_go_to_line_ask(void);
     141static void caret_move(int drow, int dcolumn, enum dir_spec align_dir);
     142static void caret_move_word_left(void);
     143static void caret_move_word_right(void);
    153144
    154145static bool selection_active(void);
    155146static void selection_sel_all(void);
    156147static void selection_sel_range(spt_t pa, spt_t pb);
     148static void selection_sel_prev_word(void);
     149static void selection_sel_next_word(void);
    157150static void selection_get_points(spt_t *pa, spt_t *pb);
    158151static void selection_delete(void);
    159152static void selection_copy(void);
    160153static void insert_clipboard_data(void);
    161 
    162 static void search(char *pattern, bool reverse);
    163 static void search_prompt(bool reverse);
    164 static void search_repeat(void);
    165154
    166155static void pt_get_sof(spt_t *pt);
     
    171160static bool pt_is_delimiter(spt_t *pt);
    172161static bool pt_is_punctuation(spt_t *pt);
    173 static spt_t pt_find_word_left(spt_t spt);
    174 static spt_t pt_find_word_left(spt_t spt);
    175 
    176162static int tag_cmp(tag_t const *a, tag_t const *b);
    177163static int spt_cmp(spt_t const *a, spt_t const *b);
     
    184170{
    185171        kbd_event_t ev;
     172        coord_t coord;
    186173        bool new_file;
    187         int rc;
     174
     175        spt_t pt;
    188176
    189177        con = console_init(stdin, stdout);
     
    198186
    199187        /* Start with an empty sheet. */
    200         rc = sheet_create(&doc.sh);
    201         if (rc != EOK) {
    202                 printf("Out of memory.\n");
    203                 return -1;
    204         }
     188        sheet_init(&doc.sh);
    205189
    206190        /* Place caret at the beginning of file. */
    207         spt_t sof;
    208         pt_get_sof(&sof);
    209         sheet_place_tag(doc.sh, &sof, &pane.caret_pos);
    210         pane.ideal_column = 1;
     191        coord.row = coord.column = 1;
     192        sheet_get_cell_pt(&doc.sh, &coord, dir_before, &pt);
     193        sheet_place_tag(&doc.sh, &pt, &pane.caret_pos);
     194        pane.ideal_column = coord.column;
    211195
    212196        if (argc == 2) {
     
    224208                new_file = true;
    225209
     210        /* Move to beginning of file. */
     211        caret_move(-ED_INFTY, -ED_INFTY, dir_before);
     212
    226213        /* Place selection start tag. */
    227         sheet_place_tag(doc.sh, &sof, &pane.sel_start);
    228 
    229         /* Move to beginning of file. */
    230         pt_get_sof(&sof);
    231         caret_move(sof, true, true);
     214        tag_get_pt(&pane.caret_pos, &pt);
     215        sheet_place_tag(&doc.sh, &pt, &pane.sel_start);
    232216
    233217        /* Initial display */
     
    377361static void key_handle_ctrl(kbd_event_t const *ev)
    378362{
    379         spt_t pt;
    380363        switch (ev->key) {
    381364        case KC_Q:
     
    409392                selection_sel_all();
    410393                break;
     394        case KC_W:
     395                if (selection_active())
     396                        break;
     397                selection_sel_prev_word();
     398                selection_delete();
     399                break;
    411400        case KC_RIGHT:
    412                 caret_move_word_right(false);
     401                caret_move_word_right();
    413402                break;
    414403        case KC_LEFT:
    415                 caret_move_word_left(false);
    416                 break;
    417         case KC_L:
    418                 caret_go_to_line_ask();
    419                 break;
    420         case KC_F:
    421                 search_prompt(false);
    422                 break;
    423         case KC_N:
    424                 search_repeat();
    425                 break;
    426         case KC_HOME:
    427                 pt_get_sof(&pt);
    428                 caret_move(pt, false, true);
    429                 break;
    430         case KC_END:
    431                 pt_get_eof(&pt);
    432                 caret_move(pt, false, true);
     404                caret_move_word_left();
    433405                break;
    434406        default:
     
    439411static void key_handle_shift_ctrl(kbd_event_t const *ev)
    440412{
    441         spt_t pt;
    442413        switch(ev->key) {
    443414        case KC_LEFT:
    444                 caret_move_word_left(true);
     415                selection_sel_prev_word();
    445416                break;
    446417        case KC_RIGHT:
    447                 caret_move_word_right(true);
    448                 break;
    449         case KC_F:
    450                 search_prompt(true);
    451                 break;
    452         case KC_HOME:
    453                 pt_get_sof(&pt);
    454                 caret_move(pt, true, true);
    455                 break;
    456         case KC_END:
    457                 pt_get_eof(&pt);
    458                 caret_move(pt, true, true);
     418                selection_sel_next_word();
    459419                break;
    460420        default:
     
    463423}
    464424
    465 /** Move caret while preserving or resetting selection. */
    466 static void caret_move(spt_t new_caret_pt, bool select, bool update_ideal_column)
    467 {
    468         spt_t old_caret_pt, old_sel_pt;
     425static void key_handle_movement(unsigned int key, bool select)
     426{
     427        spt_t pt;
     428        spt_t caret_pt;
    469429        coord_t c_old, c_new;
    470430        bool had_sel;
    471431
    472432        /* Check if we had selection before. */
    473         tag_get_pt(&pane.caret_pos, &old_caret_pt);
    474         tag_get_pt(&pane.sel_start, &old_sel_pt);
    475         had_sel = !spt_equal(&old_caret_pt, &old_sel_pt);
    476 
    477         /* Place tag of the caret */
    478         sheet_remove_tag(doc.sh, &pane.caret_pos);
    479         sheet_place_tag(doc.sh, &new_caret_pt, &pane.caret_pos);
     433        tag_get_pt(&pane.caret_pos, &caret_pt);
     434        tag_get_pt(&pane.sel_start, &pt);
     435        had_sel = !spt_equal(&caret_pt, &pt);
     436
     437        switch (key) {
     438        case KC_LEFT:
     439                caret_move(0, -1, dir_before);
     440                break;
     441        case KC_RIGHT:
     442                caret_move(0, 0, dir_after);
     443                break;
     444        case KC_UP:
     445                caret_move(-1, 0, dir_before);
     446                break;
     447        case KC_DOWN:
     448                caret_move(+1, 0, dir_before);
     449                break;
     450        case KC_HOME:
     451                caret_move(0, -ED_INFTY, dir_before);
     452                break;
     453        case KC_END:
     454                caret_move(0, +ED_INFTY, dir_before);
     455                break;
     456        case KC_PAGE_UP:
     457                caret_move(-pane.rows, 0, dir_before);
     458                break;
     459        case KC_PAGE_DOWN:
     460                caret_move(+pane.rows, 0, dir_before);
     461                break;
     462        default:
     463                break;
     464        }
    480465
    481466        if (select == false) {
    482467                /* Move sel_start to the same point as caret. */
    483                 sheet_remove_tag(doc.sh, &pane.sel_start);
    484                 sheet_place_tag(doc.sh, &new_caret_pt, &pane.sel_start);
    485         }
    486 
    487         spt_get_coord(&new_caret_pt, &c_new);
     468                sheet_remove_tag(&doc.sh, &pane.sel_start);
     469                tag_get_pt(&pane.caret_pos, &pt);
     470                sheet_place_tag(&doc.sh, &pt, &pane.sel_start);
     471        }
     472
    488473        if (select) {
    489                 spt_get_coord(&old_caret_pt, &c_old);
     474                tag_get_pt(&pane.caret_pos, &pt);
     475                spt_get_coord(&caret_pt, &c_old);
     476                spt_get_coord(&pt, &c_new);
    490477
    491478                if (c_old.row == c_new.row)
     
    498485                pane.rflags |= REDRAW_TEXT;
    499486        }
    500        
    501         if (update_ideal_column)
    502                 pane.ideal_column = c_new.column;
    503        
    504         caret_update();
    505 }
    506 
    507 static void key_handle_movement(unsigned int key, bool select)
    508 {
    509         switch (key) {
    510         case KC_LEFT:
    511                 caret_move_relative(0, -1, dir_before, select);
    512                 break;
    513         case KC_RIGHT:
    514                 caret_move_relative(0, 0, dir_after, select);
    515                 break;
    516         case KC_UP:
    517                 caret_move_relative(-1, 0, dir_before, select);
    518                 break;
    519         case KC_DOWN:
    520                 caret_move_relative(+1, 0, dir_before, select);
    521                 break;
    522         case KC_HOME:
    523                 caret_move_relative(0, -ED_INFTY, dir_after, select);
    524                 break;
    525         case KC_END:
    526                 caret_move_relative(0, +ED_INFTY, dir_before, select);
    527                 break;
    528         case KC_PAGE_UP:
    529                 caret_move_relative(-pane.rows, 0, dir_before, select);
    530                 break;
    531         case KC_PAGE_DOWN:
    532                 caret_move_relative(+pane.rows, 0, dir_before, select);
    533                 break;
    534         default:
    535                 break;
    536         }
    537487}
    538488
     
    570520        char *fname;
    571521       
    572         fname = prompt("Save As", old_fname);
     522        fname = filename_prompt("Save As", old_fname);
    573523        if (fname == NULL) {
    574524                status_display("Save cancelled.");
     
    585535}
    586536
    587 /** Ask for a string. */
    588 static char *prompt(char const *prompt, char const *init_value)
     537/** Ask for a file name. */
     538static char *filename_prompt(char const *prompt, char const *init_value)
    589539{
    590540        kbd_event_t ev;
     
    707657
    708658        do {
    709                 sheet_copy_out(doc.sh, &sp, epos, buf, BUF_SIZE, &bep);
     659                sheet_copy_out(&doc.sh, &sp, epos, buf, BUF_SIZE, &bep);
    710660                bytes = str_size(buf);
    711661
     
    742692
    743693        while (true) {
    744                 sheet_copy_out(doc.sh, &sp, epos, &buf[bpos], buf_size - bpos,
     694                sheet_copy_out(&doc.sh, &sp, epos, &buf[bpos], buf_size - bpos,
    745695                    &bep);
    746696                bytes = str_size(&buf[bpos]);
     
    764714        int sh_rows, rows;
    765715
    766         sheet_get_num_rows(doc.sh, &sh_rows);
     716        sheet_get_num_rows(&doc.sh, &sh_rows);
    767717        rows = min(sh_rows - pane.sh_row + 1, pane.rows);
    768718
     
    834784                rbc.row = pane.sh_row + i;
    835785                rbc.column = pane.sh_column;
    836                 sheet_get_cell_pt(doc.sh, &rbc, dir_before, &rb);
     786                sheet_get_cell_pt(&doc.sh, &rbc, dir_before, &rb);
    837787
    838788                /* Ending point for row display */
    839789                rec.row = pane.sh_row + i;
    840790                rec.column = pane.sh_column + pane.columns;
    841                 sheet_get_cell_pt(doc.sh, &rec, dir_before, &re);
     791                sheet_get_cell_pt(&doc.sh, &rec, dir_before, &re);
    842792
    843793                /* Copy the text of the row to the buffer. */
    844                 sheet_copy_out(doc.sh, &rb, &re, row_buf, ROW_BUF_SIZE, &dep);
     794                sheet_copy_out(&doc.sh, &rb, &re, row_buf, ROW_BUF_SIZE, &dep);
    845795
    846796                /* Display text from the buffer. */
     
    892842                /* Fill until the end of display area. */
    893843
    894                 if ((unsigned)s_column - 1 < scr_columns)
    895                         fill = scr_columns - (s_column - 1);
     844                if (str_length(row_buf) < (unsigned) scr_columns)
     845                        fill = scr_columns - str_length(row_buf);
    896846                else
    897847                        fill = 0;
     
    911861        spt_t caret_pt;
    912862        coord_t coord;
    913         int last_row;
    914863
    915864        tag_get_pt(&pane.caret_pos, &caret_pt);
    916865        spt_get_coord(&caret_pt, &coord);
    917866
    918         sheet_get_num_rows(doc.sh, &last_row);
    919 
    920867        const char *fname = (doc.file_name != NULL) ? doc.file_name : "<unnamed>";
    921868
    922869        console_set_pos(con, 0, scr_rows - 1);
    923870        console_set_style(con, STYLE_INVERTED);
    924         int n = printf(" %d, %d (%d): File '%s'. Ctrl-Q Quit  Ctrl-S Save  "
    925             "Ctrl-E Save As", coord.row, coord.column, last_row, fname);
     871        int n = printf(" %d, %d: File '%s'. Ctrl-Q Quit  Ctrl-S Save  "
     872            "Ctrl-E Save As", coord.row, coord.column, fname);
    926873       
    927874        int pos = scr_columns - 1 - n;
     
    959906        cbuf[offs] = '\0';
    960907
    961         (void) sheet_insert(doc.sh, &pt, dir_before, cbuf);
     908        (void) sheet_insert(&doc.sh, &pt, dir_before, cbuf);
    962909
    963910        pane.rflags |= REDRAW_ROW;
     
    976923
    977924        coord.column -= 1;
    978         sheet_get_cell_pt(doc.sh, &coord, dir_before, &sp);
    979 
    980         (void) sheet_delete(doc.sh, &sp, &ep);
     925        sheet_get_cell_pt(&doc.sh, &coord, dir_before, &sp);
     926
     927        (void) sheet_delete(&doc.sh, &sp, &ep);
    981928
    982929        pane.rflags |= REDRAW_ROW;
     
    994941        spt_get_coord(&sp, &sc);
    995942
    996         sheet_get_cell_pt(doc.sh, &sc, dir_after, &ep);
     943        sheet_get_cell_pt(&doc.sh, &sc, dir_after, &ep);
    997944        spt_get_coord(&ep, &ec);
    998945
    999         (void) sheet_delete(doc.sh, &sp, &ep);
     946        (void) sheet_delete(&doc.sh, &sp, &ep);
    1000947
    1001948        pane.rflags |= REDRAW_ROW;
     
    1044991}
    1045992
    1046 /** Relatively move caret position.
     993/** Change the caret position.
    1047994 *
    1048995 * Moves caret relatively to the current position. Looking at the first
     
    1050997 * to a new character cell, and thus a new character. Then we either go to the
    1051998 * point before the the character or after it, depending on @a align_dir.
    1052  *
    1053  * @param select true if the selection tag should stay where it is
    1054999 */
    1055 static void caret_move_relative(int drow, int dcolumn, enum dir_spec align_dir,
    1056     bool select)
     1000static void caret_move(int drow, int dcolumn, enum dir_spec align_dir)
    10571001{
    10581002        spt_t pt;
     
    10721016                else {
    10731017                        coord.row--;
    1074                         sheet_get_row_width(doc.sh, coord.row, &coord.column);
     1018                        sheet_get_row_width(&doc.sh, coord.row, &coord.column);
    10751019                }
    10761020        }
    10771021        if (drow > 0) {
    1078                 sheet_get_num_rows(doc.sh, &num_rows);
     1022                sheet_get_num_rows(&doc.sh, &num_rows);
    10791023                if (coord.row > num_rows) coord.row = num_rows;
    10801024        }
     
    10891033         * coordinates. The character can be wider than one cell (e.g. tab).
    10901034         */
    1091         sheet_get_cell_pt(doc.sh, &coord, align_dir, &pt);
     1035        sheet_get_cell_pt(&doc.sh, &coord, align_dir, &pt);
     1036        sheet_remove_tag(&doc.sh, &pane.caret_pos);
     1037        sheet_place_tag(&doc.sh, &pt, &pane.caret_pos);
    10921038
    10931039        /* For non-vertical movement set the new value for @c ideal_column. */
    1094         caret_move(pt, select, !pure_vertical);
    1095 }
    1096 
    1097 /** Absolutely move caret position.
    1098  *
    1099  * Moves caret to a specified position. We get to a new character cell, and
    1100  * thus a new character. Then we either go to the point before the the character
    1101  * or after it, depending on @a align_dir.
    1102  *
    1103  * @param select true if the selection tag should stay where it is
    1104  */
    1105 static void caret_move_absolute(int row, int column, enum dir_spec align_dir,
    1106     bool select)
    1107 {
    1108         coord_t coord;
    1109         coord.row = row;
    1110         coord.column = column;
    1111        
     1040        if (!pure_vertical) {
     1041                spt_get_coord(&pt, &coord);
     1042                pane.ideal_column = coord.column;
     1043        }
     1044
     1045        caret_update();
     1046}
     1047
     1048static void caret_move_word_left(void)
     1049{
    11121050        spt_t pt;
    1113         sheet_get_cell_pt(doc.sh, &coord, align_dir, &pt);
    1114        
    1115         caret_move(pt, select, true);
    1116 }
    1117 
    1118 /** Find beginning of a word to the left of spt */
    1119 static spt_t pt_find_word_left(spt_t spt)
    1120 {
     1051
    11211052        do {
    1122                 spt_prev_char(spt, &spt);
    1123         } while (!pt_is_word_beginning(&spt));
    1124         return spt;
    1125 }
    1126 
    1127 /** Find beginning of a word to the right of spt */
    1128 static spt_t pt_find_word_right(spt_t spt)
    1129 {
     1053                caret_move(0, -1, dir_before);
     1054
     1055                tag_get_pt(&pane.caret_pos, &pt);
     1056
     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));
     1060
     1061        pane.rflags |= REDRAW_TEXT;
     1062}
     1063
     1064static void caret_move_word_right(void)
     1065{
     1066        spt_t pt;
     1067
    11301068        do {
    1131                 spt_next_char(spt, &spt);
    1132         } while (!pt_is_word_beginning(&spt));
    1133         return spt;
    1134 }
    1135 
    1136 static void caret_move_word_left(bool select)
    1137 {
    1138         spt_t pt;
    1139         tag_get_pt(&pane.caret_pos, &pt);
    1140         spt_t word_left = pt_find_word_left(pt);
    1141         caret_move(word_left, select, true);
    1142 }
    1143 
    1144 static void caret_move_word_right(bool select)
    1145 {
    1146         spt_t pt;
    1147         tag_get_pt(&pane.caret_pos, &pt);
    1148         spt_t word_right = pt_find_word_right(pt);
    1149         caret_move(word_right, select, true);
    1150 }
    1151 
    1152 /** Ask for line and go to it. */
    1153 static void caret_go_to_line_ask(void)
    1154 {
    1155         char *sline;
    1156        
    1157         sline = prompt("Go to line", "");
    1158         if (sline == NULL) {
    1159                 status_display("Go to line cancelled.");
    1160                 return;
    1161         }
    1162        
    1163         char *endptr;
    1164         int line = strtol(sline, &endptr, 10);
    1165         if (*endptr != '\0') {
    1166                 free(sline);
    1167                 status_display("Invalid number entered.");
    1168                 return;
    1169         }
    1170         free(sline);
    1171        
    1172         caret_move_absolute(line, pane.ideal_column, dir_before, false);
    1173 }
    1174 
    1175 /* Search operations */
    1176 static int search_spt_producer(void *data, wchar_t *ret)
    1177 {
    1178         assert(data != NULL);
    1179         assert(ret != NULL);
    1180         spt_t *spt = data;
    1181         *ret = spt_next_char(*spt, spt);
    1182         return EOK;
    1183 }
    1184 
    1185 static int search_spt_reverse_producer(void *data, wchar_t *ret)
    1186 {
    1187         assert(data != NULL);
    1188         assert(ret != NULL);
    1189         spt_t *spt = data;
    1190         *ret = spt_prev_char(*spt, spt);
    1191         return EOK;
    1192 }
    1193 
    1194 static int search_spt_mark(void *data, void **mark)
    1195 {
    1196         assert(data != NULL);
    1197         assert(mark != NULL);
    1198         spt_t *spt = data;
    1199         spt_t *new = calloc(1, sizeof(spt_t));
    1200         *mark = new;
    1201         if (new == NULL)
    1202                 return ENOMEM;
    1203         *new = *spt;
    1204         return EOK;
    1205 }
    1206 
    1207 static void search_spt_mark_free(void *data)
    1208 {
    1209         free(data);
    1210 }
    1211 
    1212 static search_ops_t search_spt_ops = {
    1213         .equals = char_exact_equals,
    1214         .producer = search_spt_producer,
    1215         .mark = search_spt_mark,
    1216         .mark_free = search_spt_mark_free,
    1217 };
    1218 
    1219 static search_ops_t search_spt_reverse_ops = {
    1220         .equals = char_exact_equals,
    1221         .producer = search_spt_reverse_producer,
    1222         .mark = search_spt_mark,
    1223         .mark_free = search_spt_mark_free,
    1224 };
    1225 
    1226 /** Ask for line and go to it. */
    1227 static void search_prompt(bool reverse)
    1228 {
    1229         char *pattern;
    1230        
    1231         const char *prompt_text = "Find next";
    1232         if (reverse)
    1233                 prompt_text = "Find previous";
    1234        
    1235         const char *default_value = "";
    1236         if (pane.previous_search)
    1237                 default_value = pane.previous_search;
    1238        
    1239         pattern = prompt(prompt_text, default_value);
    1240         if (pattern == NULL) {
    1241                 status_display("Search cancelled.");
    1242                 return;
    1243         }
    1244        
    1245         if (pane.previous_search)
    1246                 free(pane.previous_search);
    1247         pane.previous_search = pattern;
    1248         pane.previous_search_reverse = reverse;
    1249        
    1250         search(pattern, reverse);
    1251 }
    1252 
    1253 static void search_repeat(void)
    1254 {
    1255         if (pane.previous_search == NULL) {
    1256                 status_display("No previous search to repeat.");
    1257                 return;
    1258         }
    1259        
    1260         search(pane.previous_search, pane.previous_search_reverse);
    1261 }
    1262 
    1263 static void search(char *pattern, bool reverse)
    1264 {
    1265         status_display("Searching...");
    1266        
    1267         spt_t sp, producer_pos;
    1268         tag_get_pt(&pane.caret_pos, &sp);
    1269        
    1270         /* Start searching on the position before/after caret */
    1271         if (!reverse) {
    1272                 spt_next_char(sp, &sp);
    1273         }
    1274         else {
    1275                 spt_prev_char(sp, &sp);
    1276         }
    1277         producer_pos = sp;
    1278        
    1279         search_ops_t ops = search_spt_ops;
    1280         if (reverse)
    1281                 ops = search_spt_reverse_ops;
    1282        
    1283         search_t *search = search_init(pattern, &producer_pos, ops, reverse);
    1284         if (search == NULL) {
    1285                 status_display("Failed initializing search.");
    1286                 return;
    1287         }
    1288        
    1289         match_t match;
    1290         int rc = search_next_match(search, &match);
    1291         if (rc != EOK) {
    1292                 status_display("Failed searching.");
    1293                 search_fini(search);
    1294         }
    1295        
    1296         if (match.end) {
    1297                 status_display("Match found.");
    1298                 assert(match.end != NULL);
    1299                 spt_t *end = match.end;
    1300                 caret_move(*end, false, true);
    1301                 while (match.length > 0) {
    1302                         match.length--;
    1303                         if (reverse) {
    1304                                 spt_next_char(*end, end);
    1305                         }
    1306                         else {
    1307                                 spt_prev_char(*end, end);
    1308                         }
    1309                 }
    1310                 caret_move(*end, true, true);
    1311                 free(end);
    1312         }
    1313         else {
    1314                 status_display("Not found.");
    1315         }
    1316        
    1317         search_fini(search);
     1069                caret_move(0, 0, dir_after);
     1070
     1071                tag_get_pt(&pane.caret_pos, &pt);
     1072
     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));
     1076
     1077        pane.rflags |= REDRAW_TEXT;
    13181078}
    13191079
     
    13551115
    13561116        if (rel < 0)
    1357                 sheet_delete(doc.sh, &pa, &pb);
     1117                sheet_delete(&doc.sh, &pa, &pb);
    13581118        else
    1359                 sheet_delete(doc.sh, &pb, &pa);
     1119                sheet_delete(&doc.sh, &pb, &pa);
    13601120
    13611121        if (ca.row == cb.row)
     
    13791139static void selection_sel_range(spt_t pa, spt_t pb)
    13801140{
    1381         sheet_remove_tag(doc.sh, &pane.sel_start);
    1382         sheet_place_tag(doc.sh, &pa, &pane.sel_start);
    1383         sheet_remove_tag(doc.sh, &pane.caret_pos);
    1384         sheet_place_tag(doc.sh, &pb, &pane.caret_pos);
     1141        sheet_remove_tag(&doc.sh, &pane.sel_start);
     1142        sheet_place_tag(&doc.sh, &pa, &pane.sel_start);
     1143        sheet_remove_tag(&doc.sh, &pane.caret_pos);
     1144        sheet_place_tag(&doc.sh, &pb, &pane.caret_pos);
    13851145
    13861146        pane.rflags |= REDRAW_TEXT;
    13871147        caret_update();
     1148}
     1149
     1150/** Add the previous word to the selection */
     1151static void selection_sel_prev_word(void)
     1152{
     1153        spt_t cpt, wpt, spt, ept;
     1154
     1155        selection_get_points(&spt, &ept);
     1156
     1157        tag_get_pt(&pane.caret_pos, &cpt);
     1158        caret_move_word_left();
     1159        tag_get_pt(&pane.caret_pos, &wpt);
     1160
     1161        if (spt_cmp(&spt, &cpt) == 0)
     1162                selection_sel_range(ept, wpt);
     1163        else
     1164                selection_sel_range(spt, wpt);
     1165}
     1166
     1167/** Add the next word to the selection */
     1168static void selection_sel_next_word(void)
     1169{
     1170        spt_t cpt, wpt, spt, ept;
     1171
     1172        selection_get_points(&spt, &ept);
     1173
     1174        tag_get_pt(&pane.caret_pos, &cpt);
     1175        caret_move_word_right();
     1176        tag_get_pt(&pane.caret_pos, &wpt);
     1177
     1178        if (spt_cmp(&ept, &cpt) == 0)
     1179                selection_sel_range(spt, wpt);
     1180        else
     1181                selection_sel_range(ept, wpt);
    13881182}
    13891183
     
    14311225
    14321226        coord.row = coord.column = 1;
    1433         sheet_get_cell_pt(doc.sh, &coord, dir_before, pt);
     1227        sheet_get_cell_pt(&doc.sh, &coord, dir_before, pt);
    14341228}
    14351229
     
    14401234        int num_rows;
    14411235
    1442         sheet_get_num_rows(doc.sh, &num_rows);
     1236        sheet_get_num_rows(&doc.sh, &num_rows);
    14431237        coord.row = num_rows + 1;
    14441238        coord.column = 1;
    14451239
    1446         sheet_get_cell_pt(doc.sh, &coord, dir_after, pt);
     1240        sheet_get_cell_pt(&doc.sh, &coord, dir_after, pt);
    14471241}
    14481242
     
    14551249        coord.column = 1;
    14561250
    1457         sheet_get_cell_pt(doc.sh, &coord, dir_before, spt);
     1251        sheet_get_cell_pt(&doc.sh, &coord, dir_before, spt);
    14581252}
    14591253
     
    14651259
    14661260        spt_get_coord(cpt, &coord);
    1467         sheet_get_row_width(doc.sh, coord.row, &row_width);
     1261        sheet_get_row_width(&doc.sh, coord.row, &row_width);
    14681262        coord.column = row_width - 1;
    14691263
    1470         sheet_get_cell_pt(doc.sh, &coord, dir_after, ept);
     1264        sheet_get_cell_pt(&doc.sh, &coord, dir_after, ept);
    14711265}
    14721266
     
    14941288
    14951289        coord.column -= 1;
    1496         sheet_get_cell_pt(doc.sh, &coord, dir_before, &lp);
     1290        sheet_get_cell_pt(&doc.sh, &coord, dir_before, &lp);
    14971291
    14981292        return pt_is_delimiter(&lp)
     
    15161310
    15171311        coord.column += 1;
    1518         sheet_get_cell_pt(doc.sh, &coord, dir_after, &rp);
     1312        sheet_get_cell_pt(&doc.sh, &coord, dir_after, &rp);
    15191313
    15201314        ch = range_get_str(pt, &rp);
     
    15421336
    15431337        coord.column += 1;
    1544         sheet_get_cell_pt(doc.sh, &coord, dir_after, &rp);
     1338        sheet_get_cell_pt(&doc.sh, &coord, dir_after, &rp);
    15451339
    15461340        ch = range_get_str(pt, &rp);
Note: See TracChangeset for help on using the changeset viewer.