aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xclint.py257
-rw-r--r--cmake/FindLuaJit.cmake2
-rw-r--r--config/CMakeLists.txt5
-rw-r--r--config/config.h.in2
-rw-r--r--runtime/autoload/getscript.vim667
-rw-r--r--runtime/autoload/remote/host.vim17
-rw-r--r--runtime/doc/autocmd.txt19
-rw-r--r--runtime/doc/eval.txt9
-rw-r--r--runtime/doc/help.txt1
-rw-r--r--runtime/doc/nvim_python.txt3
-rw-r--r--runtime/doc/options.txt32
-rw-r--r--runtime/doc/pi_getscript.txt482
-rw-r--r--runtime/doc/usr_05.txt1
-rw-r--r--runtime/doc/usr_21.txt4
-rw-r--r--runtime/doc/usr_41.txt2
-rw-r--r--runtime/optwin.vim3
-rw-r--r--runtime/plugin/getscriptPlugin.vim41
-rw-r--r--src/nvim/auevents.lua1
-rw-r--r--src/nvim/buffer.c10
-rw-r--r--src/nvim/buffer_defs.h1
-rw-r--r--src/nvim/edit.c17
-rw-r--r--src/nvim/eval.c29
-rw-r--r--src/nvim/eval.h3
-rw-r--r--src/nvim/eval_defs.h2
-rw-r--r--src/nvim/ex_cmds.c6
-rw-r--r--src/nvim/fileio.c35
-rw-r--r--src/nvim/log.c2
-rw-r--r--src/nvim/memline.c6
-rw-r--r--src/nvim/memline_defs.h2
-rw-r--r--src/nvim/normal.c7
-rw-r--r--src/nvim/ops.c4
-rw-r--r--src/nvim/option.c117
-rw-r--r--src/nvim/option_defs.h1
-rw-r--r--src/nvim/options.lua8
-rw-r--r--src/nvim/os/env.c33
-rw-r--r--src/nvim/os/shell.c3
-rw-r--r--src/nvim/os/signal.c12
-rw-r--r--src/nvim/path.c3
-rw-r--r--src/nvim/po/it.po46
-rw-r--r--src/nvim/search.c19
-rw-r--r--src/nvim/shada.c307
-rw-r--r--src/nvim/testdir/test53.in4
-rw-r--r--src/nvim/testdir/test53.ok1
-rw-r--r--src/nvim/version.c24
-rw-r--r--test/functional/legacy/autocmd_option_spec.lua277
-rw-r--r--test/functional/legacy/fixeol_spec.lua72
46 files changed, 1079 insertions, 1520 deletions
diff --git a/clint.py b/clint.py
index 0eaab6e3f6..d507837e58 100755
--- a/clint.py
+++ b/clint.py
@@ -198,6 +198,8 @@ _ERROR_CATEGORIES = [
'runtime/printf',
'runtime/printf_format',
'runtime/threadsafe_fn',
+ 'syntax/parenthesis',
+ 'whitespace/alignment',
'whitespace/blank_line',
'whitespace/braces',
'whitespace/comma',
@@ -213,7 +215,7 @@ _ERROR_CATEGORIES = [
'whitespace/parens',
'whitespace/semicolon',
'whitespace/tab',
- 'whitespace/todo'
+ 'whitespace/todo',
]
# The default state of the category filter. This is overrided by the --filter=
@@ -826,9 +828,9 @@ def Error(filename, linenum, category, confidence, message):
_RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile(
r'\\([abfnrtv?"\\\']|\d+|x[0-9a-fA-F]+)')
# Matches strings. Escape codes should already be removed by ESCAPES.
-_RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES = re.compile(r'"[^"]*"')
+_RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES = re.compile(r'"([^"]*)"')
# Matches characters. Escape codes should already be removed by ESCAPES.
-_RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES = re.compile(r"'.'")
+_RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES = re.compile(r"'(.)'")
# Matches multi-line C++ comments.
# This RE is a little bit more complicated than one might expect, because we
# have to take care of space removals tools so we can handle comments inside
@@ -923,39 +925,48 @@ def CleanseComments(line):
class CleansedLines(object):
- """Holds 3 copies of all lines with different preprocessing applied to them.
+ """Holds 5 copies of all lines with different preprocessing applied to them.
1) elided member contains lines without strings and comments,
2) lines member contains lines without comments, and
- 3) raw_lines member contains all the lines without processing.
+ 3) raw_lines member contains all the lines with multiline comments replaced.
+ 4) init_lines member contains all the lines without processing.
+ 5) elided_with_space_strings is like elided, but with string literals
+ looking like `" "`.
All these three members are of <type 'list'>, and of the same length.
"""
- def __init__(self, lines):
+ def __init__(self, lines, init_lines):
self.elided = []
self.lines = []
self.raw_lines = lines
self.num_lines = len(lines)
+ self.init_lines = init_lines
self.lines_without_raw_strings = lines
+ self.elided_with_space_strings = []
for linenum in range(len(self.lines_without_raw_strings)):
self.lines.append(CleanseComments(
self.lines_without_raw_strings[linenum]))
elided = self._CollapseStrings(
self.lines_without_raw_strings[linenum])
self.elided.append(CleanseComments(elided))
+ elided = CleanseComments(self._CollapseStrings(
+ self.lines_without_raw_strings[linenum], True))
+ self.elided_with_space_strings.append(elided)
def NumLines(self):
"""Returns the number of lines represented."""
return self.num_lines
@staticmethod
- def _CollapseStrings(elided):
+ def _CollapseStrings(elided, keep_spaces=False):
"""Collapses strings and chars on a line to simple "" or '' blocks.
We nix strings first so we're not fooled by text like '"http://"'
Args:
elided: The line being processed.
+ keep_spaces: If true, collapse to
Returns:
The line with collapsed strings.
@@ -964,12 +975,75 @@ class CleansedLines(object):
# Remove escaped characters first to make quote/single quote
# collapsing basic. Things that look like escaped characters
# shouldn't occur outside of strings and chars.
- elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub('', elided)
- elided = _RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES.sub("''", elided)
- elided = _RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES.sub('""', elided)
+ elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub(
+ '' if not keep_spaces else lambda m: ' ' * len(m.group(0)),
+ elided)
+ elided = _RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES.sub(
+ "''" if not keep_spaces
+ else lambda m: "'" + (' ' * len(m.group(1))) + "'",
+ elided)
+ elided = _RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES.sub(
+ '""' if not keep_spaces
+ else lambda m: '"' + (' ' * len(m.group(1))) + '"',
+ elided)
return elided
+BRACES = {
+ '(': ')',
+ '{': '}',
+ '[': ']',
+ # '<': '>', C++-specific pair removed
+}
+
+
+CLOSING_BRACES = dict(((v, k) for k, v in BRACES.items()))
+
+
+def GetExprBracesPosition(clean_lines, linenum, pos):
+ """List positions of all kinds of braces
+
+ If input points to ( or { or [ then function proceeds until finding the
+ position which closes it.
+
+ Args:
+ clean_lines: A CleansedLines instance containing the file.
+ linenum: Current line number.
+ pos: A position on the line.
+
+ Yields:
+ A tuple (linenum, pos, brace, depth) that points to each brace.
+ Additionally each new line (linenum, pos, 's', depth) is yielded, for each
+ line end (linenum, pos, 'e', depth) is yielded and at the very end it
+ yields (linenum, pos, None, None).
+ """
+ depth = 0
+ yielded_line_start = True
+ startpos = pos
+ while linenum < clean_lines.NumLines() - 1:
+ line = clean_lines.elided_with_space_strings[linenum]
+ if not line.startswith('#') or yielded_line_start:
+ # Ignore #ifdefs, but not if it is macros that are checked
+ for i, brace in enumerate(line[startpos:]):
+ pos = i + startpos
+ if brace != ' ' and not yielded_line_start:
+ yield (linenum, pos, 's', depth)
+ yielded_line_start = True
+ if brace in BRACES:
+ depth += 1
+ yield (linenum, pos, brace, depth)
+ elif brace in CLOSING_BRACES:
+ yield (linenum, pos, brace, depth)
+ depth -= 1
+ if depth == 0:
+ yield (linenum, pos, None, None)
+ return
+ yield (linenum, len(line) - 1, 'e', depth)
+ yielded_line_start = False
+ startpos = 0
+ linenum += 1
+
+
def FindEndOfExpressionInLine(line, startpos, depth, startchar, endchar):
"""Find the position just after the matching endchar.
@@ -995,9 +1069,9 @@ def FindEndOfExpressionInLine(line, startpos, depth, startchar, endchar):
def CloseExpression(clean_lines, linenum, pos):
- """If input points to ( or { or [ or <, finds the position that closes it.
+ """If input points to ( or { or [, finds the position that closes it.
- If lines[linenum][pos] points to a '(' or '{' or '[' or '<', finds the
+ If lines[linenum][pos] points to a '(' or '{' or '[', finds the
linenum/pos that correspond to the closing of the expression.
Args:
@@ -1014,16 +1088,9 @@ def CloseExpression(clean_lines, linenum, pos):
line = clean_lines.elided[linenum]
startchar = line[pos]
- if startchar not in '({[<':
+ if startchar not in BRACES:
return (line, clean_lines.NumLines(), -1)
- if startchar == '(':
- endchar = ')'
- if startchar == '[':
- endchar = ']'
- if startchar == '{':
- endchar = '}'
- if startchar == '<':
- endchar = '>'
+ endchar = BRACES[startchar]
# Check first line
(end_pos, num_open) = FindEndOfExpressionInLine(
@@ -1300,6 +1367,23 @@ def CheckForMultilineCommentsAndStrings(filename, clean_lines, linenum, error):
'Use C++11 raw strings or concatenation instead.')
+def CheckForOldStyleComments(filename, line, linenum, error):
+ """Logs an error if we see /*-style comment
+
+ Args:
+ filename: The name of the current file.
+ line: The text of the line to check.
+ linenum: The number of the line to check.
+ error: The function to call with any errors found.
+ """
+ if line.find('/*') >= 0 and line[-1] != '\\':
+ error(filename, linenum, 'readability/old_style_comment', 5,
+ '/*-style comment found, it should be replaced with //-style. '
+ '/*-style comments are only allowed inside macros. '
+ 'Note that you should not use /*-style comments to document '
+ 'macros itself, use doxygen-style comments for this.')
+
+
threading_list = (
('asctime(', 'os_asctime_r('),
('ctime(', 'os_ctime_r('),
@@ -1968,6 +2052,92 @@ def FindPreviousMatchingAngleBracket(clean_lines, linenum, init_prefix):
return False
+def CheckExpressionAlignment(filename, clean_lines, linenum, error, startpos=0):
+ """Checks for the correctness of alignment inside expressions
+
+ Args:
+ filename: The name of the current file.
+ clean_lines: A CleansedLines instance containing the file.
+ linenum: The number of the line to check.
+ error: The function to call with any errors found.
+ startpos: Position where to start searching for expression start.
+ """
+ level_starts = {}
+ line = clean_lines.elided_with_space_strings[linenum]
+ prev_line_start = Search(r'\S', line).start()
+ depth_line_starts = {}
+ pos = min([
+ idx
+ for idx in (
+ line.find(k, startpos)
+ for k in BRACES
+ if k != '{'
+ )
+ if idx >= 0
+ ] + [len(line) + 1])
+ if pos == len(line) + 1:
+ return
+ ignore_error_levels = set()
+ firstlinenum = linenum
+ for linenum, pos, brace, depth in GetExprBracesPosition(
+ clean_lines, linenum, pos
+ ):
+ line = clean_lines.elided_with_space_strings[linenum]
+ if depth is None:
+ if pos < len(line) - 1:
+ CheckExpressionAlignment(filename, clean_lines, linenum, error,
+ pos + 1)
+ return
+ elif depth <= 0:
+ error(filename, linenum, 'syntax/parenthesis', 4,
+ 'Unbalanced parenthesis')
+ return
+ if brace == 's':
+ assert firstlinenum != linenum
+ if level_starts[depth][1]:
+ if line[pos] == BRACES[depth_line_starts[depth][1]]:
+ if pos != depth_line_starts[depth][0]:
+ if depth not in ignore_error_levels:
+ error(filename, linenum, 'whitespace/indent', 2,
+ 'End of the inner expression should have '
+ 'the same indent as start')
+ else:
+ if (pos != depth_line_starts[depth][0] + 4
+ and not (depth_line_starts[depth][1] == '{'
+ and pos == depth_line_starts[depth][0] + 2)):
+ if depth not in ignore_error_levels:
+ error(filename, linenum, 'whitespace/indent', 2,
+ 'Inner expression indentation should be 4')
+ else:
+ if (pos != level_starts[depth][0] + 1
+ + (level_starts[depth][2] == '{')):
+ if depth not in ignore_error_levels:
+ error(filename, linenum, 'whitespace/alignment', 2,
+ 'Inner expression should be aligned '
+ 'as opening brace + 1 (+ 2 in case of {)')
+ prev_line_start = pos
+ elif brace == 'e':
+ pass
+ else:
+ opening = brace in BRACES
+ if opening:
+ # Only treat {} as part of the expression if it is preceded by
+ # "=" (brace initializer) or "(type)" (construct like (struct
+ # foo) { ... }).
+ if brace == '{' and not (Search(
+ r'(?:= *|\((?:struct )?\w+(\s*\[\w*\])?\)) *$',
+ line[:pos])
+ ):
+ ignore_error_levels.add(depth)
+ line_ended_with_opening = (
+ pos == len(line) - 2 * (line.endswith(' \\')) - 1)
+ level_starts[depth] = (pos, line_ended_with_opening, brace)
+ if line_ended_with_opening:
+ depth_line_starts[depth] = (prev_line_start, brace)
+ else:
+ del level_starts[depth]
+
+
def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
"""Checks for the correctness of various spacing issues in the code.
@@ -1975,7 +2145,8 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
if/for/while/switch, no spaces around parens in function calls, two
spaces between code and comment, don't start a block with a blank
line, don't end a function with a blank line, don't add a blank line
- after public/protected/private, don't have too many blank lines in a row.
+ after public/protected/private, don't have too many blank lines in a row,
+ spaces after {, spaces before }.
Args:
filename: The name of the current file.
@@ -2236,6 +2407,10 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
# Next we will look for issues with function calls.
CheckSpacingForFunctionCall(filename, line, linenum, error)
+ # Check whether everything inside expressions is aligned correctly
+ if any((line.find(k) >= 0 for k in BRACES if k != '{')):
+ CheckExpressionAlignment(filename, clean_lines, linenum, error)
+
# Except after an opening paren, or after another opening brace (in case of
# an initializer list, for instance), you should have spaces before your
# braces. And since you should never have braces at the beginning of a line,
@@ -2292,8 +2467,6 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
'Extra space before [')
# You shouldn't have a space before a semicolon at the end of the line.
- # There's a special case for "for" since the style guide allows space before
- # the semicolon there.
if Search(r':\s*;\s*$', line):
error(filename, linenum, 'whitespace/semicolon', 5,
'Semicolon defining empty statement. Use {} instead.')
@@ -2301,12 +2474,18 @@ def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
error(filename, linenum, 'whitespace/semicolon', 5,
'Line contains only semicolon. If this should be an empty'
' statement, use {} instead.')
- elif (Search(r'\s+;\s*$', line) and
- not Search(r'\bfor\b', line)):
+ elif Search(r'\s+;\s*$', line):
error(filename, linenum, 'whitespace/semicolon', 5,
'Extra space before last semicolon. If this should be an empty '
'statement, use {} instead.')
+ if Search(r'\{(?!\})\S', line):
+ error(filename, linenum, 'whitespace/braces', 5,
+ 'Missing space after {')
+ if Search(r'\S(?<!\{)\}', line):
+ error(filename, linenum, 'whitespace/braces', 5,
+ 'Missing space before }')
+
def GetPreviousNonBlankLine(clean_lines, linenum):
"""Return the most recent non-blank line and its line number.
@@ -2361,11 +2540,27 @@ def CheckBraces(filename, clean_lines, linenum, error):
' of the previous line')
# An else clause should be on the same line as the preceding closing brace.
+ # If there is no preceding closing brace, there should be one.
if Match(r'\s*else\s*', line):
prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
if Match(r'\s*}\s*$', prevline):
error(filename, linenum, 'whitespace/newline', 4,
'An else should appear on the same line as the preceding }')
+ else:
+ error(filename, linenum, 'readability/braces', 5,
+ 'An else should always have braces before it')
+
+ # If should always have a brace
+ for blockstart in ('if', 'while', 'for'):
+ if Match(r'\s*{0}[^{{]*$'.format(blockstart), line):
+ pos = line.find(blockstart)
+ pos = line.find('(', pos)
+ if pos > 0:
+ (endline, _, endpos) = CloseExpression(
+ clean_lines, linenum, pos)
+ if endline[endpos:].find('{') == -1:
+ error(filename, linenum, 'readability/braces', 5,
+ '{0} should always use braces'.format(blockstart))
# If braces come on one side of an else, they should be on both.
# However, we have to worry about "else if" that spans multiple lines!
@@ -3026,12 +3221,14 @@ def ProcessLine(filename, file_extension, clean_lines, line,
arguments : filename, clean_lines, line, error
"""
raw_lines = clean_lines.raw_lines
+ init_lines = clean_lines.init_lines
ParseNolintSuppressions(filename, raw_lines[line], line, error)
nesting_state.Update(filename, clean_lines, line, error)
if nesting_state.stack and nesting_state.stack[-1].inline_asm != _NO_ASM:
return
CheckForFunctionLengths(filename, clean_lines, line, function_state, error)
CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error)
+ CheckForOldStyleComments(filename, init_lines[line], line, error)
CheckStyle(
filename, clean_lines, line, file_extension, nesting_state, error)
CheckLanguage(filename, clean_lines, line, file_extension, include_state,
@@ -3072,12 +3269,12 @@ def ProcessFileData(filename, file_extension, lines, error,
for line in range(1, len(lines)):
ParseKnownErrorSuppressions(filename, lines, line)
- if _cpplint_state.record_errors_file:
- raw_lines = lines[:]
+ init_lines = lines[:]
+ if _cpplint_state.record_errors_file:
def RecordedError(filename, linenum, category, confidence, message):
if not IsErrorSuppressedByNolint(category, linenum):
- key = raw_lines[linenum - 1 if linenum else 0:linenum + 2]
+ key = init_lines[linenum - 1 if linenum else 0:linenum + 2]
err = [filename, key, category]
json.dump(err, _cpplint_state.record_errors_file)
_cpplint_state.record_errors_file.write('\n')
@@ -3089,7 +3286,7 @@ def ProcessFileData(filename, file_extension, lines, error,
CheckForHeaderGuard(filename, lines, error)
RemoveMultiLineComments(filename, lines, error)
- clean_lines = CleansedLines(lines)
+ clean_lines = CleansedLines(lines, init_lines)
for line in range(clean_lines.NumLines()):
ProcessLine(filename, file_extension, clean_lines, line,
include_state, function_state, nesting_state, error,
diff --git a/cmake/FindLuaJit.cmake b/cmake/FindLuaJit.cmake
index 59642d11b9..e9ff53ab62 100644
--- a/cmake/FindLuaJit.cmake
+++ b/cmake/FindLuaJit.cmake
@@ -34,7 +34,7 @@ endif()
if(MSVC)
list(APPEND LUAJIT_NAMES lua51)
elseif(MINGW)
- list(APPEND LUAJIT_NAMES libluajit)
+ list(APPEND LUAJIT_NAMES libluajit libluajit-5.1)
else()
list(APPEND LUAJIT_NAMES luajit-5.1)
endif()
diff --git a/config/CMakeLists.txt b/config/CMakeLists.txt
index b780291264..3d7660ed58 100644
--- a/config/CMakeLists.txt
+++ b/config/CMakeLists.txt
@@ -51,7 +51,10 @@ if(JEMALLOC_FOUND)
set(HAVE_JEMALLOC 1)
endif()
-check_function_exists(putenv HAVE_PUTENV)
+check_function_exists(_putenv_s HAVE_PUTENV_S)
+if(WIN32 AND NOT HAVE_PUTENV_S)
+ message(SEND_ERROR "_putenv_s() function not found on your system.")
+endif()
check_function_exists(opendir HAVE_OPENDIR)
check_function_exists(readlink HAVE_READLINK)
check_function_exists(setenv HAVE_SETENV)
diff --git a/config/config.h.in b/config/config.h.in
index 7d901180b4..017cb80f2f 100644
--- a/config/config.h.in
+++ b/config/config.h.in
@@ -29,7 +29,7 @@
#cmakedefine HAVE_LOCALE_H
#cmakedefine HAVE_NL_LANGINFO_CODESET
#cmakedefine HAVE_NL_MSG_CAT_CNTR
-#cmakedefine HAVE_PUTENV
+#cmakedefine HAVE_PUTENV_S
#cmakedefine HAVE_PWD_H
#cmakedefine HAVE_READLINK
// TODO: add proper cmake check
diff --git a/runtime/autoload/getscript.vim b/runtime/autoload/getscript.vim
deleted file mode 100644
index d50bc2edc0..0000000000
--- a/runtime/autoload/getscript.vim
+++ /dev/null
@@ -1,667 +0,0 @@
-" ---------------------------------------------------------------------
-" getscript.vim
-" Author: Charles E. Campbell
-" Date: Jan 21, 2014
-" Version: 36
-" Installing: :help glvs-install
-" Usage: :help glvs
-"
-" GetLatestVimScripts: 642 1 :AutoInstall: getscript.vim
-"redraw!|call inputsave()|call input("Press <cr> to continue")|call inputrestore()
-" ---------------------------------------------------------------------
-" Initialization: {{{1
-" if you're sourcing this file, surely you can't be
-" expecting vim to be in its vi-compatible mode!
-if exists("g:loaded_getscript")
- finish
-endif
-let g:loaded_getscript= "v36"
-if &cp
- echoerr "GetLatestVimScripts is not vi-compatible; not loaded (you need to set nocp)"
- finish
-endif
-if v:version < 702
- echohl WarningMsg
- echo "***warning*** this version of getscript needs vim 7.2"
- echohl Normal
- finish
-endif
-let s:keepcpo = &cpo
-set cpo&vim
-"DechoTabOn
-
-" ---------------------------
-" Global Variables: {{{1
-" ---------------------------
-" Cygwin Detection ------- {{{2
-if !exists("g:getscript_cygwin")
- if has("win32") || has("win95") || has("win64") || has("win16")
- if &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$'
- let g:getscript_cygwin= 1
- else
- let g:getscript_cygwin= 0
- endif
- else
- let g:getscript_cygwin= 0
- endif
-endif
-
-" wget vs curl {{{2
-if !exists("g:GetLatestVimScripts_wget")
- if executable("wget")
- let g:GetLatestVimScripts_wget= "wget"
- elseif executable("curl")
- let g:GetLatestVimScripts_wget= "curl"
- else
- let g:GetLatestVimScripts_wget = 'echo "GetLatestVimScripts needs wget or curl"'
- let g:GetLatestVimScripts_options = ""
- endif
-endif
-
-" options that wget and curl require:
-if !exists("g:GetLatestVimScripts_options")
- if g:GetLatestVimScripts_wget == "wget"
- let g:GetLatestVimScripts_options= "-q -O"
- elseif g:GetLatestVimScripts_wget == "curl"
- let g:GetLatestVimScripts_options= "-s -O"
- else
- let g:GetLatestVimScripts_options= ""
- endif
-endif
-
-" by default, allow autoinstall lines to work
-if !exists("g:GetLatestVimScripts_allowautoinstall")
- let g:GetLatestVimScripts_allowautoinstall= 1
-endif
-
-" set up default scriptaddr address
-if !exists("g:GetLatestVimScripts_scriptaddr")
- let g:GetLatestVimScripts_scriptaddr = 'http://vim.sourceforge.net/script.php?script_id='
-endif
-
-"" For debugging:
-"let g:GetLatestVimScripts_wget = "echo"
-"let g:GetLatestVimScripts_options = "options"
-
-" ---------------------------------------------------------------------
-" Check If AutoInstall Capable: {{{1
-let s:autoinstall= ""
-if g:GetLatestVimScripts_allowautoinstall
-
- if (has("win32") || has("gui_win32") || has("gui_win32s") || has("win16") || has("win64") || has("win32unix") || has("win95")) && &shell != "bash"
- " windows (but not cygwin/bash)
- let s:dotvim= "vimfiles"
- if !exists("g:GetLatestVimScripts_mv")
- let g:GetLatestVimScripts_mv= "ren"
- endif
-
- else
- " unix
- let s:dotvim= ".vim"
- if !exists("g:GetLatestVimScripts_mv")
- let g:GetLatestVimScripts_mv= "mv"
- endif
- endif
-
- if exists("g:GetLatestVimScripts_autoinstalldir") && isdirectory(g:GetLatestVimScripts_autoinstalldir)
- let s:autoinstall= g:GetLatestVimScripts_autoinstalldir"
- elseif exists('$HOME') && isdirectory(expand("$HOME")."/".s:dotvim)
- let s:autoinstall= $HOME."/".s:dotvim
- endif
-" call Decho("s:autoinstall<".s:autoinstall.">")
-"else "Decho
-" call Decho("g:GetLatestVimScripts_allowautoinstall=".g:GetLatestVimScripts_allowautoinstall.": :AutoInstall: disabled")
-endif
-
-" ---------------------------------------------------------------------
-" Public Interface: {{{1
-com! -nargs=0 GetLatestVimScripts call getscript#GetLatestVimScripts()
-com! -nargs=0 GetScript call getscript#GetLatestVimScripts()
-silent! com -nargs=0 GLVS call getscript#GetLatestVimScripts()
-
-" ---------------------------------------------------------------------
-" GetLatestVimScripts: this function gets the latest versions of {{{1
-" scripts based on the list in
-" (first dir in runtimepath)/GetLatest/GetLatestVimScripts.dat
-fun! getscript#GetLatestVimScripts()
-" call Dfunc("GetLatestVimScripts() autoinstall<".s:autoinstall.">")
-
-" insure that wget is executable
- if executable(g:GetLatestVimScripts_wget) != 1
- echoerr "GetLatestVimScripts needs ".g:GetLatestVimScripts_wget." which apparently is not available on your system"
-" call Dret("GetLatestVimScripts : wget not executable/availble")
- return
- endif
-
- " insure that fnameescape() is available
- if !exists("*fnameescape")
- echoerr "GetLatestVimScripts needs fnameescape() (provided by 7.1.299 or later)"
- return
- endif
-
- " Find the .../GetLatest subdirectory under the runtimepath
- for datadir in split(&rtp,',') + ['']
- if isdirectory(datadir."/GetLatest")
-" call Decho("found directory<".datadir.">")
- let datadir= datadir . "/GetLatest"
- break
- endif
- if filereadable(datadir."GetLatestVimScripts.dat")
-" call Decho("found ".datadir."/GetLatestVimScripts.dat")
- break
- endif
- endfor
-
- " Sanity checks: readability and writability
- if datadir == ""
- echoerr 'Missing "GetLatest/" on your runtimepath - see :help glvs-dist-install'
-" call Dret("GetLatestVimScripts : unable to find a GetLatest subdirectory")
- return
- endif
- if filewritable(datadir) != 2
- echoerr "(getLatestVimScripts) Your ".datadir." isn't writable"
-" call Dret("GetLatestVimScripts : non-writable directory<".datadir.">")
- return
- endif
- let datafile= datadir."/GetLatestVimScripts.dat"
- if !filereadable(datafile)
- echoerr "Your data file<".datafile."> isn't readable"
-" call Dret("GetLatestVimScripts : non-readable datafile<".datafile.">")
- return
- endif
- if !filewritable(datafile)
- echoerr "Your data file<".datafile."> isn't writable"
-" call Dret("GetLatestVimScripts : non-writable datafile<".datafile.">")
- return
- endif
- " --------------------
- " Passed sanity checks
- " --------------------
-
-" call Decho("datadir <".datadir.">")
-" call Decho("datafile <".datafile.">")
-
- " don't let any event handlers interfere (like winmanager's, taglist's, etc)
- let eikeep = &ei
- let hlskeep = &hls
- let acdkeep = &acd
- set ei=all hls&vim noacd
-
- " Edit the datafile (ie. GetLatestVimScripts.dat):
- " 1. record current directory (origdir),
- " 2. change directory to datadir,
- " 3. split window
- " 4. edit datafile
- let origdir= getcwd()
-" call Decho("exe cd ".fnameescape(substitute(datadir,'\','/','ge')))
- exe "cd ".fnameescape(substitute(datadir,'\','/','ge'))
- split
-" call Decho("exe e ".fnameescape(substitute(datafile,'\','/','ge')))
- exe "e ".fnameescape(substitute(datafile,'\','/','ge'))
- res 1000
- let s:downloads = 0
- let s:downerrors= 0
-
- " Check on dependencies mentioned in plugins
-" call Decho(" ")
-" call Decho("searching plugins for GetLatestVimScripts dependencies")
- let lastline = line("$")
-" call Decho("lastline#".lastline)
- let firstdir = substitute(&rtp,',.*$','','')
- let plugins = split(globpath(firstdir,"plugin/**/*.vim"),'\n')
- let plugins = plugins + split(globpath(firstdir,"AsNeeded/**/*.vim"),'\n')
- let foundscript = 0
-
- " this loop updates the GetLatestVimScripts.dat file
- " with dependencies explicitly mentioned in the plugins
- " via GetLatestVimScripts: ... lines
- " It reads the plugin script at the end of the GetLatestVimScripts.dat
- " file, examines it, and then removes it.
- for plugin in plugins
-" call Decho(" ")
-" call Decho("plugin<".plugin.">")
-
- " read plugin in
- " evidently a :r creates a new buffer (the "#" buffer) that is subsequently unused -- bwiping it
- $
-" call Decho(".dependency checking<".plugin."> line$=".line("$"))
-" call Decho("..exe silent r ".fnameescape(plugin))
- exe "silent r ".fnameescape(plugin)
- exe "silent bwipe ".bufnr("#")
-
- while search('^"\s\+GetLatestVimScripts:\s\+\d\+\s\+\d\+','W') != 0
- let depscript = substitute(getline("."),'^"\s\+GetLatestVimScripts:\s\+\d\+\s\+\d\+\s\+\(.*\)$','\1','e')
- let depscriptid = substitute(getline("."),'^"\s\+GetLatestVimScripts:\s\+\(\d\+\)\s\+.*$','\1','')
- let llp1 = lastline+1
-" call Decho("..depscript<".depscript.">")
-
- " found a "GetLatestVimScripts: # #" line in the script;
- " check if its already in the datafile by searching backwards from llp1,
- " the (prior to reading in the plugin script) last line plus one of the GetLatestVimScripts.dat file,
- " for the script-id with no wrapping allowed.
- let curline = line(".")
- let noai_script = substitute(depscript,'\s*:AutoInstall:\s*','','e')
- exe llp1
- let srchline = search('^\s*'.depscriptid.'\s\+\d\+\s\+.*$','bW')
- if srchline == 0
- " this second search is taken when, for example, a 0 0 scriptname is to be skipped over
- let srchline= search('\<'.noai_script.'\>','bW')
- endif
-" call Decho("..noai_script<".noai_script."> depscriptid#".depscriptid." srchline#".srchline." curline#".line(".")." lastline#".lastline)
-
- if srchline == 0
- " found a new script to permanently include in the datafile
- let keep_rega = @a
- let @a = substitute(getline(curline),'^"\s\+GetLatestVimScripts:\s\+','','')
- echomsg "Appending <".@a."> to ".datafile." for ".depscript
-" call Decho("..Appending <".@a."> to ".datafile." for ".depscript)
- exe lastline."put a"
- let @a = keep_rega
- let lastline = llp1
- let curline = curline + 1
- let foundscript = foundscript + 1
-" else " Decho
-" call Decho("..found <".noai_script."> (already in datafile at line#".srchline.")")
- endif
-
- let curline = curline + 1
- exe curline
- endwhile
-
- " llp1: last line plus one
- let llp1= lastline + 1
-" call Decho(".deleting lines: ".llp1.",$d")
- exe "silent! ".llp1.",$d"
- endfor
-" call Decho("--- end dependency checking loop --- foundscript=".foundscript)
-" call Decho(" ")
-" call Dredir("BUFFER TEST (GetLatestVimScripts 1)","ls!")
-
- if foundscript == 0
- setlocal nomod
- endif
-
- " --------------------------------------------------------------------
- " Check on out-of-date scripts using GetLatest/GetLatestVimScripts.dat
- " --------------------------------------------------------------------
-" call Decho("begin: checking out-of-date scripts using datafile<".datafile.">")
- setlocal lz
- 1
-" /^-----/,$g/^\s*\d/call Decho(getline("."))
- 1
- /^-----/,$g/^\s*\d/call s:GetOneScript()
-" call Decho("--- end out-of-date checking --- ")
-
- " Final report (an echomsg)
- try
- silent! ?^-------?
- catch /^Vim\%((\a\+)\)\=:E114/
-" call Dret("GetLatestVimScripts : nothing done!")
- return
- endtry
- exe "norm! kz\<CR>"
- redraw!
- let s:msg = ""
- if s:downloads == 1
- let s:msg = "Downloaded one updated script to <".datadir.">"
- elseif s:downloads == 2
- let s:msg= "Downloaded two updated scripts to <".datadir.">"
- elseif s:downloads > 1
- let s:msg= "Downloaded ".s:downloads." updated scripts to <".datadir.">"
- else
- let s:msg= "Everything was already current"
- endif
- if s:downerrors > 0
- let s:msg= s:msg." (".s:downerrors." downloading errors)"
- endif
- echomsg s:msg
- " save the file
- if &mod
- silent! w!
- endif
- q!
-
- " restore events and current directory
- exe "cd ".fnameescape(substitute(origdir,'\','/','ge'))
- let &ei = eikeep
- let &hls = hlskeep
- let &acd = acdkeep
- setlocal nolz
-" call Dredir("BUFFER TEST (GetLatestVimScripts 2)","ls!")
-" call Dret("GetLatestVimScripts : did ".s:downloads." downloads")
-endfun
-
-" ---------------------------------------------------------------------
-" GetOneScript: (Get Latest Vim Script) this function operates {{{1
-" on the current line, interpreting two numbers and text as
-" ScriptID, SourceID, and Filename.
-" It downloads any scripts that have newer versions from vim.sourceforge.net.
-fun! s:GetOneScript(...)
-" call Dfunc("GetOneScript()")
-
- " set options to allow progress to be shown on screen
- let rega= @a
- let t_ti= &t_ti
- let t_te= &t_te
- let rs = &rs
- set t_ti= t_te= nors
-
- " put current line on top-of-screen and interpret it into
- " a script identifer : used to obtain webpage
- " source identifier : used to identify current version
- " and an associated comment: used to report on what's being considered
- if a:0 >= 3
- let scriptid = a:1
- let srcid = a:2
- let fname = a:3
- let cmmnt = ""
-" call Decho("scriptid<".scriptid.">")
-" call Decho("srcid <".srcid.">")
-" call Decho("fname <".fname.">")
- else
- let curline = getline(".")
- if curline =~ '^\s*#'
- let @a= rega
-" call Dret("GetOneScript : skipping a pure comment line")
- return
- endif
- let parsepat = '^\s*\(\d\+\)\s\+\(\d\+\)\s\+\(.\{-}\)\(\s*#.*\)\=$'
- try
- let scriptid = substitute(curline,parsepat,'\1','e')
- catch /^Vim\%((\a\+)\)\=:E486/
- let scriptid= 0
- endtry
- try
- let srcid = substitute(curline,parsepat,'\2','e')
- catch /^Vim\%((\a\+)\)\=:E486/
- let srcid= 0
- endtry
- try
- let fname= substitute(curline,parsepat,'\3','e')
- catch /^Vim\%((\a\+)\)\=:E486/
- let fname= ""
- endtry
- try
- let cmmnt= substitute(curline,parsepat,'\4','e')
- catch /^Vim\%((\a\+)\)\=:E486/
- let cmmnt= ""
- endtry
-" call Decho("curline <".curline.">")
-" call Decho("parsepat<".parsepat.">")
-" call Decho("scriptid<".scriptid.">")
-" call Decho("srcid <".srcid.">")
-" call Decho("fname <".fname.">")
- endif
-
- " plugin author protection from downloading his/her own scripts atop their latest work
- if scriptid == 0 || srcid == 0
- " When looking for :AutoInstall: lines, skip scripts that have 0 0 scriptname
- let @a= rega
-" call Dret("GetOneScript : skipping a scriptid==srcid==0 line")
- return
- endif
-
- let doautoinstall= 0
- if fname =~ ":AutoInstall:"
-" call Decho("case AutoInstall: fname<".fname.">")
- let aicmmnt= substitute(fname,'\s\+:AutoInstall:\s\+',' ','')
-" call Decho("aicmmnt<".aicmmnt."> s:autoinstall=".s:autoinstall)
- if s:autoinstall != ""
- let doautoinstall = g:GetLatestVimScripts_allowautoinstall
- endif
- else
- let aicmmnt= fname
- endif
-" call Decho("aicmmnt<".aicmmnt.">: doautoinstall=".doautoinstall)
-
- exe "norm z\<CR>"
- redraw!
-" call Decho('considering <'.aicmmnt.'> scriptid='.scriptid.' srcid='.srcid)
- echo 'considering <'.aicmmnt.'> scriptid='.scriptid.' srcid='.srcid
-
- " grab a copy of the plugin's vim.sourceforge.net webpage
- let scriptaddr = g:GetLatestVimScripts_scriptaddr.scriptid
- let tmpfile = tempname()
- let v:errmsg = ""
-
- " make up to three tries at downloading the description
- let itry= 1
- while itry <= 3
-" call Decho(".try#".itry." to download description of <".aicmmnt."> with addr=".scriptaddr)
- if has("win32") || has("win16") || has("win95")
-" call Decho(".new|exe silent r!".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(tmpfile).' '.shellescape(scriptaddr)."|bw!")
- new|exe "silent r!".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(tmpfile).' '.shellescape(scriptaddr)|bw!
- else
-" call Decho(".exe silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(tmpfile)." ".shellescape(scriptaddr))
- exe "silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(tmpfile)." ".shellescape(scriptaddr)
- endif
- if itry == 1
- exe "silent vsplit ".fnameescape(tmpfile)
- else
- silent! e %
- endif
- setlocal bh=wipe
-
- " find the latest source-id in the plugin's webpage
- silent! 1
- let findpkg= search('Click on the package to download','W')
- if findpkg > 0
- break
- endif
- let itry= itry + 1
- endwhile
-" call Decho(" --- end downloading tries while loop --- itry=".itry)
-
- " testing: did finding "Click on the package..." fail?
- if findpkg == 0 || itry >= 4
- silent q!
- call delete(tmpfile)
- " restore options
- let &t_ti = t_ti
- let &t_te = t_te
- let &rs = rs
- let s:downerrors = s:downerrors + 1
-" call Decho("***warning*** couldn'".'t find "Click on the package..." in description page for <'.aicmmnt.">")
- echomsg "***warning*** couldn'".'t find "Click on the package..." in description page for <'.aicmmnt.">"
-" call Dret("GetOneScript : srch for /Click on the package/ failed")
- let @a= rega
- return
- endif
-" call Decho('found "Click on the package to download"')
-
- let findsrcid= search('src_id=','W')
- if findsrcid == 0
- silent q!
- call delete(tmpfile)
- " restore options
- let &t_ti = t_ti
- let &t_te = t_te
- let &rs = rs
- let s:downerrors = s:downerrors + 1
-" call Decho("***warning*** couldn'".'t find "src_id=" in description page for <'.aicmmnt.">")
- echomsg "***warning*** couldn'".'t find "src_id=" in description page for <'.aicmmnt.">"
- let @a= rega
-" call Dret("GetOneScript : srch for /src_id/ failed")
- return
- endif
-" call Decho('found "src_id=" in description page')
-
- let srcidpat = '^\s*<td class.*src_id=\(\d\+\)">\([^<]\+\)<.*$'
- let latestsrcid= substitute(getline("."),srcidpat,'\1','')
- let sname = substitute(getline("."),srcidpat,'\2','') " script name actually downloaded
-" call Decho("srcidpat<".srcidpat."> latestsrcid<".latestsrcid."> sname<".sname.">")
- silent q!
- call delete(tmpfile)
-
- " convert the strings-of-numbers into numbers
- let srcid = srcid + 0
- let latestsrcid = latestsrcid + 0
-" call Decho("srcid=".srcid." latestsrcid=".latestsrcid." sname<".sname.">")
-
- " has the plugin's most-recent srcid increased, which indicates that it has been updated
- if latestsrcid > srcid
-" call Decho("[latestsrcid=".latestsrcid."] <= [srcid=".srcid."]: need to update <".sname.">")
-
- let s:downloads= s:downloads + 1
- if sname == bufname("%")
- " GetLatestVimScript has to be careful about downloading itself
- let sname= "NEW_".sname
- endif
-
- " -----------------------------------------------------------------------------
- " the plugin has been updated since we last obtained it, so download a new copy
- " -----------------------------------------------------------------------------
-" call Decho(".downloading new <".sname.">")
- echomsg ".downloading new <".sname.">"
- if has("win32") || has("win16") || has("win95")
-" call Decho(".new|exe silent r!".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(sname)." ".shellescape('http://vim.sourceforge.net/scripts/download_script.php?src_id='.latestsrcid)."|q")
- new|exe "silent r!".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(sname)." ".shellescape('http://vim.sourceforge.net/scripts/download_script.php?src_id='.latestsrcid)|q
- else
-" call Decho(".exe silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(sname)." ".shellescape('http://vim.sourceforge.net/scripts/download_script.php?src_id='))
- exe "silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(sname)." ".shellescape('http://vim.sourceforge.net/scripts/download_script.php?src_id=').latestsrcid
- endif
-
- " --------------------------------------------------------------------------
- " AutoInstall: only if doautoinstall has been requested by the plugin itself
- " --------------------------------------------------------------------------
-" call Decho("checking if plugin requested autoinstall: doautoinstall=".doautoinstall)
- if doautoinstall
-" call Decho(" ")
-" call Decho("Autoinstall: getcwd<".getcwd()."> filereadable(".sname.")=".filereadable(sname))
- if filereadable(sname)
-" call Decho("<".sname."> is readable")
-" call Decho("exe silent !".g:GetLatestVimScripts_mv." ".shellescape(sname)." ".shellescape(s:autoinstall))
- exe "silent !".g:GetLatestVimScripts_mv." ".shellescape(sname)." ".shellescape(s:autoinstall)
- let curdir = fnameescape(substitute(getcwd(),'\','/','ge'))
- let installdir= curdir."/Installed"
- if !isdirectory(installdir)
- call mkdir(installdir)
- endif
-" call Decho("curdir<".curdir."> installdir<".installdir.">")
-" call Decho("exe cd ".fnameescape(s:autoinstall))
- exe "cd ".fnameescape(s:autoinstall)
-
- " determine target directory for moves
- let firstdir= substitute(&rtp,',.*$','','')
- let pname = substitute(sname,'\..*','.vim','')
-" call Decho("determine tgtdir: is <".firstdir.'/AsNeeded/'.pname." readable?")
- if filereadable(firstdir.'/AsNeeded/'.pname)
- let tgtdir= "AsNeeded"
- else
- let tgtdir= "plugin"
- endif
-" call Decho("tgtdir<".tgtdir."> pname<".pname.">")
-
- " decompress
- if sname =~ '\.bz2$'
-" call Decho("decompress: attempt to bunzip2 ".sname)
- exe "sil !bunzip2 ".shellescape(sname)
- let sname= substitute(sname,'\.bz2$','','')
-" call Decho("decompress: new sname<".sname."> after bunzip2")
- elseif sname =~ '\.gz$'
-" call Decho("decompress: attempt to gunzip ".sname)
- exe "sil !gunzip ".shellescape(sname)
- let sname= substitute(sname,'\.gz$','','')
-" call Decho("decompress: new sname<".sname."> after gunzip")
- elseif sname =~ '\.xz$'
-" call Decho("decompress: attempt to unxz ".sname)
- exe "sil !unxz ".shellescape(sname)
- let sname= substitute(sname,'\.xz$','','')
-" call Decho("decompress: new sname<".sname."> after unxz")
- else
-" call Decho("no decompression needed")
- endif
-
- " distribute archive(.zip, .tar, .vba, ...) contents
- if sname =~ '\.zip$'
-" call Decho("dearchive: attempt to unzip ".sname)
- exe "silent !unzip -o ".shellescape(sname)
- elseif sname =~ '\.tar$'
-" call Decho("dearchive: attempt to untar ".sname)
- exe "silent !tar -xvf ".shellescape(sname)
- elseif sname =~ '\.tgz$'
-" call Decho("dearchive: attempt to untar+gunzip ".sname)
- exe "silent !tar -zxvf ".shellescape(sname)
- elseif sname =~ '\.taz$'
-" call Decho("dearchive: attempt to untar+uncompress ".sname)
- exe "silent !tar -Zxvf ".shellescape(sname)
- elseif sname =~ '\.tbz$'
-" call Decho("dearchive: attempt to untar+bunzip2 ".sname)
- exe "silent !tar -jxvf ".shellescape(sname)
- elseif sname =~ '\.txz$'
-" call Decho("dearchive: attempt to untar+xz ".sname)
- exe "silent !tar -Jxvf ".shellescape(sname)
- elseif sname =~ '\.vba$'
-" call Decho("dearchive: attempt to handle a vimball: ".sname)
- silent 1split
- if exists("g:vimball_home")
- let oldvimballhome= g:vimball_home
- endif
- let g:vimball_home= s:autoinstall
- exe "silent e ".fnameescape(sname)
- silent so %
- silent q
- if exists("oldvimballhome")
- let g:vimball_home= oldvimballhome
- else
- unlet g:vimball_home
- endif
- else
-" call Decho("no dearchiving needed")
- endif
-
- " ---------------------------------------------
- " move plugin to plugin/ or AsNeeded/ directory
- " ---------------------------------------------
- if sname =~ '.vim$'
-" call Decho("dearchive: attempt to simply move ".sname." to ".tgtdir)
- exe "silent !".g:GetLatestVimScripts_mv." ".shellescape(sname)." ".tgtdir
- else
-" call Decho("dearchive: move <".sname."> to installdir<".installdir.">")
- exe "silent !".g:GetLatestVimScripts_mv." ".shellescape(sname)." ".installdir
- endif
- if tgtdir != "plugin"
-" call Decho("exe silent !".g:GetLatestVimScripts_mv." plugin/".shellescape(pname)." ".tgtdir)
- exe "silent !".g:GetLatestVimScripts_mv." plugin/".shellescape(pname)." ".tgtdir
- endif
-
- " helptags step
- let docdir= substitute(&rtp,',.*','','e')."/doc"
-" call Decho("helptags: docdir<".docdir.">")
- exe "helptags ".fnameescape(docdir)
- exe "cd ".fnameescape(curdir)
- endif
- if fname !~ ':AutoInstall:'
- let modline=scriptid." ".latestsrcid." :AutoInstall: ".fname.cmmnt
- else
- let modline=scriptid." ".latestsrcid." ".fname.cmmnt
- endif
- else
- let modline=scriptid." ".latestsrcid." ".fname.cmmnt
- endif
-
- " update the data in the <GetLatestVimScripts.dat> file
- call setline(line("."),modline)
-" call Decho("update data in ".expand("%")."#".line(".").": modline<".modline.">")
-" else " Decho
-" call Decho("[latestsrcid=".latestsrcid."] <= [srcid=".srcid."], no need to update")
- endif
-
- " restore options
- let &t_ti = t_ti
- let &t_te = t_te
- let &rs = rs
- let @a = rega
-" call Dredir("BUFFER TEST (GetOneScript)","ls!")
-
-" call Dret("GetOneScript")
-endfun
-
-" ---------------------------------------------------------------------
-" Restore Options: {{{1
-let &cpo= s:keepcpo
-unlet s:keepcpo
-
-" ---------------------------------------------------------------------
-" Modelines: {{{1
-" vim: ts=8 sts=2 fdm=marker nowrap
diff --git a/runtime/autoload/remote/host.vim b/runtime/autoload/remote/host.vim
index afbf136861..d04dea180c 100644
--- a/runtime/autoload/remote/host.vim
+++ b/runtime/autoload/remote/host.vim
@@ -168,10 +168,15 @@ function! s:UpdateRemotePlugins()
let hosts = keys(s:hosts)
for host in hosts
if has_key(s:plugin_patterns, host)
- let commands = commands
- \ + ['" '.host.' plugins']
- \ + s:RegistrationCommands(host)
- \ + ['', '']
+ try
+ let commands +=
+ \ ['" '.host.' plugins']
+ \ + s:RegistrationCommands(host)
+ \ + ['', '']
+ catch
+ echomsg v:throwpoint
+ echomsg v:exception
+ endtry
endif
endfor
call writefile(commands, s:remote_plugins_manifest)
@@ -212,9 +217,11 @@ function! s:RequirePythonHost(host)
return channel_id
endif
catch
+ echomsg v:throwpoint
echomsg v:exception
endtry
- throw 'Failed to load Python host. You can try to see what happened '.
+ throw 'Failed to load '. a:host.orig_name . ' host. '.
+ \ 'You can try to see what happened '.
\ 'by starting Neovim with the environment variable '.
\ '$NVIM_PYTHON_LOG_FILE set to a file and opening '.
\ 'the generated log file. Also, the host stderr will be available '.
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index a0ed91c95d..38d53249d1 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -258,6 +258,7 @@ Name triggered by ~
|Syntax| when the 'syntax' option has been set
|EncodingChanged| after the 'encoding' option has been changed
|TermChanged| after the value of 'term' has changed
+|OptionSet| after setting any option
Startup and exit
|VimEnter| after doing all the startup stuff
@@ -745,6 +746,24 @@ MenuPopup Just before showing the popup menu (under the
o Operator-pending
i Insert
c Command line
+ *OptionSet*
+OptionSet After setting an option. The pattern is
+ matched against the long option name.
+ The |v:option_old| variable indicates the
+ old option value, |v:option_new| variable
+ indicates the newly set value, the
+ |v:option_type| variable indicates whether
+ it's global or local scoped and |<amatch>|
+ indicates what option has been set.
+
+ Note: It's a bad idea, to reset an option
+ during this autocommand, since this will
+ probably break plugins. You can always use
+ |noa| to prevent triggering this autocommand.
+ Could be used, to check for existence of the
+ 'backupdir' and 'undodir' options and create
+ directories, if they don't exist yet.
+
*QuickFixCmdPre*
QuickFixCmdPre Before a quickfix command is run (|:make|,
|:lmake|, |:grep|, |:lgrep|, |:grepadd|,
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 7b12d2082f..4ff0636b61 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1535,6 +1535,15 @@ v:oldfiles List of file names that is loaded from the |shada| file on
than String this will cause trouble.
{only when compiled with the |+shada| feature}
+ *v:option_new*
+v:option_new New value of the option. Valid while executing an |OptionSet|
+ autocommand.
+ *v:option_old*
+v:option_old Old value of the option. Valid while executing an |OptionSet|
+ autocommand.
+ *v:option_type*
+v:option_type Scope of the set command. Valid while executing an
+ |OptionSet| autocommand. Can be either "global" or "local"
*v:operator* *operator-variable*
v:operator The last operator given in Normal mode. This is a single
character except for commands starting with <g> or <z>,
diff --git a/runtime/doc/help.txt b/runtime/doc/help.txt
index bb19805a20..766a440cb3 100644
--- a/runtime/doc/help.txt
+++ b/runtime/doc/help.txt
@@ -162,7 +162,6 @@ Remarks about specific systems ~
|os_win32.txt| MS-Windows
*standard-plugin-list*
Standard plugins ~
-|pi_getscript.txt| Downloading latest version of Vim scripts
|pi_gzip.txt| Reading and writing compressed files
|pi_netrw.txt| Reading and writing files over a network
|pi_paren.txt| Highlight matching parens
diff --git a/runtime/doc/nvim_python.txt b/runtime/doc/nvim_python.txt
index 1c345b4532..a2fc968db4 100644
--- a/runtime/doc/nvim_python.txt
+++ b/runtime/doc/nvim_python.txt
@@ -49,6 +49,9 @@ To use Vim Python 2/3 plugins with Nvim, do the following:
>
$ pip3 install --user neovim
<
+Note: If you previously installed the package, get the latest version by
+ appending the `--upgrade` flag to the commands above.
+
==============================================================================
*g:python_host_prog*
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 70a585654e..e171c617db 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt* For Vim version 7.4. Last change: 2014 Dec 17
+*options.txt* For Vim version 7.4. Last change: 2015 Oct 15
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -2178,15 +2178,16 @@ A jump table for the options with a short description can be found at |Q_op|.
'endofline' 'eol' boolean (default on)
local to buffer
When writing a file and this option is off and the 'binary' option
- is on, no <EOL> will be written for the last line in the file. This
- option is automatically set when starting to edit a new file, unless
- the file does not have an <EOL> for the last line in the file, in
- which case it is reset. Normally you don't have to set or reset this
- option. When 'binary' is off the value is not used when writing the
- file. When 'binary' is on it is used to remember the presence of a
- <EOL> for the last line in the file, so that when you write the file
- the situation from the original file can be kept. But you can change
- it if you want to.
+ is on, or 'fixeol' option is off, no <EOL> will be written for the
+ last line in the file. This option is automatically set or reset when
+ starting to edit a new file, depending on whether file has an <EOL>
+ for the last line in the file. Normally you don't have to set or
+ reset this option.
+ When 'binary' is off and 'fixeol' is on the value is not used when
+ writing the file. When 'binary' is on or 'fixeol' is off it is used
+ to remember the presence of a <EOL> for the last line in the file, so
+ that when you write the file the situation from the original file can
+ be kept. But you can change it if you want to.
*'equalalways'* *'ea'* *'noequalalways'* *'noea'*
'equalalways' 'ea' boolean (default on)
@@ -2541,6 +2542,17 @@ A jump table for the options with a short description can be found at |Q_op|.
fold:c Folded |hl-Folded|
diff:c DiffDelete |hl-DiffDelete|
+ *'fixendofline'* *'fixeol'* *'nofixendofline'* *'nofixeol'*
+'fixendofline' 'fixeol' boolean (default on)
+ local to buffer
+ {not in Vi}
+ When writing a file and this option is on, <EOL> at the end of file
+ will be restored if missing. Turn this option off if you want to
+ preserve the situation from the original file.
+ When the 'binary' option is set the value of this option doesn't
+ matter.
+ See the 'endofline' option.
+
*'fkmap'* *'fk'* *'nofkmap'* *'nofk'*
'fkmap' 'fk' boolean (default off) *E198*
global
diff --git a/runtime/doc/pi_getscript.txt b/runtime/doc/pi_getscript.txt
deleted file mode 100644
index 628d9b74e5..0000000000
--- a/runtime/doc/pi_getscript.txt
+++ /dev/null
@@ -1,482 +0,0 @@
-*pi_getscript.txt* For Vim version 7.0. Last change: 2013 Nov 29
->
- GETSCRIPT REFERENCE MANUAL by Charles E. Campbell
-<
-Authors: Charles E. Campbell <NdrOchip@ScampbellPfamilyA.Mbiz>
- (remove NOSPAM from the email address)
- *GetLatestVimScripts-copyright*
-Copyright: (c) 2004-2012 by Charles E. Campbell *glvs-copyright*
- The VIM LICENSE (see |copyright|) applies to the files in this
- package, including getscriptPlugin.vim, getscript.vim,
- GetLatestVimScripts.dist, and pi_getscript.txt, except use "getscript"
- instead of "VIM". Like anything else that's free, getscript and its
- associated files are provided *as is* and comes with no warranty of
- any kind, either expressed or implied. No guarantees of
- merchantability. No guarantees of suitability for any purpose. By
- using this plugin, you agree that in no event will the copyright
- holder be liable for any damages resulting from the use of this
- software. Use at your own risk!
-
-Getscript is a plugin that simplifies retrieval of the latest versions of the
-scripts that you yourself use! Typing |:GLVS| will invoke getscript; it will
-then use the <GetLatestVimScripts.dat> (see |GetLatestVimScripts_dat|) file to
-get the latest versions of scripts listed therein from http://vim.sf.net/.
-
-==============================================================================
-1. Contents *glvs-contents* *glvs* *getscript*
- *GetLatestVimScripts*
-
- 1. Contents........................................: |glvs-contents|
- 2. GetLatestVimScripts -- Getting Started..........: |glvs-install|
- 3. GetLatestVimScripts Usage.......................: |glvs-usage|
- 4. GetLatestVimScripts Data File...................: |glvs-data|
- 5. GetLatestVimScripts Friendly Plugins............: |glvs-plugins|
- 6. GetLatestVimScripts AutoInstall.................: |glvs-autoinstall|
- 7. GetLatestViMScripts Options.....................: |glvs-options|
- 8. GetLatestVimScripts Algorithm...................: |glvs-alg|
- 9. GetLatestVimScripts History.....................: |glvs-hist|
-
-
-==============================================================================
-2. GetLatestVimScripts -- Getting Started *getscript-start*
- *getlatestvimscripts-install*
-
- VERSION FROM VIM DISTRIBUTION *glvs-dist-install*
-
-Vim 7.0 does not include the GetLatestVimScripts.dist file which
-serves as an example and a template. So, you'll need to create
-your own! See |GetLatestVimScripts_dat|.
-
- VERSION FROM VIM SF NET *glvs-install*
-
-NOTE: The last step, that of renaming/moving the GetLatestVimScripts.dist
-file, is for those who have just downloaded GetLatestVimScripts.tar.bz2 for
-the first time.
-
-The GetLatestVimScripts.dist file serves as an example and a template for your
-own personal list. Feel free to remove all the scripts mentioned within it;
-the "important" part of it is the first two lines.
-
-Your computer needs to have wget or curl for GetLatestVimScripts to do its work.
-
- 1. if compressed: gunzip getscript.vba.gz
- 2. Unix:
- vim getscript.vba
- :so %
- :q
- cd ~/.vim/GetLatest
- mv GetLatestVimScripts.dist GetLatestVimScripts.dat
- (edit GetLatestVimScripts.dat to install your own personal
- list of desired plugins -- see |GetLatestVimScripts_dat|)
-
- 3. Windows:
- vim getscript.vba
- :so %
- :q
- cd **path-to-vimfiles**/GetLatest
- mv GetLatestVimScripts.dist GetLatestVimScripts.dat
- (edit GetLatestVimScripts.dat to install your own personal
- list of desired plugins -- see |GetLatestVimScripts_dat|)
-
-
-==============================================================================
-3. GetLatestVimScripts Usage *glvs-usage* *:GLVS*
-
-Unless it has been defined elsewhere, >
-
- :GLVS
-
-will invoke GetLatestVimScripts(). If some other plugin has defined that
-command, then you may type
->
- :GetLatestVimScripts
-<
-The script will attempt to update and, if permitted, will automatically
-install scripts from http://vim.sourceforge.net/. To do so it will peruse a
-file,
->
- .vim/GetLatest/GetLatestVimScripts.dat (unix)
-<
-or >
- ..wherever..\vimfiles\GetLatest\GetLatestVimScripts.dat (windows)
-(see |glvs-data|), and examine plugins in your [.vim|vimfiles]/plugin
-directory (see |glvs-plugins|).
-
-Scripts which have been downloaded will appear in the
-~/.vim/GetLatest (unix) or ..wherever..\vimfiles\GetLatest (windows)
-subdirectory. GetLatestVimScripts will attempt to automatically
-install them if you have the following line in your <.vimrc>: >
-
- let g:GetLatestVimScripts_allowautoinstall=1
-
-The <GetLatestVimScripts.dat> file will be automatically be updated to
-reflect the latest version of script(s) so downloaded.
-(also see |glvs-options|)
-
-
-==============================================================================
-4. GetLatestVimScripts Data File *getscript-data* *glvs-data*
- *:GetLatestVimScripts_dat*
-The data file <GetLatestVimScripts.dat> must have for its first two lines
-the following text:
->
- ScriptID SourceID Filename
- --------------------------
-<
-Following those two lines are three columns; the first two are numeric
-followed by a text column. The GetLatest/GetLatestVimScripts.dist file
-contains an example of such a data file. Anything following a #... is
-ignored, so you may embed comments in the file.
-
-The first number on each line gives the script's ScriptID. When you're about
-to use a web browser to look at scripts on http://vim.sf.net/, just before you
-click on the script's link, you'll see a line resembling
-
- http://vim.sourceforge.net/scripts/script.php?script_id=40
-
-The "40" happens to be a ScriptID that GetLatestVimScripts needs to
-download the associated page, and is assigned by vim.sf.net itself
-during initial uploading of the plugin.
-
-The second number on each line gives the script's SourceID. The SourceID
-records the count of uploaded scripts as determined by vim.sf.net; hence it
-serves to indicate "when" a script was uploaded. Setting the SourceID to 1
-insures that GetLatestVimScripts will assume that the script it has is
-out-of-date.
-
-The SourceID is extracted by GetLatestVimScripts from the script's page on
-vim.sf.net; whenever it is greater than the one stored in the
-GetLatestVimScripts.dat file, the script will be downloaded
-(see |GetLatestVimScripts_dat|).
-
-If your script's author has included a special comment line in his/her plugin,
-the plugin itself will be used by GetLatestVimScripts to build your
-<GetLatestVimScripts.dat> file, including any dependencies on other scripts it
-may have. As an example, consider: >
-
- " GetLatestVimScripts: 884 1 :AutoInstall: AutoAlign.vim
-
-This comment line tells getscript.vim to check vimscript #884 and that the
-script is automatically installable. Getscript will also use this line to
-help build the GetLatestVimScripts.dat file, by including a line such as: >
-
- 884 1 :AutoInstall: AutoAlign.vim
-<
-assuming that such a line isn't already in GetLatestVimScripts.dat file.
-See |glvs-plugins| for more. Thus, GetLatestVimScripts thus provides a
-comprehensive ability to keep your plugins up-to-date!
-
-In summary:
-
- * Optionally tell getscript that it is allowed to build/append a
- GetLatestVimScripts.dat file based upon already installed plugins: >
- let g:GetLatestVimScripts_allowautoinstall=1
-<
- * A line such as >
- " GetLatestVimScripts: 884 1 :AutoInstall: AutoAlign.vim
-< in an already-downloaded plugin constitutes the concurrence of the
- plugin author that getscript may do AutoInstall. Not all plugins
- may be AutoInstall-able, and the plugin's author is best situated
- to know whether or not his/her plugin will AutoInstall properly.
-
- * A line such as >
- 884 1 :AutoInstall: AutoAlign.vim
-< in your GetLatestVimScripts.dat file constitutes your permission
- to getscript to do AutoInstall. AutoInstall requires both your
- and the plugin author's permission. See |GetLatestVimScripts_dat|.
-
-
- *GetLatestVimScripts_dat*
-As an example of a <GetLatestVimScripts.dat> file:
->
- ScriptID SourceID Filename
- --------------------------
- 294 1 :AutoInstall: Align.vim
- 120 2 Decho.vim
- 40 3 DrawIt.tar.gz
- 451 4 EasyAccents.vim
- 195 5 engspchk.vim
- 642 6 GetLatestVimScripts.vim
- 489 7 Manpageview.vim
-<
-Note: the first two lines are required, but essentially act as comments.
-
-
-==============================================================================
-5. GetLatestVimScripts Friendly Plugins *getscript-plugins* *glvs-plugins*
-
- (this section is for plugin authors)~
-
-If a plugin author includes the following comment anywhere in their plugin,
-GetLatestVimScripts will find it and use it to automatically build the user's
-GetLatestVimScripts.dat files:
->
- src_id
- v
- " GetLatestVimScripts: ### ### yourscriptname
- ^
- scriptid
-<
-As an author, you should include such a line in to refer to your own script
-plus any additional lines describing any plugin dependencies it may have.
-Same format, of course!
-
-If your command is auto-installable (see |glvs-autoinstall|), and most scripts
-are, then you may include :AutoInstall: just before "yourscriptname":
->
- src_id
- v
- " GetLatestVimScripts: ### ### :AutoInstall: yourscriptname
- ^
- scriptid
-<
-NOTE: The :AutoInstall: feature requires both the plugin author's and~
- the user's permission to operate!~
-
-GetLatestVimScripts commands for those scripts are then appended, if not
-already present, to the user's GetLatest/GetLatestVimScripts.dat file. It is
-a relatively painless way to automate the acquisition of any scripts your
-plugins depend upon.
-
-Now, as an author, you probably don't want GetLatestVimScripts to download
-your own scripts atop your own copy, thereby overwriting your not-yet-released
-hard work. GetLatestVimScripts provides a solution for this: put
->
- 0 0 yourscriptname
-<
-into your <GetLatestVimScripts.dat> file and GetLatestVimScripts will skip
-examining the "yourscriptname" scripts for those GetLatestVimScripts comment
-lines. As a result, those lines won't be inadvertently installed into your
-<GetLatestVimScripts.dat> file and subsequently used to download your own
-scripts. This is especially important to do if you've included the
-:AutoInstall: option.
-
-Be certain to use the same "yourscriptname" in the "0 0 yourscriptname" line
-as you've used in your GetLatestVimScripts comment!
-
-
-==============================================================================
-6. GetLatestVimScripts AutoInstall *getscript-autoinstall*
- *glvs-autoinstall*
-
-GetLatestVimScripts now supports "AutoInstall". Not all scripts are
-supportive of auto-install, as they may have special things you need to do to
-install them (please refer to the script's "install" directions). On the
-other hand, most scripts will be auto-installable.
-
-To let GetLatestVimScripts do an autoinstall, the data file's comment field
-should begin with (surrounding blanks are ignored): >
-
- :AutoInstall:
-<
-Both colons are needed, and it should begin the comment (yourscriptname)
-field.
-
-One may prevent any autoinstalling by putting the following line in your
-<.vimrc>: >
-
- let g:GetLatestVimScripts_allowautoinstall= 0
-<
-With :AutoInstall: enabled, as it is by default, files which end with
-
- ---.tar.bz2 : decompressed & untarred in .vim/ directory
- ---.vba.bz2 : decompressed in .vim/ directory, then vimball handles it
- ---.vim.bz2 : decompressed & moved into .vim/plugin directory
- ---.tar.gz : decompressed & untarred in .vim/ directory
- ---.vba.gz : decompressed in .vim/ directory, then vimball handles it
- ---.vim.gz : decompressed & moved into .vim/plugin directory
- ---.vba : unzipped in .vim/ directory
- ---.vim : moved to .vim/plugin directory
- ---.zip : unzipped in .vim/ directory
-
-and which merely need to have their components placed by the untar/gunzip or
-move-to-plugin-directory process should be auto-installable. Vimballs, of
-course, should always be auto-installable.
-
-When is a script not auto-installable? Let me give an example:
-
- .vim/after/syntax/blockhl.vim
-
-The <blockhl.vim> script provides block highlighting for C/C++ programs; it is
-available at:
-
- http://vim.sourceforge.net/scripts/script.php?script_id=104
-
-Currently, vim's after/syntax only supports by-filetype scripts (in
-blockhl.vim's case, that's after/syntax/c.vim). Hence, auto-install would
-possibly overwrite the current user's after/syntax/c.vim file.
-
-In my own case, I use <aftersyntax.vim> (renamed to after/syntax/c.vim) to
-allow a after/syntax/c/ directory:
-
- http://vim.sourceforge.net/scripts/script.php?script_id=1023
-
-The script allows multiple syntax files to exist separately in the
-after/syntax/c subdirectory. I can't bundle aftersyntax.vim in and build an
-appropriate tarball for auto-install because of the potential for the
-after/syntax/c.vim contained in it to overwrite a user's c.vim.
-
-
-==============================================================================
-7. GetLatestVimScripts Options *glvs-options*
->
- g:GetLatestVimScripts_wget
-< default= "wget"
- This variable holds the name of the command for obtaining
- scripts.
->
- g:GetLatestVimScripts_options
-< default= "-q -O"
- This variable holds the options to be used with the
- g:GetLatestVimScripts_wget command.
->
- g:GetLatestVimScripts_allowautoinstall
-< default= 1
- This variable indicates whether GetLatestVimScripts is allowed
- to attempt to automatically install scripts. Furthermore, the
- plugin author has to have explicitly indicated that his/her
- plugin is automatically installable (via the :AutoInstall:
- keyword in the GetLatestVimScripts comment line).
->
- g:GetLatestVimScripts_autoinstalldir
-< default= $HOME/.vim (linux)
- default= $HOME/vimfiles (windows)
- Override where :AutoInstall: scripts will be installed.
- Doesn't override vimball installation.
->
- g:GetLatestVimScripts_scriptaddr
-< default='http://vim.sourceforge.net/script.php?script_id='
- Override this if your system needs
- ... ='http://vim.sourceforge.net/script/script.php?script_id='
-
-==============================================================================
-8. GetLatestVimScripts Algorithm *glvs-algorithm* *glvs-alg*
-
-The Vim sourceforge page dynamically creates a page by keying off of the
-so-called script-id. Within the webpage of
-
- http://vim.sourceforge.net/scripts/script.php?script_id=40
-
-is a line specifying the latest source-id (src_id). The source identifier
-numbers are always increasing, hence if the src_id is greater than the one
-recorded for the script in GetLatestVimScripts then it's time to download a
-newer copy of that script.
-
-GetLatestVimScripts will then download the script and update its internal
-database of script ids, source ids, and scriptnames.
-
-The AutoInstall process will:
-
- Move the file from GetLatest/ to the following directory
- Unix : $HOME/.vim
- Windows: $HOME\vimfiles
- if the downloaded file ends with ".bz2"
- bunzip2 it
- else if the downloaded file ends with ".gz"
- gunzip it
- if the resulting file ends with ".zip"
- unzip it
- else if the resulting file ends with ".tar"
- tar -oxvf it
- else if the resulting file ends with ".vim"
- move it to the plugin subdirectory
-
-
-==============================================================================
-9. GetLatestVimScripts History *getscript-history* *glvs-hist* {{{1
-
-v36 Apr 22, 2013 : * (glts) suggested use of plugin/**/*.vim instead of
- plugin/*.vim in globpath() call.
- * (Andy Wokula) got warning message when setting
- g:loaded_getscriptPlugin
-v35 Apr 07, 2012 : * (MengHuan Yu) pointed out that the script url has
- changed (somewhat). However, it doesn't work, and
- the original one does (under Linux). I'll make it
- yet-another-option.
-v34 Jun 23, 2011 : * handles additional decompression options for tarballs
- (tgz taz tbz txz)
-v33 May 31, 2011 : * using fnameescape() instead of escape()
- * *.xz support
-v32 Jun 19, 2010 : * (Jan Steffens) added support for xz compression
-v31 Jun 29, 2008 : * (Bill McCarthy) fixed having hls enabled with getscript
- * (David Schaefer) the acd option interferes with vimballs
- Solution: bypass the acd option
-v30 Jun 13, 2008 : * GLVS now checks for existence of fnameescape() and will
- issue an error message if it is not supported
-v29 Jan 07, 2008 : * Bram M pointed out that cpo is a global option and that
- getscriptPlugin.vim was setting it but not restoring it.
-v28 Jan 02, 2008 : * improved shell quoting character handling, cygwin
- interface, register-a bypass
- Oct 29, 2007 * Bill McCarthy suggested a change to getscript that avoids
- creating pop-up windows
-v24 Apr 16, 2007 : * removed save&restore of the fo option during script
- loading
-v23 Nov 03, 2006 : * ignores comments (#...)
- * handles vimballs
-v22 Oct 13, 2006 : * supports automatic use of curl if wget is not
- available
-v21 May 01, 2006 : * now takes advantage of autoloading.
-v20 Dec 23, 2005 : * Eric Haarbauer found&fixed a bug with unzip use;
- unzip needs the -o flag to overwrite.
-v19 Nov 28, 2005 : * v18's GetLatestVimScript line accessed the wrong
- script! Fixed.
-v18 Mar 21, 2005 : * bugfix to automatic database construction
- * bugfix - nowrapscan caused an error
- (tnx to David Green for the fix)
- Apr 01, 2005 * if shell is bash, "mv" instead of "ren" used in
- :AutoInstall:s, even though its o/s is windows
- Apr 01, 2005 * when downloading errors occurred, GLVS was
- terminating early. It now just goes on to trying
- the next script (after trying three times to
- download a script description page)
- Apr 20, 2005 * bugfix - when a failure to download occurred,
- GetLatestVimScripts would stop early and claim that
- everything was current. Fixed.
-v17 Aug 25, 2004 : * g:GetLatestVimScripts_allowautoinstall, which
- defaults to 1, can be used to prevent all
- :AutoInstall:
-v16 Aug 25, 2004 : * made execution of bunzip2/gunzip/tar/zip silent
- * fixed bug with :AutoInstall: use of helptags
-v15 Aug 24, 2004 : * bugfix: the "0 0 comment" download prevention wasn't
- always preventing downloads (just usually). Fixed.
-v14 Aug 24, 2004 : * bugfix -- helptags was using dotvim, rather than
- s:dotvim. Fixed.
-v13 Aug 23, 2004 : * will skip downloading a file if its scriptid or srcid
- is zero. Useful for script authors; that way their
- own GetLatestVimScripts activity won't overwrite
- their scripts.
-v12 Aug 23, 2004 : * bugfix - a "return" got left in the distribution that
- was intended only for testing. Removed, now works.
- * :AutoInstall: implemented
-v11 Aug 20, 2004 : * GetLatestVimScripts is now a plugin:
- * :GetLatestVimScripts command
- * (runtimepath)/GetLatest/GetLatestVimScripts.dat
- now holds scripts that need updating
-v10 Apr 19, 2004 : * moved history from script to doc
-v9 Jan 23, 2004 : windows (win32/win16/win95) will use
- double quotes ("") whereas other systems will use
- single quotes ('') around the urls in calls via wget
-v8 Dec 01, 2003 : makes three tries at downloading
-v7 Sep 02, 2003 : added error messages if "Click on..." or "src_id="
- not found in downloaded webpage
- Uses t_ti, t_te, and rs to make progress visible
-v6 Aug 06, 2003 : final status messages now display summary of work
- ( "Downloaded someqty scripts" or
- "Everything was current")
- Now GetLatestVimScripts is careful about downloading
- GetLatestVimScripts.vim itself!
- (goes to <NEW_GetLatestVimScripts.vim>)
-v5 Aug 04, 2003 : missing an endif near bottom
-v4 Jun 17, 2003 : redraw! just before each "considering" message
-v3 May 27, 2003 : Protects downloaded files from errant shell
- expansions with single quotes: '...'
-v2 May 14, 2003 : extracts name of item to be obtained from the
- script file. Uses it instead of comment field
- for output filename; comment is used in the
- "considering..." line and is now just a comment!
- * Fixed a bug: a string-of-numbers is not the
- same as a number, so I added zero to them
- and they became numbers. Fixes comparison.
-
-==============================================================================
-vim:tw=78:ts=8:ft=help:fdm=marker
diff --git a/runtime/doc/usr_05.txt b/runtime/doc/usr_05.txt
index a130d84630..86fcf0cc2f 100644
--- a/runtime/doc/usr_05.txt
+++ b/runtime/doc/usr_05.txt
@@ -285,7 +285,6 @@ Where can you find plugins?
- You could write one yourself, see |write-plugin|.
Some plugins come as a vimball archive, see |vimball|.
-Some plugins can be updated automatically, see |getscript|.
USING A GLOBAL PLUGIN
diff --git a/runtime/doc/usr_21.txt b/runtime/doc/usr_21.txt
index bdff81ef69..f99c3263d0 100644
--- a/runtime/doc/usr_21.txt
+++ b/runtime/doc/usr_21.txt
@@ -70,9 +70,7 @@ difference. Without it executes the program normally, with the range a number
of text lines is filtered through the program.
Executing a whole row of programs this way is possible. But a shell is much
-better at it. You can start a new shell this way: >
-
- :shell
+better at it. You can start a new shell with |:terminal|.
This is similar to using CTRL-Z to suspend Vim. The difference is that a new
shell is started.
diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt
index 705702c083..fe9d9b4d62 100644
--- a/runtime/doc/usr_41.txt
+++ b/runtime/doc/usr_41.txt
@@ -2465,8 +2465,6 @@ utility is recommended.
For utmost portability use Vim itself to pack scripts together. This can be
done with the Vimball utility. See |vimball|.
-It's good if you add a line to allow automatic updating. See |glvs-plugins|.
-
==============================================================================
Next chapter: |usr_42.txt| Add new menus
diff --git a/runtime/optwin.vim b/runtime/optwin.vim
index 09406f260b..dde5dd0c61 100644
--- a/runtime/optwin.vim
+++ b/runtime/optwin.vim
@@ -926,6 +926,9 @@ call <SID>BinOptionL("bin")
call append("$", "endofline\tlast line in the file has an end-of-line")
call append("$", "\t(local to buffer)")
call <SID>BinOptionL("eol")
+call append("$", "fixeol\tfixes missing end-of-line at end of text file")
+call append("$", "\t(local to buffer)")
+call <SID>BinOptionL("fixeol")
if has("multi_byte")
call append("$", "bomb\tprepend a Byte Order Mark to the file")
call append("$", "\t(local to buffer)")
diff --git a/runtime/plugin/getscriptPlugin.vim b/runtime/plugin/getscriptPlugin.vim
deleted file mode 100644
index fb0fbeab7b..0000000000
--- a/runtime/plugin/getscriptPlugin.vim
+++ /dev/null
@@ -1,41 +0,0 @@
-" ---------------------------------------------------------------------
-" getscriptPlugin.vim
-" Author: Charles E. Campbell
-" Date: Nov 29, 2013
-" Installing: :help glvs-install
-" Usage: :help glvs
-"
-" GetLatestVimScripts: 642 1 :AutoInstall: getscript.vim
-"
-" (Rom 15:11 WEB) Again, "Praise the Lord, all you Gentiles! Let
-" all the peoples praise Him."
-" ---------------------------------------------------------------------
-" Initialization: {{{1
-" if you're sourcing this file, surely you can't be
-" expecting vim to be in its vi-compatible mode
-if exists("g:loaded_getscriptPlugin")
- finish
-endif
-if &cp
- if &verbose
- echo "GetLatestVimScripts is not vi-compatible; not loaded (you need to set nocp)"
- endif
- finish
-endif
-let g:loaded_getscriptPlugin = "v36"
-let s:keepcpo = &cpo
-set cpo&vim
-
-" ---------------------------------------------------------------------
-" Public Interface: {{{1
-com! -nargs=0 GetLatestVimScripts call getscript#GetLatestVimScripts()
-com! -nargs=0 GetScripts call getscript#GetLatestVimScripts()
-silent! com -nargs=0 GLVS call getscript#GetLatestVimScripts()
-
-" ---------------------------------------------------------------------
-" Restore Options: {{{1
-let &cpo= s:keepcpo
-unlet s:keepcpo
-
-" ---------------------------------------------------------------------
-" vim: ts=8 sts=2 fdm=marker nowrap
diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua
index 7624dd2303..aa4a8d8332 100644
--- a/src/nvim/auevents.lua
+++ b/src/nvim/auevents.lua
@@ -57,6 +57,7 @@ return {
'InsertLeave', -- when leaving Insert mode
'JobActivity', -- when job sent some data
'MenuPopup', -- just before popup menu is displayed
+ 'OptionSet', -- after setting any option
'QuickFixCmdPost', -- after :make, :grep etc.
'QuickFixCmdPre', -- before :make, :grep etc.
'QuitPre', -- before :quit
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 7978dc8969..762cd3efd3 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -1414,7 +1414,6 @@ buflist_new (
return NULL;
if (aborting()) /* autocmds may abort script processing */
return NULL;
- /* buf->b_nwindows = 0; why was this here? */
free_buffer_stuff(buf, FALSE); /* delete local variables et al. */
/* Init the options. */
@@ -1475,6 +1474,9 @@ buflist_new (
fmarks_check_names(buf); /* check file marks for this file */
buf->b_p_bl = (flags & BLN_LISTED) ? TRUE : FALSE; /* init 'buflisted' */
if (!(flags & BLN_DUMMY)) {
+ // Tricky: these autocommands may change the buffer list. They could also
+ // split the window with re-using the one empty buffer. This may result in
+ // unexpectedly losing the empty buffer.
apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, buf);
if (!buf_valid(buf)) {
return NULL;
@@ -3745,8 +3747,10 @@ int build_stl_str_hl(
// Put a `<` to mark where we truncated at
*trunc_p = '<';
- // Advance the pointer to the end of the string
- trunc_p = trunc_p + STRLEN(trunc_p);
+ if (width + 1 < maxwidth) {
+ // Advance the pointer to the end of the string
+ trunc_p = trunc_p + STRLEN(trunc_p);
+ }
// Fill up for half a double-wide character.
while (++width < maxwidth) {
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 3eabb7ee43..6b5bbe3b00 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -612,6 +612,7 @@ struct file_buffer {
char_u *b_p_cfu; /* 'completefunc' */
char_u *b_p_ofu; /* 'omnifunc' */
int b_p_eol; /* 'endofline' */
+ int b_p_fixeol; /* 'fixendofline' */
int b_p_et; /* 'expandtab' */
int b_p_et_nobin; /* b_p_et saved for binary mode */
char_u *b_p_fenc; /* 'fileencoding' */
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 8dc2844d8e..9ba5d96e16 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -5017,8 +5017,9 @@ insertchar (
int textwidth;
char_u *p;
int fo_ins_blank;
+ int force_format = flags & INSCHAR_FORMAT;
- textwidth = comp_textwidth(flags & INSCHAR_FORMAT);
+ textwidth = comp_textwidth(force_format);
fo_ins_blank = has_format_option(FO_INS_BLANK);
/*
@@ -5037,7 +5038,7 @@ insertchar (
* before 'textwidth'
*/
if (textwidth > 0
- && ((flags & INSCHAR_FORMAT)
+ && (force_format
|| (!ascii_iswhite(c)
&& !((State & REPLACE_FLAG)
&& !(State & VREPLACE_FLAG)
@@ -5051,8 +5052,11 @@ insertchar (
/* Format with 'formatexpr' when it's set. Use internal formatting
* when 'formatexpr' isn't set or it returns non-zero. */
int do_internal = TRUE;
+ colnr_T virtcol = get_nolist_virtcol()
+ + char2cells(c != NUL ? c : gchar_cursor());
- if (*curbuf->b_p_fex != NUL && (flags & INSCHAR_NO_FEX) == 0) {
+ if (*curbuf->b_p_fex != NUL && (flags & INSCHAR_NO_FEX) == 0
+ && (force_format || virtcol > (colnr_T)textwidth)) {
do_internal = (fex_format(curwin->w_cursor.lnum, 1L, c) != 0);
/* It may be required to save for undo again, e.g. when setline()
* was called. */
@@ -7427,15 +7431,14 @@ static int ins_bs(int c, int mode, int *inserted_space_p)
* delete newline!
*/
if (curwin->w_cursor.col == 0) {
- lnum = Insstart_orig.lnum;
+ lnum = Insstart.lnum;
if (curwin->w_cursor.lnum == lnum || revins_on) {
if (u_save((linenr_T)(curwin->w_cursor.lnum - 2),
(linenr_T)(curwin->w_cursor.lnum + 1)) == FAIL) {
return FALSE;
}
- --Insstart_orig.lnum;
- Insstart_orig.col = MAXCOL;
- Insstart = Insstart_orig;
+ --Insstart.lnum;
+ Insstart.col = MAXCOL;
}
/*
* In replace mode:
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index f104098dbf..b60886704e 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -373,6 +373,9 @@ static struct vimvar {
{VV_NAME("progpath", VAR_STRING), VV_RO},
{VV_NAME("command_output", VAR_STRING), 0},
{VV_NAME("completed_item", VAR_DICT), VV_RO},
+ {VV_NAME("option_new", VAR_STRING), VV_RO},
+ {VV_NAME("option_old", VAR_STRING), VV_RO},
+ {VV_NAME("option_type", VAR_STRING), VV_RO},
{VV_NAME("msgpack_types", VAR_DICT), VV_RO},
};
@@ -5648,6 +5651,14 @@ bool garbage_collect(void)
ABORTING(set_ref_in_ht)(&fc->l_avars.dv_hashtab, copyID, NULL);
}
+ // Jobs
+ {
+ TerminalJobData *data;
+ map_foreach_value(jobs, data, {
+ ABORTING(set_ref_dict)(data->self, copyID);
+ })
+ }
+
// v: vars
ABORTING(set_ref_in_ht)(&vimvarht, copyID, NULL);
@@ -5725,8 +5736,7 @@ static int free_unref_items(int copyID)
// Go through the list of dicts and free items without the copyID.
// Don't free dicts that are referenced internally.
for (dict_T *dd = first_dict; dd != NULL; ) {
- if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
- && !dd->internal_refcount) {
+ if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)) {
// Free the Dictionary and ordinary items it contains, but don't
// recurse into Lists and Dictionaries, they will be in the list
// of dicts or list of lists. */
@@ -5967,7 +5977,6 @@ dict_T *dict_alloc(void) FUNC_ATTR_NONNULL_RET
d->dv_scope = 0;
d->dv_refcount = 0;
d->dv_copyID = 0;
- d->internal_refcount = 0;
QUEUE_INIT(&d->watchers);
return d;
@@ -21238,9 +21247,13 @@ void ex_oldfiles(exarg_T *eap)
}
}
-
-
-
+// reset v:option_new, v:option_old and v:option_type
+void reset_v_option_vars(void)
+{
+ set_vim_var_string(VV_OPTION_NEW, NULL, -1);
+ set_vim_var_string(VV_OPTION_OLD, NULL, -1);
+ set_vim_var_string(VV_OPTION_TYPE, NULL, -1);
+}
/*
* Adjust a filename, according to a string of modifiers.
@@ -21613,7 +21626,6 @@ static inline bool common_job_callbacks(dict_T *vopts, ufunc_T **on_stdout,
if (get_dict_callback(vopts, "on_stdout", on_stdout)
&& get_dict_callback(vopts, "on_stderr", on_stderr)
&& get_dict_callback(vopts, "on_exit", on_exit)) {
- vopts->internal_refcount++;
vopts->dv_refcount++;
return true;
}
@@ -21675,7 +21687,6 @@ static inline void free_term_job_data_event(void **argv)
}
if (data->self) {
- data->self->internal_refcount--;
dict_unref(data->self);
}
queue_free(data->events);
@@ -21926,7 +21937,7 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments)
true,
NULL);
- arguments->lv_refcount--;
+ list_unref(arguments);
// Restore caller scope information
restore_funccal(provider_caller_scope.funccalp);
provider_caller_scope = saved_provider_caller_scope;
diff --git a/src/nvim/eval.h b/src/nvim/eval.h
index 8ccf71068c..19a1bbb083 100644
--- a/src/nvim/eval.h
+++ b/src/nvim/eval.h
@@ -108,6 +108,9 @@ enum {
VV_PROGPATH,
VV_COMMAND_OUTPUT,
VV_COMPLETED_ITEM,
+ VV_OPTION_NEW,
+ VV_OPTION_OLD,
+ VV_OPTION_TYPE,
VV_MSGPACK_TYPES,
VV_LEN, /* number of v: vars */
};
diff --git a/src/nvim/eval_defs.h b/src/nvim/eval_defs.h
index bd50d6b829..ed419268d2 100644
--- a/src/nvim/eval_defs.h
+++ b/src/nvim/eval_defs.h
@@ -118,8 +118,6 @@ struct dictvar_S {
dict_T *dv_copydict; /* copied dict used by deepcopy() */
dict_T *dv_used_next; /* next dict in used dicts list */
dict_T *dv_used_prev; /* previous dict in used dicts list */
- int internal_refcount; // number of internal references to
- // prevent garbage collection
QUEUE watchers; // dictionary key watchers set by user code
};
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 3f19421a75..d902234ef7 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -2112,7 +2112,6 @@ do_ecmd (
goto theend;
if (buf->b_ml.ml_mfp == NULL) { /* no memfile yet */
oldbuf = FALSE;
- buf->b_nwindows = 0;
} else { /* existing memfile */
oldbuf = TRUE;
(void)buf_check_timestamp(buf, FALSE);
@@ -2138,7 +2137,7 @@ do_ecmd (
* Make the (new) buffer the one used by the current window.
* If the old buffer becomes unused, free it if ECMD_HIDE is FALSE.
* If the current buffer was empty and has no file name, curbuf
- * is returned by buflist_new().
+ * is returned by buflist_new(), nothing to do here.
*/
if (buf != curbuf) {
/*
@@ -2225,8 +2224,7 @@ do_ecmd (
}
xfree(new_name);
au_new_curbuf = NULL;
- } else
- ++curbuf->b_nwindows;
+ }
curwin->w_pcmark.lnum = 1;
curwin->w_pcmark.col = 0;
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index 5ac133a0c3..1a6c85abaa 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -1544,6 +1544,11 @@ rewind_retry:
/* First try finding a NL, for Dos and Unix */
if (try_dos || try_unix) {
for (p = ptr; p < ptr + size; ++p) {
+ // Reset the carriage return counter.
+ if (try_mac) {
+ try_mac = 1;
+ }
+
if (*p == NL) {
if (!try_unix
|| (try_dos && p > ptr && p[-1] == CAR))
@@ -1551,6 +1556,8 @@ rewind_retry:
else
fileformat = EOL_UNIX;
break;
+ } else if (*p == CAR && try_mac) {
+ try_mac++;
}
}
@@ -1571,6 +1578,10 @@ rewind_retry:
if (try_mac > try_unix)
fileformat = EOL_MAC;
}
+ } else if (fileformat == EOL_UNKNOWN && try_mac == 1) {
+ // Looking for CR but found no end-of-line markers at all:
+ // use the default format.
+ fileformat = default_fileformat();
}
}
@@ -1922,10 +1933,10 @@ failed:
check_marks_read();
/*
- * Trick: We remember if the last line of the read didn't have
- * an eol even when 'binary' is off, for when writing it again with
- * 'binary' on. This is required for
- * ":autocmd FileReadPost *.gz set bin|'[,']!gunzip" to work.
+ * We remember if the last line of the read didn't have
+ * an eol even when 'binary' is off, to support turning 'fixeol' off,
+ * or writing the read again with 'binary' on. The latter is required
+ * for ":autocmd FileReadPost *.gz set bin|'[,']!gunzip" to work.
*/
curbuf->b_no_eol_lnum = read_no_eol_lnum;
@@ -3310,7 +3321,7 @@ restore_backup:
/* write failed or last line has no EOL: stop here */
if (end == 0
|| (lnum == end
- && write_bin
+ && (write_bin || !buf->b_p_fixeol)
&& (lnum == buf->b_no_eol_lnum
|| (lnum == buf->b_ml.ml_line_count && !buf->b_p_eol)))) {
++lnum; /* written the line, count it */
@@ -4331,8 +4342,6 @@ void shorten_fnames(int force)
/// @return [allocated] - A new filename, made up from:
/// * fname + ext, if fname not NULL.
/// * current dir + ext, if fname is NULL.
-/// On Windows, and if ext starts with ".", a "_" is
-/// preprended to ext (for filename to be valid).
/// Result is guaranteed to:
/// * be ended by <ext>.
/// * have a basename with at most BASENAMELEN chars:
@@ -4386,15 +4395,6 @@ char *modname(const char *fname, const char *ext, bool prepend_dot)
char *s;
s = ptr + strlen(ptr);
-#if defined(WIN3264)
- // If there is no file name, and the extension starts with '.', put a
- // '_' before the dot, because just ".ext" may be invalid if it's on a
- // FAT partition, and on HPFS it doesn't matter.
- else if ((fname == NULL || *fname == NUL) && *ext == '.') {
- *s++ = '_';
- }
-#endif
-
// Append the extension.
// ext can start with '.' and cannot exceed 3 more characters.
strcpy(s, ext);
@@ -6418,7 +6418,7 @@ apply_autocmds_group (
* invalid.
*/
if (fname_io == NULL) {
- if (event == EVENT_COLORSCHEME)
+ if (event == EVENT_COLORSCHEME || event == EVENT_OPTIONSET)
autocmd_fname = NULL;
else if (fname != NULL && *fname != NUL)
autocmd_fname = fname;
@@ -6468,6 +6468,7 @@ apply_autocmds_group (
if (event == EVENT_COLORSCHEME
|| event == EVENT_FILETYPE
|| event == EVENT_FUNCUNDEFINED
+ || event == EVENT_OPTIONSET
|| event == EVENT_QUICKFIXCMDPOST
|| event == EVENT_QUICKFIXCMDPRE
|| event == EVENT_REMOTEREPLY
diff --git a/src/nvim/log.c b/src/nvim/log.c
index 08b6d0483e..5767da03af 100644
--- a/src/nvim/log.c
+++ b/src/nvim/log.c
@@ -14,7 +14,7 @@
# include <unistd.h>
#endif
-#define USR_LOG_FILE "$HOME/.nvimlog"
+#define USR_LOG_FILE "$HOME" _PATHSEPSTR ".nvimlog"
static uv_mutex_t mutex;
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index 0ba8dd98d0..c91a25df6e 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -3954,8 +3954,10 @@ long ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp)
if (ffdos)
size += lnum - 1;
- /* Don't count the last line break if 'bin' and 'noeol'. */
- if (buf->b_p_bin && !buf->b_p_eol && buf->b_ml.ml_line_count == lnum) {
+ /* Don't count the last line break if 'noeol' and ('bin' or
+ * 'nofixeol'). */
+ if ((!buf->b_p_fixeol || buf->b_p_bin) && !buf->b_p_eol
+ && buf->b_ml.ml_line_count == lnum) {
size -= ffdos + 1;
}
}
diff --git a/src/nvim/memline_defs.h b/src/nvim/memline_defs.h
index bcc1c673d2..34a002af5d 100644
--- a/src/nvim/memline_defs.h
+++ b/src/nvim/memline_defs.h
@@ -41,7 +41,7 @@ typedef struct memline {
int ml_flags;
infoptr_T *ml_stack; /* stack of pointer blocks (array of IPTRs) */
- int ml_stack_top; /* current top if ml_stack */
+ int ml_stack_top; /* current top of ml_stack */
int ml_stack_size; /* total number of entries in ml_stack */
linenr_T ml_line_lnum; /* line number of cached line, 0 if not valid */
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index ad53e9bf24..a2e473fcb8 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -7466,6 +7466,13 @@ static void nv_object(cmdarg_T *cap)
flag = current_block(cap->oap, cap->count1, include, '<', '>');
break;
case 't': /* "at" = a tag block (xml and html) */
+ // Do not adjust oap->end in do_pending_operator()
+ // otherwise there are different results for 'dit'
+ // (note leading whitespace in last line):
+ // 1) <b> 2) <b>
+ // foobar foobar
+ // </b> </b>
+ cap->retval |= CA_NO_ADJ_OP_END;
flag = current_tagblock(cap->oap, cap->count1, include);
break;
case 'p': /* "ap" = a paragraph */
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 956b9c7758..bef0ebaeed 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -4964,7 +4964,7 @@ void cursor_pos_info(void)
&char_count_cursor, len, eol_size);
if (lnum == curbuf->b_ml.ml_line_count
&& !curbuf->b_p_eol
- && curbuf->b_p_bin
+ && (curbuf->b_p_bin || !curbuf->b_p_fixeol)
&& (long)STRLEN(s) < len)
byte_count_cursor -= eol_size;
}
@@ -4985,7 +4985,7 @@ void cursor_pos_info(void)
}
/* Correction for when last line doesn't have an EOL. */
- if (!curbuf->b_p_eol && curbuf->b_p_bin)
+ if (!curbuf->b_p_eol && (curbuf->b_p_bin || !curbuf->b_p_fixeol))
byte_count -= eol_size;
if (l_VIsual_active) {
diff --git a/src/nvim/option.c b/src/nvim/option.c
index f5080c7a91..486f2083a6 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -122,6 +122,7 @@ static char_u *p_cpt;
static char_u *p_cfu;
static char_u *p_ofu;
static int p_eol;
+static int p_fixeol;
static int p_et;
static char_u *p_fenc;
static char_u *p_ff;
@@ -1018,12 +1019,9 @@ void set_init_2(void)
*/
void set_init_3(void)
{
-#if defined(UNIX) || defined(WIN3264)
- /*
- * Set 'shellpipe' and 'shellredir', depending on the 'shell' option.
- * This is done after other initializations, where 'shell' might have been
- * set, but only if they have not been set before.
- */
+ // Set 'shellpipe' and 'shellredir', depending on the 'shell' option.
+ // This is done after other initializations, where 'shell' might have been
+ // set, but only if they have not been set before.
int idx_srr;
int do_srr;
int idx_sp;
@@ -1080,8 +1078,6 @@ void set_init_3(void)
}
xfree(p);
}
-#endif
-
set_title_defaults();
}
@@ -1503,9 +1499,10 @@ do_set (
} else if (opt_idx >= 0) { /* string */
char_u *save_arg = NULL;
char_u *s = NULL;
- char_u *oldval; /* previous value if *varp */
+ char_u *oldval = NULL; // previous value if *varp
char_u *newval;
- char_u *origval;
+ char_u *origval = NULL;
+ char_u *saved_origval = NULL;
unsigned newlen;
int comma;
int bs;
@@ -1772,14 +1769,37 @@ do_set (
/* Set the new value. */
*(char_u **)(varp) = newval;
+ if (!starting && origval != NULL) {
+ // origval may be freed by
+ // did_set_string_option(), make a copy.
+ saved_origval = vim_strsave(origval);
+ }
+
/* Handle side effects, and set the global value for
* ":set" on local options. */
errmsg = did_set_string_option(opt_idx, (char_u **)varp,
new_value_alloced, oldval, errbuf, opt_flags);
- /* If error detected, print the error message. */
- if (errmsg != NULL)
+ // If error detected, print the error message.
+ if (errmsg != NULL) {
+ xfree(saved_origval);
goto skip;
+ }
+
+ if (saved_origval != NULL) {
+ char_u buf_type[7];
+ vim_snprintf((char *)buf_type, ARRAY_SIZE(buf_type), "%s",
+ (opt_flags & OPT_LOCAL) ? "local" : "global");
+ set_vim_var_string(VV_OPTION_NEW,
+ *(char_u **)varp, -1);
+ set_vim_var_string(VV_OPTION_OLD, saved_origval, -1);
+ set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
+ apply_autocmds(EVENT_OPTIONSET,
+ (char_u *)options[opt_idx].fullname,
+ NULL, false, NULL);
+ reset_v_option_vars();
+ xfree(saved_origval);
+ }
} else {
// key code option(FIXME(tarruda): Show a warning or something
// similar)
@@ -2329,6 +2349,7 @@ set_string_option (
char_u *s;
char_u **varp;
char_u *oldval;
+ char_u *saved_oldval = NULL;
char_u *r = NULL;
if (options[opt_idx].var == NULL) /* don't set hidden option */
@@ -2342,10 +2363,30 @@ set_string_option (
: opt_flags);
oldval = *varp;
*varp = s;
- if ((r = did_set_string_option(opt_idx, varp, TRUE, oldval, NULL,
+
+ if (!starting) {
+ saved_oldval = vim_strsave(oldval);
+ }
+
+ if ((r = did_set_string_option(opt_idx, varp, (int)true, oldval, NULL,
opt_flags)) == NULL)
did_set_option(opt_idx, opt_flags, TRUE);
+ // call autocommand after handling side effects
+ if (saved_oldval != NULL) {
+ char_u buf_type[7];
+ vim_snprintf((char *)buf_type, ARRAY_SIZE(buf_type), "%s",
+ (opt_flags & OPT_LOCAL) ? "local" : "global");
+ set_vim_var_string(VV_OPTION_NEW, *varp, -1);
+ set_vim_var_string(VV_OPTION_OLD, saved_oldval, -1);
+ set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
+ apply_autocmds(EVENT_OPTIONSET,
+ (char_u *)options[opt_idx].fullname,
+ NULL, false, NULL);
+ reset_v_option_vars();
+ xfree(saved_oldval);
+ }
+
return r;
}
@@ -3547,6 +3588,9 @@ set_bool_option (
/* when 'endofline' is changed, redraw the window title */
else if ((int *)varp == &curbuf->b_p_eol) {
redraw_titles();
+ } else if ((int *)varp == &curbuf->b_p_fixeol) {
+ // when 'fixeol' is changed, redraw the window title
+ redraw_titles();
}
/* when 'bomb' is changed, redraw the window title and tab page text */
else if ((int *)varp == &curbuf->b_p_bomb) {
@@ -3814,8 +3858,29 @@ set_bool_option (
* End of handling side effects for bool options.
*/
+ // after handling side effects, call autocommand
+
options[opt_idx].flags |= P_WAS_SET;
+ if (!starting) {
+ char_u buf_old[2];
+ char_u buf_new[2];
+ char_u buf_type[7];
+ vim_snprintf((char *)buf_old, ARRAY_SIZE(buf_old), "%d",
+ old_value ? true: false);
+ vim_snprintf((char *)buf_new, ARRAY_SIZE(buf_new), "%d",
+ value ? true: false);
+ vim_snprintf((char *)buf_type, ARRAY_SIZE(buf_type), "%s",
+ (opt_flags & OPT_LOCAL) ? "local" : "global");
+ set_vim_var_string(VV_OPTION_NEW, buf_new, -1);
+ set_vim_var_string(VV_OPTION_OLD, buf_old, -1);
+ set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
+ apply_autocmds(EVENT_OPTIONSET,
+ (char_u *) options[opt_idx].fullname,
+ NULL, false, NULL);
+ reset_v_option_vars();
+ }
+
comp_col(); /* in case 'ruler' or 'showcmd' changed */
if (curwin->w_curswant != MAXCOL
&& (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0)
@@ -4187,6 +4252,23 @@ set_num_option (
options[opt_idx].flags |= P_WAS_SET;
+ if (!starting && errmsg == NULL) {
+ char_u buf_old[NUMBUFLEN];
+ char_u buf_new[NUMBUFLEN];
+ char_u buf_type[7];
+ vim_snprintf((char *)buf_old, ARRAY_SIZE(buf_old), "%ld", old_value);
+ vim_snprintf((char *)buf_new, ARRAY_SIZE(buf_new), "%ld", value);
+ vim_snprintf((char *)buf_type, ARRAY_SIZE(buf_type), "%s",
+ (opt_flags & OPT_LOCAL) ? "local" : "global");
+ set_vim_var_string(VV_OPTION_NEW, buf_new, -1);
+ set_vim_var_string(VV_OPTION_OLD, buf_old, -1);
+ set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
+ apply_autocmds(EVENT_OPTIONSET,
+ (char_u *) options[opt_idx].fullname,
+ NULL, false, NULL);
+ reset_v_option_vars();
+ }
+
comp_col(); /* in case 'columns' or 'ls' changed */
if (curwin->w_curswant != MAXCOL
&& (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0)
@@ -5221,6 +5303,7 @@ static char_u *get_varp(vimoption_T *p)
case PV_CFU: return (char_u *)&(curbuf->b_p_cfu);
case PV_OFU: return (char_u *)&(curbuf->b_p_ofu);
case PV_EOL: return (char_u *)&(curbuf->b_p_eol);
+ case PV_FIXEOL: return (char_u *)&(curbuf->b_p_fixeol);
case PV_ET: return (char_u *)&(curbuf->b_p_et);
case PV_FENC: return (char_u *)&(curbuf->b_p_fenc);
case PV_FF: return (char_u *)&(curbuf->b_p_ff);
@@ -5465,6 +5548,7 @@ void buf_copy_options(buf_T *buf, int flags)
buf->b_p_bin = p_bin;
buf->b_p_bomb = p_bomb;
buf->b_p_et = p_et;
+ buf->b_p_fixeol = p_fixeol;
buf->b_p_et_nobin = p_et_nobin;
buf->b_p_ml = p_ml;
buf->b_p_ml_nobin = p_ml_nobin;
@@ -6400,6 +6484,7 @@ void save_file_ff(buf_T *buf)
* from when editing started (save_file_ff() called).
* Also when 'endofline' was changed and 'binary' is set, or when 'bomb' was
* changed and 'binary' is not set.
+ * Also when 'endofline' was changed and 'fixeol' is not set.
* When "ignore_empty" is true don't consider a new, empty buffer to be
* changed.
*/
@@ -6414,9 +6499,9 @@ bool file_ff_differs(buf_T *buf, bool ignore_empty)
&& *ml_get_buf(buf, (linenr_T)1, FALSE) == NUL)
return FALSE;
if (buf->b_start_ffc != *buf->b_p_ff)
- return TRUE;
- if (buf->b_p_bin && buf->b_start_eol != buf->b_p_eol)
- return TRUE;
+ return true;
+ if ((buf->b_p_bin || !buf->b_p_fixeol) && buf->b_start_eol != buf->b_p_eol)
+ return true;
if (!buf->b_p_bin && buf->b_start_bomb != buf->b_p_bomb)
return TRUE;
if (buf->b_start_fenc == NULL)
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index d4d3410d5c..c72e1cf0bb 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -665,6 +665,7 @@ enum {
, BV_DEF
, BV_INC
, BV_EOL
+ , BV_FIXEOL
, BV_EP
, BV_ET
, BV_FENC
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index b22e994efe..5187340629 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -799,6 +799,14 @@ return {
defaults={if_true={vi="vert:|,fold:-"}}
},
{
+ full_name='fixendofline', abbreviation='fixeol',
+ type='bool', scope={'buffer'},
+ vi_def=true,
+ redraw={'statuslines'},
+ varname='p_fixeol',
+ defaults={if_true={vi=true}}
+ },
+ {
full_name='fkmap', abbreviation='fk',
type='bool', scope={'global'},
vi_def=true,
diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c
index bf6db97fcf..a791dca39c 100644
--- a/src/nvim/os/env.c
+++ b/src/nvim/os/env.c
@@ -46,7 +46,19 @@ bool os_env_exists(const char *name)
int os_setenv(const char *name, const char *value, int overwrite)
FUNC_ATTR_NONNULL_ALL
{
+#ifdef HAVE_SETENV
return setenv(name, value, overwrite);
+#elif defined(HAVE_PUTENV_S)
+ if (!overwrite && os_getenv(name) != NULL) {
+ return 0;
+ }
+ if (_putenv_s(name, value) == 0) {
+ return 0;
+ }
+ return -1;
+#else
+# error "This system has no implementation available for os_setenv()"
+#endif
}
/// Unset environment variable
@@ -141,6 +153,27 @@ void init_homedir(void)
char_u *var = (char_u *)os_getenv("HOME");
+#ifdef WIN32
+ // Typically, $HOME is not defined on Windows, unless the user has
+ // specifically defined it for Vim's sake. However, on Windows NT
+ // platforms, $HOMEDRIVE and $HOMEPATH are automatically defined for
+ // each user. Try constructing $HOME from these.
+ if (var == NULL) {
+ const char *homedrive = os_getenv("HOMEDRIVE");
+ const char *homepath = os_getenv("HOMEPATH");
+ if (homepath == NULL) {
+ homepath = "\\";
+ }
+ if (homedrive != NULL && strlen(homedrive) + strlen(homepath) < MAXPATHL) {
+ snprintf((char *)NameBuff, MAXPATHL, "%s%s", homedrive, homepath);
+ if (NameBuff[0] != NUL) {
+ var = NameBuff;
+ vim_setenv("HOME", (char *)NameBuff);
+ }
+ }
+ }
+#endif
+
if (var != NULL) {
#ifdef UNIX
/*
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index 57e25560de..3813c45726 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.c
@@ -418,7 +418,8 @@ static void read_input(DynamicBuffer *buf)
// Finished a line, add a NL, unless this line should not have one.
// FIXME need to make this more readable
if (lnum != curbuf->b_op_end.lnum
- || !curbuf->b_p_bin
+ || (!curbuf->b_p_bin
+ && curbuf->b_p_fixeol)
|| (lnum != curbuf->b_no_eol_lnum
&& (lnum !=
curbuf->b_ml.ml_line_count
diff --git a/src/nvim/os/signal.c b/src/nvim/os/signal.c
index 7158721433..0ff6016e32 100644
--- a/src/nvim/os/signal.c
+++ b/src/nvim/os/signal.c
@@ -32,9 +32,13 @@ void signal_init(void)
signal_watcher_init(&loop, &shup, NULL);
signal_watcher_init(&loop, &squit, NULL);
signal_watcher_init(&loop, &sterm, NULL);
+#ifdef SIGPIPE
signal_watcher_start(&spipe, on_signal, SIGPIPE);
+#endif
signal_watcher_start(&shup, on_signal, SIGHUP);
+#ifdef SIGQUIT
signal_watcher_start(&squit, on_signal, SIGQUIT);
+#endif
signal_watcher_start(&sterm, on_signal, SIGTERM);
#ifdef SIGPWR
signal_watcher_init(&loop, &spwr, NULL);
@@ -82,12 +86,16 @@ static char * signal_name(int signum)
case SIGPWR:
return "SIGPWR";
#endif
+#ifdef SIGPIPE
case SIGPIPE:
return "SIGPIPE";
+#endif
case SIGTERM:
return "SIGTERM";
+#ifdef SIGQUIT
case SIGQUIT:
return "SIGQUIT";
+#endif
case SIGHUP:
return "SIGHUP";
default:
@@ -123,11 +131,15 @@ static void on_signal(SignalWatcher *handle, int signum, void *data)
ml_sync_all(false, false);
break;
#endif
+#ifdef SIGPIPE
case SIGPIPE:
// Ignore
break;
+#endif
case SIGTERM:
+#ifdef SIGQUIT
case SIGQUIT:
+#endif
case SIGHUP:
if (!rejecting_deadly) {
deadly_signal(signum);
diff --git a/src/nvim/path.c b/src/nvim/path.c
index 877ef1565a..253035ed99 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.c
@@ -467,16 +467,13 @@ bool path_has_wildcard(const char_u *p)
return false;
}
-#if defined(UNIX)
/*
* Unix style wildcard expansion code.
- * It's here because it's used both for Unix and Mac.
*/
static int pstrcmp(const void *a, const void *b)
{
return pathcmp(*(char **)a, *(char **)b, -1);
}
-#endif
/// Checks if a path has a character path_expand can expand.
/// @param p The path to expand.
diff --git a/src/nvim/po/it.po b/src/nvim/po/it.po
index 7fe61c45bc..729697eee3 100644
--- a/src/nvim/po/it.po
+++ b/src/nvim/po/it.po
@@ -25,9 +25,8 @@ msgstr ""
"Content-Transfer-Encoding: 8-bit\n"
#: ../api/private/helpers.c:201
-#, fuzzy
msgid "Unable to get option value"
-msgstr "impossibile ottenere il valore di opzione"
+msgstr "Impossibile ottenere il valore di opzione"
#: ../api/private/helpers.c:204
msgid "internal error: unknown option type"
@@ -827,18 +826,16 @@ msgid "sort() argument"
msgstr "argomento di sort()"
#: ../eval.c:13721
-#, fuzzy
msgid "uniq() argument"
-msgstr "argomento di add()"
+msgstr "argomento di uniq()"
#: ../eval.c:13776
msgid "E702: Sort compare function failed"
msgstr "E702: Funzione confronto nel sort non riuscita"
#: ../eval.c:13806
-#, fuzzy
msgid "E882: Uniq compare function failed"
-msgstr "E702: Funzione confronto nel sort non riuscita"
+msgstr "E882: Funzione di comparazione 'uniq' fallita"
#: ../eval.c:14085
msgid "(Invalid)"
@@ -963,16 +960,12 @@ msgid "E129: Function name required"
msgstr "E129: Nome funzione necessario"
#: ../eval.c:17824
-#, fuzzy, c-format
msgid "E128: Function name must start with a capital or \"s:\": %s"
-msgstr ""
-"E128: Il nome funzione deve iniziare con una maiuscola o contenere ':': %s"
+msgstr "E128: Il nome funzione deve iniziare con una maiuscola o \"s:\": %s"
#: ../eval.c:17833
-#, fuzzy, c-format
msgid "E884: Function name cannot contain a colon: %s"
-msgstr ""
-"E128: Il nome funzione deve iniziare con una maiuscola o contenere ':': %s"
+msgstr "E884: Il nome funzione non può contenere una virgola: %s"
#: ../eval.c:18336
#, c-format
@@ -2667,18 +2660,17 @@ msgid "E17: \"%s\" is a directory"
msgstr "E17: \"%s\" è una directory"
#: ../globals.h:1020
-#, fuzzy
msgid "E900: Invalid job id"
-msgstr "E49: Quantità di 'scroll' non valida"
+msgstr "E900: 'Job id' non valido"
#: ../globals.h:1021
msgid "E901: Job table is full"
-msgstr ""
+msgstr "E901: Job table piena"
#: ../globals.h:1022
#, c-format
msgid "E902: \"%s\" is not an executable"
-msgstr ""
+msgstr "E902: \"%s\" non è un esegubile"
#: ../globals.h:1024
#, c-format
@@ -2703,7 +2695,7 @@ msgstr "E22: Script troppo nidificati"
#: ../globals.h:1031
msgid "E23: No alternate file"
-msgstr "E23: Nessun file alternato"
+msgstr "E23: Nessun file alternativo"
#: ../globals.h:1032
msgid "E24: No such abbreviation"
@@ -2791,9 +2783,8 @@ msgid "E37: No write since last change (add ! to override)"
msgstr "E37: Non salvato dopo modifica (aggiungi ! per eseguire comunque)"
#: ../globals.h:1055
-#, fuzzy
msgid "E37: No write since last change"
-msgstr "[Non salvato dopo l'ultima modifica]\n"
+msgstr "E37: Non salvato dall'ultima modifica"
#: ../globals.h:1056
msgid "E38: Null argument"
@@ -2857,8 +2848,7 @@ msgstr "E46: Non posso cambiare la variabile read-only \"%s\""
#: ../globals.h:1075
#, c-format
msgid "E794: Cannot set variable in the sandbox: \"%s\""
-msgstr ""
-"E794: Non posso impostare la variabile read-only in ambiente protetto: \"%s\""
+msgstr "E794: Non posso impostare la variabile read-only in ambiente protetto: \"%s\""
#: ../globals.h:1076
msgid "E47: Error while reading errorfile"
@@ -4869,9 +4859,8 @@ msgid "E777: String or List expected"
msgstr "E777: aspettavo Stringa o Lista"
#: ../regexp.c:359
-#, fuzzy, c-format
msgid "E369: invalid item in %s%%[]"
-msgstr "E239: Testo 'sign' non valido: %s"
+msgstr "E369: elemento non valido in %s%%[]"
#: ../regexp.c:374
#, c-format
@@ -5004,7 +4993,7 @@ msgstr "E866: (NFA regexp) %c fuori posto"
#: ../regexp_nfa.c:242
#, c-format
msgid "E877: (NFA regexp) Invalid character class: %<PRId64>"
-msgstr ""
+msgstr "E877: (NFA regexp) Classe di caratteri non valida: %<PRId64>"
#: ../regexp_nfa.c:1261
#, c-format
@@ -5611,14 +5600,12 @@ msgid "E765: 'spellfile' does not have %<PRId64> entries"
msgstr "E765: 'spellfile' non ha %<PRId64> elementi"
#: ../spell.c:8074
-#, fuzzy, c-format
msgid "Word '%.*s' removed from %s"
-msgstr "Parola rimossa da %s"
+msgstr "Parola '%.*s' rimossa da %s"
#: ../spell.c:8117
-#, fuzzy, c-format
msgid "Word '%.*s' added to %s"
-msgstr "Parola aggiunta a %s"
+msgstr "Parola '%.*s' aggiunta a %s"
#: ../spell.c:8381
msgid "E763: Word characters differ between spell files"
@@ -6100,9 +6087,8 @@ msgstr "Vim: Errore leggendo l'input, esco...\n"
#. This happens when the FileChangedRO autocommand changes the
#. * file in a way it becomes shorter.
#: ../undo.c:379
-#, fuzzy
msgid "E881: Line count changed unexpectedly"
-msgstr "E834: Il conteggio delle righe è inaspettatamente cambiato"
+msgstr "E881: Il conteggio delle righe è inaspettatamente cambiato"
#: ../undo.c:627
#, c-format
diff --git a/src/nvim/search.c b/src/nvim/search.c
index cb461c9ef2..fb7dfa350b 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -918,7 +918,7 @@ static int first_submatch(regmmatch_T *rp)
* Careful: If spats[0].off.line == TRUE and spats[0].off.off == 0 this
* makes the movement linewise without moving the match position.
*
- * return 0 for failure, 1 for found, 2 for found and line offset added
+ * Return 0 for failure, 1 for found, 2 for found and line offset added.
*/
int do_search(
oparg_T *oap, /* can be NULL */
@@ -3193,6 +3193,7 @@ current_tagblock (
int do_include = include;
bool save_p_ws = p_ws;
int retval = FAIL;
+ int is_inclusive = true;
p_ws = false;
@@ -3287,9 +3288,16 @@ again:
if (inc_cursor() < 0)
break;
} else {
- /* Exclude the '<' of the end tag. */
- if (*get_cursor_pos_ptr() == '<')
+ char_u *c = get_cursor_pos_ptr();
+ // Exclude the '<' of the end tag.
+ // If the closing tag is on new line, do not decrement cursor, but make
+ // operation exclusive, so that the linefeed will be selected
+ if (*c == '<' && !VIsual_active && curwin->w_cursor.col == 0) {
+ // do not decrement cursor
+ is_inclusive = false;
+ } else if (*c == '<') {
dec_cursor();
+ }
}
end_pos = curwin->w_cursor;
@@ -3334,8 +3342,9 @@ again:
* on an empty area. */
curwin->w_cursor = start_pos;
oap->inclusive = false;
- } else
- oap->inclusive = true;
+ } else {
+ oap->inclusive = is_inclusive;
+ }
}
retval = OK;
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index e21c6f17fe..340c14066a 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -10,7 +10,9 @@
#include <stdint.h>
#include <inttypes.h>
#include <errno.h>
-#include <unistd.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
#include <assert.h>
#include <msgpack.h>
@@ -203,11 +205,11 @@ enum SRNIFlags {
kSDReadHeader = (1 << kSDItemHeader), ///< Determines whether header should
///< be read (it is usually ignored).
kSDReadUndisableableData = (
- (1 << kSDItemSearchPattern)
- | (1 << kSDItemSubString)
- | (1 << kSDItemJump)), ///< Data reading which cannot be disabled by &shada
- ///< or other options except for disabling reading
- ///< ShaDa as a whole.
+ (1 << kSDItemSearchPattern)
+ | (1 << kSDItemSubString)
+ | (1 << kSDItemJump)), ///< Data reading which cannot be disabled by
+ ///< &shada or other options except for disabling
+ ///< reading ShaDa as a whole.
kSDReadRegisters = (1 << kSDItemRegister), ///< Determines whether registers
///< should be read (may only be
///< disabled when writing, but
@@ -444,7 +446,7 @@ typedef struct sd_write_def {
.attr = { __VA_ARGS__ } \
} \
}
-#define DEFAULT_POS {1, 0, 0}
+#define DEFAULT_POS { 1, 0, 0 }
static const pos_T default_pos = DEFAULT_POS;
static const ShadaEntry sd_default_values[] = {
[kSDItemMissing] = { .type = kSDItemMissing, .timestamp = 0 },
@@ -531,11 +533,14 @@ static inline void hmll_init(HMLList *const hmll, const size_t size)
///
/// @param hmll Pointer to the list.
/// @param cur_entry Name of the variable to iterate over.
+/// @param code Code to execute on each iteration.
///
/// @return `for` cycle header (use `HMLL_FORALL(hmll, cur_entry) {body}`).
-#define HMLL_FORALL(hmll, cur_entry) \
+#define HMLL_FORALL(hmll, cur_entry, code) \
for (HMLListEntry *cur_entry = (hmll)->first; cur_entry != NULL; \
- cur_entry = cur_entry->next)
+ cur_entry = cur_entry->next) { \
+ code \
+ } \
/// Remove entry from the linked list
///
@@ -631,11 +636,14 @@ static inline void hmll_insert(HMLList *const hmll,
/// @param hmll Pointer to the list.
/// @param cur_entry Name of the variable to iterate over, must be already
/// defined.
+/// @param code Code to execute on each iteration.
///
/// @return `for` cycle header (use `HMLL_FORALL(hmll, cur_entry) {body}`).
-#define HMLL_ITER_BACK(hmll, cur_entry) \
+#define HMLL_ITER_BACK(hmll, cur_entry, code) \
for (cur_entry = (hmll)->last; cur_entry != NULL; \
- cur_entry = cur_entry->prev)
+ cur_entry = cur_entry->prev) { \
+ code \
+ }
/// Free linked list
///
@@ -957,11 +965,11 @@ static int shada_read_file(const char *const file, const int flags)
if (p_verbose > 0) {
verbose_enter();
smsg(_("Reading ShaDa file \"%s\"%s%s%s"),
- fname,
- (flags & kShaDaWantInfo) ? _(" info") : "",
- (flags & kShaDaWantMarks) ? _(" marks") : "",
- (flags & kShaDaGetOldfiles) ? _(" oldfiles") : "",
- of_ret != 0 ? _(" FAILED") : "");
+ fname,
+ (flags & kShaDaWantInfo) ? _(" info") : "",
+ (flags & kShaDaWantMarks) ? _(" marks") : "",
+ (flags & kShaDaGetOldfiles) ? _(" oldfiles") : "",
+ of_ret != 0 ? _(" FAILED") : "");
verbose_leave();
}
@@ -1009,8 +1017,8 @@ static const void *shada_hist_iter(const void *const iter,
.histtype = history_type,
.string = (char *) hist_he.hisstr,
.sep = (char) (history_type == HIST_SEARCH
- ? (char) hist_he.hisstr[STRLEN(hist_he.hisstr) + 1]
- : 0),
+ ? (char) hist_he.hisstr[STRLEN(hist_he.hisstr) + 1]
+ : 0),
.additional_elements = hist_he.additional_elements,
}
}
@@ -1072,11 +1080,11 @@ static void hms_insert(HistoryMergerState *const hms_p, const ShadaEntry entry,
}
}
HMLListEntry *insert_after;
- HMLL_ITER_BACK(hmll, insert_after) {
+ HMLL_ITER_BACK(hmll, insert_after, {
if (insert_after->data.timestamp <= entry.timestamp) {
break;
}
- }
+ })
hmll_insert(hmll, insert_after, entry, can_free_entry);
}
@@ -1134,14 +1142,14 @@ static inline void hms_to_he_array(const HistoryMergerState *const hms_p,
FUNC_ATTR_NONNULL_ALL
{
histentry_T *hist = hist_array;
- HMLL_FORALL(&hms_p->hmll, cur_entry) {
+ HMLL_FORALL(&hms_p->hmll, cur_entry, {
hist->timestamp = cur_entry->data.timestamp;
hist->hisnum = (int) (hist - hist_array) + 1;
hist->hisstr = (char_u *) cur_entry->data.data.history_item.string;
hist->additional_elements =
cur_entry->data.data.history_item.additional_elements;
hist++;
- }
+ })
*new_hisnum = (int) (hist - hist_array);
*new_hisidx = *new_hisnum - 1;
}
@@ -1159,10 +1167,11 @@ static inline void hms_dealloc(HistoryMergerState *const hms_p)
///
/// @param[in] hms_p Merger structure to iterate over.
/// @param[out] cur_entry Name of the iterator variable.
+/// @param code Code to execute on each iteration.
///
/// @return for cycle header. Use `HMS_ITER(hms_p, cur_entry) {body}`.
-#define HMS_ITER(hms_p, cur_entry) \
- HMLL_FORALL(&((hms_p)->hmll), cur_entry)
+#define HMS_ITER(hms_p, cur_entry, code) \
+ HMLL_FORALL(&((hms_p)->hmll), cur_entry, code)
/// Find buffer for given buffer name (cached)
///
@@ -1339,18 +1348,18 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
(cur_entry.data.search_pattern.is_substitute_pattern
? &set_substitute_pattern
: &set_search_pattern)((SearchPattern) {
- .magic = cur_entry.data.search_pattern.magic,
- .no_scs = !cur_entry.data.search_pattern.smartcase,
- .off = {
- .dir = cur_entry.data.search_pattern.search_backward ? '?' : '/',
- .line = cur_entry.data.search_pattern.has_line_offset,
- .end = cur_entry.data.search_pattern.place_cursor_at_end,
- .off = cur_entry.data.search_pattern.offset,
- },
- .pat = (char_u *) cur_entry.data.search_pattern.pat,
- .additional_data = cur_entry.data.search_pattern.additional_data,
- .timestamp = cur_entry.timestamp,
- });
+ .magic = cur_entry.data.search_pattern.magic,
+ .no_scs = !cur_entry.data.search_pattern.smartcase,
+ .off = {
+ .dir = cur_entry.data.search_pattern.search_backward ? '?' : '/',
+ .line = cur_entry.data.search_pattern.has_line_offset,
+ .end = cur_entry.data.search_pattern.place_cursor_at_end,
+ .off = cur_entry.data.search_pattern.offset,
+ },
+ .pat = (char_u *) cur_entry.data.search_pattern.pat,
+ .additional_data = cur_entry.data.search_pattern.additional_data,
+ .timestamp = cur_entry.timestamp,
+ });
if (cur_entry.data.search_pattern.is_last_used) {
set_last_used_pattern(
cur_entry.data.search_pattern.is_substitute_pattern);
@@ -2428,13 +2437,13 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
}
const unsigned srni_flags = (unsigned) (
- kSDReadUndisableableData
- | kSDReadUnknown
- | (dump_history ? kSDReadHistory : 0)
- | (dump_registers ? kSDReadRegisters : 0)
- | (dump_global_vars ? kSDReadVariables : 0)
- | (dump_global_marks ? kSDReadGlobalMarks : 0)
- | (num_marked_files ? kSDReadLocalMarks | kSDReadChanges : 0));
+ kSDReadUndisableableData
+ | kSDReadUnknown
+ | (dump_history ? kSDReadHistory : 0)
+ | (dump_registers ? kSDReadRegisters : 0)
+ | (dump_global_vars ? kSDReadVariables : 0)
+ | (dump_global_marks ? kSDReadGlobalMarks : 0)
+ | (num_marked_files ? kSDReadLocalMarks | kSDReadChanges : 0));
msgpack_packer *const packer = msgpack_packer_new(sd_writer,
&msgpack_sd_writer_write);
@@ -2893,16 +2902,16 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
for (size_t i = 0; i < HIST_COUNT; i++) {
if (dump_one_history[i]) {
hms_insert_whole_neovim_history(&wms->hms[i]);
- HMS_ITER(&wms->hms[i], cur_entry) {
+ HMS_ITER(&wms->hms[i], cur_entry, {
if (!shada_pack_encoded_entry(
- packer, &sd_writer->sd_conv, (PossiblyFreedShadaEntry) {
- .data = cur_entry->data,
- .can_free_entry = cur_entry->can_free_entry,
- }, max_kbyte)) {
+ packer, &sd_writer->sd_conv, (PossiblyFreedShadaEntry) {
+ .data = cur_entry->data,
+ .can_free_entry = cur_entry->can_free_entry,
+ }, max_kbyte)) {
ret = kSDWriteFailed;
break;
}
- }
+ })
hms_dealloc(&wms->hms[i]);
if (ret == kSDWriteFailed) {
goto shada_write_exit;
@@ -3353,8 +3362,8 @@ static inline char *get_converted_string(const vimconv_T *const sd_conv,
entry_name " entry at position %" PRIu64 " " \
error_desc
#define CHECK_KEY(key, expected) ( \
- key.via.str.size == sizeof(expected) - 1 \
- && STRNCMP(key.via.str.ptr, expected, sizeof(expected) - 1) == 0)
+ key.via.str.size == sizeof(expected) - 1 \
+ && STRNCMP(key.via.str.ptr, expected, sizeof(expected) - 1) == 0)
#define CLEAR_GA_AND_ERROR_OUT(ga) \
do { \
ga_clear(&ga); \
@@ -3377,18 +3386,17 @@ static inline char *get_converted_string(const vimconv_T *const sd_conv,
tgt = proc(obj.via.attr); \
} while (0)
#define CHECK_KEY_IS_STR(entry_name) \
- do { \
- if (unpacked.data.via.map.ptr[i].key.type != MSGPACK_OBJECT_STR) { \
- emsgu(_(READERR(entry_name, "has key which is not a string")), \
- initial_fpos); \
- CLEAR_GA_AND_ERROR_OUT(ad_ga); \
- } else if (unpacked.data.via.map.ptr[i].key.via.str.size == 0) { \
- emsgu(_(READERR(entry_name, "has empty key")), initial_fpos); \
- CLEAR_GA_AND_ERROR_OUT(ad_ga); \
- } \
- } while (0)
+ if (unpacked.data.via.map.ptr[i].key.type != MSGPACK_OBJECT_STR) { \
+ emsgu(_(READERR(entry_name, "has key which is not a string")), \
+ initial_fpos); \
+ CLEAR_GA_AND_ERROR_OUT(ad_ga); \
+ } else if (unpacked.data.via.map.ptr[i].key.via.str.size == 0) { \
+ emsgu(_(READERR(entry_name, "has empty key")), initial_fpos); \
+ CLEAR_GA_AND_ERROR_OUT(ad_ga); \
+ }
#define CHECKED_KEY(entry_name, name, error_desc, tgt, condition, attr, proc) \
- if (CHECK_KEY(unpacked.data.via.map.ptr[i].key, name)) { \
+ else if (CHECK_KEY( /* NOLINT(readability/braces) */ \
+ unpacked.data.via.map.ptr[i].key, name)) { \
CHECKED_ENTRY( \
condition, "has " name " key value " error_desc, \
entry_name, unpacked.data.via.map.ptr[i].val, \
@@ -3408,17 +3416,17 @@ static inline char *get_converted_string(const vimconv_T *const sd_conv,
#define INT_KEY(entry_name, name, tgt, proc) \
CHECKED_KEY( \
entry_name, name, "which is not an integer", tgt, \
- (unpacked.data.via.map.ptr[i].val.type \
- == MSGPACK_OBJECT_POSITIVE_INTEGER \
- || unpacked.data.via.map.ptr[i].val.type \
- == MSGPACK_OBJECT_NEGATIVE_INTEGER), \
+ ((unpacked.data.via.map.ptr[i].val.type \
+ == MSGPACK_OBJECT_POSITIVE_INTEGER) \
+ || (unpacked.data.via.map.ptr[i].val.type \
+ == MSGPACK_OBJECT_NEGATIVE_INTEGER)), \
i64, proc)
#define INTEGER_KEY(entry_name, name, tgt) \
INT_KEY(entry_name, name, tgt, TOINT)
#define LONG_KEY(entry_name, name, tgt) \
INT_KEY(entry_name, name, tgt, TOLONG)
#define ADDITIONAL_KEY \
- { \
+ else { /* NOLINT(readability/braces) */ \
ga_grow(&ad_ga, 1); \
memcpy(((char *)ad_ga.ga_data) + ((size_t) ad_ga.ga_len \
* sizeof(*unpacked.data.via.map.ptr)), \
@@ -3427,9 +3435,9 @@ static inline char *get_converted_string(const vimconv_T *const sd_conv,
ad_ga.ga_len++; \
}
#define CONVERTED(str, len) ( \
- sd_reader->sd_conv.vc_type != CONV_NONE \
- ? get_converted_string(&sd_reader->sd_conv, (str), (len)) \
- : xmemdupz((str), (len)))
+ sd_reader->sd_conv.vc_type != CONV_NONE \
+ ? get_converted_string(&sd_reader->sd_conv, (str), (len)) \
+ : xmemdupz((str), (len)))
#define BIN_CONVERTED(b) CONVERTED(b.ptr, b.size)
#define SET_ADDITIONAL_DATA(tgt, name) \
do { \
@@ -3623,38 +3631,28 @@ shada_read_next_item_start:
garray_T ad_ga;
ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1);
for (size_t i = 0; i < unpacked.data.via.map.size; i++) {
- CHECK_KEY_IS_STR("search pattern");
+ CHECK_KEY_IS_STR("search pattern")
BOOLEAN_KEY("search pattern", SEARCH_KEY_MAGIC,
entry->data.search_pattern.magic)
- else
- BOOLEAN_KEY("search pattern", SEARCH_KEY_SMARTCASE,
- entry->data.search_pattern.smartcase)
- else
- BOOLEAN_KEY("search pattern", SEARCH_KEY_HAS_LINE_OFFSET,
- entry->data.search_pattern.has_line_offset)
- else
- BOOLEAN_KEY("search pattern", SEARCH_KEY_PLACE_CURSOR_AT_END,
- entry->data.search_pattern.place_cursor_at_end)
- else
- BOOLEAN_KEY("search pattern", SEARCH_KEY_IS_LAST_USED,
- entry->data.search_pattern.is_last_used)
- else
- BOOLEAN_KEY("search pattern", SEARCH_KEY_IS_SUBSTITUTE_PATTERN,
- entry->data.search_pattern.is_substitute_pattern)
- else
- BOOLEAN_KEY("search pattern", SEARCH_KEY_HIGHLIGHTED,
- entry->data.search_pattern.highlighted)
- else
- BOOLEAN_KEY("search pattern", SEARCH_KEY_BACKWARD,
- entry->data.search_pattern.search_backward)
- else
- INTEGER_KEY("search pattern", SEARCH_KEY_OFFSET,
- entry->data.search_pattern.offset)
- else
- CONVERTED_STRING_KEY("search pattern", SEARCH_KEY_PAT,
- entry->data.search_pattern.pat)
- else
- ADDITIONAL_KEY
+ BOOLEAN_KEY("search pattern", SEARCH_KEY_SMARTCASE,
+ entry->data.search_pattern.smartcase)
+ BOOLEAN_KEY("search pattern", SEARCH_KEY_HAS_LINE_OFFSET,
+ entry->data.search_pattern.has_line_offset)
+ BOOLEAN_KEY("search pattern", SEARCH_KEY_PLACE_CURSOR_AT_END,
+ entry->data.search_pattern.place_cursor_at_end)
+ BOOLEAN_KEY("search pattern", SEARCH_KEY_IS_LAST_USED,
+ entry->data.search_pattern.is_last_used)
+ BOOLEAN_KEY("search pattern", SEARCH_KEY_IS_SUBSTITUTE_PATTERN,
+ entry->data.search_pattern.is_substitute_pattern)
+ BOOLEAN_KEY("search pattern", SEARCH_KEY_HIGHLIGHTED,
+ entry->data.search_pattern.highlighted)
+ BOOLEAN_KEY("search pattern", SEARCH_KEY_BACKWARD,
+ entry->data.search_pattern.search_backward)
+ INTEGER_KEY("search pattern", SEARCH_KEY_OFFSET,
+ entry->data.search_pattern.offset)
+ CONVERTED_STRING_KEY("search pattern", SEARCH_KEY_PAT,
+ entry->data.search_pattern.pat)
+ ADDITIONAL_KEY
}
if (entry->data.search_pattern.pat == NULL) {
emsgu(_(READERR("search pattern", "has no pattern")), initial_fpos);
@@ -3675,7 +3673,7 @@ shada_read_next_item_start:
garray_T ad_ga;
ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1);
for (size_t i = 0; i < unpacked.data.via.map.size; i++) {
- CHECK_KEY_IS_STR("mark");
+ CHECK_KEY_IS_STR("mark")
if (CHECK_KEY(unpacked.data.via.map.ptr[i].key, KEY_NAME_CHAR)) {
if (type_u64 == kSDItemJump || type_u64 == kSDItemChange) {
emsgu(_(READERR("mark", "has n key which is only valid for "
@@ -3688,15 +3686,11 @@ shada_read_next_item_start:
"has n key value which is not an unsigned integer",
"mark", unpacked.data.via.map.ptr[i].val,
entry->data.filemark.name, u64, TOCHAR);
- } else {
- LONG_KEY("mark", KEY_LNUM, entry->data.filemark.mark.lnum)
- else
- INTEGER_KEY("mark", KEY_COL, entry->data.filemark.mark.col)
- else
- STRING_KEY("mark", KEY_FILE, entry->data.filemark.fname)
- else
- ADDITIONAL_KEY
}
+ LONG_KEY("mark", KEY_LNUM, entry->data.filemark.mark.lnum)
+ INTEGER_KEY("mark", KEY_COL, entry->data.filemark.mark.col)
+ STRING_KEY("mark", KEY_FILE, entry->data.filemark.fname)
+ ADDITIONAL_KEY
}
if (entry->data.filemark.fname == NULL) {
emsgu(_(READERR("mark", "is missing file name")), initial_fpos);
@@ -3721,48 +3715,44 @@ shada_read_next_item_start:
garray_T ad_ga;
ga_init(&ad_ga, sizeof(*(unpacked.data.via.map.ptr)), 1);
for (size_t i = 0; i < unpacked.data.via.map.size; i++) {
- CHECK_KEY_IS_STR("register");
- TYPED_KEY("register", REG_KEY_TYPE, "an unsigned integer",
- entry->data.reg.type, POSITIVE_INTEGER, u64, TOU8)
- else
- TYPED_KEY("register", KEY_NAME_CHAR, "an unsigned integer",
- entry->data.reg.name, POSITIVE_INTEGER, u64, TOCHAR)
- else
- TYPED_KEY("register", REG_KEY_WIDTH, "an unsigned integer",
- entry->data.reg.width, POSITIVE_INTEGER, u64, TOSIZE)
- else
- if (CHECK_KEY(unpacked.data.via.map.ptr[i].key,
- REG_KEY_CONTENTS)) {
- if (unpacked.data.via.map.ptr[i].val.type != MSGPACK_OBJECT_ARRAY) {
- emsgu(_(READERR(
- "register",
- "has " REG_KEY_CONTENTS " key with non-array value")),
- initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
- }
- if (unpacked.data.via.map.ptr[i].val.via.array.size == 0) {
- emsgu(_(READERR("register",
- "has " REG_KEY_CONTENTS " key with empty array")),
- initial_fpos);
+ CHECK_KEY_IS_STR("register")
+ if (CHECK_KEY(unpacked.data.via.map.ptr[i].key,
+ REG_KEY_CONTENTS)) {
+ if (unpacked.data.via.map.ptr[i].val.type != MSGPACK_OBJECT_ARRAY) {
+ emsgu(_(READERR("register",
+ "has " REG_KEY_CONTENTS
+ " key with non-array value")),
+ initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ }
+ if (unpacked.data.via.map.ptr[i].val.via.array.size == 0) {
+ emsgu(_(READERR("register",
+ "has " REG_KEY_CONTENTS " key with empty array")),
+ initial_fpos);
+ CLEAR_GA_AND_ERROR_OUT(ad_ga);
+ }
+ const msgpack_object_array arr =
+ unpacked.data.via.map.ptr[i].val.via.array;
+ for (size_t i = 0; i < arr.size; i++) {
+ if (arr.ptr[i].type != MSGPACK_OBJECT_BIN) {
+ emsgu(_(READERR("register", "has " REG_KEY_CONTENTS " array "
+ "with non-binary value")), initial_fpos);
CLEAR_GA_AND_ERROR_OUT(ad_ga);
}
- const msgpack_object_array arr =
- unpacked.data.via.map.ptr[i].val.via.array;
- for (size_t i = 0; i < arr.size; i++) {
- if (arr.ptr[i].type != MSGPACK_OBJECT_BIN) {
- emsgu(_(READERR("register", "has " REG_KEY_CONTENTS " array "
- "with non-binary value")), initial_fpos);
- CLEAR_GA_AND_ERROR_OUT(ad_ga);
- }
- }
- entry->data.reg.contents_size = arr.size;
- entry->data.reg.contents = xmalloc(arr.size * sizeof(char *));
- for (size_t i = 0; i < arr.size; i++) {
- entry->data.reg.contents[i] = BIN_CONVERTED(arr.ptr[i].via.bin);
- }
- } else {
- ADDITIONAL_KEY
}
+ entry->data.reg.contents_size = arr.size;
+ entry->data.reg.contents = xmalloc(arr.size * sizeof(char *));
+ for (size_t i = 0; i < arr.size; i++) {
+ entry->data.reg.contents[i] = BIN_CONVERTED(arr.ptr[i].via.bin);
+ }
+ }
+ TYPED_KEY("register", REG_KEY_TYPE, "an unsigned integer",
+ entry->data.reg.type, POSITIVE_INTEGER, u64, TOU8)
+ TYPED_KEY("register", KEY_NAME_CHAR, "an unsigned integer",
+ entry->data.reg.name, POSITIVE_INTEGER, u64, TOCHAR)
+ TYPED_KEY("register", REG_KEY_WIDTH, "an unsigned integer",
+ entry->data.reg.width, POSITIVE_INTEGER, u64, TOSIZE)
+ ADDITIONAL_KEY
}
if (entry->data.reg.contents == NULL) {
emsgu(_(READERR("register", "has missing " REG_KEY_CONTENTS " array")),
@@ -3830,8 +3820,8 @@ shada_read_next_item_hist_no_conv:
+ 1); // Separator character
entry->data.history_item.string = xmalloc(strsize);
memcpy(entry->data.history_item.string,
- unpacked.data.via.array.ptr[1].via.bin.ptr,
- unpacked.data.via.array.ptr[1].via.bin.size);
+ unpacked.data.via.array.ptr[1].via.bin.ptr,
+ unpacked.data.via.array.ptr[1].via.bin.size);
} else {
size_t len = unpacked.data.via.array.ptr[1].via.bin.size;
char *const converted = string_convert(
@@ -3951,17 +3941,14 @@ shada_read_next_item_hist_no_conv:
const size_t j = i;
{
for (size_t i = 0; i < unpacked.data.via.map.size; i++) {
- CHECK_KEY_IS_STR("buffer list entry");
+ CHECK_KEY_IS_STR("buffer list entry")
LONG_KEY("buffer list entry", KEY_LNUM,
- entry->data.buffer_list.buffers[j].pos.lnum)
- else
- INTEGER_KEY("buffer list entry", KEY_COL,
- entry->data.buffer_list.buffers[j].pos.col)
- else
- STRING_KEY("buffer list entry", KEY_FILE,
- entry->data.buffer_list.buffers[j].fname)
- else
- ADDITIONAL_KEY
+ entry->data.buffer_list.buffers[j].pos.lnum)
+ INTEGER_KEY("buffer list entry", KEY_COL,
+ entry->data.buffer_list.buffers[j].pos.col)
+ STRING_KEY("buffer list entry", KEY_FILE,
+ entry->data.buffer_list.buffers[j].fname)
+ ADDITIONAL_KEY
}
}
}
diff --git a/src/nvim/testdir/test53.in b/src/nvim/testdir/test53.in
index 8ca9c9ed29..7c35b2e853 100644
--- a/src/nvim/testdir/test53.in
+++ b/src/nvim/testdir/test53.in
@@ -23,6 +23,7 @@ jfXdit
0fXdit
fXdat
0fXdat
+dit
:"
:put =matchstr(\"abcd\", \".\", 0, 2) " b
:put =matchstr(\"abcd\", \"..\", 0, 2) " bc
@@ -97,6 +98,9 @@ voo "nah" sdf " asdf" sdf " sdf" sd
-<b>asdX<i>a<i />sdf</i>asdf</b>-
-<b>asdf<i>Xasdf</i>asdf</b>-
-<b>asdX<i>as<b />df</i>asdf</b>-
+-<b>
+innertext object
+</b>
</begin>
SEARCH:
foobar
diff --git a/src/nvim/testdir/test53.ok b/src/nvim/testdir/test53.ok
index 0c0b9ded16..05206972a4 100644
--- a/src/nvim/testdir/test53.ok
+++ b/src/nvim/testdir/test53.ok
@@ -11,6 +11,7 @@ voo "zzzzzzzzzzzzzzzzzzzzzzzzzzzzsd
-<b></b>-
-<b>asdfasdf</b>-
--
+-<b></b>
</begin>
b
bc
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 069574c087..c340211b02 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -95,7 +95,7 @@ static int included_patches[] = {
// 901,
// 900 NA
// 899 NA
- // 898,
+ 898,
// 897,
// 896,
// 895,
@@ -198,17 +198,17 @@ static int included_patches[] = {
// 798,
// 797,
// 796 NA
- // 795,
+ 795,
// 794 NA
793,
// 792,
791,
- // 790,
- // 789,
+ 790,
+ 789,
// 788 NA
- // 787,
- // 786,
- // 785,
+ 787,
+ 786,
+ 785,
784,
// 783 NA
// 782,
@@ -335,10 +335,10 @@ static int included_patches[] = {
// 661,
660,
659,
- // 658,
+ 658,
// 657 NA
// 656,
- // 655,
+ 655,
// 654,
653,
// 652 NA
@@ -348,17 +348,17 @@ static int included_patches[] = {
// 648 NA
// 647 NA
646,
- // 645,
+ 645,
// 644 NA
// 643,
// 642,
// 641,
- // 640,
+ 640,
// 639,
// 638 NA
637,
636,
- // 635,
+ 635,
// 634,
633,
// 632 NA
diff --git a/test/functional/legacy/autocmd_option_spec.lua b/test/functional/legacy/autocmd_option_spec.lua
new file mode 100644
index 0000000000..855e9c6271
--- /dev/null
+++ b/test/functional/legacy/autocmd_option_spec.lua
@@ -0,0 +1,277 @@
+local helpers = require('test.functional.helpers')
+local nvim = helpers.meths
+local clear, eq, neq = helpers.clear, helpers.eq, helpers.neq
+local curbuf, buf = helpers.curbuf, helpers.bufmeths
+local source, execute = helpers.source, helpers.execute
+
+local function declare_hook_function()
+ source([[
+ fu! AutoCommand(match, bufnr, winnr)
+ let l:acc = {
+ \ 'option' : a:match,
+ \ 'oldval' : v:option_old,
+ \ 'newval' : v:option_new,
+ \ 'scope' : v:option_type,
+ \ 'attr' : {
+ \ 'bufnr' : a:bufnr,
+ \ 'winnr' : a:winnr,
+ \ }
+ \ }
+ call add(g:ret, l:acc)
+ endfu
+ ]])
+end
+
+local function set_hook(pattern)
+ execute(
+ 'au OptionSet '
+ .. pattern ..
+ ' :call AutoCommand(expand("<amatch>"), bufnr("%"), winnr())'
+ )
+end
+
+local function init_var()
+ execute('let g:ret = []')
+end
+
+local function get_result()
+ local ret = nvim.get_var('ret')
+ init_var()
+ return ret
+end
+
+local function expected_table(option, oldval, newval, scope, attr)
+ return {
+ option = option,
+ oldval = tostring(oldval),
+ newval = tostring(newval),
+ scope = scope,
+ attr = attr,
+ }
+end
+
+local function expected_combination(...)
+ local args = {...}
+ local ret = get_result()
+
+ if not (#args == #ret) then
+ local expecteds = {}
+ for _, v in pairs(args) do
+ table.insert(expecteds, expected_table(unpack(v)))
+ end
+ eq(expecteds, ret)
+ return
+ end
+
+ for i, v in ipairs(args) do
+ local attr = v[5]
+ if not attr then
+ -- remove attr entries
+ ret[i].attr = nil
+ else
+ -- remove attr entries which are not required
+ for k in pairs(ret[i].attr) do
+ if not attr[k] then
+ ret[i].attr[k] = nil
+ end
+ end
+ end
+ eq(expected_table(unpack(v)), ret[i])
+ end
+end
+
+local function expected_empty()
+ eq({}, get_result())
+end
+
+local function make_buffer()
+ local old_buf = curbuf()
+ execute('new')
+ local new_buf = curbuf()
+ execute('wincmd p') -- move previous window
+
+ neq(old_buf, new_buf)
+ eq(old_buf, curbuf())
+
+ return new_buf
+end
+
+describe('au OptionSet', function()
+ describe('with any opton (*)', function()
+
+ before_each(function()
+ clear()
+ declare_hook_function()
+ init_var()
+ set_hook('*')
+ end)
+
+ it('should be called in setting number option', function()
+ execute('set nu')
+ expected_combination({'number', 0, 1, 'global'})
+
+ execute('setlocal nonu')
+ expected_combination({'number', 1, 0, 'local'})
+
+ execute('setglobal nonu')
+ expected_combination({'number', 1, 0, 'global'})
+ end)
+
+ it('should be called in setting autoindent option',function()
+ execute('setlocal ai')
+ expected_combination({'autoindent', 0, 1, 'local'})
+
+ execute('setglobal ai')
+ expected_combination({'autoindent', 0, 1, 'global'})
+
+ execute('set noai')
+ expected_combination({'autoindent', 1, 0, 'global'})
+ end)
+
+ it('should be called in inverting global autoindent option',function()
+ execute('set ai!')
+ expected_combination({'autoindent', 0, 1, 'global'})
+ end)
+
+ it('should be called in being unset local autoindent option',function()
+ execute('setlocal ai')
+ expected_combination({'autoindent', 0, 1, 'local'})
+
+ execute('setlocal ai<')
+ expected_combination({'autoindent', 1, 0, 'local'})
+ end)
+
+ it('should be called in setting global list and number option at the same time',function()
+ execute('set list nu')
+ expected_combination(
+ {'list', 0, 1, 'global'},
+ {'number', 0, 1, 'global'}
+ )
+ end)
+
+ it('should not print anything, use :noa', function()
+ execute('noa set nolist nonu')
+ expected_empty()
+ end)
+
+ it('should be called in setting local acd', function()
+ execute('setlocal acd')
+ expected_combination({'autochdir', 0, 1, 'local'})
+ end)
+
+ it('should be called in setting autoread', function()
+ execute('set noar')
+ expected_combination({'autoread', 1, 0, 'global'})
+
+ execute('setlocal ar')
+ expected_combination({'autoread', 0, 1, 'local'})
+ end)
+
+ it('should be called in inverting global autoread', function()
+ execute('setglobal invar')
+ expected_combination({'autoread', 1, 0, 'global'})
+ end)
+
+ it('should be called in setting backspace option through :let', function()
+ execute('let &bs=""')
+ expected_combination({'backspace', 'indent,eol,start', '', 'global'})
+ end)
+
+ describe('being set by setbufvar()', function()
+ it('should not trigger because option name is invalid', function()
+ execute('call setbufvar(1, "&l:bk", 1)')
+ expected_empty()
+ end)
+
+ it('should trigger using correct option name', function()
+ execute('call setbufvar(1, "&backup", 1)')
+ expected_combination({'backup', 0, 1, 'local'})
+ end)
+
+ it('should trigger if the current buffer is different from the targetted buffer', function()
+ local new_buffer = make_buffer()
+ local new_bufnr = buf.get_number(new_buffer)
+
+ execute('call setbufvar(' .. new_bufnr .. ', "&buftype", "nofile")')
+ expected_combination({'buftype', '', 'nofile', 'local', {bufnr = new_bufnr}})
+ end)
+ end)
+ end)
+
+ describe('with specific option', function()
+
+ before_each(function()
+ clear()
+ declare_hook_function()
+ init_var()
+ end)
+
+ it('should be called iff setting readonly', function()
+ set_hook('readonly')
+
+ execute('set nu')
+ expected_empty()
+
+ execute('setlocal ro')
+ expected_combination({'readonly', 0, 1, 'local'})
+
+ execute('setglobal ro')
+ expected_combination({'readonly', 0, 1, 'global'})
+
+ execute('set noro')
+ expected_combination({'readonly', 1, 0, 'global'})
+ end)
+
+ describe('being set by setbufvar()', function()
+ it('should not trigger because option name does not match with backup', function()
+ set_hook('backup')
+
+ execute('call setbufvar(1, "&l:bk", 1)')
+ expected_empty()
+ end)
+
+ it('should trigger, use correct option name backup', function()
+ set_hook('backup')
+
+ execute('call setbufvar(1, "&backup", 1)')
+ expected_combination({'backup', 0, 1, 'local'})
+ end)
+
+ it('should trigger if the current buffer is different from the targetted buffer', function()
+ set_hook('buftype')
+
+ local new_buffer = make_buffer()
+ local new_bufnr = buf.get_number(new_buffer)
+
+ execute('call setbufvar(' .. new_bufnr .. ', "&buftype", "nofile")')
+ expected_combination({'buftype', '', 'nofile', 'local', {bufnr = new_bufnr}})
+ end)
+ end)
+
+ describe('being set by neovim api', function()
+ it('should trigger if a boolean option be set globally', function()
+ set_hook('autochdir')
+
+ nvim.set_option('autochdir', true)
+ eq(true, nvim.get_option('autochdir'))
+ expected_combination({'autochdir', '0', '1', 'global'})
+ end)
+
+ it('should trigger if a number option be set globally', function()
+ set_hook('cmdheight')
+
+ nvim.set_option('cmdheight', 5)
+ eq(5, nvim.get_option('cmdheight'))
+ expected_combination({'cmdheight', 1, 5, 'global'})
+ end)
+
+ it('should trigger if a string option be set globally', function()
+ set_hook('ambiwidth')
+
+ nvim.set_option('ambiwidth', 'double')
+ eq('double', nvim.get_option('ambiwidth'))
+ expected_combination({'ambiwidth', 'single', 'double', 'global'})
+ end)
+ end)
+ end)
+end)
diff --git a/test/functional/legacy/fixeol_spec.lua b/test/functional/legacy/fixeol_spec.lua
new file mode 100644
index 0000000000..578178d707
--- /dev/null
+++ b/test/functional/legacy/fixeol_spec.lua
@@ -0,0 +1,72 @@
+-- Tests for 'fixeol'
+
+local helpers = require('test.functional.helpers')
+local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
+
+describe('fixeol', function()
+ local function rmtestfiles()
+ os.remove('test.out')
+ os.remove('XXEol')
+ os.remove('XXNoEol')
+ os.remove('XXTestEol')
+ os.remove('XXTestNoEol')
+ end
+ setup(function()
+ clear()
+ rmtestfiles()
+ end)
+ teardown(function()
+ rmtestfiles()
+ end)
+
+ it('is working', function()
+ -- First write two test files – with and without trailing EOL.
+ -- Use Unix fileformat for consistency.
+ execute('set ff=unix')
+ execute('enew!')
+ feed('awith eol<esc>:w! XXEol<cr>')
+ execute('enew!')
+ execute('set noeol nofixeol')
+ feed('awithout eol<esc>:w! XXNoEol<cr>')
+ execute('set eol fixeol')
+ execute('bwipe XXEol XXNoEol')
+
+ -- Try editing files with 'fixeol' disabled.
+ execute('e! XXEol')
+ feed('ostays eol<esc>:set nofixeol<cr>')
+ execute('w! XXTestEol')
+ execute('e! XXNoEol')
+ feed('ostays without<esc>:set nofixeol<cr>')
+ execute('w! XXTestNoEol')
+ execute('bwipe XXEol XXNoEol XXTestEol XXTestNoEol')
+ execute('set fixeol')
+
+ -- Append "END" to each file so that we can see what the last written char was.
+ feed('ggdGaEND<esc>:w >>XXEol<cr>')
+ execute('w >>XXNoEol')
+ execute('w >>XXTestEol')
+ execute('w >>XXTestNoEol')
+
+ -- Concatenate the results.
+ execute('e! test.out')
+ feed('a0<esc>:$r XXEol<cr>')
+ execute('$r XXNoEol')
+ feed('Go1<esc>:$r XXTestEol<cr>')
+ execute('$r XXTestNoEol')
+ execute('w')
+
+ -- Assert buffer contents.
+ expect([=[
+ 0
+ with eol
+ END
+ without eolEND
+ 1
+ with eol
+ stays eol
+ END
+ without eol
+ stays withoutEND]=])
+ end)
+end)