To: vim_dev@googlegroups.com Subject: Patch 8.1.1966 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.1966 Problem: Some code in options.c fits better elsewhere. Solution: Move functions from options.c to other files. (Yegappan Lakshmanan, closes #4889) Files: src/evalfunc.c, src/globals.h, src/indent.c, src/map.c, src/option.c, src/proto/map.pro, src/proto/option.pro, src/proto/quickfix.pro, src/proto/screen.pro, src/proto/spell.pro, src/proto/window.pro, src/quickfix.c, src/screen.c, src/spell.c, src/window.c *** ../vim-8.1.1965/src/evalfunc.c 2019-09-01 20:16:48.003438501 +0200 --- src/evalfunc.c 2019-09-02 22:17:58.065928246 +0200 *************** *** 25,31 **** #endif static char *e_listblobarg = N_("E899: Argument of %s must be a List or Blob"); - static char *e_stringreq = N_("E928: String required"); #ifdef FEAT_FLOAT static void f_abs(typval_T *argvars, typval_T *rettv); --- 25,30 ---- *************** *** 141,151 **** static void f_getftype(typval_T *argvars, typval_T *rettv); static void f_getjumplist(typval_T *argvars, typval_T *rettv); static void f_getline(typval_T *argvars, typval_T *rettv); - static void f_getloclist(typval_T *argvars UNUSED, typval_T *rettv UNUSED); static void f_getpid(typval_T *argvars, typval_T *rettv); static void f_getcurpos(typval_T *argvars, typval_T *rettv); static void f_getpos(typval_T *argvars, typval_T *rettv); - static void f_getqflist(typval_T *argvars, typval_T *rettv); static void f_getreg(typval_T *argvars, typval_T *rettv); static void f_getregtype(typval_T *argvars, typval_T *rettv); static void f_gettabinfo(typval_T *argvars, typval_T *rettv); --- 140,148 ---- *************** *** 279,287 **** static void f_setenv(typval_T *argvars, typval_T *rettv); static void f_setfperm(typval_T *argvars, typval_T *rettv); static void f_setline(typval_T *argvars, typval_T *rettv); - static void f_setloclist(typval_T *argvars, typval_T *rettv); static void f_setpos(typval_T *argvars, typval_T *rettv); - static void f_setqflist(typval_T *argvars, typval_T *rettv); static void f_setreg(typval_T *argvars, typval_T *rettv); static void f_settagstack(typval_T *argvars, typval_T *rettv); #ifdef FEAT_CRYPT --- 276,282 ---- *************** *** 4771,4819 **** get_buffer_lines(curbuf, lnum, end, retlist, rettv); } - #ifdef FEAT_QUICKFIX - static void - get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg, typval_T *rettv) - { - if (what_arg->v_type == VAR_UNKNOWN) - { - if (rettv_list_alloc(rettv) == OK) - if (is_qf || wp != NULL) - (void)get_errorlist(NULL, wp, -1, rettv->vval.v_list); - } - else - { - if (rettv_dict_alloc(rettv) == OK) - if (is_qf || (wp != NULL)) - { - if (what_arg->v_type == VAR_DICT) - { - dict_T *d = what_arg->vval.v_dict; - - if (d != NULL) - qf_get_properties(wp, d, rettv->vval.v_dict); - } - else - emsg(_(e_dictreq)); - } - } - } - #endif - - /* - * "getloclist()" function - */ - static void - f_getloclist(typval_T *argvars UNUSED, typval_T *rettv UNUSED) - { - #ifdef FEAT_QUICKFIX - win_T *wp; - - wp = find_win_by_nr_or_id(&argvars[0]); - get_qf_loc_list(FALSE, wp, &argvars[1], rettv); - #endif - } - /* * "getpid()" function */ --- 4766,4771 ---- *************** *** 4895,4911 **** } /* - * "getqflist()" function - */ - static void - f_getqflist(typval_T *argvars UNUSED, typval_T *rettv UNUSED) - { - #ifdef FEAT_QUICKFIX - get_qf_loc_list(TRUE, NULL, &argvars[0], rettv); - #endif - } - - /* * "getreg()" function */ static void --- 4847,4852 ---- *************** *** 9626,9715 **** } /* - * Used by "setqflist()" and "setloclist()" functions - */ - static void - set_qf_ll_list( - win_T *wp UNUSED, - typval_T *list_arg UNUSED, - typval_T *action_arg UNUSED, - typval_T *what_arg UNUSED, - typval_T *rettv) - { - #ifdef FEAT_QUICKFIX - static char *e_invact = N_("E927: Invalid action: '%s'"); - char_u *act; - int action = 0; - static int recursive = 0; - #endif - - rettv->vval.v_number = -1; - - #ifdef FEAT_QUICKFIX - if (list_arg->v_type != VAR_LIST) - emsg(_(e_listreq)); - else if (recursive != 0) - emsg(_(e_au_recursive)); - else - { - list_T *l = list_arg->vval.v_list; - dict_T *d = NULL; - int valid_dict = TRUE; - - if (action_arg->v_type == VAR_STRING) - { - act = tv_get_string_chk(action_arg); - if (act == NULL) - return; /* type error; errmsg already given */ - if ((*act == 'a' || *act == 'r' || *act == ' ' || *act == 'f') && - act[1] == NUL) - action = *act; - else - semsg(_(e_invact), act); - } - else if (action_arg->v_type == VAR_UNKNOWN) - action = ' '; - else - emsg(_(e_stringreq)); - - if (action_arg->v_type != VAR_UNKNOWN - && what_arg->v_type != VAR_UNKNOWN) - { - if (what_arg->v_type == VAR_DICT) - d = what_arg->vval.v_dict; - else - { - emsg(_(e_dictreq)); - valid_dict = FALSE; - } - } - - ++recursive; - if (l != NULL && action && valid_dict && set_errorlist(wp, l, action, - (char_u *)(wp == NULL ? ":setqflist()" : ":setloclist()"), - d) == OK) - rettv->vval.v_number = 0; - --recursive; - } - #endif - } - - /* - * "setloclist()" function - */ - static void - f_setloclist(typval_T *argvars, typval_T *rettv) - { - win_T *win; - - rettv->vval.v_number = -1; - - win = find_win_by_nr_or_id(&argvars[0]); - if (win != NULL) - set_qf_ll_list(win, &argvars[1], &argvars[2], &argvars[3], rettv); - } - - /* * "setpos()" function */ static void --- 9567,9572 ---- *************** *** 9753,9767 **** } /* - * "setqflist()" function - */ - static void - f_setqflist(typval_T *argvars, typval_T *rettv) - { - set_qf_ll_list(NULL, &argvars[0], &argvars[1], &argvars[2], rettv); - } - - /* * "setreg()" function */ static void --- 9610,9615 ---- *** ../vim-8.1.1965/src/globals.h 2019-09-01 16:01:25.584754569 +0200 --- src/globals.h 2019-09-02 22:17:58.065928246 +0200 *************** *** 1550,1555 **** --- 1550,1556 ---- EXTERN char e_cannot_mod[] INIT(= N_("E995: Cannot modify existing variable")); EXTERN char e_readonlyvar[] INIT(= N_("E46: Cannot change read-only variable \"%s\"")); EXTERN char e_readonlysbx[] INIT(= N_("E794: Cannot set variable in the sandbox: \"%s\"")); + EXTERN char e_stringreq[] INIT(= N_("E928: String required")); EXTERN char e_emptykey[] INIT(= N_("E713: Cannot use empty key for Dictionary")); EXTERN char e_dictreq[] INIT(= N_("E715: Dictionary required")); EXTERN char e_listidx[] INIT(= N_("E684: list index out of range: %ld")); *** ../vim-8.1.1965/src/indent.c 2019-08-21 14:36:29.387376100 +0200 --- src/indent.c 2019-09-02 22:26:07.515680305 +0200 *************** *** 4457,4459 **** --- 4457,4817 ---- } #endif + + #if defined(FEAT_VARTABS) || defined(PROTO) + + /* + * Set the integer values corresponding to the string setting of 'vartabstop'. + * "array" will be set, caller must free it if needed. + */ + int + tabstop_set(char_u *var, int **array) + { + int valcount = 1; + int t; + char_u *cp; + + if (var[0] == NUL || (var[0] == '0' && var[1] == NUL)) + { + *array = NULL; + return TRUE; + } + + for (cp = var; *cp != NUL; ++cp) + { + if (cp == var || cp[-1] == ',') + { + char_u *end; + + if (strtol((char *)cp, (char **)&end, 10) <= 0) + { + if (cp != end) + emsg(_(e_positive)); + else + emsg(_(e_invarg)); + return FALSE; + } + } + + if (VIM_ISDIGIT(*cp)) + continue; + if (cp[0] == ',' && cp > var && cp[-1] != ',' && cp[1] != NUL) + { + ++valcount; + continue; + } + emsg(_(e_invarg)); + return FALSE; + } + + *array = ALLOC_MULT(int, valcount + 1); + if (*array == NULL) + return FALSE; + (*array)[0] = valcount; + + t = 1; + for (cp = var; *cp != NUL;) + { + (*array)[t++] = atoi((char *)cp); + while (*cp != NUL && *cp != ',') + ++cp; + if (*cp != NUL) + ++cp; + } + + return TRUE; + } + + /* + * Calculate the number of screen spaces a tab will occupy. + * If "vts" is set then the tab widths are taken from that array, + * otherwise the value of ts is used. + */ + int + tabstop_padding(colnr_T col, int ts_arg, int *vts) + { + int ts = ts_arg == 0 ? 8 : ts_arg; + int tabcount; + colnr_T tabcol = 0; + int t; + int padding = 0; + + if (vts == NULL || vts[0] == 0) + return ts - (col % ts); + + tabcount = vts[0]; + + for (t = 1; t <= tabcount; ++t) + { + tabcol += vts[t]; + if (tabcol > col) + { + padding = (int)(tabcol - col); + break; + } + } + if (t > tabcount) + padding = vts[tabcount] - (int)((col - tabcol) % vts[tabcount]); + + return padding; + } + + /* + * Find the size of the tab that covers a particular column. + */ + int + tabstop_at(colnr_T col, int ts, int *vts) + { + int tabcount; + colnr_T tabcol = 0; + int t; + int tab_size = 0; + + if (vts == 0 || vts[0] == 0) + return ts; + + tabcount = vts[0]; + for (t = 1; t <= tabcount; ++t) + { + tabcol += vts[t]; + if (tabcol > col) + { + tab_size = vts[t]; + break; + } + } + if (t > tabcount) + tab_size = vts[tabcount]; + + return tab_size; + } + + /* + * Find the column on which a tab starts. + */ + colnr_T + tabstop_start(colnr_T col, int ts, int *vts) + { + int tabcount; + colnr_T tabcol = 0; + int t; + int excess; + + if (vts == NULL || vts[0] == 0) + return (col / ts) * ts; + + tabcount = vts[0]; + for (t = 1; t <= tabcount; ++t) + { + tabcol += vts[t]; + if (tabcol > col) + return tabcol - vts[t]; + } + + excess = tabcol % vts[tabcount]; + return excess + ((col - excess) / vts[tabcount]) * vts[tabcount]; + } + + /* + * Find the number of tabs and spaces necessary to get from one column + * to another. + */ + void + tabstop_fromto( + colnr_T start_col, + colnr_T end_col, + int ts_arg, + int *vts, + int *ntabs, + int *nspcs) + { + int spaces = end_col - start_col; + colnr_T tabcol = 0; + int padding = 0; + int tabcount; + int t; + int ts = ts_arg == 0 ? curbuf->b_p_ts : ts_arg; + + if (vts == NULL || vts[0] == 0) + { + int tabs = 0; + int initspc = 0; + + initspc = ts - (start_col % ts); + if (spaces >= initspc) + { + spaces -= initspc; + tabs++; + } + tabs += spaces / ts; + spaces -= (spaces / ts) * ts; + + *ntabs = tabs; + *nspcs = spaces; + return; + } + + // Find the padding needed to reach the next tabstop. + tabcount = vts[0]; + for (t = 1; t <= tabcount; ++t) + { + tabcol += vts[t]; + if (tabcol > start_col) + { + padding = (int)(tabcol - start_col); + break; + } + } + if (t > tabcount) + padding = vts[tabcount] - (int)((start_col - tabcol) % vts[tabcount]); + + // If the space needed is less than the padding no tabs can be used. + if (spaces < padding) + { + *ntabs = 0; + *nspcs = spaces; + return; + } + + *ntabs = 1; + spaces -= padding; + + // At least one tab has been used. See if any more will fit. + while (spaces != 0 && ++t <= tabcount) + { + padding = vts[t]; + if (spaces < padding) + { + *nspcs = spaces; + return; + } + ++*ntabs; + spaces -= padding; + } + + *ntabs += spaces / vts[tabcount]; + *nspcs = spaces % vts[tabcount]; + } + + /* + * See if two tabstop arrays contain the same values. + */ + int + tabstop_eq(int *ts1, int *ts2) + { + int t; + + if ((ts1 == 0 && ts2) || (ts1 && ts2 == 0)) + return FALSE; + if (ts1 == ts2) + return TRUE; + if (ts1[0] != ts2[0]) + return FALSE; + + for (t = 1; t <= ts1[0]; ++t) + if (ts1[t] != ts2[t]) + return FALSE; + + return TRUE; + } + + #if defined(FEAT_BEVAL) || defined(PROTO) + /* + * Copy a tabstop array, allocating space for the new array. + */ + int * + tabstop_copy(int *oldts) + { + int *newts; + int t; + + if (oldts == NULL) + return NULL; + newts = ALLOC_MULT(int, oldts[0] + 1); + if (newts != NULL) + for (t = 0; t <= oldts[0]; ++t) + newts[t] = oldts[t]; + return newts; + } + #endif + + /* + * Return a count of the number of tabstops. + */ + int + tabstop_count(int *ts) + { + return ts != NULL ? ts[0] : 0; + } + + /* + * Return the first tabstop, or 8 if there are no tabstops defined. + */ + int + tabstop_first(int *ts) + { + return ts != NULL ? ts[1] : 8; + } + + #endif + + /* + * Return the effective shiftwidth value for current buffer, using the + * 'tabstop' value when 'shiftwidth' is zero. + */ + long + get_sw_value(buf_T *buf) + { + return get_sw_value_col(buf, 0); + } + + /* + * Idem, using "pos". + */ + static long + get_sw_value_pos(buf_T *buf, pos_T *pos) + { + pos_T save_cursor = curwin->w_cursor; + long sw_value; + + curwin->w_cursor = *pos; + sw_value = get_sw_value_col(buf, get_nolist_virtcol()); + curwin->w_cursor = save_cursor; + return sw_value; + } + + /* + * Idem, using the first non-black in the current line. + */ + long + get_sw_value_indent(buf_T *buf) + { + pos_T pos = curwin->w_cursor; + + pos.col = getwhitecols_curline(); + return get_sw_value_pos(buf, &pos); + } + + /* + * Idem, using virtual column "col". + */ + long + get_sw_value_col(buf_T *buf, colnr_T col UNUSED) + { + return buf->b_p_sw ? buf->b_p_sw : + #ifdef FEAT_VARTABS + tabstop_at(col, buf->b_p_ts, buf->b_p_vts_array); + #else + buf->b_p_ts; + #endif + } + + /* + * Return the effective softtabstop value for the current buffer, using the + * 'shiftwidth' value when 'softtabstop' is negative. + */ + long + get_sts_value(void) + { + return curbuf->b_p_sts < 0 ? get_sw_value(curbuf) : curbuf->b_p_sts; + } *** ../vim-8.1.1965/src/map.c 2019-08-18 22:25:54.665447991 +0200 --- src/map.c 2019-09-02 22:26:52.303474156 +0200 *************** *** 2193,2198 **** --- 2193,2389 ---- } #endif + #if defined(FEAT_LANGMAP) || defined(PROTO) + /* + * Any character has an equivalent 'langmap' character. This is used for + * keyboards that have a special language mode that sends characters above + * 128 (although other characters can be translated too). The "to" field is a + * Vim command character. This avoids having to switch the keyboard back to + * ASCII mode when leaving Insert mode. + * + * langmap_mapchar[] maps any of 256 chars to an ASCII char used for Vim + * commands. + * langmap_mapga.ga_data is a sorted table of langmap_entry_T. This does the + * same as langmap_mapchar[] for characters >= 256. + * + * Use growarray for 'langmap' chars >= 256 + */ + typedef struct + { + int from; + int to; + } langmap_entry_T; + + static garray_T langmap_mapga; + + /* + * Search for an entry in "langmap_mapga" for "from". If found set the "to" + * field. If not found insert a new entry at the appropriate location. + */ + static void + langmap_set_entry(int from, int to) + { + langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data); + int a = 0; + int b = langmap_mapga.ga_len; + + // Do a binary search for an existing entry. + while (a != b) + { + int i = (a + b) / 2; + int d = entries[i].from - from; + + if (d == 0) + { + entries[i].to = to; + return; + } + if (d < 0) + a = i + 1; + else + b = i; + } + + if (ga_grow(&langmap_mapga, 1) != OK) + return; // out of memory + + // insert new entry at position "a" + entries = (langmap_entry_T *)(langmap_mapga.ga_data) + a; + mch_memmove(entries + 1, entries, + (langmap_mapga.ga_len - a) * sizeof(langmap_entry_T)); + ++langmap_mapga.ga_len; + entries[0].from = from; + entries[0].to = to; + } + + /* + * Apply 'langmap' to multi-byte character "c" and return the result. + */ + int + langmap_adjust_mb(int c) + { + langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data); + int a = 0; + int b = langmap_mapga.ga_len; + + while (a != b) + { + int i = (a + b) / 2; + int d = entries[i].from - c; + + if (d == 0) + return entries[i].to; // found matching entry + if (d < 0) + a = i + 1; + else + b = i; + } + return c; // no entry found, return "c" unmodified + } + + void + langmap_init(void) + { + int i; + + for (i = 0; i < 256; i++) + langmap_mapchar[i] = i; // we init with a one-to-one map + ga_init2(&langmap_mapga, sizeof(langmap_entry_T), 8); + } + + /* + * Called when langmap option is set; the language map can be + * changed at any time! + */ + void + langmap_set(void) + { + char_u *p; + char_u *p2; + int from, to; + + ga_clear(&langmap_mapga); // clear the previous map first + langmap_init(); // back to one-to-one map + + for (p = p_langmap; p[0] != NUL; ) + { + for (p2 = p; p2[0] != NUL && p2[0] != ',' && p2[0] != ';'; + MB_PTR_ADV(p2)) + { + if (p2[0] == '\\' && p2[1] != NUL) + ++p2; + } + if (p2[0] == ';') + ++p2; // abcd;ABCD form, p2 points to A + else + p2 = NULL; // aAbBcCdD form, p2 is NULL + while (p[0]) + { + if (p[0] == ',') + { + ++p; + break; + } + if (p[0] == '\\' && p[1] != NUL) + ++p; + from = (*mb_ptr2char)(p); + to = NUL; + if (p2 == NULL) + { + MB_PTR_ADV(p); + if (p[0] != ',') + { + if (p[0] == '\\') + ++p; + to = (*mb_ptr2char)(p); + } + } + else + { + if (p2[0] != ',') + { + if (p2[0] == '\\') + ++p2; + to = (*mb_ptr2char)(p2); + } + } + if (to == NUL) + { + semsg(_("E357: 'langmap': Matching character missing for %s"), + transchar(from)); + return; + } + + if (from >= 256) + langmap_set_entry(from, to); + else + langmap_mapchar[from & 255] = to; + + // Advance to next pair + MB_PTR_ADV(p); + if (p2 != NULL) + { + MB_PTR_ADV(p2); + if (*p == ';') + { + p = p2; + if (p[0] != NUL) + { + if (p[0] != ',') + { + semsg(_("E358: 'langmap': Extra characters after semicolon: %s"), p); + return; + } + ++p; + } + break; + } + } + } + } + } + #endif + static void do_exmap(exarg_T *eap, int isabbrev) { *** ../vim-8.1.1965/src/option.c 2019-08-24 15:50:42.814107646 +0200 --- src/option.c 2019-09-02 22:17:58.069928229 +0200 *************** *** 3244,3260 **** #endif static void set_string_option_global(int opt_idx, char_u **varp); static char *did_set_string_option(int opt_idx, char_u **varp, int new_value_alloced, char_u *oldval, char *errbuf, int opt_flags, int *value_checked); - static char *set_chars_option(char_u **varp); #ifdef FEAT_STL_OPT static char *check_stl_option(char_u *s); #endif #ifdef FEAT_CLIPBOARD static char *check_clipboard_option(void); #endif - #ifdef FEAT_SPELL - static char *did_set_spell_option(int is_spellfile); - static char *compile_cap_prog(synblock_T *synblock); - #endif #ifdef FEAT_EVAL static void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx); #endif --- 3244,3255 ---- *************** *** 3276,3285 **** static void option_value2string(struct vimoption *, int opt_flags); static void check_winopt(winopt_T *wop); static int wc_use_keyname(char_u *varp, long *wcp); - #ifdef FEAT_LANGMAP - static void langmap_init(void); - static void langmap_set(void); - #endif static void paste_option_changed(void); static void compatible_set(void); #ifdef FEAT_LINEBREAK --- 3271,3276 ---- *************** *** 6158,6164 **** * Return TRUE if "val" is a valid name: only consists of alphanumeric ASCII * characters or characters in "allowed". */ ! static int valid_name(char_u *val, char *allowed) { char_u *s; --- 6149,6155 ---- * Return TRUE if "val" is a valid name: only consists of alphanumeric ASCII * characters or characters in "allowed". */ ! int valid_name(char_u *val, char *allowed) { char_u *s; *************** *** 6179,6209 **** return valid_name(val, ".-_"); } - #if defined(FEAT_SPELL) || defined(PROTO) - /* - * Return TRUE if "val" is a valid 'spellang' value. - */ - int - valid_spellang(char_u *val) - { - return valid_name(val, ".-_,@"); - } - - /* - * Return TRUE if "val" is a valid 'spellfile' value. - */ - static int - valid_spellfile(char_u *val) - { - char_u *s; - - for (s = val; *s != NUL; ++s) - if (!vim_isfilec(*s) && *s != ',') - return FALSE; - return TRUE; - } - #endif - /* * Handle string options that need some action to perform when changed. * Returns NULL for success, or an error message for an error. --- 6170,6175 ---- *************** *** 8000,8216 **** return errmsg; } - #if defined(FEAT_SYN_HL) || defined(PROTO) - /* - * Simple int comparison function for use with qsort() - */ - static int - int_cmp(const void *a, const void *b) - { - return *(const int *)a - *(const int *)b; - } - - /* - * Handle setting 'colorcolumn' or 'textwidth' in window "wp". - * Returns error message, NULL if it's OK. - */ - char * - check_colorcolumn(win_T *wp) - { - char_u *s; - int col; - int count = 0; - int color_cols[256]; - int i; - int j = 0; - - if (wp->w_buffer == NULL) - return NULL; /* buffer was closed */ - - for (s = wp->w_p_cc; *s != NUL && count < 255;) - { - if (*s == '-' || *s == '+') - { - /* -N and +N: add to 'textwidth' */ - col = (*s == '-') ? -1 : 1; - ++s; - if (!VIM_ISDIGIT(*s)) - return e_invarg; - col = col * getdigits(&s); - if (wp->w_buffer->b_p_tw == 0) - goto skip; /* 'textwidth' not set, skip this item */ - col += wp->w_buffer->b_p_tw; - if (col < 0) - goto skip; - } - else if (VIM_ISDIGIT(*s)) - col = getdigits(&s); - else - return e_invarg; - color_cols[count++] = col - 1; /* 1-based to 0-based */ - skip: - if (*s == NUL) - break; - if (*s != ',') - return e_invarg; - if (*++s == NUL) - return e_invarg; /* illegal trailing comma as in "set cc=80," */ - } - - vim_free(wp->w_p_cc_cols); - if (count == 0) - wp->w_p_cc_cols = NULL; - else - { - wp->w_p_cc_cols = ALLOC_MULT(int, count + 1); - if (wp->w_p_cc_cols != NULL) - { - /* sort the columns for faster usage on screen redraw inside - * win_line() */ - qsort(color_cols, count, sizeof(int), int_cmp); - - for (i = 0; i < count; ++i) - /* skip duplicates */ - if (j == 0 || wp->w_p_cc_cols[j - 1] != color_cols[i]) - wp->w_p_cc_cols[j++] = color_cols[i]; - wp->w_p_cc_cols[j] = -1; /* end marker */ - } - } - - return NULL; /* no error */ - } - #endif - - /* - * Handle setting 'listchars' or 'fillchars'. - * Returns error message, NULL if it's OK. - */ - static char * - set_chars_option(char_u **varp) - { - int round, i, len, entries; - char_u *p, *s; - int c1 = 0, c2 = 0, c3 = 0; - struct charstab - { - int *cp; - char *name; - }; - static struct charstab filltab[] = - { - {&fill_stl, "stl"}, - {&fill_stlnc, "stlnc"}, - {&fill_vert, "vert"}, - {&fill_fold, "fold"}, - {&fill_diff, "diff"}, - }; - static struct charstab lcstab[] = - { - {&lcs_eol, "eol"}, - {&lcs_ext, "extends"}, - {&lcs_nbsp, "nbsp"}, - {&lcs_prec, "precedes"}, - {&lcs_space, "space"}, - {&lcs_tab2, "tab"}, - {&lcs_trail, "trail"}, - #ifdef FEAT_CONCEAL - {&lcs_conceal, "conceal"}, - #else - {NULL, "conceal"}, - #endif - }; - struct charstab *tab; - - if (varp == &p_lcs) - { - tab = lcstab; - entries = sizeof(lcstab) / sizeof(struct charstab); - } - else - { - tab = filltab; - entries = sizeof(filltab) / sizeof(struct charstab); - } - - /* first round: check for valid value, second round: assign values */ - for (round = 0; round <= 1; ++round) - { - if (round > 0) - { - /* After checking that the value is valid: set defaults: space for - * 'fillchars', NUL for 'listchars' */ - for (i = 0; i < entries; ++i) - if (tab[i].cp != NULL) - *(tab[i].cp) = (varp == &p_lcs ? NUL : ' '); - - if (varp == &p_lcs) - { - lcs_tab1 = NUL; - lcs_tab3 = NUL; - } - else - fill_diff = '-'; - } - p = *varp; - while (*p) - { - for (i = 0; i < entries; ++i) - { - len = (int)STRLEN(tab[i].name); - if (STRNCMP(p, tab[i].name, len) == 0 - && p[len] == ':' - && p[len + 1] != NUL) - { - c2 = c3 = 0; - s = p + len + 1; - c1 = mb_ptr2char_adv(&s); - if (mb_char2cells(c1) > 1) - continue; - if (tab[i].cp == &lcs_tab2) - { - if (*s == NUL) - continue; - c2 = mb_ptr2char_adv(&s); - if (mb_char2cells(c2) > 1) - continue; - if (!(*s == ',' || *s == NUL)) - { - c3 = mb_ptr2char_adv(&s); - if (mb_char2cells(c3) > 1) - continue; - } - } - - if (*s == ',' || *s == NUL) - { - if (round) - { - if (tab[i].cp == &lcs_tab2) - { - lcs_tab1 = c1; - lcs_tab2 = c2; - lcs_tab3 = c3; - } - else if (tab[i].cp != NULL) - *(tab[i].cp) = c1; - - } - p = s; - break; - } - } - } - - if (i == entries) - return e_invarg; - if (*p == ',') - ++p; - } - } - - return NULL; /* no error */ - } - #ifdef FEAT_STL_OPT /* * Check validity of options with the 'statusline' format. --- 7966,7971 ---- *************** *** 8376,8446 **** } #endif - #ifdef FEAT_SPELL - /* - * Handle side effects of setting 'spell'. - * Return an error message or NULL for success. - */ - static char * - did_set_spell_option(int is_spellfile) - { - char *errmsg = NULL; - win_T *wp; - int l; - - if (is_spellfile) - { - l = (int)STRLEN(curwin->w_s->b_p_spf); - if (l > 0 && (l < 4 - || STRCMP(curwin->w_s->b_p_spf + l - 4, ".add") != 0)) - errmsg = e_invarg; - } - - if (errmsg == NULL) - { - FOR_ALL_WINDOWS(wp) - if (wp->w_buffer == curbuf && wp->w_p_spell) - { - errmsg = did_set_spelllang(wp); - break; - } - } - return errmsg; - } - - /* - * Set curbuf->b_cap_prog to the regexp program for 'spellcapcheck'. - * Return error message when failed, NULL when OK. - */ - static char * - compile_cap_prog(synblock_T *synblock) - { - regprog_T *rp = synblock->b_cap_prog; - char_u *re; - - if (*synblock->b_p_spc == NUL) - synblock->b_cap_prog = NULL; - else - { - /* Prepend a ^ so that we only match at one column */ - re = concat_str((char_u *)"^", synblock->b_p_spc); - if (re != NULL) - { - synblock->b_cap_prog = vim_regcomp(re, RE_MAGIC); - vim_free(re); - if (synblock->b_cap_prog == NULL) - { - synblock->b_cap_prog = rp; /* restore the previous program */ - return e_invarg; - } - } - } - - vim_regfree(rp); - return NULL; - } - #endif - #if defined(FEAT_EVAL) || defined(PROTO) /* * Set the script_ctx for an option, taking care of setting the buffer- or --- 8131,8136 ---- *************** *** 10839,10893 **** return (p->fullname[0] == 't' && p->fullname[1] == '_'); } - /* - * Compute columns for ruler and shown command. 'sc_col' is also used to - * decide what the maximum length of a message on the status line can be. - * If there is a status line for the last window, 'sc_col' is independent - * of 'ru_col'. - */ - - #define COL_RULER 17 /* columns needed by standard ruler */ - - void - comp_col(void) - { - #if defined(FEAT_CMDL_INFO) - int last_has_status = (p_ls == 2 || (p_ls == 1 && !ONE_WINDOW)); - - sc_col = 0; - ru_col = 0; - if (p_ru) - { - # ifdef FEAT_STL_OPT - ru_col = (ru_wid ? ru_wid : COL_RULER) + 1; - # else - ru_col = COL_RULER + 1; - # endif - /* no last status line, adjust sc_col */ - if (!last_has_status) - sc_col = ru_col; - } - if (p_sc) - { - sc_col += SHOWCMD_COLS; - if (!p_ru || last_has_status) /* no need for separating space */ - ++sc_col; - } - sc_col = Columns - sc_col; - ru_col = Columns - ru_col; - if (sc_col <= 0) /* screen too narrow, will become a mess */ - sc_col = 1; - if (ru_col <= 0) - ru_col = 1; - #else - sc_col = Columns; - ru_col = Columns; - #endif - #ifdef FEAT_EVAL - set_vim_var_nr(VV_ECHOSPACE, sc_col - 1); - #endif - } - #if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) || defined(PROTO) /* * Unset local option value, similar to ":set opt<". --- 10529,10534 ---- *************** *** 12307,12503 **** return FALSE; } - #if defined(FEAT_LANGMAP) || defined(PROTO) - /* - * Any character has an equivalent 'langmap' character. This is used for - * keyboards that have a special language mode that sends characters above - * 128 (although other characters can be translated too). The "to" field is a - * Vim command character. This avoids having to switch the keyboard back to - * ASCII mode when leaving Insert mode. - * - * langmap_mapchar[] maps any of 256 chars to an ASCII char used for Vim - * commands. - * langmap_mapga.ga_data is a sorted table of langmap_entry_T. This does the - * same as langmap_mapchar[] for characters >= 256. - * - * Use growarray for 'langmap' chars >= 256 - */ - typedef struct - { - int from; - int to; - } langmap_entry_T; - - static garray_T langmap_mapga; - - /* - * Search for an entry in "langmap_mapga" for "from". If found set the "to" - * field. If not found insert a new entry at the appropriate location. - */ - static void - langmap_set_entry(int from, int to) - { - langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data); - int a = 0; - int b = langmap_mapga.ga_len; - - /* Do a binary search for an existing entry. */ - while (a != b) - { - int i = (a + b) / 2; - int d = entries[i].from - from; - - if (d == 0) - { - entries[i].to = to; - return; - } - if (d < 0) - a = i + 1; - else - b = i; - } - - if (ga_grow(&langmap_mapga, 1) != OK) - return; /* out of memory */ - - /* insert new entry at position "a" */ - entries = (langmap_entry_T *)(langmap_mapga.ga_data) + a; - mch_memmove(entries + 1, entries, - (langmap_mapga.ga_len - a) * sizeof(langmap_entry_T)); - ++langmap_mapga.ga_len; - entries[0].from = from; - entries[0].to = to; - } - - /* - * Apply 'langmap' to multi-byte character "c" and return the result. - */ - int - langmap_adjust_mb(int c) - { - langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data); - int a = 0; - int b = langmap_mapga.ga_len; - - while (a != b) - { - int i = (a + b) / 2; - int d = entries[i].from - c; - - if (d == 0) - return entries[i].to; /* found matching entry */ - if (d < 0) - a = i + 1; - else - b = i; - } - return c; /* no entry found, return "c" unmodified */ - } - - static void - langmap_init(void) - { - int i; - - for (i = 0; i < 256; i++) - langmap_mapchar[i] = i; /* we init with a one-to-one map */ - ga_init2(&langmap_mapga, sizeof(langmap_entry_T), 8); - } - - /* - * Called when langmap option is set; the language map can be - * changed at any time! - */ - static void - langmap_set(void) - { - char_u *p; - char_u *p2; - int from, to; - - ga_clear(&langmap_mapga); /* clear the previous map first */ - langmap_init(); /* back to one-to-one map */ - - for (p = p_langmap; p[0] != NUL; ) - { - for (p2 = p; p2[0] != NUL && p2[0] != ',' && p2[0] != ';'; - MB_PTR_ADV(p2)) - { - if (p2[0] == '\\' && p2[1] != NUL) - ++p2; - } - if (p2[0] == ';') - ++p2; /* abcd;ABCD form, p2 points to A */ - else - p2 = NULL; /* aAbBcCdD form, p2 is NULL */ - while (p[0]) - { - if (p[0] == ',') - { - ++p; - break; - } - if (p[0] == '\\' && p[1] != NUL) - ++p; - from = (*mb_ptr2char)(p); - to = NUL; - if (p2 == NULL) - { - MB_PTR_ADV(p); - if (p[0] != ',') - { - if (p[0] == '\\') - ++p; - to = (*mb_ptr2char)(p); - } - } - else - { - if (p2[0] != ',') - { - if (p2[0] == '\\') - ++p2; - to = (*mb_ptr2char)(p2); - } - } - if (to == NUL) - { - semsg(_("E357: 'langmap': Matching character missing for %s"), - transchar(from)); - return; - } - - if (from >= 256) - langmap_set_entry(from, to); - else - langmap_mapchar[from & 255] = to; - - /* Advance to next pair */ - MB_PTR_ADV(p); - if (p2 != NULL) - { - MB_PTR_ADV(p2); - if (*p == ';') - { - p = p2; - if (p[0] != NUL) - { - if (p[0] != ',') - { - semsg(_("E358: 'langmap': Extra characters after semicolon: %s"), p); - return; - } - ++p; - } - break; - } - } - } - } - } - #endif - /* * Return TRUE if format option 'x' is in effect. * Take care of no formatting when 'paste' is set. --- 11948,11953 ---- *************** *** 13012,13375 **** return check_opt_strings(p, p_ff_values, FALSE); } - #if defined(FEAT_VARTABS) || defined(PROTO) - - /* - * Set the integer values corresponding to the string setting of 'vartabstop'. - * "array" will be set, caller must free it if needed. - */ - int - tabstop_set(char_u *var, int **array) - { - int valcount = 1; - int t; - char_u *cp; - - if (var[0] == NUL || (var[0] == '0' && var[1] == NUL)) - { - *array = NULL; - return TRUE; - } - - for (cp = var; *cp != NUL; ++cp) - { - if (cp == var || cp[-1] == ',') - { - char_u *end; - - if (strtol((char *)cp, (char **)&end, 10) <= 0) - { - if (cp != end) - emsg(_(e_positive)); - else - emsg(_(e_invarg)); - return FALSE; - } - } - - if (VIM_ISDIGIT(*cp)) - continue; - if (cp[0] == ',' && cp > var && cp[-1] != ',' && cp[1] != NUL) - { - ++valcount; - continue; - } - emsg(_(e_invarg)); - return FALSE; - } - - *array = ALLOC_MULT(int, valcount + 1); - if (*array == NULL) - return FALSE; - (*array)[0] = valcount; - - t = 1; - for (cp = var; *cp != NUL;) - { - (*array)[t++] = atoi((char *)cp); - while (*cp != NUL && *cp != ',') - ++cp; - if (*cp != NUL) - ++cp; - } - - return TRUE; - } - - /* - * Calculate the number of screen spaces a tab will occupy. - * If "vts" is set then the tab widths are taken from that array, - * otherwise the value of ts is used. - */ - int - tabstop_padding(colnr_T col, int ts_arg, int *vts) - { - int ts = ts_arg == 0 ? 8 : ts_arg; - int tabcount; - colnr_T tabcol = 0; - int t; - int padding = 0; - - if (vts == NULL || vts[0] == 0) - return ts - (col % ts); - - tabcount = vts[0]; - - for (t = 1; t <= tabcount; ++t) - { - tabcol += vts[t]; - if (tabcol > col) - { - padding = (int)(tabcol - col); - break; - } - } - if (t > tabcount) - padding = vts[tabcount] - (int)((col - tabcol) % vts[tabcount]); - - return padding; - } - - /* - * Find the size of the tab that covers a particular column. - */ - int - tabstop_at(colnr_T col, int ts, int *vts) - { - int tabcount; - colnr_T tabcol = 0; - int t; - int tab_size = 0; - - if (vts == 0 || vts[0] == 0) - return ts; - - tabcount = vts[0]; - for (t = 1; t <= tabcount; ++t) - { - tabcol += vts[t]; - if (tabcol > col) - { - tab_size = vts[t]; - break; - } - } - if (t > tabcount) - tab_size = vts[tabcount]; - - return tab_size; - } - - /* - * Find the column on which a tab starts. - */ - colnr_T - tabstop_start(colnr_T col, int ts, int *vts) - { - int tabcount; - colnr_T tabcol = 0; - int t; - int excess; - - if (vts == NULL || vts[0] == 0) - return (col / ts) * ts; - - tabcount = vts[0]; - for (t = 1; t <= tabcount; ++t) - { - tabcol += vts[t]; - if (tabcol > col) - return tabcol - vts[t]; - } - - excess = tabcol % vts[tabcount]; - return excess + ((col - excess) / vts[tabcount]) * vts[tabcount]; - } - - /* - * Find the number of tabs and spaces necessary to get from one column - * to another. - */ - void - tabstop_fromto( - colnr_T start_col, - colnr_T end_col, - int ts_arg, - int *vts, - int *ntabs, - int *nspcs) - { - int spaces = end_col - start_col; - colnr_T tabcol = 0; - int padding = 0; - int tabcount; - int t; - int ts = ts_arg == 0 ? curbuf->b_p_ts : ts_arg; - - if (vts == NULL || vts[0] == 0) - { - int tabs = 0; - int initspc = 0; - - initspc = ts - (start_col % ts); - if (spaces >= initspc) - { - spaces -= initspc; - tabs++; - } - tabs += spaces / ts; - spaces -= (spaces / ts) * ts; - - *ntabs = tabs; - *nspcs = spaces; - return; - } - - /* Find the padding needed to reach the next tabstop. */ - tabcount = vts[0]; - for (t = 1; t <= tabcount; ++t) - { - tabcol += vts[t]; - if (tabcol > start_col) - { - padding = (int)(tabcol - start_col); - break; - } - } - if (t > tabcount) - padding = vts[tabcount] - (int)((start_col - tabcol) % vts[tabcount]); - - /* If the space needed is less than the padding no tabs can be used. */ - if (spaces < padding) - { - *ntabs = 0; - *nspcs = spaces; - return; - } - - *ntabs = 1; - spaces -= padding; - - /* At least one tab has been used. See if any more will fit. */ - while (spaces != 0 && ++t <= tabcount) - { - padding = vts[t]; - if (spaces < padding) - { - *nspcs = spaces; - return; - } - ++*ntabs; - spaces -= padding; - } - - *ntabs += spaces / vts[tabcount]; - *nspcs = spaces % vts[tabcount]; - } - - /* - * See if two tabstop arrays contain the same values. - */ - int - tabstop_eq(int *ts1, int *ts2) - { - int t; - - if ((ts1 == 0 && ts2) || (ts1 && ts2 == 0)) - return FALSE; - if (ts1 == ts2) - return TRUE; - if (ts1[0] != ts2[0]) - return FALSE; - - for (t = 1; t <= ts1[0]; ++t) - if (ts1[t] != ts2[t]) - return FALSE; - - return TRUE; - } - - #if defined(FEAT_BEVAL) || defined(PROTO) - /* - * Copy a tabstop array, allocating space for the new array. - */ - int * - tabstop_copy(int *oldts) - { - int *newts; - int t; - - if (oldts == NULL) - return NULL; - newts = ALLOC_MULT(int, oldts[0] + 1); - if (newts != NULL) - for (t = 0; t <= oldts[0]; ++t) - newts[t] = oldts[t]; - return newts; - } - #endif - - /* - * Return a count of the number of tabstops. - */ - int - tabstop_count(int *ts) - { - return ts != NULL ? ts[0] : 0; - } - - /* - * Return the first tabstop, or 8 if there are no tabstops defined. - */ - int - tabstop_first(int *ts) - { - return ts != NULL ? ts[1] : 8; - } - - #endif - - /* - * Return the effective shiftwidth value for current buffer, using the - * 'tabstop' value when 'shiftwidth' is zero. - */ - long - get_sw_value(buf_T *buf) - { - return get_sw_value_col(buf, 0); - } - - /* - * Idem, using "pos". - */ - static long - get_sw_value_pos(buf_T *buf, pos_T *pos) - { - pos_T save_cursor = curwin->w_cursor; - long sw_value; - - curwin->w_cursor = *pos; - sw_value = get_sw_value_col(buf, get_nolist_virtcol()); - curwin->w_cursor = save_cursor; - return sw_value; - } - - /* - * Idem, using the first non-black in the current line. - */ - long - get_sw_value_indent(buf_T *buf) - { - pos_T pos = curwin->w_cursor; - - pos.col = getwhitecols_curline(); - return get_sw_value_pos(buf, &pos); - } - - /* - * Idem, using virtual column "col". - */ - long - get_sw_value_col(buf_T *buf, colnr_T col UNUSED) - { - return buf->b_p_sw ? buf->b_p_sw : - #ifdef FEAT_VARTABS - tabstop_at(col, buf->b_p_ts, buf->b_p_vts_array); - #else - buf->b_p_ts; - #endif - } - - /* - * Return the effective softtabstop value for the current buffer, using the - * 'shiftwidth' value when 'softtabstop' is negative. - */ - long - get_sts_value(void) - { - return curbuf->b_p_sts < 0 ? get_sw_value(curbuf) : curbuf->b_p_sts; - } - /* * Return the effective 'scrolloff' value for the current window, using the * global value when appropriate. --- 12462,12467 ---- *** ../vim-8.1.1965/src/proto/map.pro 2019-08-01 14:26:53.196455837 +0200 --- src/proto/map.pro 2019-09-02 22:17:58.069928229 +0200 *************** *** 19,24 **** --- 19,27 ---- void get_maparg(typval_T *argvars, typval_T *rettv, int exact); void init_mappings(void); void add_map(char_u *map, int mode); + int langmap_adjust_mb(int c); + void langmap_init(void); + void langmap_set(void); void ex_abbreviate(exarg_T *eap); void ex_map(exarg_T *eap); void ex_unmap(exarg_T *eap); *** ../vim-8.1.1965/src/proto/option.pro 2019-08-24 15:50:42.814107646 +0200 --- src/proto/option.pro 2019-09-02 22:17:58.069928229 +0200 *************** *** 22,29 **** void set_string_option_direct(char_u *name, int opt_idx, char_u *val, int opt_flags, int set_sid); void set_string_option_direct_in_win(win_T *wp, char_u *name, int opt_idx, char_u *val, int opt_flags, int set_sid); void set_string_option_direct_in_buf(buf_T *buf, char_u *name, int opt_idx, char_u *val, int opt_flags, int set_sid); ! int valid_spellang(char_u *val); ! char *check_colorcolumn(win_T *wp); void set_term_option_sctx_idx(char *name, int opt_idx); int get_option_value(char_u *name, long *numval, char_u **stringval, int opt_flags); int get_option_value_strict(char_u *name, long *numval, char_u **stringval, int opt_type, void *from); --- 22,28 ---- void set_string_option_direct(char_u *name, int opt_idx, char_u *val, int opt_flags, int set_sid); void set_string_option_direct_in_win(win_T *wp, char_u *name, int opt_idx, char_u *val, int opt_flags, int set_sid); void set_string_option_direct_in_buf(buf_T *buf, char_u *name, int opt_idx, char_u *val, int opt_flags, int set_sid); ! int valid_name(char_u *val, char *allowed); void set_term_option_sctx_idx(char *name, int opt_idx); int get_option_value(char_u *name, long *numval, char_u **stringval, int opt_flags); int get_option_value_strict(char_u *name, long *numval, char_u **stringval, int opt_type, void *from); *************** *** 38,44 **** void free_termoptions(void); void free_one_termoption(char_u *var); void set_term_defaults(void); - void comp_col(void); void unset_global_local_option(char_u *name, void *from); char_u *get_equalprg(void); void win_copy_options(win_T *wp_from, win_T *wp_to); --- 37,42 ---- *************** *** 51,57 **** void set_context_in_set_cmd(expand_T *xp, char_u *arg, int opt_flags); int ExpandSettings(expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file); int ExpandOldSetting(int *num_file, char_u ***file); - int langmap_adjust_mb(int c); int has_format_option(int x); int shortmess(int x); void vimrc_found(char_u *fname, char_u *envname); --- 49,54 ---- *** ../vim-8.1.1965/src/proto/quickfix.pro 2019-08-20 20:13:40.330821936 +0200 --- src/proto/quickfix.pro 2019-09-02 22:17:58.069928229 +0200 *************** *** 26,36 **** void ex_cbelow(exarg_T *eap); void ex_cfile(exarg_T *eap); void ex_vimgrep(exarg_T *eap); - int get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, list_T *list); - int qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict); int set_errorlist(win_T *wp, list_T *list, int action, char_u *title, dict_T *what); int set_ref_in_quickfix(int copyID); void ex_cbuffer(exarg_T *eap); void ex_cexpr(exarg_T *eap); void ex_helpgrep(exarg_T *eap); /* vim: set ft=c : */ --- 26,38 ---- void ex_cbelow(exarg_T *eap); void ex_cfile(exarg_T *eap); void ex_vimgrep(exarg_T *eap); int set_errorlist(win_T *wp, list_T *list, int action, char_u *title, dict_T *what); int set_ref_in_quickfix(int copyID); void ex_cbuffer(exarg_T *eap); void ex_cexpr(exarg_T *eap); void ex_helpgrep(exarg_T *eap); + void f_getloclist(typval_T *argvars, typval_T *rettv); + void f_getqflist(typval_T *argvars, typval_T *rettv); + void f_setloclist(typval_T *argvars, typval_T *rettv); + void f_setqflist(typval_T *argvars, typval_T *rettv); /* vim: set ft=c : */ *** ../vim-8.1.1965/src/proto/screen.pro 2019-06-14 19:23:35.502289836 +0200 --- src/proto/screen.pro 2019-09-02 22:17:58.069928229 +0200 *************** *** 59,65 **** --- 59,67 ---- int redrawing(void); int messaging(void); void showruler(int always); + void comp_col(void); int number_width(win_T *wp); int screen_screencol(void); int screen_screenrow(void); + char *set_chars_option(char_u **varp); /* vim: set ft=c : */ *** ../vim-8.1.1965/src/proto/spell.pro 2019-08-20 20:13:40.330821936 +0200 --- src/proto/spell.pro 2019-09-02 22:17:58.069928229 +0200 *************** *** 34,37 **** --- 34,41 ---- int spell_word_start(int startcol); void spell_expand_check_cap(colnr_T col); int expand_spelling(linenr_T lnum, char_u *pat, char_u ***matchp); + int valid_spellang(char_u *val); + int valid_spellfile(char_u *val); + char *did_set_spell_option(int is_spellfile); + char *compile_cap_prog(synblock_T *synblock); /* vim: set ft=c : */ *** ../vim-8.1.1965/src/proto/window.pro 2019-08-30 15:46:27.188906163 +0200 --- src/proto/window.pro 2019-09-02 22:17:58.069928229 +0200 *************** *** 82,87 **** --- 82,88 ---- int win_hasvertsplit(void); int get_win_number(win_T *wp, win_T *first_win); int get_tab_number(tabpage_T *tp); + char *check_colorcolumn(win_T *wp); int win_getid(typval_T *argvars); int win_gotoid(typval_T *argvars); void win_id2tabwin(typval_T *argvars, list_T *list); *** ../vim-8.1.1965/src/quickfix.c 2019-08-20 20:13:40.334821916 +0200 --- src/quickfix.c 2019-09-02 22:27:33.731283427 +0200 *************** *** 6305,6311 **** * Add each quickfix error to list "list" as a dictionary. * If qf_idx is -1, use the current list. Otherwise, use the specified list. */ ! int get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, list_T *list) { qf_info_T *qi = qi_arg; --- 6305,6311 ---- * Add each quickfix error to list "list" as a dictionary. * If qf_idx is -1, use the current list. Otherwise, use the specified list. */ ! static int get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, list_T *list) { qf_info_T *qi = qi_arg; *************** *** 6678,6684 **** * dictionary. 'what' contains the details to return. If 'list_idx' is -1, * then current list is used. Otherwise the specified list is used. */ ! int qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict) { qf_info_T *qi = &ql_info; --- 6678,6684 ---- * dictionary. 'what' contains the details to return. If 'list_idx' is -1, * then current list is used. Otherwise the specified list is used. */ ! static int qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict) { qf_info_T *qi = &ql_info; *************** *** 7824,7828 **** curwin->w_llist = qi; } } - #endif /* FEAT_QUICKFIX */ --- 7824,7976 ---- curwin->w_llist = qi; } } #endif /* FEAT_QUICKFIX */ + + #if defined(FEAT_EVAL) || defined(PROTO) + # ifdef FEAT_QUICKFIX + static void + get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg, typval_T *rettv) + { + if (what_arg->v_type == VAR_UNKNOWN) + { + if (rettv_list_alloc(rettv) == OK) + if (is_qf || wp != NULL) + (void)get_errorlist(NULL, wp, -1, rettv->vval.v_list); + } + else + { + if (rettv_dict_alloc(rettv) == OK) + if (is_qf || (wp != NULL)) + { + if (what_arg->v_type == VAR_DICT) + { + dict_T *d = what_arg->vval.v_dict; + + if (d != NULL) + qf_get_properties(wp, d, rettv->vval.v_dict); + } + else + emsg(_(e_dictreq)); + } + } + } + # endif + + /* + * "getloclist()" function + */ + void + f_getloclist(typval_T *argvars UNUSED, typval_T *rettv UNUSED) + { + # ifdef FEAT_QUICKFIX + win_T *wp; + + wp = find_win_by_nr_or_id(&argvars[0]); + get_qf_loc_list(FALSE, wp, &argvars[1], rettv); + # endif + } + + /* + * "getqflist()" function + */ + void + f_getqflist(typval_T *argvars UNUSED, typval_T *rettv UNUSED) + { + # ifdef FEAT_QUICKFIX + get_qf_loc_list(TRUE, NULL, &argvars[0], rettv); + # endif + } + + /* + * Used by "setqflist()" and "setloclist()" functions + */ + static void + set_qf_ll_list( + win_T *wp UNUSED, + typval_T *list_arg UNUSED, + typval_T *action_arg UNUSED, + typval_T *what_arg UNUSED, + typval_T *rettv) + { + # ifdef FEAT_QUICKFIX + static char *e_invact = N_("E927: Invalid action: '%s'"); + char_u *act; + int action = 0; + static int recursive = 0; + # endif + + rettv->vval.v_number = -1; + + # ifdef FEAT_QUICKFIX + if (list_arg->v_type != VAR_LIST) + emsg(_(e_listreq)); + else if (recursive != 0) + emsg(_(e_au_recursive)); + else + { + list_T *l = list_arg->vval.v_list; + dict_T *d = NULL; + int valid_dict = TRUE; + + if (action_arg->v_type == VAR_STRING) + { + act = tv_get_string_chk(action_arg); + if (act == NULL) + return; // type error; errmsg already given + if ((*act == 'a' || *act == 'r' || *act == ' ' || *act == 'f') && + act[1] == NUL) + action = *act; + else + semsg(_(e_invact), act); + } + else if (action_arg->v_type == VAR_UNKNOWN) + action = ' '; + else + emsg(_(e_stringreq)); + + if (action_arg->v_type != VAR_UNKNOWN + && what_arg->v_type != VAR_UNKNOWN) + { + if (what_arg->v_type == VAR_DICT) + d = what_arg->vval.v_dict; + else + { + emsg(_(e_dictreq)); + valid_dict = FALSE; + } + } + + ++recursive; + if (l != NULL && action && valid_dict && set_errorlist(wp, l, action, + (char_u *)(wp == NULL ? ":setqflist()" : ":setloclist()"), + d) == OK) + rettv->vval.v_number = 0; + --recursive; + } + # endif + } + + /* + * "setloclist()" function + */ + void + f_setloclist(typval_T *argvars, typval_T *rettv) + { + win_T *win; + + rettv->vval.v_number = -1; + + win = find_win_by_nr_or_id(&argvars[0]); + if (win != NULL) + set_qf_ll_list(win, &argvars[1], &argvars[2], &argvars[3], rettv); + } + + /* + * "setqflist()" function + */ + void + f_setqflist(typval_T *argvars, typval_T *rettv) + { + set_qf_ll_list(NULL, &argvars[0], &argvars[1], &argvars[2], rettv); + } + #endif *** ../vim-8.1.1965/src/screen.c 2019-08-24 20:54:15.979845564 +0200 --- src/screen.c 2019-09-02 22:28:45.642952273 +0200 *************** *** 10771,10776 **** --- 10771,10825 ---- } #endif + /* + * Compute columns for ruler and shown command. 'sc_col' is also used to + * decide what the maximum length of a message on the status line can be. + * If there is a status line for the last window, 'sc_col' is independent + * of 'ru_col'. + */ + + #define COL_RULER 17 // columns needed by standard ruler + + void + comp_col(void) + { + #if defined(FEAT_CMDL_INFO) + int last_has_status = (p_ls == 2 || (p_ls == 1 && !ONE_WINDOW)); + + sc_col = 0; + ru_col = 0; + if (p_ru) + { + # ifdef FEAT_STL_OPT + ru_col = (ru_wid ? ru_wid : COL_RULER) + 1; + # else + ru_col = COL_RULER + 1; + # endif + // no last status line, adjust sc_col + if (!last_has_status) + sc_col = ru_col; + } + if (p_sc) + { + sc_col += SHOWCMD_COLS; + if (!p_ru || last_has_status) // no need for separating space + ++sc_col; + } + sc_col = Columns - sc_col; + ru_col = Columns - ru_col; + if (sc_col <= 0) // screen too narrow, will become a mess + sc_col = 1; + if (ru_col <= 0) + ru_col = 1; + #else + sc_col = Columns; + ru_col = Columns; + #endif + #ifdef FEAT_EVAL + set_vim_var_nr(VV_ECHOSPACE, sc_col - 1); + #endif + } + #if defined(FEAT_LINEBREAK) || defined(PROTO) /* * Return the width of the 'number' and 'relativenumber' column. *************** *** 10840,10842 **** --- 10889,11021 ---- return screen_cur_row; } #endif + + /* + * Handle setting 'listchars' or 'fillchars'. + * Returns error message, NULL if it's OK. + */ + char * + set_chars_option(char_u **varp) + { + int round, i, len, entries; + char_u *p, *s; + int c1 = 0, c2 = 0, c3 = 0; + struct charstab + { + int *cp; + char *name; + }; + static struct charstab filltab[] = + { + {&fill_stl, "stl"}, + {&fill_stlnc, "stlnc"}, + {&fill_vert, "vert"}, + {&fill_fold, "fold"}, + {&fill_diff, "diff"}, + }; + static struct charstab lcstab[] = + { + {&lcs_eol, "eol"}, + {&lcs_ext, "extends"}, + {&lcs_nbsp, "nbsp"}, + {&lcs_prec, "precedes"}, + {&lcs_space, "space"}, + {&lcs_tab2, "tab"}, + {&lcs_trail, "trail"}, + #ifdef FEAT_CONCEAL + {&lcs_conceal, "conceal"}, + #else + {NULL, "conceal"}, + #endif + }; + struct charstab *tab; + + if (varp == &p_lcs) + { + tab = lcstab; + entries = sizeof(lcstab) / sizeof(struct charstab); + } + else + { + tab = filltab; + entries = sizeof(filltab) / sizeof(struct charstab); + } + + // first round: check for valid value, second round: assign values + for (round = 0; round <= 1; ++round) + { + if (round > 0) + { + // After checking that the value is valid: set defaults: space for + // 'fillchars', NUL for 'listchars' + for (i = 0; i < entries; ++i) + if (tab[i].cp != NULL) + *(tab[i].cp) = (varp == &p_lcs ? NUL : ' '); + + if (varp == &p_lcs) + { + lcs_tab1 = NUL; + lcs_tab3 = NUL; + } + else + fill_diff = '-'; + } + p = *varp; + while (*p) + { + for (i = 0; i < entries; ++i) + { + len = (int)STRLEN(tab[i].name); + if (STRNCMP(p, tab[i].name, len) == 0 + && p[len] == ':' + && p[len + 1] != NUL) + { + c2 = c3 = 0; + s = p + len + 1; + c1 = mb_ptr2char_adv(&s); + if (mb_char2cells(c1) > 1) + continue; + if (tab[i].cp == &lcs_tab2) + { + if (*s == NUL) + continue; + c2 = mb_ptr2char_adv(&s); + if (mb_char2cells(c2) > 1) + continue; + if (!(*s == ',' || *s == NUL)) + { + c3 = mb_ptr2char_adv(&s); + if (mb_char2cells(c3) > 1) + continue; + } + } + + if (*s == ',' || *s == NUL) + { + if (round) + { + if (tab[i].cp == &lcs_tab2) + { + lcs_tab1 = c1; + lcs_tab2 = c2; + lcs_tab3 = c3; + } + else if (tab[i].cp != NULL) + *(tab[i].cp) = c1; + + } + p = s; + break; + } + } + } + + if (i == entries) + return e_invarg; + if (*p == ',') + ++p; + } + } + + return NULL; // no error + } *** ../vim-8.1.1965/src/spell.c 2019-08-21 14:36:29.391376081 +0200 --- src/spell.c 2019-09-02 22:29:11.610832640 +0200 *************** *** 8833,8836 **** return ga.ga_len; } ! #endif /* FEAT_SPELL */ --- 8833,8922 ---- return ga.ga_len; } ! /* ! * Return TRUE if "val" is a valid 'spellang' value. ! */ ! int ! valid_spellang(char_u *val) ! { ! return valid_name(val, ".-_,@"); ! } ! ! /* ! * Return TRUE if "val" is a valid 'spellfile' value. ! */ ! int ! valid_spellfile(char_u *val) ! { ! char_u *s; ! ! for (s = val; *s != NUL; ++s) ! if (!vim_isfilec(*s) && *s != ',') ! return FALSE; ! return TRUE; ! } ! ! /* ! * Handle side effects of setting 'spell'. ! * Return an error message or NULL for success. ! */ ! char * ! did_set_spell_option(int is_spellfile) ! { ! char *errmsg = NULL; ! win_T *wp; ! int l; ! ! if (is_spellfile) ! { ! l = (int)STRLEN(curwin->w_s->b_p_spf); ! if (l > 0 && (l < 4 ! || STRCMP(curwin->w_s->b_p_spf + l - 4, ".add") != 0)) ! errmsg = e_invarg; ! } ! ! if (errmsg == NULL) ! { ! FOR_ALL_WINDOWS(wp) ! if (wp->w_buffer == curbuf && wp->w_p_spell) ! { ! errmsg = did_set_spelllang(wp); ! break; ! } ! } ! return errmsg; ! } ! ! /* ! * Set curbuf->b_cap_prog to the regexp program for 'spellcapcheck'. ! * Return error message when failed, NULL when OK. ! */ ! char * ! compile_cap_prog(synblock_T *synblock) ! { ! regprog_T *rp = synblock->b_cap_prog; ! char_u *re; ! ! if (*synblock->b_p_spc == NUL) ! synblock->b_cap_prog = NULL; ! else ! { ! // Prepend a ^ so that we only match at one column ! re = concat_str((char_u *)"^", synblock->b_p_spc); ! if (re != NULL) ! { ! synblock->b_cap_prog = vim_regcomp(re, RE_MAGIC); ! vim_free(re); ! if (synblock->b_cap_prog == NULL) ! { ! synblock->b_cap_prog = rp; // restore the previous program ! return e_invarg; ! } ! } ! } ! ! vim_regfree(rp); ! return NULL; ! } ! ! #endif // FEAT_SPELL *** ../vim-8.1.1965/src/window.c 2019-09-01 20:21:53.070152262 +0200 --- src/window.c 2019-09-02 22:24:30.776125352 +0200 *************** *** 6816,6821 **** --- 6816,6902 ---- return TRUE; } + #if defined(FEAT_SYN_HL) || defined(PROTO) + /* + * Simple int comparison function for use with qsort() + */ + static int + int_cmp(const void *a, const void *b) + { + return *(const int *)a - *(const int *)b; + } + + /* + * Handle setting 'colorcolumn' or 'textwidth' in window "wp". + * Returns error message, NULL if it's OK. + */ + char * + check_colorcolumn(win_T *wp) + { + char_u *s; + int col; + int count = 0; + int color_cols[256]; + int i; + int j = 0; + + if (wp->w_buffer == NULL) + return NULL; // buffer was closed + + for (s = wp->w_p_cc; *s != NUL && count < 255;) + { + if (*s == '-' || *s == '+') + { + // -N and +N: add to 'textwidth' + col = (*s == '-') ? -1 : 1; + ++s; + if (!VIM_ISDIGIT(*s)) + return e_invarg; + col = col * getdigits(&s); + if (wp->w_buffer->b_p_tw == 0) + goto skip; // 'textwidth' not set, skip this item + col += wp->w_buffer->b_p_tw; + if (col < 0) + goto skip; + } + else if (VIM_ISDIGIT(*s)) + col = getdigits(&s); + else + return e_invarg; + color_cols[count++] = col - 1; // 1-based to 0-based + skip: + if (*s == NUL) + break; + if (*s != ',') + return e_invarg; + if (*++s == NUL) + return e_invarg; // illegal trailing comma as in "set cc=80," + } + + vim_free(wp->w_p_cc_cols); + if (count == 0) + wp->w_p_cc_cols = NULL; + else + { + wp->w_p_cc_cols = ALLOC_MULT(int, count + 1); + if (wp->w_p_cc_cols != NULL) + { + // sort the columns for faster usage on screen redraw inside + // win_line() + qsort(color_cols, count, sizeof(int), int_cmp); + + for (i = 0; i < count; ++i) + // skip duplicates + if (j == 0 || wp->w_p_cc_cols[j - 1] != color_cols[i]) + wp->w_p_cc_cols[j++] = color_cols[i]; + wp->w_p_cc_cols[j] = -1; // end marker + } + } + + return NULL; // no error + } + #endif + #if defined(FEAT_EVAL) || defined(PROTO) int win_getid(typval_T *argvars) *** ../vim-8.1.1965/src/version.c 2019-09-02 21:44:55.598219399 +0200 --- src/version.c 2019-09-02 22:29:31.350741708 +0200 *************** *** 763,764 **** --- 763,766 ---- { /* Add new patch number below this line */ + /**/ + 1966, /**/ -- Apathy Error: Don't bother striking any key. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///