mirror of
https://github.com/neovim/neovim.git
synced 2025-12-09 16:12:48 +00:00
Merge pull request #13559 from janlazo/vim-8.2.0162
vim-patch:8.1.1657,8.2.{162,262,264,272}
This commit is contained in:
1
.github/workflows/ci.yml
vendored
1
.github/workflows/ci.yml
vendored
@@ -55,6 +55,7 @@ jobs:
|
|||||||
- name: Install brew packages
|
- name: Install brew packages
|
||||||
if: matrix.os == 'osx'
|
if: matrix.os == 'osx'
|
||||||
run: |
|
run: |
|
||||||
|
rm -f /usr/local/bin/2to3
|
||||||
brew update >/dev/null
|
brew update >/dev/null
|
||||||
brew install automake ccache cpanminus ninja
|
brew install automake ccache cpanminus ninja
|
||||||
brew upgrade
|
brew upgrade
|
||||||
|
|||||||
@@ -5248,8 +5248,10 @@ void ex_viusage(exarg_T *eap)
|
|||||||
/// @param tagname Name of the tags file ("tags" for English, "tags-fr" for
|
/// @param tagname Name of the tags file ("tags" for English, "tags-fr" for
|
||||||
/// French)
|
/// French)
|
||||||
/// @param add_help_tags Whether to add the "help-tags" tag
|
/// @param add_help_tags Whether to add the "help-tags" tag
|
||||||
static void helptags_one(char_u *const dir, const char_u *const ext,
|
/// @param ignore_writeerr ignore write error
|
||||||
const char_u *const tagfname, const bool add_help_tags)
|
static void helptags_one(char_u *dir, const char_u *ext, const char_u *tagfname,
|
||||||
|
bool add_help_tags, bool ignore_writeerr)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
garray_T ga;
|
garray_T ga;
|
||||||
int filecount;
|
int filecount;
|
||||||
@@ -5293,7 +5295,9 @@ static void helptags_one(char_u *const dir, const char_u *const ext,
|
|||||||
|
|
||||||
FILE *const fd_tags = os_fopen((char *)NameBuff, "w");
|
FILE *const fd_tags = os_fopen((char *)NameBuff, "w");
|
||||||
if (fd_tags == NULL) {
|
if (fd_tags == NULL) {
|
||||||
EMSG2(_("E152: Cannot open %s for writing"), NameBuff);
|
if (!ignore_writeerr) {
|
||||||
|
EMSG2(_("E152: Cannot open %s for writing"), NameBuff);
|
||||||
|
}
|
||||||
FreeWild(filecount, files);
|
FreeWild(filecount, files);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -5441,7 +5445,9 @@ static void helptags_one(char_u *const dir, const char_u *const ext,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Generate tags in one help directory, taking care of translations.
|
/// Generate tags in one help directory, taking care of translations.
|
||||||
static void do_helptags(char_u *dirname, bool add_help_tags)
|
static void do_helptags(char_u *dirname, bool add_help_tags,
|
||||||
|
bool ignore_writeerr)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
garray_T ga;
|
garray_T ga;
|
||||||
@@ -5523,17 +5529,17 @@ static void do_helptags(char_u *dirname, bool add_help_tags)
|
|||||||
ext[1] = fname[5];
|
ext[1] = fname[5];
|
||||||
ext[2] = fname[6];
|
ext[2] = fname[6];
|
||||||
}
|
}
|
||||||
helptags_one(dirname, ext, fname, add_help_tags);
|
helptags_one(dirname, ext, fname, add_help_tags, ignore_writeerr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ga_clear(&ga);
|
ga_clear(&ga);
|
||||||
FreeWild(filecount, files);
|
FreeWild(filecount, files);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void helptags_cb(char_u *fname, void *cookie)
|
||||||
helptags_cb(char_u *fname, void *cookie)
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
do_helptags(fname, *(bool *)cookie);
|
do_helptags(fname, *(bool *)cookie, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -5562,7 +5568,7 @@ void ex_helptags(exarg_T *eap)
|
|||||||
if (dirname == NULL || !os_isdir(dirname)) {
|
if (dirname == NULL || !os_isdir(dirname)) {
|
||||||
EMSG2(_("E150: Not a directory: %s"), eap->arg);
|
EMSG2(_("E150: Not a directory: %s"), eap->arg);
|
||||||
} else {
|
} else {
|
||||||
do_helptags(dirname, add_help_tags);
|
do_helptags(dirname, add_help_tags, false);
|
||||||
}
|
}
|
||||||
xfree(dirname);
|
xfree(dirname);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3052,57 +3052,57 @@ static bool find_is_eval_item(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Find the identifier under or to the right of the cursor.
|
||||||
* Find the identifier under or to the right of the cursor.
|
// "find_type" can have one of three values:
|
||||||
* "find_type" can have one of three values:
|
// FIND_IDENT: find an identifier (keyword)
|
||||||
* FIND_IDENT: find an identifier (keyword)
|
// FIND_STRING: find any non-white text
|
||||||
* FIND_STRING: find any non-white string
|
// FIND_IDENT + FIND_STRING: find any non-white text, identifier preferred.
|
||||||
* FIND_IDENT + FIND_STRING: find any non-white string, identifier preferred.
|
// FIND_EVAL: find text useful for C program debugging
|
||||||
* FIND_EVAL: find text useful for C program debugging
|
//
|
||||||
*
|
// There are three steps:
|
||||||
* There are three steps:
|
// 1. Search forward for the start of an identifier/text. Doesn't move if
|
||||||
* 1. Search forward for the start of an identifier/string. Doesn't move if
|
// already on one.
|
||||||
* already on one.
|
// 2. Search backward for the start of this identifier/text.
|
||||||
* 2. Search backward for the start of this identifier/string.
|
// This doesn't match the real Vi but I like it a little better and it
|
||||||
* This doesn't match the real Vi but I like it a little better and it
|
// shouldn't bother anyone.
|
||||||
* shouldn't bother anyone.
|
// 3. Search forward to the end of this identifier/text.
|
||||||
* 3. Search forward to the end of this identifier/string.
|
// When FIND_IDENT isn't defined, we backup until a blank.
|
||||||
* When FIND_IDENT isn't defined, we backup until a blank.
|
//
|
||||||
*
|
// Returns the length of the text, or zero if no text is found.
|
||||||
* Returns the length of the string, or zero if no string is found.
|
// If text is found, a pointer to the text is put in "*text". This
|
||||||
* If a string is found, a pointer to the string is put in "*string". This
|
// points into the current buffer line and is not always NUL terminated.
|
||||||
* string is not always NUL terminated.
|
size_t find_ident_under_cursor(char_u **text, int find_type)
|
||||||
*/
|
FUNC_ATTR_NONNULL_ARG(1)
|
||||||
size_t find_ident_under_cursor(char_u **string, int find_type)
|
|
||||||
{
|
{
|
||||||
return find_ident_at_pos(curwin, curwin->w_cursor.lnum,
|
return find_ident_at_pos(curwin, curwin->w_cursor.lnum,
|
||||||
curwin->w_cursor.col, string, find_type);
|
curwin->w_cursor.col, text, NULL, find_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Like find_ident_under_cursor(), but for any window and any position.
|
* Like find_ident_under_cursor(), but for any window and any position.
|
||||||
* However: Uses 'iskeyword' from the current window!.
|
* However: Uses 'iskeyword' from the current window!.
|
||||||
*/
|
*/
|
||||||
size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol,
|
size_t find_ident_at_pos(
|
||||||
char_u **string, int find_type)
|
win_T *wp,
|
||||||
|
linenr_T lnum,
|
||||||
|
colnr_T startcol,
|
||||||
|
char_u **text,
|
||||||
|
int *textcol, // column where "text" starts, can be NULL
|
||||||
|
int find_type)
|
||||||
|
FUNC_ATTR_NONNULL_ARG(1, 4)
|
||||||
{
|
{
|
||||||
char_u *ptr;
|
int col = 0; // init to shut up GCC
|
||||||
int col = 0; /* init to shut up GCC */
|
|
||||||
int i;
|
int i;
|
||||||
int this_class = 0;
|
int this_class = 0;
|
||||||
int prev_class;
|
int prev_class;
|
||||||
int prevcol;
|
int prevcol;
|
||||||
int bn = 0; // bracket nesting
|
int bn = 0; // bracket nesting
|
||||||
|
|
||||||
/*
|
// if i == 0: try to find an identifier
|
||||||
* if i == 0: try to find an identifier
|
// if i == 1: try to find any non-white text
|
||||||
* if i == 1: try to find any non-white string
|
char_u *ptr = ml_get_buf(wp->w_buffer, lnum, false);
|
||||||
*/
|
for (i = (find_type & FIND_IDENT) ? 0 : 1; i < 2; i++) {
|
||||||
ptr = ml_get_buf(wp->w_buffer, lnum, false);
|
// 1. skip to start of identifier/text
|
||||||
for (i = (find_type & FIND_IDENT) ? 0 : 1; i < 2; ++i) {
|
|
||||||
/*
|
|
||||||
* 1. skip to start of identifier/string
|
|
||||||
*/
|
|
||||||
col = startcol;
|
col = startcol;
|
||||||
while (ptr[col] != NUL) {
|
while (ptr[col] != NUL) {
|
||||||
// Stop at a ']' to evaluate "a[x]".
|
// Stop at a ']' to evaluate "a[x]".
|
||||||
@@ -3120,7 +3120,7 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol,
|
|||||||
bn = ptr[col] == ']';
|
bn = ptr[col] == ']';
|
||||||
|
|
||||||
//
|
//
|
||||||
// 2. Back up to start of identifier/string.
|
// 2. Back up to start of identifier/text.
|
||||||
//
|
//
|
||||||
// Remember class of character under cursor.
|
// Remember class of character under cursor.
|
||||||
if ((find_type & FIND_EVAL) && ptr[col] == ']') {
|
if ((find_type & FIND_EVAL) && ptr[col] == ']') {
|
||||||
@@ -3143,7 +3143,7 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol,
|
|||||||
col = prevcol;
|
col = prevcol;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we don't want just any old string, or we've found an
|
// If we don't want just any old text, or we've found an
|
||||||
// identifier, stop searching.
|
// identifier, stop searching.
|
||||||
if (this_class > 2) {
|
if (this_class > 2) {
|
||||||
this_class = 2;
|
this_class = 2;
|
||||||
@@ -3154,7 +3154,7 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ptr[col] == NUL || (i == 0 && this_class != 2)) {
|
if (ptr[col] == NUL || (i == 0 && this_class != 2)) {
|
||||||
// Didn't find an identifier or string.
|
// Didn't find an identifier or text.
|
||||||
if (find_type & FIND_STRING) {
|
if (find_type & FIND_STRING) {
|
||||||
EMSG(_("E348: No string under cursor"));
|
EMSG(_("E348: No string under cursor"));
|
||||||
} else {
|
} else {
|
||||||
@@ -3163,11 +3163,12 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ptr += col;
|
ptr += col;
|
||||||
*string = ptr;
|
*text = ptr;
|
||||||
|
if (textcol != NULL) {
|
||||||
|
*textcol = col;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
// 3. Find the end if the identifier/text.
|
||||||
* 3. Find the end if the identifier/string.
|
|
||||||
*/
|
|
||||||
bn = 0;
|
bn = 0;
|
||||||
startcol -= col;
|
startcol -= col;
|
||||||
col = 0;
|
col = 0;
|
||||||
|
|||||||
@@ -31,3 +31,26 @@ func Test_fileformat_autocommand()
|
|||||||
au! BufReadPre Xfile
|
au! BufReadPre Xfile
|
||||||
bw!
|
bw!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" Test for changing the fileformat using ++read
|
||||||
|
func Test_fileformat_plusplus_read()
|
||||||
|
new
|
||||||
|
call setline(1, ['one', 'two', 'three'])
|
||||||
|
w ++ff=dos Xfile1
|
||||||
|
enew!
|
||||||
|
set ff=unix
|
||||||
|
" A :read doesn't change the fileformat, but does apply to the read lines.
|
||||||
|
r ++fileformat=unix Xfile1
|
||||||
|
call assert_equal('unix', &fileformat)
|
||||||
|
call assert_equal("three\r", getline('$'))
|
||||||
|
3r ++edit Xfile1
|
||||||
|
call assert_equal('dos', &fileformat)
|
||||||
|
close!
|
||||||
|
call delete('Xfile1')
|
||||||
|
set fileformat&
|
||||||
|
call assert_fails('e ++fileformat Xfile1', 'E474:')
|
||||||
|
call assert_fails('e ++ff=abc Xfile1', 'E474:')
|
||||||
|
call assert_fails('e ++abc1 Xfile1', 'E474:')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
|||||||
@@ -56,3 +56,49 @@ func Test_help_local_additions()
|
|||||||
call delete('Xruntime', 'rf')
|
call delete('Xruntime', 'rf')
|
||||||
let &rtp = rtp_save
|
let &rtp = rtp_save
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" Test for the :helptags command
|
||||||
|
func Test_helptag_cmd()
|
||||||
|
call mkdir('Xdir/a/doc', 'p')
|
||||||
|
|
||||||
|
" No help file to process in the directory
|
||||||
|
call assert_fails('helptags Xdir', 'E151:')
|
||||||
|
|
||||||
|
call writefile([], 'Xdir/a/doc/sample.txt')
|
||||||
|
|
||||||
|
" Test for ++t argument
|
||||||
|
helptags ++t Xdir
|
||||||
|
call assert_equal(["help-tags\ttags\t1"], readfile('Xdir/tags'))
|
||||||
|
call delete('Xdir/tags')
|
||||||
|
|
||||||
|
" The following tests fail on FreeBSD for some reason
|
||||||
|
if has('unix') && !has('bsd')
|
||||||
|
" Read-only tags file
|
||||||
|
call mkdir('Xdir/doc', 'p')
|
||||||
|
call writefile([''], 'Xdir/doc/tags')
|
||||||
|
call writefile([], 'Xdir/doc/sample.txt')
|
||||||
|
call setfperm('Xdir/doc/tags', 'r-xr--r--')
|
||||||
|
call assert_fails('helptags Xdir/doc', 'E152:', getfperm('Xdir/doc/tags'))
|
||||||
|
|
||||||
|
let rtp = &rtp
|
||||||
|
let &rtp = 'Xdir'
|
||||||
|
helptags ALL
|
||||||
|
let &rtp = rtp
|
||||||
|
|
||||||
|
call delete('Xdir/doc/tags')
|
||||||
|
|
||||||
|
" No permission to read the help file
|
||||||
|
call setfperm('Xdir/a/doc/sample.txt', '-w-------')
|
||||||
|
call assert_fails('helptags Xdir', 'E153:', getfperm('Xdir/a/doc/sample.txt'))
|
||||||
|
call delete('Xdir/a/doc/sample.txt')
|
||||||
|
call delete('Xdir/tags')
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Duplicate tags in the help file
|
||||||
|
call writefile(['*tag1*', '*tag1*', '*tag2*'], 'Xdir/a/doc/sample.txt')
|
||||||
|
call assert_fails('helptags Xdir', 'E154:')
|
||||||
|
|
||||||
|
call delete('Xdir', 'rf')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
|||||||
Reference in New Issue
Block a user