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 /src/ops.c | |
parent | c61a48d25995e5ee2a3813f64c531b91bb23e9b9 (diff) | |
download | vim-git-c3328169d5566b97a6a6921067017e4369dd7cd6.tar.gz |
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.
Diffstat (limited to 'src/ops.c')
-rw-r--r-- | src/ops.c | 470 |
1 files changed, 37 insertions, 433 deletions
@@ -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 ('*') |