diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-07-23 22:15:25 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-07-23 22:15:25 +0200 |
commit | c3328169d5566b97a6a6921067017e4369dd7cd6 (patch) | |
tree | 88ffb8f039efc23a461181aeae7b0bdf606b2404 | |
parent | c61a48d25995e5ee2a3813f64c531b91bb23e9b9 (diff) |
patch 8.1.1736: viminfo support is spread outv8.1.1736
Problem: Viminfo support is spread out.
Solution: Move more viminfo code to viminfo.c. (Yegappan Lakshmanan,
closes #4717) Reorder code to make most functions static.
-rw-r--r-- | src/ex_cmds.c | 25 | ||||
-rw-r--r-- | src/fileio.c | 22 | ||||
-rw-r--r-- | src/ops.c | 470 | ||||
-rw-r--r-- | src/option.c | 43 | ||||
-rw-r--r-- | src/proto/ex_cmds.pro | 4 | ||||
-rw-r--r-- | src/proto/ops.pro | 11 | ||||
-rw-r--r-- | src/proto/option.pro | 2 | ||||
-rw-r--r-- | src/proto/search.pro | 4 | ||||
-rw-r--r-- | src/proto/viminfo.pro | 15 | ||||
-rw-r--r-- | src/search.c | 153 | ||||
-rw-r--r-- | src/structs.h | 55 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/viminfo.c | 2726 |
13 files changed, 1793 insertions, 1739 deletions
diff --git a/src/ex_cmds.c b/src/ex_cmds.c index 47d1998e8a..9e093ee1b3 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -5085,24 +5085,23 @@ global_exe(char_u *cmd) } #ifdef FEAT_VIMINFO - int -read_viminfo_sub_string(vir_T *virp, int force) +/* + * Get the previous substitute pattern. + */ + char_u * +get_old_sub(void) { - if (force) - vim_free(old_sub); - if (force || old_sub == NULL) - old_sub = viminfo_readstring(virp, 1, TRUE); - return viminfo_readline(virp); + return old_sub; } +/* + * Set the previous substitute pattern. "val" must be allocated. + */ void -write_viminfo_sub_string(FILE *fp) +set_old_sub(char_u *val) { - if (get_viminfo_parameter('/') != 0 && old_sub != NULL) - { - fputs(_("\n# Last Substitute String:\n$"), fp); - viminfo_writestring(fp, old_sub); - } + vim_free(old_sub); + old_sub = val; } #endif // FEAT_VIMINFO diff --git a/src/fileio.c b/src/fileio.c index 03183255e3..5e79870adb 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -31,9 +31,6 @@ static char_u *next_fenc(char_u **pp); #ifdef FEAT_EVAL static char_u *readfile_charconvert(char_u *fname, char_u *fenc, int *fdp); #endif -#ifdef FEAT_VIMINFO -static void check_marks_read(void); -#endif #ifdef FEAT_CRYPT static char_u *check_for_cryptkey(char_u *cryptkey, char_u *ptr, long *sizep, off_T *filesizep, int newfile, char_u *fname, int *did_ask); #endif @@ -2855,25 +2852,6 @@ readfile_charconvert( } #endif - -#ifdef FEAT_VIMINFO -/* - * Read marks for the current buffer from the viminfo file, when we support - * buffer marks and the buffer has a name. - */ - static void -check_marks_read(void) -{ - if (!curbuf->b_marks_read && get_viminfo_parameter('\'') > 0 - && curbuf->b_ffname != NULL) - read_viminfo(NULL, VIF_WANT_MARKS); - - /* Always set b_marks_read; needed when 'viminfo' is changed to include - * the ' parameter after opening a buffer. */ - curbuf->b_marks_read = TRUE; -} -#endif - #if defined(FEAT_CRYPT) || defined(PROTO) /* * Check for magic number used for encryption. Applies to the current buffer. @@ -23,45 +23,6 @@ * 37 = Selection register '*'. Only if FEAT_CLIPBOARD defined * 38 = Clipboard register '+'. Only if FEAT_CLIPBOARD and FEAT_X11 defined */ -/* - * Symbolic names for some registers. - */ -#define DELETION_REGISTER 36 -#ifdef FEAT_CLIPBOARD -# define STAR_REGISTER 37 -# ifdef FEAT_X11 -# define PLUS_REGISTER 38 -# else -# define PLUS_REGISTER STAR_REGISTER /* there is only one */ -# endif -#endif -#ifdef FEAT_DND -# define TILDE_REGISTER (PLUS_REGISTER + 1) -#endif - -#ifdef FEAT_CLIPBOARD -# ifdef FEAT_DND -# define NUM_REGISTERS (TILDE_REGISTER + 1) -# else -# define NUM_REGISTERS (PLUS_REGISTER + 1) -# endif -#else -# define NUM_REGISTERS 37 -#endif - -/* - * Each yank register has an array of pointers to lines. - */ -typedef struct -{ - char_u **y_array; /* pointer to array of line pointers */ - linenr_T y_size; /* number of lines in y_array */ - char_u y_type; /* MLINE, MCHAR or MBLOCK */ - colnr_T y_width; /* only set if y_type == MBLOCK */ -#ifdef FEAT_VIMINFO - time_t y_time_set; -#endif -} yankreg_T; static yankreg_T y_regs[NUM_REGISTERS]; @@ -160,6 +121,31 @@ static char opchars[][3] = {Ctrl_X, NUL, OPF_CHANGE}, // OP_NR_SUB }; + yankreg_T * +get_y_regs(void) +{ + return y_regs; +} + + yankreg_T * +get_y_current(void) +{ + return y_current; +} + + yankreg_T * +get_y_previous(void) +{ + return y_previous; +} + + void +set_y_previous(yankreg_T *yreg) +{ + y_previous = yreg; +} + + /* * Translate a command name into an operator type. * Must only be called with a valid operator name! @@ -1192,6 +1178,18 @@ stuff_yank(int regname, char_u *p) static int execreg_lastc = NUL; + int +get_execreg_lastc(void) +{ + return execreg_lastc; +} + + void +set_execreg_lastc(int lastc) +{ + execreg_lastc = lastc; +} + /* * Execute a yank register: copy it into the stuff buffer. * @@ -5958,400 +5956,6 @@ theend: return did_change; } -#ifdef FEAT_VIMINFO - -static yankreg_T *y_read_regs = NULL; - -#define REG_PREVIOUS 1 -#define REG_EXEC 2 - -/* - * Prepare for reading viminfo registers when writing viminfo later. - */ - void -prepare_viminfo_registers(void) -{ - y_read_regs = ALLOC_CLEAR_MULT(yankreg_T, NUM_REGISTERS); -} - - void -finish_viminfo_registers(void) -{ - int i; - int j; - - if (y_read_regs != NULL) - { - for (i = 0; i < NUM_REGISTERS; ++i) - if (y_read_regs[i].y_array != NULL) - { - for (j = 0; j < y_read_regs[i].y_size; j++) - vim_free(y_read_regs[i].y_array[j]); - vim_free(y_read_regs[i].y_array); - } - VIM_CLEAR(y_read_regs); - } -} - - int -read_viminfo_register(vir_T *virp, int force) -{ - int eof; - int do_it = TRUE; - int size; - int limit; - int i; - int set_prev = FALSE; - char_u *str; - char_u **array = NULL; - int new_type = MCHAR; /* init to shut up compiler */ - colnr_T new_width = 0; /* init to shut up compiler */ - - /* We only get here (hopefully) if line[0] == '"' */ - str = virp->vir_line + 1; - - /* If the line starts with "" this is the y_previous register. */ - if (*str == '"') - { - set_prev = TRUE; - str++; - } - - if (!ASCII_ISALNUM(*str) && *str != '-') - { - if (viminfo_error("E577: ", _("Illegal register name"), virp->vir_line)) - return TRUE; /* too many errors, pretend end-of-file */ - do_it = FALSE; - } - get_yank_register(*str++, FALSE); - if (!force && y_current->y_array != NULL) - do_it = FALSE; - - if (*str == '@') - { - /* "x@: register x used for @@ */ - if (force || execreg_lastc == NUL) - execreg_lastc = str[-1]; - } - - size = 0; - limit = 100; /* Optimized for registers containing <= 100 lines */ - if (do_it) - { - /* - * Build the new register in array[]. - * y_array is kept as-is until done. - * The "do_it" flag is reset when something is wrong, in which case - * array[] needs to be freed. - */ - if (set_prev) - y_previous = y_current; - array = ALLOC_MULT(char_u *, limit); - str = skipwhite(skiptowhite(str)); - if (STRNCMP(str, "CHAR", 4) == 0) - new_type = MCHAR; - else if (STRNCMP(str, "BLOCK", 5) == 0) - new_type = MBLOCK; - else - new_type = MLINE; - /* get the block width; if it's missing we get a zero, which is OK */ - str = skipwhite(skiptowhite(str)); - new_width = getdigits(&str); - } - - while (!(eof = viminfo_readline(virp)) - && (virp->vir_line[0] == TAB || virp->vir_line[0] == '<')) - { - if (do_it) - { - if (size == limit) - { - char_u **new_array = (char_u **) - alloc(limit * 2 * sizeof(char_u *)); - - if (new_array == NULL) - { - do_it = FALSE; - break; - } - for (i = 0; i < limit; i++) - new_array[i] = array[i]; - vim_free(array); - array = new_array; - limit *= 2; - } - str = viminfo_readstring(virp, 1, TRUE); - if (str != NULL) - array[size++] = str; - else - /* error, don't store the result */ - do_it = FALSE; - } - } - - if (do_it) - { - /* free y_array[] */ - for (i = 0; i < y_current->y_size; i++) - vim_free(y_current->y_array[i]); - vim_free(y_current->y_array); - - y_current->y_type = new_type; - y_current->y_width = new_width; - y_current->y_size = size; - y_current->y_time_set = 0; - if (size == 0) - { - y_current->y_array = NULL; - } - else - { - /* Move the lines from array[] to y_array[]. */ - y_current->y_array = ALLOC_MULT(char_u *, size); - for (i = 0; i < size; i++) - { - if (y_current->y_array == NULL) - vim_free(array[i]); - else - y_current->y_array[i] = array[i]; - } - } - } - else - { - /* Free array[] if it was filled. */ - for (i = 0; i < size; i++) - vim_free(array[i]); - } - vim_free(array); - - return eof; -} - -/* - * Accept a new style register line from the viminfo, store it when it's new. - */ - void -handle_viminfo_register(garray_T *values, int force) -{ - bval_T *vp = (bval_T *)values->ga_data; - int flags; - int name; - int type; - int linecount; - int width; - time_t timestamp; - yankreg_T *y_ptr; - int i; - - /* Check the format: - * |{bartype},{flags},{name},{type}, - * {linecount},{width},{timestamp},"line1","line2" - */ - if (values->ga_len < 6 - || vp[0].bv_type != BVAL_NR - || vp[1].bv_type != BVAL_NR - || vp[2].bv_type != BVAL_NR - || vp[3].bv_type != BVAL_NR - || vp[4].bv_type != BVAL_NR - || vp[5].bv_type != BVAL_NR) - return; - flags = vp[0].bv_nr; - name = vp[1].bv_nr; - if (name < 0 || name >= NUM_REGISTERS) - return; - type = vp[2].bv_nr; - if (type != MCHAR && type != MLINE && type != MBLOCK) - return; - linecount = vp[3].bv_nr; - if (values->ga_len < 6 + linecount) - return; - width = vp[4].bv_nr; - if (width < 0) - return; - - if (y_read_regs != NULL) - /* Reading viminfo for merging and writing. Store the register - * content, don't update the current registers. */ - y_ptr = &y_read_regs[name]; - else - y_ptr = &y_regs[name]; - - /* Do not overwrite unless forced or the timestamp is newer. */ - timestamp = (time_t)vp[5].bv_nr; - if (y_ptr->y_array != NULL && !force - && (timestamp == 0 || y_ptr->y_time_set > timestamp)) - return; - - if (y_ptr->y_array != NULL) - for (i = 0; i < y_ptr->y_size; i++) - vim_free(y_ptr->y_array[i]); - vim_free(y_ptr->y_array); - - if (y_read_regs == NULL) - { - if (flags & REG_PREVIOUS) - y_previous = y_ptr; - if ((flags & REG_EXEC) && (force || execreg_lastc == NUL)) - execreg_lastc = get_register_name(name); - } - y_ptr->y_type = type; - y_ptr->y_width = width; - y_ptr->y_size = linecount; - y_ptr->y_time_set = timestamp; - if (linecount == 0) - { - y_ptr->y_array = NULL; - return; - } - y_ptr->y_array = ALLOC_MULT(char_u *, linecount); - if (y_ptr->y_array == NULL) - { - y_ptr->y_size = 0; // ensure object state is consistent - return; - } - for (i = 0; i < linecount; i++) - { - if (vp[i + 6].bv_allocated) - { - y_ptr->y_array[i] = vp[i + 6].bv_string; - vp[i + 6].bv_string = NULL; - } - else - y_ptr->y_array[i] = vim_strsave(vp[i + 6].bv_string); - } -} - - void -write_viminfo_registers(FILE *fp) -{ - int i, j; - char_u *type; - char_u c; - int num_lines; - int max_num_lines; - int max_kbyte; - long len; - yankreg_T *y_ptr; - - fputs(_("\n# Registers:\n"), fp); - - /* Get '<' value, use old '"' value if '<' is not found. */ - max_num_lines = get_viminfo_parameter('<'); - if (max_num_lines < 0) - max_num_lines = get_viminfo_parameter('"'); - if (max_num_lines == 0) - return; - max_kbyte = get_viminfo_parameter('s'); - if (max_kbyte == 0) - return; - - for (i = 0; i < NUM_REGISTERS; i++) - { -#ifdef FEAT_CLIPBOARD - /* Skip '*'/'+' register, we don't want them back next time */ - if (i == STAR_REGISTER || i == PLUS_REGISTER) - continue; -#endif -#ifdef FEAT_DND - /* Neither do we want the '~' register */ - if (i == TILDE_REGISTER) - continue; -#endif - /* When reading viminfo for merging and writing: Use the register from - * viminfo if it's newer. */ - if (y_read_regs != NULL - && y_read_regs[i].y_array != NULL - && (y_regs[i].y_array == NULL || - y_read_regs[i].y_time_set > y_regs[i].y_time_set)) - y_ptr = &y_read_regs[i]; - else if (y_regs[i].y_array == NULL) - continue; - else - y_ptr = &y_regs[i]; - - /* Skip empty registers. */ - num_lines = y_ptr->y_size; - if (num_lines == 0 - || (num_lines == 1 && y_ptr->y_type == MCHAR - && *y_ptr->y_array[0] == NUL)) - continue; - - if (max_kbyte > 0) - { - /* Skip register if there is more text than the maximum size. */ - len = 0; - for (j = 0; j < num_lines; j++) - len += (long)STRLEN(y_ptr->y_array[j]) + 1L; - if (len > (long)max_kbyte * 1024L) - continue; - } - - switch (y_ptr->y_type) - { - case MLINE: - type = (char_u *)"LINE"; - break; - case MCHAR: - type = (char_u *)"CHAR"; - break; - case MBLOCK: - type = (char_u *)"BLOCK"; - break; - default: - semsg(_("E574: Unknown register type %d"), y_ptr->y_type); - type = (char_u *)"LINE"; - break; - } - if (y_previous == &y_regs[i]) - fprintf(fp, "\""); - c = get_register_name(i); - fprintf(fp, "\"%c", c); - if (c == execreg_lastc) - fprintf(fp, "@"); - fprintf(fp, "\t%s\t%d\n", type, (int)y_ptr->y_width); - - /* If max_num_lines < 0, then we save ALL the lines in the register */ - if (max_num_lines > 0 && num_lines > max_num_lines) - num_lines = max_num_lines; - for (j = 0; j < num_lines; j++) - { - putc('\t', fp); - viminfo_writestring(fp, y_ptr->y_array[j]); - } - - { - int flags = 0; - int remaining; - - /* New style with a bar line. Format: - * |{bartype},{flags},{name},{type}, - * {linecount},{width},{timestamp},"line1","line2" - * flags: REG_PREVIOUS - register is y_previous - * REG_EXEC - used for @@ - */ - if (y_previous == &y_regs[i]) - flags |= REG_PREVIOUS; - if (c == execreg_lastc) - flags |= REG_EXEC; - fprintf(fp, "|%d,%d,%d,%d,%d,%d,%ld", BARTYPE_REGISTER, flags, - i, y_ptr->y_type, num_lines, (int)y_ptr->y_width, - (long)y_ptr->y_time_set); - /* 11 chars for type/flags/name/type, 3 * 20 for numbers */ - remaining = LSIZE - 71; - for (j = 0; j < num_lines; j++) - { - putc(',', fp); - --remaining; - remaining = barline_writestring(fp, y_ptr->y_array[j], - remaining); - } - putc('\n', fp); - } - } -} -#endif /* FEAT_VIMINFO */ - #if defined(FEAT_CLIPBOARD) || defined(PROTO) /* * SELECTION / PRIMARY ('*') diff --git a/src/option.c b/src/option.c index c17e9128a2..3959d47114 100644 --- a/src/option.c +++ b/src/option.c @@ -5573,49 +5573,6 @@ set_options_bin( } } -#ifdef FEAT_VIMINFO -/* - * Find the parameter represented by the given character (eg ', :, ", or /), - * and return its associated value in the 'viminfo' string. - * Only works for number parameters, not for 'r' or 'n'. - * If the parameter is not specified in the string or there is no following - * number, return -1. - */ - int -get_viminfo_parameter(int type) -{ - char_u *p; - - p = find_viminfo_parameter(type); - if (p != NULL && VIM_ISDIGIT(*p)) - return atoi((char *)p); - return -1; -} - -/* - * Find the parameter represented by the given character (eg ''', ':', '"', or - * '/') in the 'viminfo' option and return a pointer to the string after it. - * Return NULL if the parameter is not specified in the string. - */ - char_u * -find_viminfo_parameter(int type) -{ - char_u *p; - - for (p = p_viminfo; *p; ++p) - { - if (*p == type) - return p + 1; - if (*p == 'n') /* 'n' is always the last one */ - break; - p = vim_strchr(p, ','); /* skip until next ',' */ - if (p == NULL) /* hit the end without finding parameter */ - break; - } - return NULL; -} -#endif - /* * Expand environment variables for some string options. * These string options cannot be indirect! diff --git a/src/proto/ex_cmds.pro b/src/proto/ex_cmds.pro index 783ed11e94..c31fee375a 100644 --- a/src/proto/ex_cmds.pro +++ b/src/proto/ex_cmds.pro @@ -34,8 +34,8 @@ void do_sub(exarg_T *eap); int do_sub_msg(int count_only); void ex_global(exarg_T *eap); void global_exe(char_u *cmd); -int read_viminfo_sub_string(vir_T *virp, int force); -void write_viminfo_sub_string(FILE *fp); +char_u *get_old_sub(void); +void set_old_sub(char_u *val); void free_old_sub(void); int prepare_tagpreview(int undo_sync); void ex_help(exarg_T *eap); diff --git a/src/proto/ops.pro b/src/proto/ops.pro index 0ff27a2c82..ed5877dfb2 100644 --- a/src/proto/ops.pro +++ b/src/proto/ops.pro @@ -1,4 +1,8 @@ /* ops.c */ +yankreg_T *get_y_regs(void); +yankreg_T *get_y_current(void); +yankreg_T *get_y_previous(void); +void set_y_previous(yankreg_T *yreg); int get_op_type(int char1, int char2); int op_on_lines(int op); int op_is_change(int op); @@ -19,6 +23,8 @@ void put_register(int name, void *reg); void free_register(void *reg); int yank_register_mline(int regname); int do_record(int c); +int get_execreg_lastc(void); +void set_execreg_lastc(int lastc); int do_execreg(int regname, int colon, int addcr, int silent); int insert_reg(int regname, int literally_arg); int get_spec_reg(int regname, char_u **argp, int *allocated, int errmsg); @@ -47,11 +53,6 @@ int fex_format(linenr_T lnum, long count, int c); void format_lines(linenr_T line_count, int avoid_fex); int paragraph_start(linenr_T lnum); void op_addsub(oparg_T *oap, linenr_T Prenum1, int g_cmd); -void prepare_viminfo_registers(void); -void finish_viminfo_registers(void); -int read_viminfo_register(vir_T *virp, int force); -void handle_viminfo_register(garray_T *values, int force); -void write_viminfo_registers(FILE *fp); void x11_export_final_selection(void); void clip_free_selection(Clipboard_T *cbd); void clip_get_selection(Clipboard_T *cbd); diff --git a/src/proto/option.pro b/src/proto/option.pro index 49b2b65706..86c751658c 100644 --- a/src/proto/option.pro +++ b/src/proto/option.pro @@ -12,8 +12,6 @@ void set_title_defaults(void); int do_set(char_u *arg, int opt_flags); int string_to_key(char_u *arg, int multi_byte); void set_options_bin(int oldval, int newval, int opt_flags); -int get_viminfo_parameter(int type); -char_u *find_viminfo_parameter(int type); void check_options(void); void check_buf_options(buf_T *buf); void free_string_option(char_u *p); diff --git a/src/proto/search.pro b/src/proto/search.pro index eb614a18fe..143333d467 100644 --- a/src/proto/search.pro +++ b/src/proto/search.pro @@ -46,6 +46,6 @@ int current_quote(oparg_T *oap, long count, int include, int quotechar); int current_search(long count, int forward); int linewhite(linenr_T lnum); void find_pattern_in_path(char_u *ptr, int dir, int len, int whole, int skip_comments, int type, long count, int action, linenr_T start_lnum, linenr_T end_lnum); -int read_viminfo_search_pattern(vir_T *virp, int force); -void write_viminfo_search_pattern(FILE *fp); +struct spat *get_spat(int idx); +int get_spat_last_idx(void); /* vim: set ft=c : */ diff --git a/src/proto/viminfo.pro b/src/proto/viminfo.pro index 0261b38617..a1f03373d7 100644 --- a/src/proto/viminfo.pro +++ b/src/proto/viminfo.pro @@ -1,18 +1,7 @@ /* viminfo.c */ -int viminfo_error(char *errnum, char *message, char_u *line); +int get_viminfo_parameter(int type); +void check_marks_read(void); int read_viminfo(char_u *file, int flags); void write_viminfo(char_u *file, int forceit); -int viminfo_readline(vir_T *virp); -char_u *viminfo_readstring(vir_T *virp, int off, int convert); -void viminfo_writestring(FILE *fd, char_u *p); -int barline_writestring(FILE *fd, char_u *s, int remaining_start); void ex_viminfo(exarg_T *eap); -int read_viminfo_filemark(vir_T *virp, int force); -void prepare_viminfo_marks(void); -void finish_viminfo_marks(void); -void handle_viminfo_mark(garray_T *values, int force); -void write_viminfo_filemarks(FILE *fp); -int removable(char_u *name); -void write_viminfo_marks(FILE *fp_out, garray_T *buflist); -void copy_viminfo_marks(vir_T *virp, FILE *fp_out, garray_T *buflist, int eof, int flags); /* vim: set ft=c : */ diff --git a/src/search.c b/src/search.c index ce87a3ef39..626bc3dafd 100644 --- a/src/search.c +++ b/src/search.c @@ -23,9 +23,6 @@ static int skip_chars(int, int); static void show_pat_in_path(char_u *, int, int, int, FILE *, linenr_T *, long); #endif -#ifdef FEAT_VIMINFO -static void wvsp_one(FILE *fp, int idx, char *s, int sc); -#endif static void search_stat(int dirc, pos_T *pos, int show_top_bot_msg, char_u *msgbuf, int recompute); /* @@ -51,31 +48,12 @@ static void search_stat(int dirc, pos_T *pos, int show_top_bot_msg, char_u *msgb * Henry Spencer's regular expression library. See regexp.c. */ -/* The offset for a search command is store in a soff struct */ -/* Note: only spats[0].off is really used */ -struct soffset -{ - int dir; /* search direction, '/' or '?' */ - int line; /* search has line offset */ - int end; /* search set cursor at end */ - long off; /* line or char offset */ -}; - -/* A search pattern and its attributes are stored in a spat struct */ -struct spat -{ - char_u *pat; /* the pattern (in allocated memory) or NULL */ - int magic; /* magicness of the pattern */ - int no_scs; /* no smartcase for this pattern */ - struct soffset off; -}; - /* * Two search patterns are remembered: One for the :substitute command and * one for other searches. last_idx points to the one that was used the last * time. */ -static struct spat spats[2] = +static spat_T spats[2] = { {NULL, TRUE, FALSE, {'/', 0, 0, 0L}}, /* last used search pat */ {NULL, TRUE, FALSE, {'/', 0, 0, 0L}} /* last used substitute pat */ @@ -90,7 +68,7 @@ static char_u lastc_bytes[MB_MAXBYTES + 1]; static int lastc_bytelen = 1; /* >1 for multi-byte char */ /* copy of spats[], for keeping the search patterns while executing autocmds */ -static struct spat saved_spats[2]; +static spat_T saved_spats[2]; # ifdef FEAT_SEARCH_EXTRA static int saved_spats_last_idx = 0; static int saved_spats_no_hlsearch = 0; @@ -349,7 +327,7 @@ free_search_patterns(void) #ifdef FEAT_SEARCH_EXTRA // copy of spats[RE_SEARCH], for keeping the search patterns while incremental // searching -static struct spat saved_last_search_spat; +static spat_T saved_last_search_spat; static int did_save_last_search_spat = 0; static int saved_last_idx = 0; static int saved_no_hlsearch = 0; @@ -1210,7 +1188,7 @@ do_search( { pos_T pos; /* position of the last match */ char_u *searchstr; - struct soffset old_off; + soffset_T old_off; int retval; /* Return value */ char_u *p; long c; @@ -5831,124 +5809,15 @@ show_pat_in_path( #endif #ifdef FEAT_VIMINFO - int -read_viminfo_search_pattern(vir_T *virp, int force) + spat_T * +get_spat(int idx) { - char_u *lp; - int idx = -1; - int magic = FALSE; - int no_scs = FALSE; - int off_line = FALSE; - int off_end = 0; - long off = 0; - int setlast = FALSE; -#ifdef FEAT_SEARCH_EXTRA - static int hlsearch_on = FALSE; -#endif - char_u *val; - - /* - * Old line types: - * "/pat", "&pat": search/subst. pat - * "~/pat", "~&pat": last used search/subst. pat - * New line types: - * "~h", "~H": hlsearch highlighting off/on - * "~<magic><smartcase><line><end><off><last><which>pat" - * <magic>: 'm' off, 'M' on - * <smartcase>: 's' off, 'S' on - * <line>: 'L' line offset, 'l' char offset - * <end>: 'E' from end, 'e' from start - * <off>: decimal, offset - * <last>: '~' last used pattern - * <which>: '/' search pat, '&' subst. pat - */ - lp = virp->vir_line; - if (lp[0] == '~' && (lp[1] == 'm' || lp[1] == 'M')) /* new line type */ - { - if (lp[1] == 'M') /* magic on */ - magic = TRUE; - if (lp[2] == 's') - no_scs = TRUE; - if (lp[3] == 'L') - off_line = TRUE; - if (lp[4] == 'E') - off_end = SEARCH_END; - lp += 5; - off = getdigits(&lp); - } - if (lp[0] == '~') /* use this pattern for last-used pattern */ - { - setlast = TRUE; - lp++; - } - if (lp[0] == '/') - idx = RE_SEARCH; - else if (lp[0] == '&') - idx = RE_SUBST; -#ifdef FEAT_SEARCH_EXTRA - else if (lp[0] == 'h') /* ~h: 'hlsearch' highlighting off */ - hlsearch_on = FALSE; - else if (lp[0] == 'H') /* ~H: 'hlsearch' highlighting on */ - hlsearch_on = TRUE; -#endif - if (idx >= 0) - { - if (force || spats[idx].pat == NULL) - { - val = viminfo_readstring(virp, (int)(lp - virp->vir_line + 1), - TRUE); - if (val != NULL) - { - set_last_search_pat(val, idx, magic, setlast); - vim_free(val); - spats[idx].no_scs = no_scs; - spats[idx].off.line = off_line; - spats[idx].off.end = off_end; - spats[idx].off.off = off; -#ifdef FEAT_SEARCH_EXTRA - if (setlast) - set_no_hlsearch(!hlsearch_on); -#endif - } - } - } - return viminfo_readline(virp); -} - - void -write_viminfo_search_pattern(FILE *fp) -{ - if (get_viminfo_parameter('/') != 0) - { -#ifdef FEAT_SEARCH_EXTRA - fprintf(fp, "\n# hlsearch on (H) or off (h):\n~%c", - (no_hlsearch || find_viminfo_parameter('h') != NULL) ? 'h' : 'H'); -#endif - wvsp_one(fp, RE_SEARCH, "", '/'); - wvsp_one(fp, RE_SUBST, _("Substitute "), '&'); - } + return &spats[idx]; } - static void -wvsp_one( - FILE *fp, /* file to write to */ - int idx, /* spats[] index */ - char *s, /* search pat */ - int sc) /* dir char */ + int +get_spat_last_idx(void) { - if (spats[idx].pat != NULL) - { - fprintf(fp, _("\n# Last %sSearch Pattern:\n~"), s); - /* off.dir is not stored, it's reset to forward */ - fprintf(fp, "%c%c%c%c%ld%s%c", - spats[idx].magic ? 'M' : 'm', /* magic */ - spats[idx].no_scs ? 's' : 'S', /* smartcase */ - spats[idx].off.line ? 'L' : 'l', /* line offset */ - spats[idx].off.end ? 'E' : 'e', /* offset from end */ - spats[idx].off.off, /* offset */ - last_idx == idx ? "~" : "", /* last used pat */ - sc); - viminfo_writestring(fp, spats[idx].pat); - } + return last_idx; } -#endif /* FEAT_VIMINFO */ +#endif diff --git a/src/structs.h b/src/structs.h index 367c70db39..ac233629c3 100644 --- a/src/structs.h +++ b/src/structs.h @@ -3751,3 +3751,58 @@ typedef enum { FIND_POPUP, // also find popup windows FAIL_POPUP // return NULL if mouse on popup window } mouse_find_T; + +// Symbolic names for some registers. +#define DELETION_REGISTER 36 +#ifdef FEAT_CLIPBOARD +# define STAR_REGISTER 37 +# ifdef FEAT_X11 +# define PLUS_REGISTER 38 +# else +# define PLUS_REGISTER STAR_REGISTER // there is only one +# endif +#endif +#ifdef FEAT_DND +# define TILDE_REGISTER (PLUS_REGISTER + 1) +#endif + +#ifdef FEAT_CLIPBOARD +# ifdef FEAT_DND +# define NUM_REGISTERS (TILDE_REGISTER + 1) +# else +# define NUM_REGISTERS (PLUS_REGISTER + 1) +# endif +#else +# define NUM_REGISTERS 37 +#endif + +// Each yank register has an array of pointers to lines. +typedef struct +{ + char_u **y_array; // pointer to array of line pointers + linenr_T y_size; // number of lines in y_array + char_u y_type; // MLINE, MCHAR or MBLOCK + colnr_T y_width; // only set if y_type == MBLOCK +#ifdef FEAT_VIMINFO + time_t y_time_set; +#endif +} yankreg_T; + +// The offset for a search command is store in a soff struct +// Note: only spats[0].off is really used +typedef struct soffset +{ + int dir; // search direction, '/' or '?' + int line; // search has line offset + int end; // search set cursor at end + long off; // line or char offset +} soffset_T; + +// A search pattern and its attributes are stored in a spat struct +typedef struct spat +{ + char_u *pat; // the pattern (in allocated memory) or NULL + int magic; // magicness of the pattern + int no_scs; // no smartcase for this pattern + soffset_T off; +} spat_T; diff --git a/src/version.c b/src/version.c index e8f5d7fc37..4e91567a31 100644 --- a/src/version.c +++ b/src/version.c @@ -778,6 +778,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1736, +/**/ 1735, /**/ 1734, diff --git a/src/viminfo.c b/src/viminfo.c index 7e192cecd7..cd3bbb65c6 100644 --- a/src/viminfo.c +++ b/src/viminfo.c @@ -19,6 +19,47 @@ static int viminfo_errcnt; /* + * Find the parameter represented by the given character (eg ''', ':', '"', or + * '/') in the 'viminfo' option and return a pointer to the string after it. + * Return NULL if the parameter is not specified in the string. + */ + static char_u * +find_viminfo_parameter(int type) +{ + char_u *p; + + for (p = p_viminfo; *p; ++p) + { + if (*p == type) + return p + 1; + if (*p == 'n') // 'n' is always the last one + break; + p = vim_strchr(p, ','); // skip until next ',' + if (p == NULL) // hit the end without finding parameter + break; + } + return NULL; +} + +/* + * Find the parameter represented by the given character (eg ', :, ", or /), + * and return its associated value in the 'viminfo' string. + * Only works for number parameters, not for 'r' or 'n'. + * If the parame |