Ignore:
File:
1 edited

Legend:

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

    rdd13349 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
     
    111106#define BUF_SIZE 64
    112107#define TAB_WIDTH 8
     108#define ED_INFTY 65536
    113109
    114110/** Maximum filename length that can be entered. */
     
    130126static int file_save_range(char const *fname, spt_t const *spos,
    131127    spt_t const *epos);
     128static char *filename_prompt(char const *prompt, char const *init_value);
    132129static char *range_get_str(spt_t const *spos, spt_t const *epos);
    133 
    134 static char *prompt(char const *prompt, char const *init_value);
    135130
    136131static void pane_text_display(void);
     
    144139static void delete_char_after(void);
    145140static void caret_update(void);
    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);
    151 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);
    152144
    153145static bool selection_active(void);
    154146static void selection_sel_all(void);
    155147static void selection_sel_range(spt_t pa, spt_t pb);
     148static void selection_sel_prev_word(void);
     149static void selection_sel_next_word(void);
    156150static void selection_get_points(spt_t *pa, spt_t *pb);
    157151static void selection_delete(void);
    158152static void selection_copy(void);
    159153static void insert_clipboard_data(void);
    160 
    161 static void search(char *pattern, bool reverse);
    162 static void search_prompt(bool reverse);
    163 static void search_repeat(void);
    164154
    165155static void pt_get_sof(spt_t *pt);
     
    170160static bool pt_is_delimiter(spt_t *pt);
    171161static 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 
    175162static int tag_cmp(tag_t const *a, tag_t const *b);
    176163static int spt_cmp(spt_t const *a, spt_t const *b);
     
    183170{
    184171        kbd_event_t ev;
     172        coord_t coord;
    185173        bool new_file;
    186         int rc;
     174
     175        spt_t pt;
    187176
    188177        con = console_init(stdin, stdout);
     
    197186
    198187        /* Start with an empty sheet. */
    199         rc = sheet_create(&doc.sh);
    200         if (rc != EOK) {
    201                 printf("Out of memory.\n");
    202                 return -1;
    203         }
     188        sheet_init(&doc.sh);
    204189
    205190        /* Place caret at the beginning of file. */
    206         spt_t sof;
    207         pt_get_sof(&sof);
    208         sheet_place_tag(doc.sh, &sof, &pane.caret_pos);
    209         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;
    210195
    211196        if (argc == 2) {
     
    223208                new_file = true;
    224209
     210        /* Move to beginning of file. */
     211        caret_move(-ED_INFTY, -ED_INFTY, dir_before);
     212
    225213        /* Place selection start tag. */
    226         sheet_place_tag(doc.sh, &sof, &pane.sel_start);
    227 
    228         /* Move to beginning of file. */
    229         pt_get_sof(&sof);
    230         caret_move(sof, true, true);
     214        tag_get_pt(&pane.caret_pos, &pt);
     215        sheet_place_tag(&doc.sh, &pt, &pane.sel_start);
    231216
    232217        /* Initial display */
     
    376361static void key_handle_ctrl(kbd_event_t const *ev)
    377362{
    378         spt_t pt;
    379363        switch (ev->key) {
    380364        case KC_Q:
     
    408392                selection_sel_all();
    409393                break;
     394        case KC_W:
     395                if (selection_active())
     396                        break;
     397                selection_sel_prev_word();
     398                selection_delete();
     399                break;
    410400        case KC_RIGHT:
    411                 caret_move_word_right(false);
     401                caret_move_word_right();
    412402                break;
    413403        case KC_LEFT:
    414                 caret_move_word_left(false);
    415                 break;
    416         case KC_L:
    417                 caret_go_to_line_ask();
    418                 break;
    419         case KC_F:
    420                 search_prompt(false);
    421                 break;
    422         case KC_N:
    423                 search_repeat();
    424                 break;
    425         case KC_HOME:
    426                 pt_get_sof(&pt);
    427                 caret_move(pt, false, true);
    428                 break;
    429         case KC_END:
    430                 pt_get_eof(&pt);
    431                 caret_move(pt, false, true);
     404                caret_move_word_left();
    432405                break;
    433406        default:
     
    438411static void key_handle_shift_ctrl(kbd_event_t const *ev)
    439412{
    440         spt_t pt;
    441413        switch(ev->key) {
    442414        case KC_LEFT:
    443                 caret_move_word_left(true);
     415                selection_sel_prev_word();
    444416                break;
    445417        case KC_RIGHT:
    446                 caret_move_word_right(true);
    447                 break;
    448         case KC_F:
    449                 search_prompt(true);
    450                 break;
    451         case KC_HOME:
    452                 pt_get_sof(&pt);
    453                 caret_move(pt, true, true);
    454                 break;
    455         case KC_END:
    456                 pt_get_eof(&pt);
    457                 caret_move(pt, true, true);
     418                selection_sel_next_word();
    458419                break;
    459420        default:
     
    462423}
    463424
    464 /** Move caret while preserving or resetting selection. */
    465 static void caret_move(spt_t new_caret_pt, bool select, bool update_ideal_column)
    466 {
    467         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;
    468429        coord_t c_old, c_new;
    469430        bool had_sel;
    470431
    471432        /* Check if we had selection before. */
    472         tag_get_pt(&pane.caret_pos, &old_caret_pt);
    473         tag_get_pt(&pane.sel_start, &old_sel_pt);
    474         had_sel = !spt_equal(&old_caret_pt, &old_sel_pt);
    475 
    476         /* Place tag of the caret */
    477         sheet_remove_tag(doc.sh, &pane.caret_pos);
    478         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        }
    479465
    480466        if (select == false) {
    481467                /* Move sel_start to the same point as caret. */
    482                 sheet_remove_tag(doc.sh, &pane.sel_start);
    483                 sheet_place_tag(doc.sh, &new_caret_pt, &pane.sel_start);
    484         }
    485 
    486         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
    487473        if (select) {
    488                 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);
    489477
    490478                if (c_old.row == c_new.row)
     
    497485                pane.rflags |= REDRAW_TEXT;
    498486        }
    499        
    500         if (update_ideal_column)
    501                 pane.ideal_column = c_new.column;
    502        
    503         caret_update();
    504 }
    505 
    506 static void key_handle_movement(unsigned int key, bool select)
    507 {
    508         spt_t pt;
    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                 tag_get_pt(&pane.caret_pos, &pt);
    524                 pt_get_sol(&pt, &pt);
    525                 caret_move(pt, select, true);
    526                 break;
    527         case KC_END:
    528                 tag_get_pt(&pane.caret_pos, &pt);
    529                 pt_get_eol(&pt, &pt);
    530                 caret_move(pt, select, true);
    531                 break;
    532         case KC_PAGE_UP:
    533                 caret_move_relative(-pane.rows, 0, dir_before, select);
    534                 break;
    535         case KC_PAGE_DOWN:
    536                 caret_move_relative(+pane.rows, 0, dir_before, select);
    537                 break;
    538         default:
    539                 break;
    540         }
    541487}
    542488
     
    574520        char *fname;
    575521       
    576         fname = prompt("Save As", old_fname);
     522        fname = filename_prompt("Save As", old_fname);
    577523        if (fname == NULL) {
    578524                status_display("Save cancelled.");
     
    589535}
    590536
    591 /** Ask for a string. */
    592 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)
    593539{
    594540        kbd_event_t ev;
     
    711657
    712658        do {
    713                 sheet_copy_out(doc.sh, &sp, epos, buf, BUF_SIZE, &bep);
     659                sheet_copy_out(&doc.sh, &sp, epos, buf, BUF_SIZE, &bep);
    714660                bytes = str_size(buf);
    715661
     
    746692
    747693        while (true) {
    748                 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,
    749695                    &bep);
    750696                bytes = str_size(&buf[bpos]);
     
    768714        int sh_rows, rows;
    769715
    770         sheet_get_num_rows(doc.sh, &sh_rows);
     716        sheet_get_num_rows(&doc.sh, &sh_rows);
    771717        rows = min(sh_rows - pane.sh_row + 1, pane.rows);
    772718
     
    838784                rbc.row = pane.sh_row + i;
    839785                rbc.column = pane.sh_column;
    840                 sheet_get_cell_pt(doc.sh, &rbc, dir_before, &rb);
     786                sheet_get_cell_pt(&doc.sh, &rbc, dir_before, &rb);
    841787
    842788                /* Ending point for row display */
    843789                rec.row = pane.sh_row + i;
    844790                rec.column = pane.sh_column + pane.columns;
    845                 sheet_get_cell_pt(doc.sh, &rec, dir_before, &re);
     791                sheet_get_cell_pt(&doc.sh, &rec, dir_before, &re);
    846792
    847793                /* Copy the text of the row to the buffer. */
    848                 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);
    849795
    850796                /* Display text from the buffer. */
     
    896842                /* Fill until the end of display area. */
    897843
    898                 if ((unsigned)s_column - 1 < scr_columns)
    899                         fill = scr_columns - (s_column - 1);
     844                if (str_length(row_buf) < (unsigned) scr_columns)
     845                        fill = scr_columns - str_length(row_buf);
    900846                else
    901847                        fill = 0;
     
    915861        spt_t caret_pt;
    916862        coord_t coord;
    917         int last_row;
    918863
    919864        tag_get_pt(&pane.caret_pos, &caret_pt);
    920865        spt_get_coord(&caret_pt, &coord);
    921866
    922         sheet_get_num_rows(doc.sh, &last_row);
    923 
    924867        const char *fname = (doc.file_name != NULL) ? doc.file_name : "<unnamed>";
    925868
    926869        console_set_pos(con, 0, scr_rows - 1);
    927870        console_set_style(con, STYLE_INVERTED);
    928         int n = printf(" %d, %d (%d): File '%s'. Ctrl-Q Quit  Ctrl-S Save  "
    929             "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);
    930873       
    931874        int pos = scr_columns - 1 - n;
     
    963906        cbuf[offs] = '\0';
    964907
    965         (void) sheet_insert(doc.sh, &pt, dir_before, cbuf);
     908        (void) sheet_insert(&doc.sh, &pt, dir_before, cbuf);
    966909
    967910        pane.rflags |= REDRAW_ROW;
     
    980923
    981924        coord.column -= 1;
    982         sheet_get_cell_pt(doc.sh, &coord, dir_before, &sp);
    983 
    984         (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);
    985928
    986929        pane.rflags |= REDRAW_ROW;
     
    998941        spt_get_coord(&sp, &sc);
    999942
    1000         sheet_get_cell_pt(doc.sh, &sc, dir_after, &ep);
     943        sheet_get_cell_pt(&doc.sh, &sc, dir_after, &ep);
    1001944        spt_get_coord(&ep, &ec);
    1002945
    1003         (void) sheet_delete(doc.sh, &sp, &ep);
     946        (void) sheet_delete(&doc.sh, &sp, &ep);
    1004947
    1005948        pane.rflags |= REDRAW_ROW;
     
    1048991}
    1049992
    1050 /** Relatively move caret position.
     993/** Change the caret position.
    1051994 *
    1052995 * Moves caret relatively to the current position. Looking at the first
     
    1054997 * to a new character cell, and thus a new character. Then we either go to the
    1055998 * point before the the character or after it, depending on @a align_dir.
    1056  *
    1057  * @param select true if the selection tag should stay where it is
    1058999 */
    1059 static void caret_move_relative(int drow, int dcolumn, enum dir_spec align_dir,
    1060     bool select)
     1000static void caret_move(int drow, int dcolumn, enum dir_spec align_dir)
    10611001{
    10621002        spt_t pt;
     
    10761016                else {
    10771017                        coord.row--;
    1078                         sheet_get_row_width(doc.sh, coord.row, &coord.column);
     1018                        sheet_get_row_width(&doc.sh, coord.row, &coord.column);
    10791019                }
    10801020        }
    10811021        if (drow > 0) {
    1082                 sheet_get_num_rows(doc.sh, &num_rows);
     1022                sheet_get_num_rows(&doc.sh, &num_rows);
    10831023                if (coord.row > num_rows) coord.row = num_rows;
    10841024        }
     
    10931033         * coordinates. The character can be wider than one cell (e.g. tab).
    10941034         */
    1095         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);
    10961038
    10971039        /* For non-vertical movement set the new value for @c ideal_column. */
    1098         caret_move(pt, select, !pure_vertical);
    1099 }
    1100 
    1101 /** Absolutely move caret position.
    1102  *
    1103  * Moves caret to a specified position. We get to a new character cell, and
    1104  * thus a new character. Then we either go to the point before the the character
    1105  * or after it, depending on @a align_dir.
    1106  *
    1107  * @param select true if the selection tag should stay where it is
    1108  */
    1109 static void caret_move_absolute(int row, int column, enum dir_spec align_dir,
    1110     bool select)
    1111 {
    1112         coord_t coord;
    1113         coord.row = row;
    1114         coord.column = column;
    1115        
     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{
    11161050        spt_t pt;
    1117         sheet_get_cell_pt(doc.sh, &coord, align_dir, &pt);
    1118        
    1119         caret_move(pt, select, true);
    1120 }
    1121 
    1122 /** Find beginning of a word to the left of spt */
    1123 static spt_t pt_find_word_left(spt_t spt)
    1124 {
     1051
    11251052        do {
    1126                 spt_prev_char(spt, &spt);
    1127         } while (!pt_is_word_beginning(&spt));
    1128         return spt;
    1129 }
    1130 
    1131 /** Find beginning of a word to the right of spt */
    1132 static spt_t pt_find_word_right(spt_t spt)
    1133 {
     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
    11341068        do {
    1135                 spt_next_char(spt, &spt);
    1136         } while (!pt_is_word_beginning(&spt));
    1137         return spt;
    1138 }
    1139 
    1140 static void caret_move_word_left(bool select)
    1141 {
    1142         spt_t pt;
    1143         tag_get_pt(&pane.caret_pos, &pt);
    1144         spt_t word_left = pt_find_word_left(pt);
    1145         caret_move(word_left, select, true);
    1146 }
    1147 
    1148 static void caret_move_word_right(bool select)
    1149 {
    1150         spt_t pt;
    1151         tag_get_pt(&pane.caret_pos, &pt);
    1152         spt_t word_right = pt_find_word_right(pt);
    1153         caret_move(word_right, select, true);
    1154 }
    1155 
    1156 /** Ask for line and go to it. */
    1157 static void caret_go_to_line_ask(void)
    1158 {
    1159         char *sline;
    1160        
    1161         sline = prompt("Go to line", "");
    1162         if (sline == NULL) {
    1163                 status_display("Go to line cancelled.");
    1164                 return;
    1165         }
    1166        
    1167         char *endptr;
    1168         int line = strtol(sline, &endptr, 10);
    1169         if (*endptr != '\0') {
    1170                 free(sline);
    1171                 status_display("Invalid number entered.");
    1172                 return;
    1173         }
    1174         free(sline);
    1175        
    1176         caret_move_absolute(line, pane.ideal_column, dir_before, false);
    1177 }
    1178 
    1179 /* Search operations */
    1180 static int search_spt_producer(void *data, wchar_t *ret)
    1181 {
    1182         assert(data != NULL);
    1183         assert(ret != NULL);
    1184         spt_t *spt = data;
    1185         *ret = spt_next_char(*spt, spt);
    1186         return EOK;
    1187 }
    1188 
    1189 static int search_spt_reverse_producer(void *data, wchar_t *ret)
    1190 {
    1191         assert(data != NULL);
    1192         assert(ret != NULL);
    1193         spt_t *spt = data;
    1194         *ret = spt_prev_char(*spt, spt);
    1195         return EOK;
    1196 }
    1197 
    1198 static int search_spt_mark(void *data, void **mark)
    1199 {
    1200         assert(data != NULL);
    1201         assert(mark != NULL);
    1202         spt_t *spt = data;
    1203         spt_t *new = calloc(1, sizeof(spt_t));
    1204         *mark = new;
    1205         if (new == NULL)
    1206                 return ENOMEM;
    1207         *new = *spt;
    1208         return EOK;
    1209 }
    1210 
    1211 static void search_spt_mark_free(void *data)
    1212 {
    1213         free(data);
    1214 }
    1215 
    1216 static search_ops_t search_spt_ops = {
    1217         .equals = char_exact_equals,
    1218         .producer = search_spt_producer,
    1219         .mark = search_spt_mark,
    1220         .mark_free = search_spt_mark_free,
    1221 };
    1222 
    1223 static search_ops_t search_spt_reverse_ops = {
    1224         .equals = char_exact_equals,
    1225         .producer = search_spt_reverse_producer,
    1226         .mark = search_spt_mark,
    1227         .mark_free = search_spt_mark_free,
    1228 };
    1229 
    1230 /** Ask for line and go to it. */
    1231 static void search_prompt(bool reverse)
    1232 {
    1233         char *pattern;
    1234        
    1235         const char *prompt_text = "Find next";
    1236         if (reverse)
    1237                 prompt_text = "Find previous";
    1238        
    1239         const char *default_value = "";
    1240         if (pane.previous_search)
    1241                 default_value = pane.previous_search;
    1242        
    1243         pattern = prompt(prompt_text, default_value);
    1244         if (pattern == NULL) {
    1245                 status_display("Search cancelled.");
    1246                 return;
    1247         }
    1248        
    1249         if (pane.previous_search)
    1250                 free(pane.previous_search);
    1251         pane.previous_search = pattern;
    1252         pane.previous_search_reverse = reverse;
    1253        
    1254         search(pattern, reverse);
    1255 }
    1256 
    1257 static void search_repeat(void)
    1258 {
    1259         if (pane.previous_search == NULL) {
    1260                 status_display("No previous search to repeat.");
    1261                 return;
    1262         }
    1263        
    1264         search(pane.previous_search, pane.previous_search_reverse);
    1265 }
    1266 
    1267 static void search(char *pattern, bool reverse)
    1268 {
    1269         status_display("Searching...");
    1270        
    1271         spt_t sp, producer_pos;
    1272         tag_get_pt(&pane.caret_pos, &sp);
    1273        
    1274         /* Start searching on the position before/after caret */
    1275         if (!reverse) {
    1276                 spt_next_char(sp, &sp);
    1277         }
    1278         else {
    1279                 spt_prev_char(sp, &sp);
    1280         }
    1281         producer_pos = sp;
    1282        
    1283         search_ops_t ops = search_spt_ops;
    1284         if (reverse)
    1285                 ops = search_spt_reverse_ops;
    1286        
    1287         search_t *search = search_init(pattern, &producer_pos, ops, reverse);
    1288         if (search == NULL) {
    1289                 status_display("Failed initializing search.");
    1290                 return;
    1291         }
    1292        
    1293         match_t match;
    1294         int rc = search_next_match(search, &match);
    1295         if (rc != EOK) {
    1296                 status_display("Failed searching.");
    1297                 search_fini(search);
    1298         }
    1299        
    1300         if (match.end) {
    1301                 status_display("Match found.");
    1302                 assert(match.end != NULL);
    1303                 spt_t *end = match.end;
    1304                 caret_move(*end, false, true);
    1305                 while (match.length > 0) {
    1306                         match.length--;
    1307                         if (reverse) {
    1308                                 spt_next_char(*end, end);
    1309                         }
    1310                         else {
    1311                                 spt_prev_char(*end, end);
    1312                         }
    1313                 }
    1314                 caret_move(*end, true, true);
    1315                 free(end);
    1316         }
    1317         else {
    1318                 status_display("Not found.");
    1319         }
    1320        
    1321         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;
    13221078}
    13231079
     
    13591115
    13601116        if (rel < 0)
    1361                 sheet_delete(doc.sh, &pa, &pb);
     1117                sheet_delete(&doc.sh, &pa, &pb);
    13621118        else
    1363                 sheet_delete(doc.sh, &pb, &pa);
     1119                sheet_delete(&doc.sh, &pb, &pa);
    13641120
    13651121        if (ca.row == cb.row)
     
    13831139static void selection_sel_range(spt_t pa, spt_t pb)
    13841140{
    1385         sheet_remove_tag(doc.sh, &pane.sel_start);
    1386         sheet_place_tag(doc.sh, &pa, &pane.sel_start);
    1387         sheet_remove_tag(doc.sh, &pane.caret_pos);
    1388         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);
    13891145
    13901146        pane.rflags |= REDRAW_TEXT;
    13911147        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);
    13921182}
    13931183
     
    14351225
    14361226        coord.row = coord.column = 1;
    1437         sheet_get_cell_pt(doc.sh, &coord, dir_before, pt);
     1227        sheet_get_cell_pt(&doc.sh, &coord, dir_before, pt);
    14381228}
    14391229
     
    14441234        int num_rows;
    14451235
    1446         sheet_get_num_rows(doc.sh, &num_rows);
     1236        sheet_get_num_rows(&doc.sh, &num_rows);
    14471237        coord.row = num_rows + 1;
    14481238        coord.column = 1;
    14491239
    1450         sheet_get_cell_pt(doc.sh, &coord, dir_after, pt);
     1240        sheet_get_cell_pt(&doc.sh, &coord, dir_after, pt);
    14511241}
    14521242
     
    14591249        coord.column = 1;
    14601250
    1461         sheet_get_cell_pt(doc.sh, &coord, dir_before, spt);
     1251        sheet_get_cell_pt(&doc.sh, &coord, dir_before, spt);
    14621252}
    14631253
     
    14691259
    14701260        spt_get_coord(cpt, &coord);
    1471         sheet_get_row_width(doc.sh, coord.row, &row_width);
     1261        sheet_get_row_width(&doc.sh, coord.row, &row_width);
    14721262        coord.column = row_width - 1;
    14731263
    1474         sheet_get_cell_pt(doc.sh, &coord, dir_after, ept);
     1264        sheet_get_cell_pt(&doc.sh, &coord, dir_after, ept);
    14751265}
    14761266
     
    14981288
    14991289        coord.column -= 1;
    1500         sheet_get_cell_pt(doc.sh, &coord, dir_before, &lp);
     1290        sheet_get_cell_pt(&doc.sh, &coord, dir_before, &lp);
    15011291
    15021292        return pt_is_delimiter(&lp)
     
    15201310
    15211311        coord.column += 1;
    1522         sheet_get_cell_pt(doc.sh, &coord, dir_after, &rp);
     1312        sheet_get_cell_pt(&doc.sh, &coord, dir_after, &rp);
    15231313
    15241314        ch = range_get_str(pt, &rp);
     
    15461336
    15471337        coord.column += 1;
    1548         sheet_get_cell_pt(doc.sh, &coord, dir_after, &rp);
     1338        sheet_get_cell_pt(&doc.sh, &coord, dir_after, &rp);
    15491339
    15501340        ch = range_get_str(pt, &rp);
Note: See TracChangeset for help on using the changeset viewer.