diff options
-rw-r--r-- | runtime/doc/options.txt | 22 | ||||
-rw-r--r-- | runtime/filetype.vim | 13 | ||||
-rw-r--r-- | runtime/pack/dist/opt/termdebug/plugin/termdebug.vim | 15 | ||||
-rw-r--r-- | src/nvim/buffer.c | 48 | ||||
-rw-r--r-- | src/nvim/eval.c | 2 | ||||
-rw-r--r-- | src/nvim/hardcopy.c | 39 | ||||
-rw-r--r-- | src/nvim/spell.c | 10 | ||||
-rw-r--r-- | src/nvim/spellfile.c | 5 | ||||
-rw-r--r-- | src/nvim/testdir/test_filetype.vim | 24 | ||||
-rw-r--r-- | src/nvim/testdir/test_statusline.vim | 24 |
10 files changed, 139 insertions, 63 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 8d4f76d3dd..e1beea0fed 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -3947,6 +3947,8 @@ A jump table for the options with a short description can be found at |Q_op|. When on allow some options that are an expression to be set in the modeline. Check the option for whether it is affected by 'modelineexpr'. Also see |modeline|. + This option cannot be set from a |modeline| or in the |sandbox|, for + security reasons. *'modelines'* *'mls'* 'modelines' 'mls' number (default 5) @@ -5807,7 +5809,9 @@ A jump table for the options with a short description can be found at |Q_op|. When the option starts with "%!" then it is used as an expression, evaluated and the result is used as the option value. Example: > :set statusline=%!MyStatusLine() -< The result can contain %{} items that will be evaluated too. +< The *g:statusline_winid* variable will be set to the |window-ID| of the + window that the status line belongs to. + The result can contain %{} items that will be evaluated too. Note that the "%!" expression is evaluated in the context of the current window and buffer, while %{} items are evaluated in the context of the window that the statusline belongs to. @@ -5936,13 +5940,15 @@ A jump table for the options with a short description can be found at |Q_op|. become empty. This will make a group like the following disappear completely from the statusline when none of the flags are set. > :set statusline=...%(\ [%M%R%H]%)... -< *g:actual_curbuf* - Beware that an expression is evaluated each and every time the status - line is displayed. The current buffer and current window will be set - temporarily to that of the window (and buffer) whose statusline is - currently being drawn. The expression will evaluate in this context. - The variable "g:actual_curbuf" is set to the `bufnr()` number of the - real current buffer. +< Beware that an expression is evaluated each and every time the status + line is displayed. + *g:actual_curbuf* *g:actual_curwin* + The current buffer and current window will be set temporarily to that + of the window (and buffer) whose statusline is currently being drawn. + The expression will evaluate in this context. The variable + "g:actual_curbuf" is set to the `bufnr()` number of the real current + buffer and "g:actual_curwin" to the |window-ID| of the real current + window. These values are strings. The 'statusline' option will be evaluated in the |sandbox| if set from a modeline, see |sandbox-option|. diff --git a/runtime/filetype.vim b/runtime/filetype.vim index 6f31eeb832..6807bef3eb 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -538,7 +538,7 @@ au BufNewFile,BufRead *.ecd setf ecd au BufNewFile,BufRead *.e,*.E call dist#ft#FTe() " Elinks configuration -au BufNewFile,BufRead */etc/elinks.conf,*/.elinks/elinks.conf setf elinks +au BufNewFile,BufRead elinks.conf setf elinks " ERicsson LANGuage; Yaws is erlang too au BufNewFile,BufRead *.erl,*.hrl,*.yaws setf erlang @@ -1130,8 +1130,17 @@ au BufNewFile,BufRead *.ora setf ora " Packet filter conf au BufNewFile,BufRead pf.conf setf pf +" Pacman Config (close enough to dosini) +au BufNewFile,BufRead */etc/pacman.conf setf dosini + +" Pacman hooks +au BufNewFile,BufRead *.hook + \ if getline(1) == '[Trigger]' | + \ setf dosini | + \ endif + " Pam conf -au BufNewFile,BufRead */etc/pam.conf setf pamconf +au BufNewFile,BufRead */etc/pam.conf setf pamconf " Pam environment au BufNewFile,BufRead pam_env.conf,.pam_environment setf pamenv diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim index 2898bd991b..6870bcec75 100644 --- a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim +++ b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim @@ -466,12 +466,17 @@ endfunc " Function called when pressing CTRL-C in the prompt buffer and when placing a " breakpoint. func s:PromptInterrupt() - if s:pid == 0 - echoerr 'Cannot interrupt gdb, did not find a process ID' + " call ch_log('Interrupting gdb') + if has('win32') + " Using job_stop() does not work on MS-Windows, need to send SIGTRAP to + " the debugger program so that gdb responds again. + if s:pid == 0 + echoerr 'Cannot interrupt gdb, did not find a process ID' + else + call debugbreak(s:pid) + endif else - "call ch_log('Interrupting gdb') - " Using job_stop(s:gdbjob, 'int') does not work. - call debugbreak(s:pid) + call jobstop(s:gdbjob) endif endfunc diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 29712e9f52..86067aceac 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3464,7 +3464,8 @@ int build_stl_str_hl( } type; } items[STL_MAX_ITEM]; #define TMPLEN 70 - char_u tmp[TMPLEN]; + char_u buf_tmp[TMPLEN]; + char_u win_tmp[TMPLEN]; char_u *usefmt = fmt; const int save_must_redraw = must_redraw; const int save_redr_type = curwin->w_redr_type; @@ -3472,10 +3473,18 @@ int build_stl_str_hl( // When the format starts with "%!" then evaluate it as an expression and // use the result as the actual format string. if (fmt[0] == '%' && fmt[1] == '!') { + typval_T tv = { + .v_type = VAR_NUMBER, + .vval.v_number = wp->handle, + }; + set_var(S_LEN("g:statusline_winid"), &tv, false); + usefmt = eval_to_string_safe(fmt + 2, NULL, use_sandbox); if (usefmt == NULL) { usefmt = fmt; } + + do_unlet(S_LEN("g:statusline_winid"), true); } if (fillchar == 0) { @@ -3904,8 +3913,10 @@ int build_stl_str_hl( // { Evaluate the expression // Store the current buffer number as a string variable - vim_snprintf((char *)tmp, sizeof(tmp), "%d", curbuf->b_fnum); - set_internal_string_var((char_u *)"g:actual_curbuf", tmp); + vim_snprintf((char *)buf_tmp, sizeof(buf_tmp), "%d", curbuf->b_fnum); + set_internal_string_var((char_u *)"g:actual_curbuf", buf_tmp); + vim_snprintf((char *)win_tmp, sizeof(win_tmp), "%d", curwin->handle); + set_internal_string_var((char_u *)"g:actual_curwin", win_tmp); buf_T *const save_curbuf = curbuf; win_T *const save_curwin = curwin; @@ -3926,6 +3937,7 @@ int build_stl_str_hl( // Remove the variable we just stored do_unlet(S_LEN("g:actual_curbuf"), true); + do_unlet(S_LEN("g:actual_curwin"), true); // } @@ -3984,8 +3996,8 @@ int build_stl_str_hl( // Store the position percentage in our temporary buffer. // Note: We cannot store the value in `num` because // `get_rel_pos` can return a named position. Ex: "Top" - get_rel_pos(wp, tmp, TMPLEN); - str = tmp; + get_rel_pos(wp, buf_tmp, TMPLEN); + str = buf_tmp; break; case STL_ARGLISTSTAT: @@ -3995,19 +4007,19 @@ int build_stl_str_hl( // at the end of the null-terminated string. // Setting the first byte to null means it will place the argument // number string at the beginning of the buffer. - tmp[0] = 0; + buf_tmp[0] = 0; // Note: The call will only return true if it actually - // appended data to the `tmp` buffer. - if (append_arg_number(wp, tmp, (int)sizeof(tmp), false)) { - str = tmp; + // appended data to the `buf_tmp` buffer. + if (append_arg_number(wp, buf_tmp, (int)sizeof(buf_tmp), false)) { + str = buf_tmp; } break; case STL_KEYMAP: fillable = false; - if (get_keymap_str(wp, (char_u *)"<%s>", tmp, TMPLEN)) { - str = tmp; + if (get_keymap_str(wp, (char_u *)"<%s>", buf_tmp, TMPLEN)) { + str = buf_tmp; } break; case STL_PAGENUM: @@ -4064,9 +4076,9 @@ int build_stl_str_hl( // (including the brackets and null terminating character) if (*wp->w_buffer->b_p_ft != NUL && STRLEN(wp->w_buffer->b_p_ft) < TMPLEN - 3) { - vim_snprintf((char *)tmp, sizeof(tmp), "[%s]", - wp->w_buffer->b_p_ft); - str = tmp; + vim_snprintf((char *)buf_tmp, sizeof(buf_tmp), "[%s]", + wp->w_buffer->b_p_ft); + str = buf_tmp; } break; @@ -4078,13 +4090,13 @@ int build_stl_str_hl( // (including the comma and null terminating character) if (*wp->w_buffer->b_p_ft != NUL && STRLEN(wp->w_buffer->b_p_ft) < TMPLEN - 2) { - vim_snprintf((char *)tmp, sizeof(tmp), ",%s", - wp->w_buffer->b_p_ft); + vim_snprintf((char *)buf_tmp, sizeof(buf_tmp), ",%s", + wp->w_buffer->b_p_ft); // Uppercase the file extension - for (char_u *t = tmp; *t != 0; t++) { + for (char_u *t = buf_tmp; *t != 0; t++) { *t = (char_u)TOUPPER_LOC(*t); } - str = tmp; + str = buf_tmp; } break; } diff --git a/src/nvim/eval.c b/src/nvim/eval.c index b7e827e86b..27c2ed1ea5 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -2818,7 +2818,7 @@ static int do_unlet_var(lval_T *const lp, char_u *const name_end, int forceit) /// @param[in] fonceit If true, do not complain if variable doesn’t exist. /// /// @return OK if it existed, FAIL otherwise. -int do_unlet(const char *const name, const size_t name_len, const int forceit) +int do_unlet(const char *const name, const size_t name_len, const bool forceit) FUNC_ATTR_NONNULL_ALL { const char *varname; diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c index f1f84e63be..4a64cc31b1 100644 --- a/src/nvim/hardcopy.c +++ b/src/nvim/hardcopy.c @@ -210,10 +210,25 @@ struct prt_ps_mbfont_S { char *defcs; }; +// Types of PS resource file currently used +typedef enum { + PRT_RESOURCE_TYPE_PROCSET = 0, + PRT_RESOURCE_TYPE_ENCODING = 1, + PRT_RESOURCE_TYPE_CMAP = 2, +} PrtResourceType; + +// String versions of PS resource types +static const char *const prt_resource_types[] = +{ + [PRT_RESOURCE_TYPE_PROCSET] = "procset", + [PRT_RESOURCE_TYPE_ENCODING] = "encoding", + [PRT_RESOURCE_TYPE_CMAP] = "cmap", +}; + struct prt_ps_resource_S { char_u name[64]; char_u filename[MAXPATHL + 1]; - int type; + PrtResourceType type; char_u title[256]; char_u version[256]; }; @@ -1171,11 +1186,6 @@ static struct prt_ps_mbfont_S prt_ps_mbfonts[] = } }; -// Types of PS resource file currently used -#define PRT_RESOURCE_TYPE_PROCSET (0) -#define PRT_RESOURCE_TYPE_ENCODING (1) -#define PRT_RESOURCE_TYPE_CMAP (2) - /* The PS prolog file version number has to match - if the prolog file is * updated, increment the number in the file and here. Version checking was * added as of VIM 6.2. @@ -1189,16 +1199,6 @@ static struct prt_ps_mbfont_S prt_ps_mbfonts[] = #define PRT_PROLOG_VERSION ((char_u *)"1.4") #define PRT_CID_PROLOG_VERSION ((char_u *)"1.0") -/* String versions of PS resource types - indexed by constants above so don't - * re-order! - */ -static char *prt_resource_types[] = -{ - "procset", - "encoding", - "cmap" -}; - // Strings to look for in a PS resource file #define PRT_RESOURCE_HEADER "%!PS-Adobe-" #define PRT_RESOURCE_RESOURCE "Resource-" @@ -1845,10 +1845,11 @@ static void prt_dsc_ints(char *comment, int count, int *ints) } static void prt_dsc_resources( - char *comment, // if NULL add to previous - char *type, - char *string + const char *comment, // if NULL add to previous + const char *type, + const char *string ) + FUNC_ATTR_NONNULL_ARG(2, 3) { if (comment != NULL) vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 4d8da1ba14..95948dac78 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -2930,8 +2930,6 @@ void spell_suggest(int count) memmove(p, line, c); STRCPY(p + c, stp->st_word); STRCAT(p, sug.su_badptr + stp->st_orglen); - ml_replace(curwin->w_cursor.lnum, p, false); - curwin->w_cursor.col = c; // For redo we use a change-word command. ResetRedobuff(); @@ -2940,7 +2938,10 @@ void spell_suggest(int count) stp->st_wordlen + sug.su_badlen - stp->st_orglen); AppendCharToRedobuff(ESC); - // After this "p" may be invalid. + // "p" may be freed here + ml_replace(curwin->w_cursor.lnum, p, false); + curwin->w_cursor.col = c; + changed_bytes(curwin->w_cursor.lnum, c); } else curwin->w_cursor = prev_cursor; @@ -3761,7 +3762,8 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so tword[sp->ts_twordlen] = NUL; if (sp->ts_prefixdepth <= PFD_NOTSPECIAL - && (sp->ts_flags & TSF_PREFIXOK) == 0) { + && (sp->ts_flags & TSF_PREFIXOK) == 0 + && pbyts != NULL) { // There was a prefix before the word. Check that the prefix // can be used with this word. // Count the length of the NULs in the prefix. If there are diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index f8c10d0258..41669789db 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -5095,7 +5095,8 @@ mkspell ( spin.si_newcompID = 127; // start compound ID at first maximum // default: fnames[0] is output file, following are input files - innames = &fnames[1]; + // When "fcount" is 1 there is only one file. + innames = &fnames[fcount == 1 ? 0 : 1]; incount = fcount - 1; wfname = xmalloc(MAXPATHL); @@ -5105,12 +5106,10 @@ mkspell ( if (fcount == 1 && len > 4 && STRCMP(fnames[0] + len - 4, ".add") == 0) { // For ":mkspell path/en.latin1.add" output file is // "path/en.latin1.add.spl". - innames = &fnames[0]; incount = 1; vim_snprintf((char *)wfname, MAXPATHL, "%s.spl", fnames[0]); } else if (fcount == 1) { // For ":mkspell path/vim" output file is "path/vim.latin1.spl". - innames = &fnames[0]; incount = 1; vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL, fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc()); diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim index 9303fac927..d440bdcb1e 100644 --- a/src/nvim/testdir/test_filetype.vim +++ b/src/nvim/testdir/test_filetype.vim @@ -139,7 +139,7 @@ let s:filename_checks = { \ 'dnsmasq': ['/etc/dnsmasq.conf'], \ 'dockerfile': ['Dockerfile', 'file.Dockerfile'], \ 'dosbatch': ['file.bat', 'file.sys'], - \ 'dosini': ['.editorconfig', '/etc/yum.conf', 'file.ini'], + \ 'dosini': ['.editorconfig', '/etc/pacman.conf', '/etc/yum.conf', 'file.ini'], \ 'dot': ['file.dot', 'file.gv'], \ 'dracula': ['file.drac', 'file.drc', 'filelvs', 'filelpe'], \ 'dsl': ['file.dsl'], @@ -150,7 +150,7 @@ let s:filename_checks = { \ 'dylanlid': ['file.lid'], \ 'ecd': ['file.ecd'], \ 'edif': ['file.edf', 'file.edif', 'file.edo'], - \ 'elinks': ['/etc/elinks.conf', '/.elinks/elinks.conf'], + \ 'elinks': ['elinks.conf'], \ 'elm': ['file.elm'], \ 'elmfilt': ['filter-rules'], \ 'erlang': ['file.erl', 'file.hrl', 'file.yaws'], @@ -639,3 +639,23 @@ func Test_setfiletype_completion() call feedkeys(":setfiletype java\<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"setfiletype java javacc javascript javascriptreact', @:) endfunc + +func Test_hook_file() + filetype on + + call writefile(['[Trigger]', 'this is pacman config'], 'Xfile.hook') + split Xfile.hook + call assert_equal('dosini', &filetype) + bwipe! + + call writefile(['not pacman'], 'Xfile.hook') + split Xfile.hook + call assert_notequal('dosini', &filetype) + bwipe! + + call delete('Xfile.hook') + filetype off +endfunc + + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_statusline.vim b/src/nvim/testdir/test_statusline.vim index 66b6e6c05c..8c81ec3431 100644 --- a/src/nvim/testdir/test_statusline.vim +++ b/src/nvim/testdir/test_statusline.vim @@ -7,6 +7,7 @@ " %X source view_util.vim +source term_util.vim func s:get_statusline() return ScreenLines(&lines - 1, &columns)[0] @@ -29,7 +30,9 @@ endfunc " Function used to display syntax group. func SyntaxItem() - return synIDattr(synID(line("."),col("."),1),"name") + call assert_equal(s:expected_curbuf, g:actual_curbuf) + call assert_equal(s:expected_curwin, g:actual_curwin) + return synIDattr(synID(line("."), col("."),1), "name") endfunc func Test_caught_error_in_statusline() @@ -218,6 +221,8 @@ func Test_statusline() "%{: Evaluate expression between '%{' and '}' and substitute result. syntax on + let s:expected_curbuf = string(bufnr('')) + let s:expected_curwin = string(win_getid()) set statusline=%{SyntaxItem()} call assert_match('^vimNumber\s*$', s:get_statusline()) s/^/"/ @@ -332,6 +337,23 @@ func Test_statusline() set statusline=%!2*3+1 call assert_match('7\s*$', s:get_statusline()) + func GetNested() + call assert_equal(string(win_getid()), g:actual_curwin) + call assert_equal(string(bufnr('')), g:actual_curbuf) + return 'nested' + endfunc + func GetStatusLine() + call assert_equal(win_getid(), g:statusline_winid) + return 'the %{GetNested()} line' + endfunc + set statusline=%!GetStatusLine() + call assert_match('the nested line', s:get_statusline()) + call assert_false(exists('g:actual_curwin')) + call assert_false(exists('g:actual_curbuf')) + call assert_false(exists('g:statusline_winid')) + delfunc GetNested + delfunc GetStatusLine + " Check statusline in current and non-current window " with the 'fillchars' option. set fillchars=stl:^,stlnc:=,vert:\|,fold:-,diff:- |