To: vim_dev@googlegroups.com Subject: Patch 8.2.3520 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3520 Problem: Cannot define a function for thesaurus completion. Solution: Add 'thesaurusfunc'. (Yegappan Lakshmanan, closes #8987, closes 8950) Files: runtime/doc/insert.txt, runtime/doc/options.txt, runtime/doc/quickref.txt, src/buffer.c, src/insexpand.c, src/option.c, src/option.h, src/optiondefs.h, src/optionstr.c, src/structs.h, src/testdir/test_edit.vim *** ../vim-8.2.3519/runtime/doc/insert.txt 2021-08-31 18:12:47.757554157 +0100 --- runtime/doc/insert.txt 2021-10-16 15:31:40.597778557 +0100 *************** *** 842,847 **** --- 842,853 ---- Other uses include translation between two languages, or grouping API functions by keyword. + If the 'thesaurusfunc' option is set, then the user + specified function is invoked to get the list of + completion matches and the 'thesaurus' option is not + used. See |complete-functions| for an explanation of + how the function is invoked and what it should return. + CTRL-T or CTRL-N Search forward for next matching keyword. This keyword replaces the previous matching keyword. *************** *** 1052,1058 **** FUNCTIONS FOR FINDING COMPLETIONS *complete-functions* ! This applies to 'completefunc' and 'omnifunc'. The function is called in two different ways: - First the function is called to find the start of the text to be completed. --- 1058,1064 ---- FUNCTIONS FOR FINDING COMPLETIONS *complete-functions* ! This applies to 'completefunc', 'thesaurusfunc' and 'omnifunc'. The function is called in two different ways: - First the function is called to find the start of the text to be completed. *** ../vim-8.2.3519/runtime/doc/options.txt 2021-10-14 17:52:19.016102283 +0100 --- runtime/doc/options.txt 2021-10-16 15:31:40.597778557 +0100 *************** *** 8009,8014 **** --- 8028,8045 ---- uses another default. Backticks cannot be used in this option for security reasons. + *'thesaurusfunc'* *tsrfu'* + 'thesaurusfunc' 'tsrfu' string (default: empty) + local to buffer + {not available when compiled without the |+eval| + feature} + This option specifies a function to be used for thesaurus completion + with CTRL-X CTRL-T. |i_CTRL-X_CTRL-T| + See |complete-functions| for an explanation of how the function is + invoked and what it should return. + This option cannot be set from a |modeline| or in the |sandbox|, for + security reasons. + *'tildeop'* *'top'* *'notildeop'* *'notop'* 'tildeop' 'top' boolean (default off) global *** ../vim-8.2.3519/runtime/doc/quickref.txt 2021-03-29 19:49:01.482055371 +0100 --- runtime/doc/quickref.txt 2021-10-16 15:31:40.597778557 +0100 *************** *** 948,953 **** --- 948,954 ---- 'textmode' 'tx' obsolete, use 'fileformat' 'textwidth' 'tw' maximum width of text that is being inserted 'thesaurus' 'tsr' list of thesaurus files for keyword completion + 'thesaurusfunc' 'tsrfu' function to be used for thesaurus completion 'tildeop' 'top' tilde command "~" behaves like an operator 'timeout' 'to' time out on mappings and key codes 'timeoutlen' 'tm' time out time in milliseconds *** ../vim-8.2.3519/src/buffer.c 2021-10-16 11:58:51.409123004 +0100 --- src/buffer.c 2021-10-16 15:31:40.597778557 +0100 *************** *** 2364,2369 **** --- 2364,2370 ---- #ifdef FEAT_COMPL_FUNC clear_string_option(&buf->b_p_cfu); clear_string_option(&buf->b_p_ofu); + clear_string_option(&buf->b_p_thsfu); #endif #ifdef FEAT_QUICKFIX clear_string_option(&buf->b_p_gp); *** ../vim-8.2.3519/src/insexpand.c 2021-10-03 12:01:23.533541368 +0100 --- src/insexpand.c 2021-10-16 15:31:40.601778604 +0100 *************** *** 299,305 **** && !curwin->w_p_spell #endif ) ! : (*curbuf->b_p_tsr == NUL && *p_tsr == NUL)) { ctrl_x_mode = CTRL_X_NORMAL; edit_submode = NULL; --- 299,309 ---- && !curwin->w_p_spell #endif ) ! : (*curbuf->b_p_tsr == NUL && *p_tsr == NUL ! #ifdef FEAT_COMPL_FUNC ! && *curbuf->b_p_thsfu == NUL ! #endif ! )) { ctrl_x_mode = CTRL_X_NORMAL; edit_submode = NULL; *************** *** 2230,2235 **** --- 2234,2258 ---- #ifdef FEAT_COMPL_FUNC /* + * Get the user-defined completion function name for completion 'type' + */ + static char_u * + get_complete_funcname(int type) + { + switch (type) + { + case CTRL_X_FUNCTION: + return curbuf->b_p_cfu; + case CTRL_X_OMNI: + return curbuf->b_p_ofu; + case CTRL_X_THESAURUS: + return curbuf->b_p_thsfu; + default: + return (char_u *)""; + } + } + + /* * Execute user defined complete function 'completefunc' or 'omnifunc', and * get matches in "matches". */ *************** *** 2246,2252 **** typval_T rettv; int save_State = State; ! funcname = (type == CTRL_X_FUNCTION) ? curbuf->b_p_cfu : curbuf->b_p_ofu; if (*funcname == NUL) return; --- 2269,2275 ---- typval_T rettv; int save_State = State; ! funcname = get_complete_funcname(type); if (*funcname == NUL) return; *************** *** 2721,2726 **** --- 2744,2764 ---- #endif /* + * Returns TRUE when using a user-defined function for thesaurus completion. + */ + static int + thesaurus_func_complete(int type UNUSED) + { + #ifdef FEAT_COMPL_FUNC + return (type == CTRL_X_THESAURUS + && curbuf->b_p_thsfu != NULL + && *curbuf->b_p_thsfu != NUL); + #else + return FALSE; + #endif + } + + /* * Get the next expansion(s), using "compl_pattern". * The search starts at position "ini" in curbuf and in the direction * compl_direction. *************** *** 2906,2912 **** case CTRL_X_DICTIONARY: case CTRL_X_THESAURUS: ! ins_compl_dictionaries( dict != NULL ? dict : (type == CTRL_X_THESAURUS ? (*curbuf->b_p_tsr == NUL --- 2944,2955 ---- case CTRL_X_DICTIONARY: case CTRL_X_THESAURUS: ! #ifdef FEAT_COMPL_FUNC ! if (thesaurus_func_complete(type)) ! expand_by_function(type, compl_pattern); ! else ! #endif ! ins_compl_dictionaries( dict != NULL ? dict : (type == CTRL_X_THESAURUS ? (*curbuf->b_p_tsr == NUL *************** *** 3760,3766 **** } // Work out completion pattern and original text -- webb ! if (ctrl_x_mode == CTRL_X_NORMAL || (ctrl_x_mode & CTRL_X_WANT_IDENT)) { if ((compl_cont_status & CONT_SOL) || ctrl_x_mode == CTRL_X_PATH_DEFINES) --- 3803,3811 ---- } // Work out completion pattern and original text -- webb ! if (ctrl_x_mode == CTRL_X_NORMAL ! || (ctrl_x_mode & CTRL_X_WANT_IDENT ! && !thesaurus_func_complete(ctrl_x_mode))) { if ((compl_cont_status & CONT_SOL) || ctrl_x_mode == CTRL_X_PATH_DEFINES) *************** *** 3910,3916 **** compl_col = (int)(compl_xp.xp_pattern - compl_pattern); compl_length = curs_col - compl_col; } ! else if (ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI) { #ifdef FEAT_COMPL_FUNC // Call user defined function 'completefunc' with "a:findstart" --- 3955,3962 ---- compl_col = (int)(compl_xp.xp_pattern - compl_pattern); compl_length = curs_col - compl_col; } ! else if (ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI ! || thesaurus_func_complete(ctrl_x_mode)) { #ifdef FEAT_COMPL_FUNC // Call user defined function 'completefunc' with "a:findstart" *************** *** 3923,3930 **** // Call 'completefunc' or 'omnifunc' and get pattern length as a // string ! funcname = ctrl_x_mode == CTRL_X_FUNCTION ! ? curbuf->b_p_cfu : curbuf->b_p_ofu; if (*funcname == NUL) { semsg(_(e_notset), ctrl_x_mode == CTRL_X_FUNCTION --- 3969,3975 ---- // Call 'completefunc' or 'omnifunc' and get pattern length as a // string ! funcname = get_complete_funcname(ctrl_x_mode); if (*funcname == NUL) { semsg(_(e_notset), ctrl_x_mode == CTRL_X_FUNCTION *** ../vim-8.2.3519/src/option.c 2021-10-09 15:39:20.459884353 +0100 --- src/option.c 2021-10-16 15:31:40.601778604 +0100 *************** *** 5433,5438 **** --- 5433,5439 ---- #ifdef FEAT_COMPL_FUNC case PV_CFU: return (char_u *)&(curbuf->b_p_cfu); case PV_OFU: return (char_u *)&(curbuf->b_p_ofu); + case PV_THSFU: return (char_u *)&(curbuf->b_p_thsfu); #endif #ifdef FEAT_EVAL case PV_TFU: return (char_u *)&(curbuf->b_p_tfu); *************** *** 5935,5940 **** --- 5936,5943 ---- COPY_OPT_SCTX(buf, BV_CFU); buf->b_p_ofu = vim_strsave(p_ofu); COPY_OPT_SCTX(buf, BV_OFU); + buf->b_p_thsfu = vim_strsave(p_thsfu); + COPY_OPT_SCTX(buf, BV_THSFU); #endif #ifdef FEAT_EVAL buf->b_p_tfu = vim_strsave(p_tfu); *** ../vim-8.2.3519/src/option.h 2021-08-03 17:33:04.651157866 +0100 --- src/option.h 2021-10-16 15:31:40.601778604 +0100 *************** *** 404,409 **** --- 404,410 ---- #ifdef FEAT_COMPL_FUNC EXTERN char_u *p_cfu; // 'completefunc' EXTERN char_u *p_ofu; // 'omnifunc' + EXTERN char_u *p_thsfu; // 'thesaurusfunc' #endif EXTERN int p_ci; // 'copyindent' #if defined(FEAT_GUI) && defined(MACOS_X) *************** *** 1217,1222 **** --- 1218,1226 ---- #endif , BV_TAGS , BV_TC + #ifdef FEAT_COMPL_FUNC + , BV_THSFU + #endif , BV_TS , BV_TW , BV_TX *** ../vim-8.2.3519/src/optiondefs.h 2021-07-26 21:19:05.380122574 +0100 --- src/optiondefs.h 2021-10-16 15:31:40.601778604 +0100 *************** *** 140,145 **** --- 140,148 ---- #ifdef FEAT_EVAL # define PV_TFU OPT_BUF(BV_TFU) #endif + #ifdef FEAT_COMPL_FUNC + # define PV_THSFU OPT_BUF(BV_THSFU) + #endif #define PV_TAGS OPT_BOTH(OPT_BUF(BV_TAGS)) #define PV_TC OPT_BOTH(OPT_BUF(BV_TC)) #define PV_TS OPT_BUF(BV_TS) *************** *** 2616,2621 **** --- 2619,2633 ---- {"thesaurus", "tsr", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA|P_NODUP|P_NDNAME, (char_u *)&p_tsr, PV_TSR, {(char_u *)"", (char_u *)0L} SCTX_INIT}, + {"thesaurusfunc", "tsrfu", P_STRING|P_ALLOCED|P_VI_DEF|P_SECURE, + #ifdef FEAT_COMPL_FUNC + (char_u *)&p_thsfu, PV_THSFU, + {(char_u *)"", (char_u *)0L} + #else + (char_u *)NULL, PV_NONE, + {(char_u *)0L, (char_u *)0L} + #endif + SCTX_INIT}, {"tildeop", "top", P_BOOL|P_VI_DEF|P_VIM, (char_u *)&p_to, PV_NONE, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, *** ../vim-8.2.3519/src/optionstr.c 2021-09-04 17:47:25.184668070 +0100 --- src/optionstr.c 2021-10-16 15:31:40.601778604 +0100 *************** *** 271,276 **** --- 271,277 ---- #ifdef FEAT_COMPL_FUNC check_string_option(&buf->b_p_cfu); check_string_option(&buf->b_p_ofu); + check_string_option(&buf->b_p_thsfu); #endif #ifdef FEAT_EVAL check_string_option(&buf->b_p_tfu); *** ../vim-8.2.3519/src/structs.h 2021-10-16 11:58:51.409123004 +0100 --- src/structs.h 2021-10-16 15:31:40.601778604 +0100 *************** *** 2864,2869 **** --- 2864,2870 ---- #ifdef FEAT_COMPL_FUNC char_u *b_p_cfu; // 'completefunc' char_u *b_p_ofu; // 'omnifunc' + char_u *b_p_thsfu; // 'thesaurusfunc' #endif #ifdef FEAT_EVAL char_u *b_p_tfu; // 'tagfunc' *** ../vim-8.2.3519/src/testdir/test_edit.vim 2021-10-02 21:48:08.639938510 +0100 --- src/testdir/test_edit.vim 2021-10-16 15:31:40.601778604 +0100 *************** *** 890,895 **** --- 890,937 ---- bw! endfunc + " Test 'thesaurusfunc' + func MyThesaurus(findstart, base) + let mythesaurus = [ + \ #{word: "happy", + \ synonyms: "cheerful,blissful,flying high,looking good,peppy"}, + \ #{word: "kind", + \ synonyms: "amiable,bleeding-heart,heart in right place"}] + if a:findstart + " locate the start of the word + let line = getline('.') + let start = col('.') - 1 + while start > 0 && line[start - 1] =~ '\a' + let start -= 1 + endwhile + return start + else + " find strings matching with "a:base" + let res = [] + for w in mythesaurus + if w.word =~ '^' . a:base + call add(res, w.word) + call extend(res, split(w.synonyms, ",")) + endif + endfor + return res + endif + endfunc + + func Test_thesaurus_func() + new + set thesaurus= + set thesaurusfunc=MyThesaurus + call setline(1, "an ki") + call cursor(1, 1) + call feedkeys("A\\\\\", 'tnix') + call assert_equal(['an amiable', ''], getline(1, '$')) + set thesaurusfunc=NonExistingFunc + call assert_fails("normal $a\\", 'E117:') + set thesaurusfunc& + %bw! + endfunc + func Test_edit_CTRL_U() " Test 'completefunc' new *** ../vim-8.2.3519/src/version.c 2021-10-16 13:44:01.208331391 +0100 --- src/version.c 2021-10-16 15:33:39.139170507 +0100 *************** *** 759,760 **** --- 759,762 ---- { /* Add new patch number below this line */ + /**/ + 3520, /**/ -- 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/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///