aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--CMakeLists.txt10
-rw-r--r--CONTRIBUTING.md6
-rw-r--r--Makefile5
-rw-r--r--cmake/RunTestsLint.cmake11
-rw-r--r--runtime/autoload/msgpack.vim820
-rw-r--r--runtime/autoload/shada.vim696
-rw-r--r--runtime/doc/develop.txt239
-rw-r--r--runtime/doc/filetype.txt143
-rw-r--r--runtime/doc/gui_w32.txt2
-rw-r--r--runtime/doc/help.txt1
-rw-r--r--runtime/doc/options.txt18
-rw-r--r--runtime/doc/pi_msgpack.txt139
-rw-r--r--runtime/doc/quickref.txt1
-rw-r--r--runtime/doc/starting.txt4
-rw-r--r--runtime/doc/todo.txt4897
-rw-r--r--runtime/doc/vi_diff.txt531
-rw-r--r--runtime/doc/vim_diff.txt2
-rw-r--r--runtime/ftplugin/shada.vim18
-rw-r--r--runtime/optwin.vim4
-rw-r--r--runtime/plugin/shada.vim39
-rw-r--r--runtime/syntax/shada.vim125
-rw-r--r--src/nvim/api/buffer.c1
-rw-r--r--src/nvim/buffer.c989
-rw-r--r--src/nvim/diff.c1
-rw-r--r--src/nvim/edit.c11
-rw-r--r--src/nvim/eval.c3
-rw-r--r--src/nvim/event/socket.c2
-rw-r--r--src/nvim/event/stream.c2
-rw-r--r--src/nvim/ex_cmds.c3
-rw-r--r--src/nvim/ex_cmds.lua22
-rw-r--r--src/nvim/ex_cmds2.c3
-rw-r--r--src/nvim/ex_docmd.c20
-rw-r--r--src/nvim/ex_eval.c2
-rw-r--r--src/nvim/ex_getln.c11
-rw-r--r--src/nvim/file_search.c1
-rw-r--r--src/nvim/fileio.c18
-rw-r--r--src/nvim/fold.c2
-rw-r--r--src/nvim/getchar.c2
-rw-r--r--src/nvim/hardcopy.c3
-rw-r--r--src/nvim/if_cscope.c2
-rw-r--r--src/nvim/keymap.c2
-rw-r--r--src/nvim/main.c3
-rw-r--r--src/nvim/mark.c3
-rw-r--r--src/nvim/mbyte.c3
-rw-r--r--src/nvim/memfile.c3
-rw-r--r--src/nvim/memline.c2
-rw-r--r--src/nvim/memory.c1
-rw-r--r--src/nvim/menu.c2
-rw-r--r--src/nvim/message.c3
-rw-r--r--src/nvim/misc1.c3
-rw-r--r--src/nvim/misc2.c3
-rw-r--r--src/nvim/move.c2
-rw-r--r--src/nvim/normal.c17
-rw-r--r--src/nvim/ops.c2
-rw-r--r--src/nvim/option.c3
-rw-r--r--src/nvim/options.lua9
-rw-r--r--src/nvim/os/fs.c29
-rw-r--r--src/nvim/os/fs_defs.h4
-rw-r--r--src/nvim/os/os_defs.h4
-rw-r--r--src/nvim/os/win_defs.h2
-rw-r--r--src/nvim/os_unix.c2
-rw-r--r--src/nvim/path.c1
-rw-r--r--src/nvim/quickfix.c3
-rw-r--r--src/nvim/screen.c3
-rw-r--r--src/nvim/search.c4
-rw-r--r--src/nvim/shada.c35
-rw-r--r--src/nvim/spell.c3
-rw-r--r--src/nvim/strings.c1
-rw-r--r--src/nvim/syntax.c3
-rw-r--r--src/nvim/tag.c3
-rw-r--r--src/nvim/terminal.c8
-rw-r--r--src/nvim/terminal.h9
-rw-r--r--src/nvim/tui/input.c32
-rw-r--r--src/nvim/tui/tui.c12
-rw-r--r--src/nvim/undo.c3
-rw-r--r--src/nvim/version.c98
-rw-r--r--src/nvim/window.c3
-rw-r--r--test/.luacheckrc13
-rw-r--r--test/benchmark/bench_re_freeze_spec.lua2
-rw-r--r--test/functional/api/menu_spec.lua2
-rw-r--r--test/functional/api/server_requests_spec.lua4
-rw-r--r--test/functional/api/vim_spec.lua2
-rw-r--r--test/functional/api/window_spec.lua8
-rw-r--r--test/functional/autocmd/tabclose_spec.lua5
-rw-r--r--test/functional/autocmd/tabnew_spec.lua6
-rw-r--r--test/functional/autocmd/tabnewentered_spec.lua6
-rw-r--r--test/functional/autocmd/termclose_spec.lua4
-rw-r--r--test/functional/clipboard/clipboard_provider_spec.lua1
-rw-r--r--test/functional/eval/glob_spec.lua1
-rw-r--r--test/functional/eval/msgpack_functions_spec.lua12
-rw-r--r--test/functional/ex_cmds/grep_spec.lua5
-rw-r--r--test/functional/ex_cmds/oldfiles_spec.lua32
-rw-r--r--test/functional/ex_cmds/profile_spec.lua2
-rw-r--r--test/functional/ex_cmds/quit_spec.lua2
-rw-r--r--test/functional/ex_cmds/recover_spec.lua1
-rw-r--r--test/functional/ex_cmds/sign_spec.lua4
-rw-r--r--test/functional/ex_cmds/wviminfo_spec.lua6
-rw-r--r--test/functional/helpers.lua23
-rw-r--r--test/functional/job/job_spec.lua12
-rw-r--r--test/functional/legacy/003_cindent_spec.lua2
-rw-r--r--test/functional/legacy/009_bufleave_autocommand_spec.lua2
-rw-r--r--test/functional/legacy/015_alignment_spec.lua2
-rw-r--r--test/functional/legacy/022_line_ending_spec.lua2
-rw-r--r--test/functional/legacy/023_edit_arguments_spec.lua2
-rw-r--r--test/functional/legacy/026_execute_while_if_spec.lua2
-rw-r--r--test/functional/legacy/027_expand_file_names_spec.lua6
-rw-r--r--test/functional/legacy/029_join_spec.lua2
-rw-r--r--test/functional/legacy/031_close_commands_spec.lua2
-rw-r--r--test/functional/legacy/038_virtual_replace_spec.lua2
-rw-r--r--test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua2
-rw-r--r--test/functional/legacy/046_multi_line_regexps_spec.lua2
-rw-r--r--test/functional/legacy/051_highlight_spec.lua2
-rw-r--r--test/functional/legacy/056_script_local_function_spec.lua2
-rw-r--r--test/functional/legacy/060_exists_and_has_functions_spec.lua4
-rw-r--r--test/functional/legacy/061_undo_tree_spec.lua9
-rw-r--r--test/functional/legacy/063_match_and_matchadd_spec.lua9
-rw-r--r--test/functional/legacy/065_float_and_logic_operators_spec.lua2
-rw-r--r--test/functional/legacy/067_augroup_exists_spec.lua2
-rw-r--r--test/functional/legacy/072_undo_file_spec.lua2
-rw-r--r--test/functional/legacy/074_global_var_in_viminfo_spec.lua2
-rw-r--r--test/functional/legacy/075_maparg_spec.lua2
-rw-r--r--test/functional/legacy/077_mf_hash_grow_spec.lua2
-rw-r--r--test/functional/legacy/078_swapfile_recover_spec.lua4
-rw-r--r--test/functional/legacy/080_substitute_spec.lua2
-rw-r--r--test/functional/legacy/082_string_comparison_spec.lua2
-rw-r--r--test/functional/legacy/084_curswant_spec.lua4
-rw-r--r--test/functional/legacy/089_number_relnumber_findfile_spec.lua2
-rw-r--r--test/functional/legacy/090_sha256_spec.lua4
-rw-r--r--test/functional/legacy/091_context_variables_spec.lua4
-rw-r--r--test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua2
-rw-r--r--test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua2
-rw-r--r--test/functional/legacy/095_regexp_multibyte_spec.lua4
-rw-r--r--test/functional/legacy/096_location_list_spec.lua2
-rw-r--r--test/functional/legacy/097_glob_path_spec.lua2
-rw-r--r--test/functional/legacy/098_scrollbind_spec.lua4
-rw-r--r--test/functional/legacy/100_undo_level_spec.lua4
-rw-r--r--test/functional/legacy/101_hlsearch_spec.lua3
-rw-r--r--test/functional/legacy/102_fnameescape_spec.lua2
-rw-r--r--test/functional/legacy/103_visual_mode_reset_spec.lua4
-rw-r--r--test/functional/legacy/105_filename_modifiers_spec.lua2
-rw-r--r--test/functional/legacy/106_errorformat_spec.lua2
-rw-r--r--test/functional/legacy/107_adjust_window_and_contents_spec.lua4
-rw-r--r--test/functional/legacy/listlbr_utf8_spec.lua4
-rw-r--r--test/functional/legacy/nested_function_spec.lua2
-rw-r--r--test/functional/legacy/qf_title_spec.lua4
-rw-r--r--test/functional/legacy/signs_spec.lua1
-rw-r--r--test/functional/legacy/writefile_spec.lua1
-rw-r--r--test/functional/normal/K_spec.lua5
-rw-r--r--test/functional/plugin/helpers.lua41
-rw-r--r--test/functional/plugin/msgpack_spec.lua699
-rw-r--r--test/functional/plugin/shada_spec.lua2845
-rw-r--r--test/functional/provider/define_spec.lua70
-rw-r--r--test/functional/server/server_spec.lua3
-rw-r--r--test/functional/shada/buffers_spec.lua47
-rw-r--r--test/functional/shada/compatibility_spec.lua15
-rw-r--r--test/functional/shada/errors_spec.lua5
-rw-r--r--test/functional/shada/helpers.lua14
-rw-r--r--test/functional/shada/history_spec.lua22
-rw-r--r--test/functional/shada/marks_spec.lua8
-rw-r--r--test/functional/shada/merging_spec.lua10
-rw-r--r--test/functional/shell/viml_system_spec.lua4
-rw-r--r--test/functional/terminal/altscreen_spec.lua1
-rw-r--r--test/functional/terminal/buffer_spec.lua1
-rw-r--r--test/functional/terminal/cursor_spec.lua2
-rw-r--r--test/functional/terminal/ex_terminal_spec.lua3
-rw-r--r--test/functional/terminal/helpers.lua2
-rw-r--r--test/functional/terminal/highlight_spec.lua2
-rw-r--r--test/functional/terminal/mouse_spec.lua5
-rw-r--r--test/functional/terminal/tui_spec.lua113
-rw-r--r--test/functional/terminal/window_spec.lua4
-rw-r--r--test/functional/terminal/window_split_tab_spec.lua3
-rw-r--r--test/functional/ui/highlight_spec.lua2
-rw-r--r--test/functional/ui/input_spec.lua1
-rw-r--r--test/functional/ui/screen.lua38
-rw-r--r--test/functional/ui/screen_basic_spec.lua5
-rw-r--r--test/functional/ui/searchhl_spec.lua4
-rw-r--r--test/functional/viml/completion_spec.lua2
-rw-r--r--test/includes/CMakeLists.txt1
-rw-r--r--test/includes/pre/sys/errno.h4
-rw-r--r--test/includes/pre/uv-errno.h4
-rw-r--r--test/unit/buffer_spec.lua98
-rw-r--r--test/unit/fileio_spec.lua1
-rw-r--r--test/unit/formatc.lua12
-rw-r--r--test/unit/garray_spec.lua19
-rw-r--r--test/unit/helpers.lua16
-rw-r--r--test/unit/os/env_spec.lua8
-rw-r--r--test/unit/os/fs_spec.lua49
-rw-r--r--test/unit/os/shell_spec.lua4
-rw-r--r--test/unit/os/users_spec.lua8
-rw-r--r--test/unit/path_spec.lua80
-rw-r--r--test/unit/preprocess.lua4
-rw-r--r--test/unit/profile_spec.lua26
-rw-r--r--test/unit/set.lua2
-rw-r--r--third-party/cmake/BuildLuarocks.cmake13
195 files changed, 7131 insertions, 6619 deletions
diff --git a/.gitignore b/.gitignore
index 0267caada2..70899dfa8d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,6 +38,9 @@ tags
# Folder generated by the unit tests
/test/includes/post/
+# generated by luacheck during `make testlint'
+/test/.luacheckcache
+
# luarocks, not added as a subtree because of the large number of blobs
/third-party/luarocks
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f11b9995c0..0633744e97 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -366,6 +366,8 @@ if(NOT BUSTED_OUTPUT_TYPE)
set(BUSTED_OUTPUT_TYPE "utfTerminal")
endif()
+find_program(LUACHECK_PRG luacheck)
+
include(InstallHelpers)
file(GLOB MANPAGES
@@ -456,3 +458,11 @@ if(BUSTED_PRG)
-P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake
DEPENDS ${BENCHMARK_PREREQS})
endif()
+
+if(LUACHECK_PRG)
+ add_custom_target(testlint
+ COMMAND ${CMAKE_COMMAND}
+ -DLUACHECK_PRG=${LUACHECK_PRG}
+ -DTEST_DIR=${CMAKE_CURRENT_SOURCE_DIR}/test
+ -P ${PROJECT_SOURCE_DIR}/cmake/RunTestsLint.cmake)
+endif()
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 01105d8379..aa88837290 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -27,9 +27,9 @@ If your issue isn't mentioned there:
[Troubleshooting#build-issues][wiki-troubleshooting-build-issues].
- For runtime issues, see
[Troubleshooting#runtime-issues][wiki-troubleshooting-runtime-issues].
- If your issue isn't mentioned there, try to reproduce your it using
- `nvim` with the smallest possible `vimrc` (or none at all via `nvim -u
- NONE`), to rule out bugs in plugins you're using.
+ If your issue isn't mentioned there, try reproducing it using `nvim`
+ with the smallest possible `vimrc` (or none at all via `nvim -u NONE`),
+ to rule out bugs in plugins you're using.
If you're using a plugin manager, comment out your plugins, then add
them back in one by one.
diff --git a/Makefile b/Makefile
index 45065769fb..343307eb2b 100644
--- a/Makefile
+++ b/Makefile
@@ -86,6 +86,9 @@ oldtest: | nvim
functionaltest: | nvim
+$(BUILD_CMD) -C build functionaltest
+testlint: | nvim
+ $(BUILD_CMD) -C build testlint
+
test: functionaltest
unittest: | nvim
@@ -110,4 +113,4 @@ lint:
-DLINT_SUPPRESS_URL="$(DOC_DOWNLOAD_URL_BASE)$(CLINT_ERRORS_FILE_PATH)" \
-P cmake/RunLint.cmake
-.PHONY: test functionaltest unittest lint clean distclean nvim libnvim cmake deps install
+.PHONY: test testlint functionaltest unittest lint clean distclean nvim libnvim cmake deps install
diff --git a/cmake/RunTestsLint.cmake b/cmake/RunTestsLint.cmake
new file mode 100644
index 0000000000..cf5465803e
--- /dev/null
+++ b/cmake/RunTestsLint.cmake
@@ -0,0 +1,11 @@
+execute_process(
+ COMMAND ${LUACHECK_PRG} -q ${TEST_DIR}
+ WORKING_DIRECTORY ${TEST_DIR}
+ ERROR_VARIABLE err
+ RESULT_VARIABLE res
+ ${EXTRA_ARGS})
+
+if(NOT res EQUAL 0)
+ message(STATUS "Output to stderr:\n${err}")
+ message(FATAL_ERROR "Linting tests failed with error: ${res}.")
+endif()
diff --git a/runtime/autoload/msgpack.vim b/runtime/autoload/msgpack.vim
new file mode 100644
index 0000000000..e6022922fe
--- /dev/null
+++ b/runtime/autoload/msgpack.vim
@@ -0,0 +1,820 @@
+if exists('g:loaded_msgpack_autoload')
+ finish
+endif
+let g:loaded_msgpack_autoload = 1
+
+""
+" Check that given value is an integer. Respects |msgpack-special-dict|.
+function msgpack#is_int(v) abort
+ return type(a:v) == type(0) || (
+ \type(a:v) == type({}) && get(a:v, '_TYPE') is# v:msgpack_types.integer)
+endfunction
+
+""
+" Check that given value is an unsigned integer. Respects
+" |msgpack-special-dict|.
+function msgpack#is_uint(v) abort
+ return msgpack#is_int(a:v) && (type(a:v) == type(0)
+ \? a:v >= 0
+ \: a:v._VAL[0] > 0)
+endfunction
+
+""
+" True if s:msgpack_init_python() function was already run.
+let s:msgpack_python_initialized = 0
+
+""
+" Cached return of s:msgpack_init_python() used when
+" s:msgpack_python_initialized is true.
+let s:msgpack_python_type = 0
+
+""
+" Create Python functions that are necessary for work. Also defines functions
+" s:msgpack_dict_strftime(format, timestamp) and s:msgpack_dict_strptime(format,
+" string).
+"
+" @return Zero in case no Python is available, empty string if Python-2 is
+" available and string `"3"` if Python-3 is available.
+function s:msgpack_init_python() abort
+ if s:msgpack_python_initialized
+ return s:msgpack_python_type
+ endif
+ let s:msgpack_python_initialized = 1
+ for suf in ['', '3']
+ try
+ execute 'python' . suf
+ \. "def shada_dict_strftime():\n"
+ \. " import datetime\n"
+ \. " import vim\n"
+ \. " fmt = vim.eval('a:format')\n"
+ \. " timestamp = vim.eval('a:timestamp')\n"
+ \. " timestamp = [int(v) for v in timestamp['_VAL']]\n"
+ \. " timestamp = timestamp[0] * (timestamp[1] << 62\n"
+ \. " | timestamp[2] << 31\n"
+ \. " | timestamp[3])\n"
+ \. " time = datetime.datetime.fromtimestamp(timestamp)\n"
+ \. " return time.strftime(fmt)\n"
+ \. "def shada_dict_strptime():\n"
+ \. " import datetime\n"
+ \. " import vim\n"
+ \. " fmt = vim.eval('a:format')\n"
+ \. " timestr = vim.eval('a:string')\n"
+ \. " timestamp = datetime.datetime.strptime(timestr, fmt)\n"
+ \. " timestamp = int(timestamp.timestamp())\n"
+ \. " if timestamp > 2 ** 31:\n"
+ \. " tsabs = abs(timestamp)"
+ \. " return ('{\"_TYPE\": v:msgpack_types.integer,'\n"
+ \. " + '\"_VAL\": [{sign},{v1},{v2},{v3}]}').format(\n"
+ \. " sign=1 if timestamp >= 0 else -1,\n"
+ \. " v1=((tsabs >> 62) & 0x3),\n"
+ \. " v2=((tsabs >> 31) & (2 ** 31 - 1)),\n"
+ \. " v3=(tsabs & (2 ** 31 - 1)))\n"
+ \. " else:\n"
+ \. " return str(timestamp)\n"
+ execute "function s:msgpack_dict_strftime(format, timestamp) abort\n"
+ \. " return py" . suf . "eval('shada_dict_strftime()')\n"
+ \. "endfunction\n"
+ \. "function s:msgpack_dict_strptime(format, string)\n"
+ \. " return eval(py" . suf . "eval('shada_dict_strptime()'))\n"
+ \. "endfunction\n"
+ let s:msgpack_python_type = suf
+ return suf
+ catch
+ continue
+ endtry
+ endfor
+
+ ""
+ " strftime() function for |msgpack-special-dict| values.
+ "
+ " @param[in] format String according to which time should be formatted.
+ " @param[in] timestamp Timestamp (seconds since epoch) to format.
+ "
+ " @return Formatted timestamp.
+ "
+ " @warning Without +python or +python3 this function does not work correctly.
+ " The VimL code contains “reference” implementation which does not
+ " really work because of precision loss.
+ function s:msgpack_dict_strftime(format, timestamp)
+ return msgpack#strftime(a:format, +msgpack#int_dict_to_str(a:timestamp))
+ endfunction
+
+ ""
+ " Function that parses given string according to given format.
+ "
+ " @param[in] format String according to which string was formatted.
+ " @param[in] string Time formatted according to format.
+ "
+ " @return Timestamp.
+ "
+ " @warning Without +python or +python3 this function is able to work only with
+ " 31-bit (32-bit signed) timestamps that have format
+ " `%Y-%m-%dT%H:%M:%S`.
+ function s:msgpack_dict_strptime(format, string)
+ let fmt = '%Y-%m-%dT%H:%M:%S'
+ if a:format isnot# fmt
+ throw 'notimplemented-format:Only ' . fmt . ' format is supported'
+ endif
+ let match = matchlist(a:string,
+ \'\v\C^(\d+)\-(\d+)\-(\d+)T(\d+)\:(\d+)\:(\d+)$')
+ if empty(match)
+ throw 'invalid-string:Given string does not match format ' . a:format
+ endif
+ call map(match, 'str2nr(v:val, 10)')
+ let [year, month, day, hour, minute, second] = match[1:6]
+ " Bisection start and end:
+ "
+ " Start: 365 days in year, 28 days in month, -12 hours tz offset.
+ let bisect_ts_start = (((((year - 1970) * 365
+ \+ (month - 1) * 28
+ \+ (day - 1)) * 24
+ \+ hour - 12) * 60
+ \+ minute) * 60
+ \+ second)
+ if bisect_ts_start < 0
+ let bisect_ts_start = 0
+ endif
+ let start_string = strftime(fmt, bisect_ts_start)
+ if start_string is# a:string
+ return bisect_ts_start
+ endif
+ " End: 366 days in year, 31 day in month, +14 hours tz offset.
+ let bisect_ts_end = (((((year - 1970) * 366
+ \+ (month - 1) * 31
+ \+ (day - 1)) * 24
+ \+ hour + 14) * 60
+ \+ minute) * 60
+ \+ second)
+ let end_string = strftime(fmt, bisect_ts_end)
+ if end_string is# a:string
+ return bisect_ts_end
+ endif
+ if start_string ># end_string
+ throw 'internal-start-gt:Internal error: start > end'
+ endif
+ if start_string is# end_string
+ throw printf('internal-start-eq:Internal error: '
+ \. 'start(%u)==end(%u), but start(%s)!=string(%s)',
+ \bisect_ts_start, bisect_ts_end,
+ \string(start_string), string(a:string))
+ endif
+ if start_string ># a:string
+ throw 'internal-start-string:Internal error: start > string'
+ endif
+ if end_string <# a:string
+ throw 'internal-end-string:Internal error: end < string'
+ endif
+ while 1
+ let bisect_ts_middle = (bisect_ts_start/2) + (bisect_ts_end/2)
+ let middle_string = strftime(fmt, bisect_ts_middle)
+ if a:string is# middle_string
+ return bisect_ts_middle
+ elseif a:string ># middle_string
+ if bisect_ts_middle == bisect_ts_start
+ let bisect_ts_start += 1
+ else
+ let bisect_ts_start = bisect_ts_middle
+ endif
+ else
+ if bisect_ts_middle == bisect_ts_end
+ let bisect_ts_end -= 1
+ else
+ let bisect_ts_end = bisect_ts_middle
+ endif
+ endif
+ if bisect_ts_start >= bisect_ts_end
+ throw 'not-found:Unable to find timestamp'
+ endif
+ endwhile
+ endfunction
+
+ return 0
+endfunction
+
+""
+" Wrapper for strftime() that respects |msgpack-special-dict|. May actually use
+" non-standard strftime() implementations for |msgpack-special-dict| values.
+"
+" @param[in] format Format string.
+" @param[in] timestamp Formatted timestamp.
+function msgpack#strftime(format, timestamp) abort
+ if type(a:timestamp) == type({})
+ call s:msgpack_init_python()
+ return s:msgpack_dict_strftime(a:format, a:timestamp)
+ else
+ return strftime(a:format, a:timestamp)
+ endif
+endfunction
+
+""
+" Parse string according to the format.
+"
+" Requires +python available. If it is not then only supported format is
+" `%Y-%m-%dT%H:%M:%S` because this is the format used by ShaDa plugin. Also in
+" this case bisection will be used (timestamps tried with strftime() up until
+" result matches the string) and only 31-bit (signed 32-bit: with negative
+" timestamps being useless this leaves 31 bits) timestamps will be supported.
+"
+" @param[in] format Time format.
+" @param[in] string Parsed time string. Must match given format.
+"
+" @return Timestamp. Possibly as |msgpack-special-dict|.
+function msgpack#strptime(format, string) abort
+ call s:msgpack_init_python()
+ return s:msgpack_dict_strptime(a:format, a:string)
+endfunction
+
+let s:MSGPACK_HIGHEST_BIT = 1
+let s:MSGPACK_HIGHEST_BIT_NR = 0
+while s:MSGPACK_HIGHEST_BIT * 2 > 0
+ let s:MSGPACK_HIGHEST_BIT = s:MSGPACK_HIGHEST_BIT * 2
+ let s:MSGPACK_HIGHEST_BIT_NR += 1
+endwhile
+
+""
+" Shift given number by given amount of bits
+function s:shift(n, s) abort
+ if a:s == 0
+ return a:n
+ elseif a:s < 0
+ let ret = a:n
+ for _ in range(-a:s)
+ let ret = ret / 2
+ endfor
+ return ret
+ else
+ let ret = a:n
+ for i in range(a:s)
+ let new_ret = ret * 2
+ if new_ret < ret
+ " Overflow: remove highest bit
+ let ret = xor(s:MSGPACK_HIGHEST_BIT, ret) * 2
+ endif
+ let ret = new_ret
+ endfor
+ return ret
+ endif
+endfunction
+
+let s:msgpack_mask_cache = {
+ \s:MSGPACK_HIGHEST_BIT_NR : s:MSGPACK_HIGHEST_BIT - 1}
+
+""
+" Apply a mask where first m bits are ones and other are zeroes to a given
+" number
+function s:mask1(n, m) abort
+ if a:m > s:MSGPACK_HIGHEST_BIT_NR + 1
+ let m = s:MSGPACK_HIGHEST_BIT_NR + 1
+ else
+ let m = a:m
+ endif
+ if !has_key(s:msgpack_mask_cache, m)
+ let p = 0
+ for _ in range(m)
+ let p = p * 2 + 1
+ endfor
+ let s:msgpack_mask_cache[m] = p
+ endif
+ return and(a:n, s:msgpack_mask_cache[m])
+endfunction
+
+""
+" Convert |msgpack-special-dict| that represents integer value to a string. Uses
+" hexadecimal representation starting with 0x because it is the easiest to
+" convert to.
+function msgpack#int_dict_to_str(v) abort
+ let v = a:v._VAL
+ " 64-bit number:
+ " 0000000001111111111222222222233333333334444444444555555555566666
+ " 1234567890123456789012345678901234567890123456789012345678901234
+ " Split in _VAL:
+ " 0000000001111111111222222222233 3333333344444444445555555555666 66
+ " 1234567890123456789012345678901 2345678901234567890123456789012 34
+ " Split by hex digits:
+ " 0000 0000 0111 1111 1112 2222 2222 2333 3333 3334 4444 4444 4555 5555 5556 6666
+ " 1234 5678 9012 3456 7890 1234 5678 9012 3456 7890 1234 5678 9012 3456 7890 1234
+ "
+ " Total split:
+ " _VAL[3] _VAL[2] _VAL[1]
+ " ______________________________________ _______________________________________ __
+ " 0000 0000 0111 1111 1112 2222 2222 233 3 3333 3334 4444 4444 4555 5555 5556 66 66
+ " 1234 5678 9012 3456 7890 1234 5678 901 2 3456 7890 1234 5678 9012 3456 7890 12 34
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^
+ " g4 g3 g2 g1
+ " ********************************** *** * ********************************** ** **
+ " 1 2 3 4 5 6
+ " 1: s:mask1(v[3], 28): first 28 bits of _VAL[3]
+ " 2: s:shift(v[3], -28): last 3 bits of _VAL[3]
+ " 3: s:mask1(v[2], 1): first bit of _VAL[2]
+ " 4: s:mask1(s:shift(v[2], -1), 28): bits 2 .. 29 of _VAL[2]
+ " 5: s:shift(v[2], -29): last 2 bits of _VAL[2]
+ " 6: s:shift(v[1], 2): _VAL[1]
+ let g4 = printf('%07x', s:mask1(v[3], 28))
+ let g3 = printf('%01x', or(s:shift(v[3], -28), s:shift(s:mask1(v[2], 1), 3)))
+ let g2 = printf('%07x', s:mask1(s:shift(v[2], -1), 28))
+ let g1 = printf('%01x', or(s:shift(v[2], -29), s:shift(v[1], 2)))
+ return ((v[0] < 0 ? '-' : '') . '0x' . g1 . g2 . g3 . g4)
+endfunction
+
+""
+" True boolean value.
+let g:msgpack#true = {'_TYPE': v:msgpack_types.boolean, '_VAL': 1}
+lockvar! g:msgpack#true
+
+""
+" False boolean value.
+let g:msgpack#false = {'_TYPE': v:msgpack_types.boolean, '_VAL': 0}
+lockvar! g:msgpack#false
+
+""
+" NIL value.
+let g:msgpack#nil = {'_TYPE': v:msgpack_types.nil, '_VAL': 0}
+lockvar! g:msgpack#nil
+
+""
+" Deduce type of |msgpack-special-dict|.
+"
+" @return zero if given dictionary is not special or name of the key in
+" v:msgpack_types dictionary.
+function msgpack#special_type(v) abort
+ if type(a:v) != type({}) || !has_key(a:v, '_TYPE')
+ return 0
+ endif
+ for [k, v] in items(v:msgpack_types)
+ if a:v._TYPE is v
+ return k
+ endif
+ endfor
+ return 0
+endfunction
+
+""
+" Mapping that maps type() output to type names.
+let s:MSGPACK_STANDARD_TYPES = {
+ \type(0): 'integer',
+ \type(0.0): 'float',
+ \type(''): 'binary',
+ \type([]): 'array',
+ \type({}): 'map',
+\}
+
+""
+" Deduce type of one of items returned by msgpackparse().
+"
+" @return Name of a key in v:msgpack_types.
+function msgpack#type(v) abort
+ let special_type = msgpack#special_type(a:v)
+ if special_type is 0
+ return s:MSGPACK_STANDARD_TYPES[type(a:v)]
+ endif
+ return special_type
+endfunction
+
+""
+" Dump nil value.
+function s:msgpack_dump_nil(v) abort
+ return 'NIL'
+endfunction
+
+""
+" Dump boolean value.
+function s:msgpack_dump_boolean(v) abort
+ return a:v._VAL ? 'TRUE' : 'FALSE'
+endfunction
+
+""
+" Dump integer msgpack value.
+function s:msgpack_dump_integer(v) abort
+ if type(a:v) == type({})
+ return msgpack#int_dict_to_str(a:v)
+ else
+ return string(a:v)
+ endif
+endfunction
+
+""
+" Dump floating-point value.
+function s:msgpack_dump_float(v) abort
+ return string(type(a:v) == type({}) ? a:v._VAL : a:v)
+endfunction
+
+""
+" Dump |msgpack-special-dict| that represents a string. If any additional
+" parameter is given then it dumps binary string.
+function s:msgpack_dump_string(v, ...) abort
+ let ret = [a:0 ? '"' : '="']
+ for v in a:v._VAL
+ call add(
+ \ret,
+ \substitute(
+ \substitute(v, '["\\]', '\\\0', 'g'),
+ \'\n', '\\0', 'g'))
+ call add(ret, '\n')
+ endfor
+ let ret[-1] = '"'
+ return join(ret, '')
+endfunction
+
+""
+" Dump binary string.
+function s:msgpack_dump_binary(v) abort
+ if type(a:v) == type({})
+ return s:msgpack_dump_string(a:v, 1)
+ else
+ return s:msgpack_dump_string({'_VAL': split(a:v, "\n", 1)}, 1)
+ endif
+endfunction
+
+""
+" Dump array value.
+function s:msgpack_dump_array(v) abort
+ let val = type(a:v) == type({}) ? a:v._VAL : a:v
+ return '[' . join(map(val[:], 'msgpack#string(v:val)'), ', ') . ']'
+endfunction
+
+""
+" Dump dictionary value.
+function s:msgpack_dump_map(v) abort
+ let ret = ['{']
+ if msgpack#special_type(a:v) is 0
+ for [k, v] in items(a:v)
+ let ret += [s:msgpack_dump_string({'_VAL': split(k, "\n", 1)}),
+ \': ',
+ \msgpack#string(v),
+ \', ']
+ unlet v
+ endfor
+ if !empty(a:v)
+ call remove(ret, -1)
+ endif
+ else
+ for [k, v] in sort(copy(a:v._VAL))
+ let ret += [msgpack#string(k),
+ \': ',
+ \msgpack#string(v),
+ \', ']
+ unlet k
+ unlet v
+ endfor
+ if !empty(a:v._VAL)
+ call remove(ret, -1)
+ endif
+ endif
+ let ret += ['}']
+ return join(ret, '')
+endfunction
+
+""
+" Dump extension value.
+function s:msgpack_dump_ext(v) abort
+ return printf('+(%i)%s', a:v._VAL[0],
+ \s:msgpack_dump_string({'_VAL': a:v._VAL[1]}, 1))
+endfunction
+
+""
+" Convert msgpack object to a string, like string() function does. Result of the
+" conversion may be passed to msgpack#eval().
+function msgpack#string(v) abort
+ if type(a:v) == type({})
+ let type = msgpack#special_type(a:v)
+ if type is 0
+ let type = 'map'
+ endif
+ else
+ let type = get(s:MSGPACK_STANDARD_TYPES, type(a:v), 0)
+ if type is 0
+ throw printf('msgpack:invtype: Unable to convert value %s', string(a:v))
+ endif
+ endif
+ return s:msgpack_dump_{type}(a:v)
+endfunction
+
+""
+" Copy msgpack object like deepcopy() does, but leave types intact
+function msgpack#deepcopy(obj) abort
+ if type(a:obj) == type([])
+ return map(copy(a:obj), 'msgpack#deepcopy(v:val)')
+ elseif type(a:obj) == type({})
+ let special_type = msgpack#special_type(a:obj)
+ if special_type is 0
+ return map(copy(a:obj), 'msgpack#deepcopy(v:val)')
+ else
+ return {
+ \'_TYPE': v:msgpack_types[special_type],
+ \'_VAL': msgpack#deepcopy(a:obj._VAL)
+ \}
+ endif
+ else
+ return copy(a:obj)
+ endif
+endfunction
+
+""
+" Convert an escaped character to needed value
+function s:msgpack_eval_str_sub(ch) abort
+ if a:ch is# 'n'
+ return '", "'
+ elseif a:ch is# '0'
+ return '\n'
+ else
+ return '\' . a:ch
+ endif
+endfunction
+
+let s:MSGPACK_SPECIAL_OBJECTS = {
+ \'NIL': '{''_TYPE'': v:msgpack_types.nil, ''_VAL'': 0}',
+ \'TRUE': '{''_TYPE'': v:msgpack_types.boolean, ''_VAL'': 1}',
+ \'FALSE': '{''_TYPE'': v:msgpack_types.boolean, ''_VAL'': 0}',
+ \'nan': '(-(1.0/0.0-1.0/0.0))',
+ \'inf': '(1.0/0.0)',
+\}
+
+""
+" Convert msgpack object dumped by msgpack#string() to a VimL object suitable
+" for msgpackdump().
+"
+" @param[in] s String to evaluate.
+" @param[in] special_objs Additional special objects, in the same format as
+" s:MSGPACK_SPECIAL_OBJECTS.
+"
+" @return Any value that msgpackparse() may return.
+function msgpack#eval(s, special_objs) abort
+ let s = a:s
+ let expr = []
+ let context = []
+ while !empty(s)
+ let s = substitute(s, '^\s*', '', '')
+ if s[0] =~# '\v^\h$'
+ let name = matchstr(s, '\v\C^\w+')
+ if has_key(s:MSGPACK_SPECIAL_OBJECTS, name)
+ call add(expr, s:MSGPACK_SPECIAL_OBJECTS[name])
+ elseif has_key(a:special_objs, name)
+ call add(expr, a:special_objs[name])
+ else
+ throw 'name-unknown:Unknown name ' . name . ': ' . s
+ endif
+ let s = s[len(name):]
+ elseif (s[0] is# '-' && s[1] =~# '\v^\d$') || s[0] =~# '\v^\d$'
+ let sign = 1
+ if s[0] is# '-'
+ let s = s[1:]
+ let sign = -1
+ endif
+ if s[0:1] is# '0x'
+ " See comment in msgpack#int_dict_to_str().
+ let s = s[2:]
+ let hexnum = matchstr(s, '\v\C^\x+')
+ if empty(hexnum)
+ throw '0x-empty:Must have number after 0x: ' . s
+ elseif len(hexnum) > 16
+ throw '0x-long:Must have at most 16 hex digits: ' . s
+ endif
+ let s = s[len(hexnum):]
+ let hexnum = repeat('0', 16 - len(hexnum)) . hexnum
+ let g1 = str2nr(hexnum[0], 16)
+ let g2 = str2nr(hexnum[1:7], 16)
+ let g3 = str2nr(hexnum[8], 16)
+ let g4 = str2nr(hexnum[9:15], 16)
+ let v1 = s:shift(g1, -2)
+ let v2 = or(or(s:shift(s:mask1(g1, 2), 29), s:shift(g2, 1)),
+ \s:mask1(s:shift(g3, -3), 1))
+ let v3 = or(s:shift(s:mask1(g3, 3), 28), g4)
+ call add(expr, printf('{''_TYPE'': v:msgpack_types.integer, '.
+ \'''_VAL'': [%i, %u, %u, %u]}',
+ \sign, v1, v2, v3))
+ else
+ let num = matchstr(s, '\v\C^\d+')
+ let s = s[len(num):]
+ if sign == -1
+ call add(expr, '-')
+ endif
+ call add(expr, num)
+ if s[0] is# '.'
+ let dec = matchstr(s, '\v\C^\.\d+%(e[+-]?\d+)?')
+ if empty(dec)
+ throw '0.-nodigits:Decimal dot must be followed by digit(s): ' . s
+ endif
+ let s = s[len(dec):]
+ call add(expr, dec)
+ endif
+ endif
+ elseif s =~# '-\?\%(inf\|nan\)'
+ if s[0] is# '-'
+ call add(expr, '-')
+ let s = s[1:]
+ endif
+ call add(expr, s:MSGPACK_SPECIAL_OBJECTS[s[0:2]])
+ let s = s[3:]
+ elseif stridx('="+', s[0]) != -1
+ let match = matchlist(s, '\v\C^(\=|\+\((\-?\d+)\)|)(\"%(\\.|[^\\"]+)*\")')
+ if empty(match)
+ throw '"-invalid:Invalid string: ' . s
+ endif
+ call add(expr, '{''_TYPE'': v:msgpack_types.')
+ if empty(match[1])
+ call add(expr, 'binary')
+ elseif match[1] is# '='
+ call add(expr, 'string')
+ else
+ call add(expr, 'ext')
+ endif
+ call add(expr, ', ''_VAL'': [')
+ if match[1][0] is# '+'
+ call add(expr, match[2] . ', [')
+ endif
+ call add(expr, substitute(match[3], '\v\C\\(.)',
+ \'\=s:msgpack_eval_str_sub(submatch(1))', 'g'))
+ if match[1][0] is# '+'
+ call add(expr, ']')
+ endif
+ call add(expr, ']}')
+ let s = s[len(match[0]):]
+ elseif s[0] is# '{'
+ call add(context, 'map')
+ call add(expr, '{''_TYPE'': v:msgpack_types.map, ''_VAL'': [')
+ call add(expr, '[')
+ let s = s[1:]
+ elseif s[0] is# '['
+ call add(context, 'array')
+ call add(expr, '[')
+ let s = s[1:]
+ elseif s[0] is# ':'
+ call add(expr, ',')
+ let s = s[1:]
+ elseif s[0] is# ','
+ if context[-1] is# 'array'
+ call add(expr, ',')
+ else
+ call add(expr, '], [')
+ endif
+ let s = s[1:]
+ elseif s[0] is# ']'
+ call remove(context, -1)
+ call add(expr, ']')
+ let s = s[1:]
+ elseif s[0] is# '}'
+ call remove(context, -1)
+ if expr[-1] is# "\x5B"
+ call remove(expr, -1)
+ else
+ call add(expr, ']')
+ endif
+ call add(expr, ']}')
+ let s = s[1:]
+ elseif s[0] is# ''''
+ let char = matchstr(s, '\m\C^''\zs.\ze''')
+ if empty(char)
+ throw 'char-invalid:Invalid integer character literal format: ' . s
+ endif
+ call add(expr, char2nr(char))
+ let s = s[len(char) + 2:]
+ else
+ throw 'unknown:Invalid non-space character: ' . s
+ endif
+ endwhile
+ if empty(expr)
+ throw 'empty:Parsed string is empty'
+ endif
+ return eval(join(expr, ''))
+endfunction
+
+""
+" Check whether two msgpack values are equal
+function msgpack#equal(a, b)
+ let atype = msgpack#type(a:a)
+ let btype = msgpack#type(a:b)
+ if atype isnot# btype
+ return 0
+ endif
+ let aspecial = msgpack#special_type(a:a)
+ let bspecial = msgpack#special_type(a:b)
+ if aspecial is# bspecial
+ if aspecial is# 0
+ if type(a:a) == type({})
+ if len(a:a) != len(a:b)
+ return 0
+ endif
+ if !empty(filter(keys(a:a), '!has_key(a:b, v:val)'))
+ return 0
+ endif
+ for [k, v] in items(a:a)
+ if !msgpack#equal(v, a:b[k])
+ return 0
+ endif
+ unlet v
+ endfor
+ return 1
+ elseif type(a:a) == type([])
+ if len(a:a) != len(a:b)
+ return 0
+ endif
+ let i = 0
+ for asubval in a:a
+ if !msgpack#equal(asubval, a:b[i])
+ return 0
+ endif
+ let i += 1
+ unlet asubval
+ endfor
+ return 1
+ elseif type(a:a) == type(0.0)
+ return (a:a == a:a ? a:a == a:b : string(a:a) ==# string(a:b))
+ else
+ return a:a ==# a:b
+ endif
+ elseif aspecial is# 'map' || aspecial is# 'array'
+ if len(a:a._VAL) != len(a:b._VAL)
+ return 0
+ endif
+ let alist = aspecial is# 'map' ? sort(copy(a:a._VAL)) : a:a._VAL
+ let blist = bspecial is# 'map' ? sort(copy(a:b._VAL)) : a:b._VAL
+ let i = 0
+ for asubval in alist
+ let bsubval = blist[i]
+ if aspecial is# 'map'
+ if !(msgpack#equal(asubval[0], bsubval[0])
+ \&& msgpack#equal(asubval[1], bsubval[1]))
+ return 0
+ endif
+ else
+ if !msgpack#equal(asubval, bsubval)
+ return 0
+ endif
+ endif
+ let i += 1
+ unlet asubval
+ unlet bsubval
+ endfor
+ return 1
+ elseif aspecial is# 'nil'
+ return 1
+ elseif aspecial is# 'float'
+ return (a:a._VAL == a:a._VAL
+ \? (a:a._VAL == a:b._VAL)
+ \: (string(a:a._VAL) ==# string(a:b._VAL)))
+ else
+ return a:a._VAL ==# a:b._VAL
+ endif
+ else
+ if atype is# 'array'
+ let a = aspecial is 0 ? a:a : a:a._VAL
+ let b = bspecial is 0 ? a:b : a:b._VAL
+ return msgpack#equal(a, b)
+ elseif atype is# 'binary'
+ let a = (aspecial is 0 ? split(a:a, "\n", 1) : a:a._VAL)
+ let b = (bspecial is 0 ? split(a:b, "\n", 1) : a:b._VAL)
+ return a ==# b
+ elseif atype is# 'map'
+ if aspecial is 0
+ let akeys = copy(a:a)
+ if len(a:b._VAL) != len(akeys)
+ return 0
+ endif
+ for [k, v] in a:b._VAL
+ if msgpack#type(k) isnot# 'string'
+ " Non-special mapping cannot have non-string keys
+ return 0
+ endif
+ if (empty(k._VAL)
+ \|| k._VAL ==# [""]
+ \|| !empty(filter(copy(k._VAL), 'stridx(v:val, "\n") != -1')))
+ " Non-special mapping cannot have zero byte in key or an empty key
+ return 0
+ endif
+ let kstr = join(k._VAL, "\n")
+ if !has_key(akeys, kstr)
+ " Protects from both missing and duplicate keys
+ return 0
+ endif
+ if !msgpack#equal(akeys[kstr], v)
+ return 0
+ endif
+ call remove(akeys, kstr)
+ unlet k
+ unlet v
+ endfor
+ return 1
+ else
+ return msgpack#equal(a:b, a:a)
+ endif
+ elseif atype is# 'float'
+ let a = aspecial is 0 ? a:a : a:a._VAL
+ let b = bspecial is 0 ? a:b : a:b._VAL
+ return (a == a ? a == b : string(a) ==# string(b))
+ elseif atype is# 'integer'
+ if aspecial is 0
+ let sign = a:a >= 0 ? 1 : -1
+ let a = sign * a:a
+ let v1 = s:mask1(s:shift(a, -62), 2)
+ let v2 = s:mask1(s:shift(a, -31), 31)
+ let v3 = s:mask1(a, 31)
+ return [sign, v1, v2, v3] == a:b._VAL
+ else
+ return msgpack#equal(a:b, a:a)
+ endif
+ else
+ throw printf('internal-invalid-type: %s == %s, but special %s /= %s',
+ \atype, btype, aspecial, bspecial)
+ endif
+ endif
+endfunction
diff --git a/runtime/autoload/shada.vim b/runtime/autoload/shada.vim
new file mode 100644
index 0000000000..9be85b6f2e
--- /dev/null
+++ b/runtime/autoload/shada.vim
@@ -0,0 +1,696 @@
+if exists('g:loaded_shada_autoload')
+ finish
+endif
+let g:loaded_shada_autoload = 1
+
+""
+" If true keep the old header entry when editing existing ShaDa file.
+"
+" Old header entry will be kept only if it is listed in the opened file. To
+" remove old header entry despite of the setting just remove it from the
+" listing. Setting it to false makes plugin ignore all header entries. Defaults
+" to 1.
+let g:shada#keep_old_header = get(g:, 'shada#keep_old_header', 1)
+
+""
+" If true then first entry will be plugin’s own header entry.
+let g:shada#add_own_header = get(g:, 'shada#add_own_header', 1)
+
+""
+" Dictionary that maps ShaDa types to their names.
+let s:SHADA_ENTRY_NAMES = {
+ \1: 'header',
+ \2: 'search_pattern',
+ \3: 'replacement_string',
+ \4: 'history_entry',
+ \5: 'register',
+ \6: 'variable',
+ \7: 'global_mark',
+ \8: 'jump',
+ \9: 'buffer_list',
+ \10: 'local_mark',
+ \11: 'change',
+\}
+
+""
+" Dictionary that maps ShaDa names to corresponding types
+let s:SHADA_ENTRY_TYPES = {}
+call map(copy(s:SHADA_ENTRY_NAMES),
+ \'extend(s:SHADA_ENTRY_TYPES, {v:val : +v:key})')
+
+""
+" Map that maps entry names to lists of keys that can be used by this entry.
+" Only contains data for entries which are represented as mappings, except for
+" the header.
+let s:SHADA_MAP_ENTRIES = {
+ \'search_pattern': ['sp', 'sh', 'ss', 'sb', 'sm', 'sc', 'sl', 'se', 'so',
+ \ 'su'],
+ \'register': ['n', 'rc', 'rw', 'rt'],
+ \'global_mark': ['n', 'f', 'l', 'c'],
+ \'local_mark': ['f', 'n', 'l', 'c'],
+ \'jump': ['f', 'l', 'c'],
+ \'change': ['f', 'l', 'c'],
+ \'header': [],
+\}
+
+""
+" Like one of the values from s:SHADA_MAP_ENTRIES, but for a single buffer in
+" buffer list entry.
+let s:SHADA_BUFFER_LIST_KEYS = ['f', 'l', 'c']
+
+""
+" List of possible history types. Maps integer values that represent history
+" types to human-readable names.
+let s:SHADA_HISTORY_TYPES = ['command', 'search', 'expression', 'input', 'debug']
+
+""
+" Map that maps entry names to their descriptions. Only for entries which have
+" list as a data type. Description is a list of lists where each entry has item
+" description and item type.
+let s:SHADA_FIXED_ARRAY_ENTRIES = {
+ \'replacement_string': [[':s replacement string', 'bin']],
+ \'history_entry': [
+ \['history type', 'histtype'],
+ \['contents', 'bin'],
+ \['separator', 'intchar'],
+ \],
+ \'variable': [['name', 'bin'], ['value', 'any']],
+\}
+
+""
+" Dictionary that maps enum names to dictionary with enum values. Dictionary
+" with enum values maps enum human-readable names to corresponding values. Enums
+" are used as type names in s:SHADA_FIXED_ARRAY_ENTRIES and
+" s:SHADA_STANDARD_KEYS.
+let s:SHADA_ENUMS = {
+ \'histtype': {
+ \'CMD': 0,
+ \'SEARCH': 1,
+ \'EXPR': 2,
+ \'INPUT': 3,
+ \'DEBUG': 4,
+ \},
+ \'regtype': {
+ \'CHARACTERWISE': 0,
+ \'LINEWISE': 1,
+ \'BLOCKWISE': 2,
+ \}
+\}
+
+""
+" Second argument to msgpack#eval.
+let s:SHADA_SPECIAL_OBJS = {}
+call map(values(s:SHADA_ENUMS),
+ \'extend(s:SHADA_SPECIAL_OBJS, map(copy(v:val), "string(v:val)"))')
+
+""
+" Like s:SHADA_ENUMS, but inner dictionary maps values to names and not names to
+" values.
+let s:SHADA_REV_ENUMS = map(copy(s:SHADA_ENUMS), '{}')
+call map(copy(s:SHADA_ENUMS),
+ \'map(copy(v:val), '
+ \. '"extend(s:SHADA_REV_ENUMS[" . string(v:key) . "], '
+ \. '{v:val : v:key})")')
+
+""
+" Maximum length of ShaDa entry name. Used to arrange entries to the table.
+let s:SHADA_MAX_ENTRY_LENGTH = max(
+ \map(values(s:SHADA_ENTRY_NAMES), 'len(v:val)')
+ \+ [len('unknown (0x)') + 16])
+
+""
+" Object that marks required value.
+let s:SHADA_REQUIRED = []
+
+""
+" Dictionary that maps default key names to their description. Description is
+" a list that contains human-readable hint, key type and default value.
+let s:SHADA_STANDARD_KEYS = {
+ \'sm': ['magic value', 'boolean', g:msgpack#true],
+ \'sc': ['smartcase value', 'boolean', g:msgpack#false],
+ \'sl': ['has line offset', 'boolean', g:msgpack#false],
+ \'se': ['place cursor at end', 'boolean', g:msgpack#false],
+ \'so': ['offset value', 'integer', 0],
+ \'su': ['is last used', 'boolean', g:msgpack#true],
+ \'ss': ['is :s pattern', 'boolean', g:msgpack#false],
+ \'sh': ['v:hlsearch value', 'boolean', g:msgpack#false],
+ \'sp': ['pattern', 'bin', s:SHADA_REQUIRED],
+ \'sb': ['search backward', 'boolean', g:msgpack#false],
+ \'rt': ['type', 'regtype', s:SHADA_ENUMS.regtype.CHARACTERWISE],
+ \'rw': ['block width', 'uint', 0],
+ \'rc': ['contents', 'binarray', s:SHADA_REQUIRED],
+ \'n': ['name', 'intchar', char2nr('"')],
+ \'l': ['line number', 'uint', 1],
+ \'c': ['column', 'uint', 0],
+ \'f': ['file name', 'bin', s:SHADA_REQUIRED],
+\}
+
+""
+" Set of entry types containing entries which require `n` key.
+let s:SHADA_REQUIRES_NAME = {'local_mark': 1, 'global_mark': 1, 'register': 1}
+
+""
+" Maximum width of human-readable hint. Used to arrange data in table.
+let s:SHADA_MAX_HINT_WIDTH = max(map(values(s:SHADA_STANDARD_KEYS),
+ \'len(v:val[0])'))
+
+""
+" Default mark name for the cases when it makes sense (i.e. for local marks).
+let s:SHADA_DEFAULT_MARK_NAME = '"'
+
+""
+" Mapping that maps timestamps represented using msgpack#string to strftime
+" output. Used by s:shada_strftime.
+let s:shada_strftime_cache = {}
+
+""
+" Mapping that maps strftime output from s:shada_strftime to timestamps.
+let s:shada_strptime_cache = {}
+
+""
+" Time format used for displaying ShaDa files.
+let s:SHADA_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S'
+
+""
+" Wrapper around msgpack#strftime that caches its output.
+"
+" Format is hardcoded to s:SHADA_TIME_FORMAT.
+function s:shada_strftime(timestamp) abort
+ let key = msgpack#string(a:timestamp)
+ if has_key(s:shada_strftime_cache, key)
+ return s:shada_strftime_cache[key]
+ endif
+ let val = msgpack#strftime(s:SHADA_TIME_FORMAT, a:timestamp)
+ let s:shada_strftime_cache[key] = val
+ let s:shada_strptime_cache[val] = a:timestamp
+ return val
+endfunction
+
+""
+" Wrapper around msgpack#strftime that uses cache created by s:shada_strftime().
+"
+" Also caches its own results. Format is hardcoded to s:SHADA_TIME_FORMAT.
+function s:shada_strptime(string) abort
+ if has_key(s:shada_strptime_cache, a:string)
+ return s:shada_strptime_cache[a:string]
+ endif
+ let ts = msgpack#strptime(s:SHADA_TIME_FORMAT, a:string)
+ let s:shada_strptime_cache[a:string] = ts
+ return ts
+endfunction
+
+""
+" Check whether given value matches given type.
+"
+" @return Zero if value matches, error message string if it does not.
+function s:shada_check_type(type, val) abort
+ let type = msgpack#type(a:val)
+ if type is# a:type
+ return 0
+ endif
+ if has_key(s:SHADA_ENUMS, a:type)
+ let msg = s:shada_check_type('uint', a:val)
+ if msg isnot 0
+ return msg
+ endif
+ if !has_key(s:SHADA_REV_ENUMS[a:type], a:val)
+ let evals_msg = join(map(sort(items(s:SHADA_REV_ENUMS[a:type])),
+ \'v:val[0] . " (" . v:val[1] . ")"'), ', ')
+ return 'Unexpected enum value: expected one of ' . evals_msg
+ endif
+ return 0
+ elseif a:type is# 'uint'
+ if type isnot# 'integer'
+ return 'Expected integer'
+ endif
+ if !(type(a:val) == type({}) ? a:val._VAL[0] == 1 : a:val >= 0)
+ return 'Value is negative'
+ endif
+ return 0
+ elseif a:type is# 'bin'
+ " Binary string without zero bytes
+ if type isnot# 'binary'
+ return 'Expected binary string'
+ elseif (type(a:val) == type({})
+ \&& !empty(filter(copy(a:val._VAL), 'stridx(v:val, "\n") != -1')))
+ return 'Expected no NUL bytes'
+ endif
+ return 0
+ elseif a:type is# 'intchar'
+ let msg = s:shada_check_type('uint', a:val)
+ if msg isnot# 0
+ return msg
+ endif
+ if a:val > 0 || a:val < 1
+ endif
+ return 0
+ elseif a:type is# 'binarray'
+ if type isnot# 'array'
+ return 'Expected array value'
+ elseif !empty(filter(copy(type(a:val) == type({}) ? a:val._VAL : a:val),
+ \'msgpack#type(v:val) isnot# "binary"'))
+ return 'Expected array of binary strings'
+ else
+ for element in (type(a:val) == type({}) ? a:val._VAL : a:val)
+ if (type(element) == type({})
+ \&& !empty(filter(copy(element._VAL), 'stridx(v:val, "\n") != -1')))
+ return 'Expected no NUL bytes'
+ endif
+ unlet element
+ endfor
+ endif
+ return 0
+ elseif a:type is# 'boolean'
+ return 'Expected boolean'
+ elseif a:type is# 'integer'
+ return 'Expected integer'
+ elseif a:type is# 'any'
+ return 0
+ endif
+ return 'Internal error: unknown type ' . a:type
+endfunction
+
+""
+" Convert msgpack mapping object to a list of strings for
+" s:shada_convert_entry().
+"
+" @param[in] map Mapping to convert.
+" @param[in] default_keys List of keys which have default value in this
+" mapping.
+" @param[in] name Name of the converted entry.
+function s:shada_convert_map(map, default_keys, name) abort
+ let ret = []
+ let keys = copy(a:default_keys)
+ call map(sort(keys(a:map)), 'index(keys, v:val) == -1 ? add(keys, v:val) : 0')
+ let descriptions = map(copy(keys),
+ \'get(s:SHADA_STANDARD_KEYS, v:val, ["", 0, 0])')
+ let max_key_len = max(map(copy(keys), 'len(v:val)'))
+ let max_desc_len = max(map(copy(descriptions),
+ \'v:val[0] is 0 ? 0 : len(v:val[0])'))
+ if max_key_len < len('Key')
+ let max_key_len = len('Key')
+ endif
+ let key_header = 'Key' . repeat('_', max_key_len - len('Key'))
+ if max_desc_len == 0
+ call add(ret, printf(' %% %s %s', key_header, 'Value'))
+ else
+ if max_desc_len < len('Description')
+ let max_desc_len = len('Description')
+ endif
+ let desc_header = ('Description'
+ \. repeat('_', max_desc_len - len('Description')))
+ call add(ret, printf(' %% %s %s %s', key_header, desc_header, 'Value'))
+ endif
+ let i = 0
+ for key in keys
+ let [description, type, default] = descriptions[i]
+ if a:name isnot# 'local_mark' && key is# 'n'
+ unlet default
+ let default = s:SHADA_REQUIRED
+ endif
+ let value = get(a:map, key, default)
+ if (key is# 'n' && !has_key(s:SHADA_REQUIRES_NAME, a:name)
+ \&& value is# s:SHADA_REQUIRED)
+ " Do nothing
+ elseif value is s:SHADA_REQUIRED
+ call add(ret, ' # Required key missing: ' . key)
+ elseif max_desc_len == 0
+ call add(ret, printf(' + %-*s %s',
+ \max_key_len, key,
+ \msgpack#string(value)))
+ else
+ if type isnot 0 && value isnot# default
+ let msg = s:shada_check_type(type, value)
+ if msg isnot 0
+ call add(ret, ' # ' . msg)
+ endif
+ endif
+ let strval = s:shada_string(type, value)
+ if msgpack#type(value) is# 'array' && msg is 0
+ let shift = 2 + 2 + max_key_len + 2 + max_desc_len + 2
+ " Value: 1 2 3 4 5 6:
+ " " + Key Description Value"
+ " 1122333445555555555566
+ if shift + strdisplaywidth(strval, shift) > 80
+ let strval = '@'
+ endif
+ endif
+ call add(ret, printf(' + %-*s %-*s %s',
+ \max_key_len, key,
+ \max_desc_len, description,
+ \strval))
+ if strval is '@'
+ for v in value
+ call add(ret, printf(' | - %s', msgpack#string(v)))
+ unlet v
+ endfor
+ endif
+ endif
+ let i += 1
+ unlet value
+ unlet default
+ endfor
+ return ret
+endfunction
+
+""
+" Wrapper around msgpack#string() which may return string from s:SHADA_REV_ENUMS
+function s:shada_string(type, v) abort
+ if (has_key(s:SHADA_ENUMS, a:type) && type(a:v) == type(0)
+ \&& has_key(s:SHADA_REV_ENUMS[a:type], a:v))
+ return s:SHADA_REV_ENUMS[a:type][a:v]
+ elseif (a:type is# 'intchar' && type(a:v) == type(0)
+ \&& strtrans(nr2char(a:v)) is# nr2char(a:v))
+ return "'" . nr2char(a:v) . "'"
+ else
+ return msgpack#string(a:v)
+ endif
+endfunction
+
+""
+" Evaluate string obtained by s:shada_string().
+function s:shada_eval(s) abort
+ return msgpack#eval(a:s, s:SHADA_SPECIAL_OBJS)
+endfunction
+
+""
+" Convert one ShaDa entry to a list of strings suitable for setline().
+"
+" Returned format looks like this:
+"
+" TODO
+function s:shada_convert_entry(entry) abort
+ if type(a:entry.type) == type({})
+ " |msgpack-special-dict| may only be used if value does not fit into the
+ " default integer type. All known entry types do fit, so it is definitely
+ " unknown entry.
+ let name = 'unknown_(' . msgpack#int_dict_to_str(a:entry.type) . ')'
+ else
+ let name = get(s:SHADA_ENTRY_NAMES, a:entry.type, 0)
+ if name is 0
+ let name = printf('unknown_(0x%x)', a:entry.type)
+ endif
+ endif
+ let title = toupper(name[0]) . tr(name[1:], '_', ' ')
+ let header = printf('%s with timestamp %s:', title,
+ \s:shada_strftime(a:entry.timestamp))
+ let ret = [header]
+ if name[:8] is# 'unknown_(' && name[-1:] is# ')'
+ call add(ret, ' = ' . msgpack#string(a:entry.data))
+ elseif has_key(s:SHADA_FIXED_ARRAY_ENTRIES, name)
+ if type(a:entry.data) != type([])
+ call add(ret, printf(' # Unexpected type: %s instead of array',
+ \msgpack#type(a:entry.data)))
+ call add(ret, ' = ' . msgpack#string(a:entry.data))
+ return ret
+ endif
+ let i = 0
+ let max_desc_len = max(map(copy(s:SHADA_FIXED_ARRAY_ENTRIES[name]),
+ \'len(v:val[0])'))
+ if max_desc_len < len('Description')
+ let max_desc_len = len('Description')
+ endif
+ let desc_header = ('Description'
+ \. repeat('_', max_desc_len - len('Description')))
+ call add(ret, printf(' @ %s %s', desc_header, 'Value'))
+ for value in a:entry.data
+ let [desc, type] = get(s:SHADA_FIXED_ARRAY_ENTRIES[name], i, ['', 0])
+ if (i == 2 && name is# 'history_entry'
+ \&& a:entry.data[0] isnot# s:SHADA_ENUMS.histtype.SEARCH)
+ let [desc, type] = ['', 0]
+ endif
+ if type isnot 0
+ let msg = s:shada_check_type(type, value)
+ if msg isnot 0
+ call add(ret, ' # ' . msg)
+ endif
+ endif
+ call add(ret, printf(' - %-*s %s', max_desc_len, desc,
+ \s:shada_string(type, value)))
+ let i += 1
+ unlet value
+ endfor
+ if (len(a:entry.data) < len(s:SHADA_FIXED_ARRAY_ENTRIES[name])
+ \&& !(name is# 'history_entry'
+ \&& len(a:entry.data) == 2
+ \&& a:entry.data[0] isnot# s:SHADA_ENUMS.histtype.SEARCH))
+ call add(ret, ' # Expected more elements in list')
+ endif
+ elseif has_key(s:SHADA_MAP_ENTRIES, name)
+ if type(a:entry.data) != type({})
+ call add(ret, printf(' # Unexpected type: %s instead of map',
+ \msgpack#type(a:entry.data)))
+ call add(ret, ' = ' . msgpack#string(a:entry.data))
+ return ret
+ endif
+ if msgpack#special_type(a:entry.data) isnot 0
+ call add(ret, ' # Entry is a special dict which is unexpected')
+ call add(ret, ' = ' . msgpack#string(a:entry.data))
+ return ret
+ endif
+ let ret += s:shada_convert_map(a:entry.data, s:SHADA_MAP_ENTRIES[name],
+ \name)
+ elseif name is# 'buffer_list'
+ if type(a:entry.data) != type([])
+ call add(ret, printf(' # Unexpected type: %s instead of array',
+ \msgpack#type(a:entry.data)))
+ call add(ret, ' = ' . msgpack#string(a:entry.data))
+ return ret
+ elseif !empty(filter(copy(a:entry.data),
+ \'type(v:val) != type({}) '
+ \. '|| msgpack#special_type(v:val) isnot 0'))
+ call add(ret, ' # Expected array of maps')
+ call add(ret, ' = ' . msgpack#string(a:entry.data))
+ return ret
+ endif
+ for bufdef in a:entry.data
+ if bufdef isnot a:entry.data[0]
+ call add(ret, '')
+ endif
+ let ret += s:shada_convert_map(bufdef, s:SHADA_BUFFER_LIST_KEYS, name)
+ endfor
+ else
+ throw 'internal-unknown-type:Internal error: unknown type name: ' . name
+ endif
+ return ret
+endfunction
+
+""
+" Order of msgpack objects in one ShaDa entry. Each item in the list is name of
+" the key in dictionaries returned by shada#read().
+let s:SHADA_ENTRY_OBJECT_SEQUENCE = ['type', 'timestamp', 'length', 'data']
+
+""
+" Convert list returned by msgpackparse() to a list of ShaDa objects
+"
+" @param[in] mpack List of VimL objects returned by msgpackparse().
+"
+" @return List of dictionaries with keys type, timestamp, length and data. Each
+" dictionary describes one ShaDa entry.
+function shada#mpack_to_sd(mpack) abort
+ let ret = []
+ let i = 0
+ for element in a:mpack
+ let key = s:SHADA_ENTRY_OBJECT_SEQUENCE[
+ \i % len(s:SHADA_ENTRY_OBJECT_SEQUENCE)]
+ if key is# 'type'
+ call add(ret, {})
+ endif
+ let ret[-1][key] = element
+ if key isnot# 'data'
+ if !msgpack#is_uint(element)
+ throw printf('not-uint:Entry %i has %s element '.
+ \'which is not an unsigned integer',
+ \len(ret), key)
+ endif
+ if key is# 'type' && msgpack#equal(element, 0)
+ throw printf('zero-uint:Entry %i has %s element '.
+ \'which is zero',
+ \len(ret), key)
+ endif
+ endif
+ let i += 1
+ unlet element
+ endfor
+ return ret
+endfunction
+
+""
+" Convert read ShaDa file to a list of lines suitable for setline()
+"
+" @param[in] shada List of ShaDa entries like returned by shada#mpack_to_sd().
+"
+" @return List of strings suitable for setline()-like functions.
+function shada#sd_to_strings(shada) abort
+ let ret = []
+ for entry in a:shada
+ let ret += s:shada_convert_entry(entry)
+ endfor
+ return ret
+endfunction
+
+""
+" Convert a readfile()-like list of strings to a list of lines suitable for
+" setline().
+"
+" @param[in] binstrings List of strings to convert.
+"
+" @return List of lines.
+function shada#get_strings(binstrings) abort
+ return shada#sd_to_strings(shada#mpack_to_sd(msgpackparse(a:binstrings)))
+endfunction
+
+""
+" Convert s:shada_convert_entry() output to original entry.
+function s:shada_convert_strings(strings) abort
+ let strings = copy(a:strings)
+ let match = matchlist(
+ \strings[0],
+ \'\v\C^(.{-})\m with timestamp \(\d\{4}-\d\d-\d\dT\d\d:\d\d:\d\d\):$')
+ if empty(match)
+ throw 'invalid-header:Header has invalid format: ' . strings[0]
+ endif
+ call remove(strings, 0)
+ let title = match[1]
+ let name = tolower(title[0]) . tr(title[1:], ' ', '_')
+ let ret = {}
+ let empty_default = g:msgpack#nil
+ if name[:8] is# 'unknown_(' && name[-1:] is# ')'
+ let ret.type = +name[9:-2]
+ elseif has_key(s:SHADA_ENTRY_TYPES, name)
+ let ret.type = s:SHADA_ENTRY_TYPES[name]
+ if has_key(s:SHADA_MAP_ENTRIES, name)
+ unlet empty_default
+ let empty_default = {}
+ elseif has_key(s:SHADA_FIXED_ARRAY_ENTRIES, name) || name is# 'buffer_list'
+ unlet empty_default
+ let empty_default = []
+ endif
+ else
+ throw 'invalid-type:Unknown type ' . name
+ endif
+ let ret.timestamp = s:shada_strptime(match[2])
+ if empty(strings)
+ let ret.data = empty_default
+ else
+ while !empty(strings)
+ if strings[0][2] is# '='
+ let data = s:shada_eval(strings[0][4:])
+ call remove(strings, 0)
+ elseif strings[0][2] is# '%'
+ if name is# 'buffer_list' && !has_key(ret, 'data')
+ let ret.data = []
+ endif
+ let match = matchlist(
+ \strings[0],
+ \'\m\C^ % \(Key_*\)\( Description_*\)\? Value')
+ if empty(match)
+ throw 'invalid-map-header:Invalid mapping header: ' . strings[0]
+ endif
+ call remove(strings, 0)
+ let key_len = len(match[1])
+ let desc_skip_len = len(match[2])
+ let data = {'_TYPE': v:msgpack_types.map, '_VAL': []}
+ while !empty(strings) && strings[0][2] is# '+'
+ let line = remove(strings, 0)[4:]
+ let key = substitute(line[:key_len - 1], '\v\C\ *$', '', '')
+ let strval = line[key_len + desc_skip_len + 2:]
+ if strval is# '@'
+ let val = []
+ while !empty(strings) && strings[0][2] is# '|'
+ if strings[0][4] isnot# '-'
+ throw ('invalid-array:Expected hyphen-minus at column 5: '
+ \. strings)
+ endif
+ call add(val, s:shada_eval(remove(strings, 0)[5:]))
+ endwhile
+ else
+ let val = s:shada_eval(strval)
+ endif
+ if (has_key(s:SHADA_STANDARD_KEYS, key)
+ \&& s:SHADA_STANDARD_KEYS[key][2] isnot# s:SHADA_REQUIRED
+ \&& msgpack#equal(s:SHADA_STANDARD_KEYS[key][2], val))
+ unlet val
+ continue
+ endif
+ call add(data._VAL, [{'_TYPE': v:msgpack_types.string, '_VAL': [key]},
+ \val])
+ unlet val
+ endwhile
+ elseif strings[0][2] is# '@'
+ let match = matchlist(
+ \strings[0],
+ \'\m\C^ @ \(Description_* \)\?Value')
+ if empty(match)
+ throw 'invalid-array-header:Invalid array header: ' . strings[0]
+ endif
+ call remove(strings, 0)
+ let desc_skip_len = len(match[1])
+ let data = []
+ while !empty(strings) && strings[0][2] is# '-'
+ let val = remove(strings, 0)[4 + desc_skip_len :]
+ call add(data, s:shada_eval(val))
+ endwhile
+ else
+ throw 'invalid-line:Unrecognized line: ' . strings[0]
+ endif
+ if !has_key(ret, 'data')
+ let ret.data = data
+ elseif type(ret.data) == type([])
+ call add(ret.data, data)
+ else
+ let ret.data = [ret.data, data]
+ endif
+ unlet data
+ endwhile
+ endif
+ let ret._data = msgpackdump([ret.data])
+ let ret.length = len(ret._data) - 1
+ for s in ret._data
+ let ret.length += len(s)
+ endfor
+ return ret
+endfunction
+
+""
+" Convert s:shada_sd_to_strings() output to a list of original entries.
+function shada#strings_to_sd(strings) abort
+ let strings = filter(copy(a:strings), 'v:val !~# ''\v^\s*%(\#|$)''')
+ let stringss = []
+ for string in strings
+ if string[0] isnot# ' '
+ call add(stringss, [])
+ endif
+ call add(stringss[-1], string)
+ endfor
+ return map(copy(stringss), 's:shada_convert_strings(v:val)')
+endfunction
+
+""
+" Convert a list of strings to list of strings suitable for writefile().
+function shada#get_binstrings(strings) abort
+ let entries = shada#strings_to_sd(a:strings)
+ if !g:shada#keep_old_header
+ call filter(entries, 'v:val.type != ' . s:SHADA_ENTRY_TYPES.header)
+ endif
+ if g:shada#add_own_header
+ let data = {'version': v:version, 'generator': 'shada.vim'}
+ let dumped_data = msgpackdump([data])
+ let length = len(dumped_data) - 1
+ for s in dumped_data
+ let length += len(s)
+ endfor
+ call insert(entries, {
+ \'type': s:SHADA_ENTRY_TYPES.header,
+ \'timestamp': localtime(),
+ \'length': length,
+ \'data': data,
+ \'_data': dumped_data,
+ \})
+ endif
+ let mpack = []
+ for entry in entries
+ let mpack += map(copy(s:SHADA_ENTRY_OBJECT_SEQUENCE), 'entry[v:val]')
+ endfor
+ return msgpackdump(mpack)
+endfunction
diff --git a/runtime/doc/develop.txt b/runtime/doc/develop.txt
index d0dd741888..668790358b 100644
--- a/runtime/doc/develop.txt
+++ b/runtime/doc/develop.txt
@@ -10,11 +10,9 @@ This text is important for those who want to be involved in further developing
Vim.
1. Design goals |design-goals|
-2. Coding style |coding-style|
-3. Design decisions |design-decisions|
-4. Assumptions |design-assumptions|
+2. Design decisions |design-decisions|
-See the file README.txt in the "src" directory for an overview of the source
+See the file "src/nvim/README.md" for a high-level overview of the source
code.
Vim is open source software. Everybody is encouraged to contribute to help
@@ -30,28 +28,6 @@ Note that quite a few items are contradicting. This is intentional. A
balance must be found between them.
-VIM IS... VI COMPATIBLE *design-compatible*
-
-First of all, it should be possible to use Vim as a drop-in replacement for
-Vi. When the user wants to, he can use Vim in compatible mode and hardly
-notice any difference with the original Vi.
-
-Exceptions:
-- We don't reproduce obvious Vi bugs in Vim.
-- There are different versions of Vi. I am using Version 3.7 (6/7/85) as a
- reference. But support for other versions is also included when possible.
- The Vi part of POSIX is not considered a definitive source.
-- Vim adds new commands, you cannot rely on some command to fail because it
- didn't exist in Vi.
-- Vim will have a lot of features that Vi doesn't have. Going back from Vim
- to Vi will be a problem, this cannot be avoided.
-- Some things are hardly ever used (open mode, sending an e-mail when
- crashing, etc.). Those will only be included when someone has a good reason
- why it should be included and it's not too much work.
-- For some items it is debatable whether Vi compatibility should be
- maintained. There will be an option flag for these.
-
-
VIM IS... IMPROVED *design-improved*
The IMproved bits of Vim should make it a better Vi, without becoming a
@@ -122,7 +98,6 @@ fast.
VIM IS... MAINTAINABLE *design-maintain*
- The source code should not become a mess. It should be reliable code.
-- Use the same layout in all files to make it easy to read |coding-style|.
- Use comments in a useful way! Quoting the function name and argument names
is NOT useful. Do explain what they are for.
- Porting to another platform should be made easy, without having to change
@@ -149,202 +124,7 @@ for plumbing."
==============================================================================
-2. Coding style *coding-style*
-
-These are the rules to use when making changes to the Vim source code. Please
-stick to these rules, to keep the sources readable and maintainable.
-
-This list is not complete. Look in the source code for more examples.
-
-
-MAKING CHANGES *style-changes*
-
-The basic steps to make changes to the code:
-1. Adjust the documentation. Doing this first gives you an impression of how
- your changes affect the user.
-2. Make the source code changes.
-3. Check ../doc/todo.txt if the change affects any listed item.
-4. Make a patch with "diff -c" against the unmodified code and docs.
-5. Make a note about what changed and include it with the patch.
-
-
-USE OF COMMON FUNCTIONS *style-functions*
-
-Some functions that are common to use, have a special Vim version. Always
-consider using the Vim version, because they were introduced with a reason.
-
-NORMAL NAME VIM NAME DIFFERENCE OF VIM VERSION
-free() vim_free() Checks for freeing NULL
-malloc() alloc() Checks for out of memory situation
-malloc() lalloc() Like alloc(), but has long argument
-strcpy() STRCPY() Includes cast to (char *), for char_u * args
-strchr() vim_strchr() Accepts special characters
-strrchr() vim_strrchr() Accepts special characters
-isspace() ascii_isspace() Can handle characters > 128
-iswhite() ascii_iswhite() Only true for tab and space
-memcpy() mch_memmove() Handles overlapped copies
-bcopy() mch_memmove() Handles overlapped copies
-memset() vim_memset() Uniform for all systems
-
-
-NAMES *style-names*
-
-Function names can not be more than 31 characters long (because of VMS).
-
-Don't use "delete" as a variable name, C++ doesn't like it.
-
-Because of the requirement that Vim runs on as many systems as possible, we
-need to avoid using names that are already defined by the system. This is a
-list of names that are known to cause trouble. The name is given as a regexp
-pattern.
-
-is.*() POSIX, ctype.h
-to.*() POSIX, ctype.h
-
-d_.* POSIX, dirent.h
-l_.* POSIX, fcntl.h
-gr_.* POSIX, grp.h
-pw_.* POSIX, pwd.h
-sa_.* POSIX, signal.h
-mem.* POSIX, string.h
-str.* POSIX, string.h
-wcs.* POSIX, string.h
-st_.* POSIX, stat.h
-tms_.* POSIX, times.h
-tm_.* POSIX, time.h
-c_.* POSIX, termios.h
-MAX.* POSIX, limits.h
-__.* POSIX, system
-_[A-Z].* POSIX, system
-E[A-Z0-9]* POSIX, errno.h
-
-.*_t POSIX, for typedefs. Use .*_T instead.
-
-wait don't use as argument to a function, conflicts with types.h
-index shadows global declaration
-time shadows global declaration
-new C++ reserved keyword
-try Borland C++ doesn't like it to be used as a variable.
-
-clear Mac curses.h
-echo Mac curses.h
-instr Mac curses.h
-meta Mac curses.h
-newwin Mac curses.h
-nl Mac curses.h
-overwrite Mac curses.h
-refresh Mac curses.h
-scroll Mac curses.h
-typeahead Mac curses.h
-
-basename() GNU string function
-dirname() GNU string function
-get_env_value() Linux system function
-
-
-VARIOUS *style-various*
-
-Typedef'ed names should end in "_T": >
- typedef int some_T;
-Define'ed names should be uppercase: >
- #define SOME_THING
-Features always start with "FEAT_": >
- #define FEAT_FOO
-
-Don't use '\"', some compilers can't handle it. '"' works fine.
-
-Don't use:
- #if HAVE_SOME
-Some compilers can't handle that and complain that "HAVE_SOME" is not defined.
-Use
- #ifdef HAVE_SOME
-or
- #if defined(HAVE_SOME)
-
-
-STYLE *style-examples*
-
-General rule: One statement per line.
-
-Wrong: if (cond) a = 1;
-
-OK: if (cond)
- a = 1;
-
-Wrong: while (cond);
-
-OK: while (cond)
- ;
-
-Wrong: do a = 1; while (cond);
-
-OK: do
- a = 1;
- while (cond);
-
-
-Functions start with:
-
-Wrong: int function_name(int arg1, int arg2)
-
-OK: /*
- * Explanation of what this function is used for.
- *
- * Return value explanation.
- */
- int
- function_name(arg1, arg2)
- int arg1; /* short comment about arg1 */
- int arg2; /* short comment about arg2 */
- {
- int local; /* comment about local */
-
- local = arg1 * arg2;
-
-NOTE: Don't use ANSI style function declarations. A few people still have to
-use a compiler that doesn't support it.
-
-
-SPACES AND PUNCTUATION *style-spaces*
-
-No space between a function name and the bracket:
-
-Wrong: func (arg);
-OK: func(arg);
-
-Do use a space after if, while, switch, etc.
-
-Wrong: if(arg) for(;;)
-OK: if (arg) for (;;)
-
-Use a space after a comma and semicolon:
-
-Wrong: func(arg1,arg2); for (i = 0;i < 2;++i)
-OK: func(arg1, arg2); for (i = 0; i < 2; ++i)
-
-Use a space before and after '=', '+', '/', etc.
-
-Wrong: var=a*5;
-OK: var = a * 5;
-
-In general: Use empty lines to group lines of code together. Put a comment
-just above the group of lines. This makes it easier to quickly see what is
-being done.
-
-OK: /* Prepare for building the table. */
- get_first_item();
- table_idx = 0;
-
- /* Build the table */
- while (has_item())
- table[table_idx++] = next_item();
-
- /* Finish up. */
- cleanup_items();
- generate_hash(table);
-
-==============================================================================
-3. Design decisions *design-decisions*
+2. Design decisions *design-decisions*
Folding
@@ -479,17 +259,4 @@ This isn't ideal, because the longer Vim is running the higher the counts
become. But in practice it is a noticeable improvement over not using the word
count.
-==============================================================================
-4. Assumptions *design-assumptions*
-
-Size of variables:
-char 8 bit signed
-char_u 8 bit unsigned
-int 32 or 64 bit signed (16 might be possible with limited features)
-unsigned 32 or 64 bit unsigned (16 as with ints)
-long 32 or 64 bit signed, can hold a pointer
-
-Note that some compilers cannot handle long lines or strings. The C89
-standard specifies a limit of 509 characters.
-
vim:tw=78:ts=8:ft=help:norl:
diff --git a/runtime/doc/filetype.txt b/runtime/doc/filetype.txt
index d1f8b1de4c..baf7550948 100644
--- a/runtime/doc/filetype.txt
+++ b/runtime/doc/filetype.txt
@@ -557,6 +557,149 @@ Since the text for this plugin is rather long it has been put in a separate
file: |pi_spec.txt|.
+SHADA *ft-shada*
+
+Allows editing binary |shada-file|s in a nice way. Opened binary files are
+displayed in the following format: >
+
+ Type with timestamp YYYY-mm-ddTHH:MM:SS:
+ % Key__ Description___ Value
+ + fooba foo bar baz fo {msgpack-value}
+ + abcde abc def ghi jk {msgpack-value}
+ Other type with timestamp YYYY-mm-ddTHH:MM:SS:
+ @ Description__ Value
+ - foo bar baz t {msgpack-value}
+ # Expected more elements in list
+ Some other type with timestamp YYYY-mm-ddTHH:MM:SS:
+ # Unexpected type: type instead of map
+ = {msgpack-value}
+
+Filetype plugin defines all |Cmd-event|s. Defined |SourceCmd| event makes
+"source file.shada" be equivalent to "|:rshada| file.shada". |BufWriteCmd|,
+|FileWriteCmd| and |FileAppendCmd| events are affected by the following
+settings:
+
+*g:shada#keep_old_header* Boolean, if set to false all header entries
+ are ignored when writing. Defaults to 1.
+*g:shada#add_own_header* Boolean, if set to true first written entry
+ will always be header entry with two values in
+ a map with attached data: |v:version| attached
+ to "version" key and "shada.vim" attached to
+ "generator" key. Defaults to 1.
+
+Format description:
+
+1. `#` starts a comment. Lines starting with space characters and then `#`
+ are ignored. Plugin may only add comment lines to indicate some errors in
+ ShaDa format. Lines containing no non-whitespace characters are also
+ ignored.
+2. Each entry starts with line that has format "{type} with timestamp
+ {timestamp}:". {timestamp} is |strftime()|-formatted string representing
+ actual UNIX timestamp value. First strftime() argument is equal to
+ `%Y-%m-%dT%H:%M:%S`. When writing this timestamp is parsed using
+ |msgpack#strptime()|, with caching (it remembers which timestamp produced
+ particular strftime() output and uses this value if you did not change
+ timestamp). {type} is one of
+ 1 - Header
+ 2 - Search pattern
+ 3 - Replacement string
+ 4 - History entry
+ 5 - Register
+ 6 - Variable
+ 7 - Global mark
+ 8 - Jump
+ 9 - Buffer list
+ 10 - Local mark
+ 11 - Change
+ * - Unknown (0x{type-hex})
+
+ Each type may be represented using Unknown entry: "Jump with timestamp ..."
+ is the same as "Unknown (0x8) with timestamp ....".
+3. After header there is one of the following lines:
+ 1. " % Key__ Description__ Value": map header. After mapping header
+ follows a table which may contain comments and lines consisting of
+ " +", key, description and |{msgpack-value}|. Key is separated by at
+ least two spaces with description, description is separated by at least
+ two spaces with the value. Each key in the map must be at most as wide
+ as "Key__" header: "Key" allows at most 3-byte keys, "Key__" allows at
+ most 5-byte keys. If keys actually occupy less bytes then the rest is
+ filled with spaces. Keys cannot be empty, end with spaces, contain two
+ consequent spaces inside of them or contain multibyte characters (use
+ "=" format if you need this). Descriptions have the same restrictions
+ on width and contents, except that empty descriptions are allowed.
+ Description column may be omitted.
+
+ When writing description is ignored. Keys with values |msgpack#equal|
+ to default ones are ignored. Order of keys is preserved. All keys are
+ treated as strings (not binary strings).
+
+ Note: specifically for buffer list entries it is allowed to have more
+ then one map header. Each map header starts a new map entry inside
+ buffer list because ShaDa buffer list entry is an array of maps. I.e. >
+
+ Buffer list with timestamp 1970-01-01T00:00:00:
+ % Key Description Value
+ + f file name "/foo"
+ + l line number 1
+ + c column 10
+<
+ is equivalent to >
+
+ Buffer list with timestamp 1970-01-01T00:00:00:
+ = [{="f": "/foo", ="c": 10}]
+<
+ and >
+
+ Buffer list with timestamp 1970-01-01T00:00:00:
+ % Key Description Value
+ + f file name "/foo"
+
+ % Key Description Value
+ + f file name "/bar"
+<
+ is equivalent to >
+
+ Buffer list with timestamp 1970-01-01T00:00:00:
+ = [{="f": "/foo"}, {="f": "/bar"}]
+<
+ Note 2: specifically for register entries special syntax for arrays was
+ designed: >
+
+ Register with timestamp 1970-01-01T00:00:00:
+ % Key Description Value
+ + rc contents @
+ | - "line1"
+ | - "line2"
+<
+ This is equivalent to >
+
+ Register with timestamp 1970-01-01T00:00:00:
+ % Key Description Value
+ + rc contents ["line1", "line2"]
+<
+ Such syntax is automatically used if array representation appears to be
+ too lengthy.
+ 2. " @ Description__ Value": array header. Same as map, but key is
+ omitted and description cannot be omitted. Array entries start with
+ " -". Example: >
+
+ History entry with timestamp 1970-01-01T00:00:00:
+ @ Description_ Value
+ - history type SEARCH
+ - contents "foo"
+ - separator '/'
+<
+ is equivalent to >
+
+ History entry with timestamp 1970-01-01T00:00:00:
+ = [SEARCH, "foo", '/']
+<
+ Note: special array syntax for register entries is not recognized here.
+ 3. " = {msgpack-value}": raw values. |{msgpack-value}| in this case may
+ have absolutely any type. Special array syntax for register entries is
+ not recognized here as well.
+
+
SQL *ft-sql*
Since the text for this plugin is rather long it has been put in a separate
diff --git a/runtime/doc/gui_w32.txt b/runtime/doc/gui_w32.txt
index 6ae7fa2431..eef0aaefb6 100644
--- a/runtime/doc/gui_w32.txt
+++ b/runtime/doc/gui_w32.txt
@@ -243,7 +243,7 @@ selection. You can use CTRL-Q instead. You can also use CTRL-Q in Insert
mode and Command-line mode to get the old meaning of CTRL-V. But CTRL-Q
doesn't work for terminals when it's used for control flow.
-NOTE: The clipboard support still has a number of bugs. See |todo|.
+NOTE: The clipboard support still has a number of bugs.
==============================================================================
4. Shell Commands *gui-shell-win32*
diff --git a/runtime/doc/help.txt b/runtime/doc/help.txt
index 9ca96dfd79..bb19805a20 100644
--- a/runtime/doc/help.txt
+++ b/runtime/doc/help.txt
@@ -94,7 +94,6 @@ General subjects ~
|tips.txt| various tips on using Vim
|message.txt| (error) messages and explanations
|quotes.txt| remarks from users of Vim
-|todo.txt| known problems and desired extensions
|develop.txt| development of Vim
|debug.txt| debugging Vim itself
|uganda.txt| Vim distribution conditions and what to do with your money
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 2b1044bead..bbf3da8de7 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -643,17 +643,6 @@ A jump table for the options with a short description can be found at |Q_op|.
compiled with the |+termresponse| feature and if |t_u7| is set to the
escape sequence to request cursor position report.
- *'antialias'* *'anti'* *'noantialias'* *'noanti'*
-'antialias' 'anti' boolean (default: off)
- global
- {only available when compiled with GUI enabled
- on Mac OS X}
- This option only has an effect in the GUI version of Vim on Mac OS X
- v10.2 or later. When on, Vim will use smooth ("antialiased") fonts,
- which can be easier to read at certain sizes on certain displays.
- Setting this option can sometimes cause problems if 'guifont' is set
- to its default (empty string).
-
*'autochdir'* *'acd'* *'noautochdir'* *'noacd'*
'autochdir' 'acd' boolean (default off)
global
@@ -991,7 +980,6 @@ A jump table for the options with a short description can be found at |Q_op|.
*'belloff'* *'bo'*
'belloff' 'bo' string (default "")
global
- {not in Vi}
Specifies for which events the bell will not be rung. It is a comma
separated list of items. For each item that is present, the bell
will be silenced. This is most useful to specify specific events in
@@ -5315,9 +5303,9 @@ A jump table for the options with a short description can be found at |Q_op|.
% When included, save and restore the buffer list. If Vim is
started with a file name argument, the buffer list is not
restored. If Vim is started without a file name argument, the
- buffer list is restored from the shada file. Buffers
- without a file name and buffers for help files are not written
- to the shada file.
+ buffer list is restored from the shada file. Quickfix
+ ('buftype'), unlisted ('buflisted'), unnamed and buffers on
+ removable media (|shada-r|) are not saved.
When followed by a number, the number specifies the maximum
number of buffers that are stored. Without a number all
buffers are stored.
diff --git a/runtime/doc/pi_msgpack.txt b/runtime/doc/pi_msgpack.txt
new file mode 100644
index 0000000000..95d6ff7467
--- /dev/null
+++ b/runtime/doc/pi_msgpack.txt
@@ -0,0 +1,139 @@
+*pi_msgpack.txt* For NeoVim version 0.1.
+
+Author: Nikolay Pavlov <kp-pav@yandex.ru>
+Copyright: (c) 2015 by Nikolay Pavlov
+
+The Apache license applies to the files in this package, including
+runtime/autoload/msgpack.vim, runtime/doc/pi_msgpack.txt and
+test/functional/plugin/msgpack_spec.lua. Like anything else that's free,
+msgpack.vim 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!
+
+==============================================================================
+1. Contents *msgpack.vim-contents*
+
+ 1. Contents..............................: |msgpack.vim-contents|
+ 2. Msgpack.vim introduction..............: |msgpack.vim-intro|
+ 3. Msgpack.vim manual....................: |msgpack.vim-manual|
+ Function arguments....................: |msgpack.vim-arguments|
+ msgpack#is_int function...............: |msgpack#is_int()|
+ msgpack#is_uint function..............: |msgpack#is_uint()|
+ msgpack#strftime function.............: |msgpack#strftime()|
+ msgpack#strptime function.............: |msgpack#strptime()|
+ msgpack#int_dict_to_str function......: |msgpack#int_dict_to_str()|
+ msgpack#special_type function.........: |msgpack#special_type()|
+ msgpack#type function.................: |msgpack#type()|
+ msgpack#deepcopy function.............: |msgpack#deepcopy()|
+ msgpack#string function...............: |msgpack#string()|
+ msgpack#eval function.................: |msgpack#eval()|
+ msgpack#equal function................: |msgpack#equal()|
+
+
+==============================================================================
+2. Msgpack.vim introduction *msgpack.vim-intro*
+
+This plugin contains utility functions to be used in conjunction with
+|msgpackdump()| and |msgpackparse()| functions.
+
+==============================================================================
+3. Msgpack.vim manual *msgpack.vim-manual*
+
+FUNCTION ARGUMENTS *msgpack.vim-arguments*
+
+Disambiguation of arguments described below. Note: if e.g. function is listed
+as accepting |{msgpack-integer}| (or anything else) it means that function
+does not check whether argument matches its description.
+
+*{msgpack-value}* Either |msgpack-special-dict| or a regular value, but
+ not function reference.
+*{msgpack-integer}* Any value for which |msgpack#type| will return
+ "integer".
+*{msgpack-special-int}* |msgpack-special-dict| representing integer.
+
+msgpack#is_int({msgpack-value}) *msgpack#is_int()*
+ Returns 1 if given {msgpack-value} is integer value, 0 otherwise.
+
+msgpack#is_uint({msgpack-value}) *msgpack#is_uint()*
+ Returns 1 if given {msgpack-value} is integer value greater or equal
+ to zero, 0 otherwise.
+
+ *msgpack#strftime*
+msgpack#strftime({format}, {msgpack-integer}) *msgpack#strftime()*
+ Same as |strftime()|, but second argument may be
+ |msgpack-special-dict|. Requires |+python| or |+python3| to really
+ work with |msgpack-special-dict|s.
+
+ *msgpack#strptime*
+msgpack#strptime({format}, {time}) *msgpack#strptime()*
+ Reverse of |msgpack#strptime()|: for any time and format
+ |msgpack#equal|( |msgpack#strptime|(format, |msgpack#strftime|(format,
+ time)), time) be true. Requires |+python| or |+python3|, without it
+ only supports non-|msgpack-special-dict| nonnegative times and format
+ equal to `%Y-%m-%dT%H:%M:%S`.
+
+msgpack#int_dict_to_str({msgpack-special-int}) *msgpack#int_dict_to_str()*
+ Function which converts |msgpack-special-dict| integer value to
+ a hexadecimal value like 0x1234567890ABCDEF (always returns exactly 16
+ hexadecimal digits).
+
+msgpack#special_type({msgpack-value}) *msgpack#special_type()*
+ Returns zero if {msgpack-value} is not |msgpack-special-dict|. If it
+ is it returns name of the key in |v:msgpack_types| which represents
+ {msgpack-value} type.
+
+msgpack#type({msgpack-value}) *msgpack#type()*
+ Returns name of the key in |v:msgpack_types| that represents
+ {msgpack-value} type. Never returns zero: this function returns
+ msgpack type which will be dumped by |msgpackdump()| should it receive
+ a list with singe {msgpack-value} as input.
+
+msgpack#deepcopy({msgpack-value}) *msgpack#deepcopy()*
+ Like |deepcopy()|, but works correctly with |msgpack-special-dict|
+ values. Plain |deepcopy()| will destroy all types in
+ |msgpack-special-dict| values because it will copy _TYPE key values,
+ while they should be preserved.
+
+msgpack#string({msgpack-value}) *msgpack#string()*
+ Like |string()|, but saves information about msgpack types. Values
+ dumped by msgpack#string may be read back by |msgpack#eval()|.
+ Returns is the following:
+
+ - Dictionaries are dumped as "{key1: value1, key2: value2}". Note:
+ msgpack allows any values in keys, so with some
+ |msgpack-special-dict| values |msgpack#string()| may produce even
+ "{{1: 2}: 3, [4]: 5}".
+ - Lists are dumped as "[value1, value2]".
+ - Strings are dumped as
+ 1. `"abc"`: binary string.
+ 2. `="abc"`: string.
+ 3. `+(10)"ext"`: extension strings (10 may be replaced with any
+ 8-bit signed integer).
+ Inside strings the following escape sequences may be present: "\0"
+ (represents NUL byte), "\n" (represents line feed) and "\""
+ (represents double quote).
+ - Floating-point and integer values are dumped using |string()| or
+ |msgpack#int_dict_to_str()|.
+ - Booleans are dumped as "TRUE" or "FALSE".
+ - Nil values are dumped as "NIL".
+
+msgpack#eval({string}, {dict}) *msgpack#eval()*
+ Transforms string created by |msgpack#string()| into a value suitable
+ for |msgpackdump()|. Second argument allows adding special values
+ that start with head characters (|/\h|) and contain only word
+ characters (|/\w|). Built-in special values are "TRUE", "FALSE",
+ "NIL", "nan" and "inf" and they cannot be overridden. Map values are
+ always evaluated to |msgpack-special-dict| values, as well as
+ hexadecimal digits. When evaluating maps order of keys is preserved.
+
+ *msgpack#equal*
+msgpack#equal({msgpack-value}, {msgpack-value}) *msgpack#equal()*
+ Returns 1 if given values are equal, 0 otherwise. When comparing
+ msgpack map values order of keys is ignored. Comparing
+ |msgpack-special-dict| with equivalent non-special-dict value
+ evaluates to 1.
+
+==============================================================================
+vim:tw=78:ts=8:ft=help:fdm=marker
diff --git a/runtime/doc/quickref.txt b/runtime/doc/quickref.txt
index 34e7851493..ea73b99ad2 100644
--- a/runtime/doc/quickref.txt
+++ b/runtime/doc/quickref.txt
@@ -600,7 +600,6 @@ Short explanation of each option: *option-list*
'allowrevins' 'ari' allow CTRL-_ in Insert and Command-line mode
'altkeymap' 'akm' for default second language (Farsi/Hebrew)
'ambiwidth' 'ambw' what to do with Unicode chars of ambiguous width
-'antialias' 'anti' Mac OS X: use smooth, antialiased fonts
'autochdir' 'acd' change directory to the file in the current window
'arabic' 'arab' for Arabic as a default second language
'arabicshape' 'arshape' do shaping for Arabic characters
diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt
index 572823eca9..f46a258e2e 100644
--- a/runtime/doc/starting.txt
+++ b/runtime/doc/starting.txt
@@ -28,8 +28,6 @@ More generally, Vim is started with:
Option arguments and file name arguments can be mixed, and any number of them
can be given. However, watch out for options that take an argument.
-For compatibility with various Vi versions, see |cmdline-arguments|.
-
Exactly one out of the following five items may be used to choose how to
start editing:
@@ -1232,6 +1230,8 @@ exactly four MessagePack objects:
With |shada-h| or 'nohlsearch'
this key is always false.
sp Binary N/A Actual pattern. Required.
+ sb Boolean false True if search direction is
+ backward.
* any none Other keys are allowed for
compatibility reasons, see
|shada-compatibility|.
diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt
deleted file mode 100644
index eeed014fdb..0000000000
--- a/runtime/doc/todo.txt
+++ /dev/null
@@ -1,4897 +0,0 @@
-*todo.txt* For Vim version 7.4. Last change: 2014 Dec 06
-
-
- VIM REFERENCE MANUAL by Bram Moolenaar
-
-
- TODO list for Vim *todo*
-
-This is a veeeery long list of known bugs, current work and desired
-improvements. To make it a little bit accessible, the items are grouped by
-subject. In the first column of the line a classification is used to be able
-to look for "the next thing to do":
-
-Priority classification:
-9 next point release
-8 next release
-7 as soon as possible
-6 soon
-5 should be included
-4 nice to have
-3 consider including
-2 maybe not
-1 probably not
-- unclassified
-
- *votes-for-changes*
-See |develop.txt| for development plans. You can vote for which items should
-be worked on, but only if you sponsor Vim development. See |sponsor|.
-
-Issues can also be entered online: http://code.google.com/p/vim/issues/list
-Updates will be forwarded to the vim_dev maillist. Issues entered there will
-not be repeated below, unless there is extra information.
-
- *known-bugs*
--------------------- Known bugs and current work -----------------------
-
-Patch to fix list range assign crash. (Yukihiro Nakadaira, 2014 Dec 1)
-
-Patch to fix range with user command. (Marcin Szamotulski, 2014 Dec 2)
-Update Dec 6, with support for user commands.
-
-When window number in Ex range is too high, give an error?
-Only when backwards compatible.
-
-:s/\n// doesn't change anything. Since 7.4.232? (Eliseo Martínez, 2014 Nov
-28) Patch on Issue 287
-
-Using vim_snprintf() in window.c can be in a function.
-
-Regexp problems:
-- The NFA engine does not implement the time limit passed to
- nfa_regexec_multi()
-- Very slow with a long line and Ruby highlighting. (John Whitley, 2014 Dec 4)
-- Bug with pattern: '\vblock (\d+)\.\n.*\d+%(\1)@<!\.$'
- (Lech Lorens, 2014 Feb 3)
-- Issue 164: freeze on regexp search.
-- Ignorecase not handled properly for multi-byte characters. (Axel Bender,
- 2013 Dec 11)
-- Using \@> and \?. (Brett Stahlman, 2013 Dec 21) Remark from Marcin Szamotulski
- Remark from Brett 2014 Jan 6 and 7.
-- Difference in NFA and old engine. (Brett Stahlman, 2014 Nov 5)
-- Bug when using \>. (Ramel, 2014 Feb 2) (Aaron Bohannon, 2014 Feb 13)
-- NFA regexp doesn't handle \%<v correctly. (Ingo Karkat, 2014 May 12)
-- Does not work with NFA regexp engine:
- \%u, \%x, \%o, \%d followed by a composing character
-- Bug relating to back references. (Ingo Karkat, 2014 Jul 24)
-- Using back reference before the capturing group sometimes works with the old
- engine, can we do this with the new engine? E.g. with
- "/\%(<\1>\)\@<=.*\%(<\/\(\w\+\)>\)\@=" matching text inside HTML tags.
-- Diff highlighting can be very slow. (Issue 309)
-
-Still using freed memory after using setloclist(). (lcd, 2014 Jul 23)
-More info Jul 24. Not clear why.
-
-Patch to make getregtype() return the right size for non-linux systems.
-(Yasuhiro Matsumoto, 2014 Jul 8)
-Breaks test_eval. Inefficient, can we only compute y_width when needed?
-
-Problem that a previous silent ":throw" causes a following try/catch not to
-work. (ZyX, 2013 Sep 28)
-
-Patch to fix recognizing function name. (Ozaki Kiichi, 2014 Nov 28)
-
-":cd C:\Windows\System32\drivers\etc*" does not work, even though the
-directory exists. (Sergio Gallelli, 2013 Dec 29)
-
-The entries added by matchaddpos() are returned by getmatches() but can't be
-set with setmatches(). (lcd47, 2014 Jun 29)
-
-Gvim: when both Tab and CTRL-I are mapped, use CTRL-I not for Tab.
-
-Problem using ":try" inside ":execute". (ZyX, 2013 Sep 15)
-
-Python: ":py raw_input('prompt')" doesn't work. (Manu Hack)
-
-Change behavior of v:hlsearch? Patch from Christian, 2014 Oct 22.
-
-Patch to recover from X server restart: hint on Issue 203 (2014 Nov 21 18:44)
-
-MS-Windows: When editing a file with a leading space, writing it uses the
-wrong name. (Aram, 2014 Nov 7) Vim 7.4.
-
-Add LessCss support. (Jenoma / Alessandro Vioni, 2014 Nov 24)
-Now with updated license, Nov 24.
-
-patch to remove FEAT_OSFILETYPE from fileio.c. (Christian, 2014 Nov 12)
-
-Value returned by virtcol() changes depending on how lines wrap. This is
-inconsistent with the documentation.
-
-Ukrainian vimtutor. (Issue 288)
-
-Regenerate the Unicode tables in mbyte.c.
-Diff from ZyX, 2014 Dec 6.
-
-Patch to fix relative numbers. (Christian Brabandt, 2014 Nov 17)
-Update Nov 26.
-
-Patch to fix wrong formatting if 'linebreak' is set. (Christian Brabandt, 2014
-Nov 12)
-
-Patch to avoid recognizing polkit as hog files. (Issue 292)
-
-Patch to support hex values for setting option value.
-(Zyx, 2015 Nov 6)
-
-On MS-Windows running tests with Mercurial has problems when the fileformat of
-the input files are changed. (Ken Takata, Taro Muraoka, 2014 Sep 25)
-Update Nov 5.
-
-MS-Windows: Crash opening very long file name starting with "\\".
-(Christian Brock, 2012 Jun 29)
-
-Patch for this from Marcin Szamotulski, 2014 Dec 28:
-8 Make the # register writable, so that it can be restored after jumping
- around in windows.
-
-Using CTRL-L while popup menu is visible behaves like CTRL-P, which is wrong.
-Patch by Yasuhiro Matsumoto, 2015 Jan 5.
-Is this right? Comment from Amadeus Demarzi.
-Another patch from Christian, Jan 6.
-Comment from Hirohito Higashi, Jan 6.
-
-Cursorline background color not mixed with character highlight.
-Patch by Yasuhiro Matsumoto, 2014 Dec 3.
-
-Problem using diff syntax with cp932 encoding. Idea from Yasuhiro Matsumoto,
-patch from Ken Takata (2014 Nov 6)
-
-ml_updatechunk() is slow when retrying for another encoding. (John Little,
-2014 Sep 11)
-
-Patch to add a different escape sequence for replace mode.
-(Omar Sandoval, 2014 Nov 30)
-
-Calling setreg() with an empty list doesn't work.
-Patch by Yasuhiro Matsumoto, 2014 Dec 14.
-
-Extended file attributes lost on write (backupcopy=no). Issue 306.
-
-Window height computed incorrectly when Vim is minimized.
-Patch to fix this. (Ingo Karkat, 2014 Dec 19)
-
-Patch to allow values greater than 255 for ctermfg/ctermbg on Windows.
-(Yasuhiro Matsumoto, 2014 Dec 5)
-
-Mixup of highlighting when there is a match and SpellBad. (ZyX, 2015 Jan 1)
-
-When 'balloonexpr' returns a list the result has a trailing newline.
-Just remove one trailing newline. (lcd, 2014 Oct 17)
-
-Make comments in the test Makefile silent. (Kartik Agaram, 2014 Sep 24)
-
-Result of systemlist() does not show whether text ended in line break.
-(Bjorn Linse, 2014 Nov 27)
-
-When in 'comments' "n:x" follows after three-part comment directly it repeats
-any one-character from the previous line. (Kartik Agaram, 2014 Sep 19)
-
-Syntax highlighting slow (hangs) in SASS file. (Niek Bosch, 2013 Aug 21)
-
-Patch to add the EndOfBuffer highlight group, used instead of NonText for "~"
-lines. (Marco Hinz, 2014 Nov 2)
-
-Adding "~" to 'cdpath' doesn't work for completion? (Davido, 2013 Aug 19)
-
-Plugins need to make a lot of effort, lots of mappings, to know what happened
-before pressing the key that triggers a plugin action. How about keeping the
-last N pressed keys, so that they do not need to be mapped?
-
-":q!" should reset modified flag for current buffer, if another buffer is
-modified no need to abandon it again.
-Patch from Yasuhiro Matsumoto, 2014 Nov 21.
-Update from Hirohito Higashi, 2014 Nov 21.
-With test, Nov 23.
-
-Wrong scrolling when using incsearch. Patch by Christian Brabandt, 2014 Dec 4.
-Is this a good solution?
-
-Can assign to s:type when a function s:type has been defined.
-Also the other way around: define a function while a variable with that name
-was already defined.
-(Yasuhiro Matsumoto, 2014 Nov 3)
-
-Patch to make closed folds line up. (Charles Campbell, 2014 Sep 12)
-
-Patch for building a 32bit Vim with 64bit MingW compiler.
-(Michael Soyka, 2014 Oct 15)
-
-Delete old code in os_msdos.c, mch_FullName().
-
-Redo only remembers the last change. Could use "{count}g." to redo an older
-change. How does the user know which change? At least have a way to list
-them: ":repeats".
-
-Patch for glob(), adding slash to normal files. (Ingo Karkat, 2014 Dec 22)
-
-Using "." to repeat an Ex command puts that command in history. Probably
-should not happen. If the command is the result of a mapping it's not put in
-history either. (Jacob Niehus, 2014 Nov 2)
-Patch from Jacob, Nov 2.
-
-"hi link" does not respect groups with GUI settings only. (Mark Lodato, 2014
-Jun 8)
-
-Bug: Autocompleting ":tag/pat" replaces "/pat" with a match but does not
-insert a space. (Micha Mos, 2014 Nov 7)
-
-Patch to add the :bvimgrep command. (Christian Brabandt, 2014 Nov 12)
-Update Dec 6.
-
-Patch to add argument to :cquit. (Thinca, 2014 Oct 12)
-
-No error for missing endwhile. (ZyX, 2014 Mar 20)
-
-start_global_changes() plus end_global_changes() causes problem for
-clip_unnamed_plus. (Jason Pleau, 2014 Sep 12)
-
-Patch to add :arglocal and :arglists. (Marcin Szamotulski, 2014 Aug 6)
-
-PHP syntax is extremely slow. (Anhad Jai Singh, 2014 Jan 19)
-
-Spell files use a latin single quote. Unicode also has another single quote:
-0x2019. (Ron Aaron, 2014 Apr 4)
-New OpenOffice spell files support this with ICONV. But they are not
-compatible with Vim spell files. The old files can no longer be downloaded.
-
-Patch to make FocusGained and FocusLost work in modern terminals. (Hayaki
-Saito, 2013 Apr 24)
-
-Win32: patch to use 64 bit stat() if possible. (Ken Takata, 2014 May 12)
-More tests May 14. Update May 29. Update Aug 10.
-
-The garbage collector may use too much stack. Make set_ref_in_item()
-iterative instead of recursive. Test program by Marc Weber (2013 Dec 10)
-Patch by Ben Fritz, 2014 Jun 22.
-Related: Vim hangs when freeing a lot of objects. Patch by Yasuhiro
-Matsumoto, 2014 Aug 26.
-
-Idea: For a window in the middle (has window above and below it), use
-right-mouse-drag on the status line to move a window up/down without changing
-its height? It's like dragging the status bar above it at the same time.
-
-Can we make ":unlet $VAR" use unsetenv() to delete the env var?
-What for systems that don't have unsetenv()?
-
-Patch to add a :domodeline command. (Christian Brabandt, 2014 Oct 21)
-
-This does not give an error: (Andre Sihera, 2014 Mar 21)
- vim -u NONE 1 2 3 -c 'bufdo if 1 | echo 1'
-This neither: (ZyX)
- vim -u NONE 1 2 3 -c 'bufdo while 1 | echo 1'
-
-'viewdir' default on MS-Windows is not a good choice, it's a system directory.
-Change 'viewdir' to "$HOME/vimfiles/view" and use 'viewdiralt' to also read
-from?
-
-Problem with upwards search on Windows (works OK on Linux). (Brett Stahlman,
-2014 Jun 8)
-
-Patch to load TCL dynamically. (Ken Takata, 2014 Sep 20)
-
-Include a plugin manager with Vim? Neobundle seems to be the best currently.
-Long message about this from ZyX, 2014 Mar 23. And following replies.
-Also see http://vim-wiki.mawercer.de/wiki/topic/vim%20plugin%20managment.html
-User view:
-- Support multiple sources, basically any http:// URL. Be able to look into
- the files before deciding to install.
-- Be able to try out a plugin and remove it again with (almost) no traces.
-- Each plugin needs a "manifest" file that has the version, dependencies
- (including Vim version and features), conflicts, list of files, etc.
- Updater uses that to decide what/how to update.
- Dependencies can use a URL for specific versions, or short name for scripts
- on vim.org.
-- Once a plugin is installed it remembers where it came from, updater checks
- there. Can manually update when really needed.
-- Must be possible to install for one user. Also system wide?
-- Can edit plugin config with Vim. Can temporarily disable a plugin.
-- Run the update manually, find latest version and install.
-- Be able to download without special tools, must work for 95% of users.
-Implementation:
-- Avoid the 'runtimepath' getting long. Need some other way to keep each
- plugin separate.
-- When installing or updating, first figure out what needs to be done. This
- may involve recursively fetching manifest files for dependencies. Then show
- the user what's going to change and ask for OK.
-- Scripts on Vim.org must be able to consist of several files. Is zip format
- sufficient? Upload the manifest? Or refer to a site that has the manifest?
-- Best is to fetch individual files or use a Vimball. Reduces dependency on
- tools that might be missing and allows inspection of the files before
- installing.
-Out of scope:
-- Overview of plugins, ratings, comments, etc. That's another world.
-- Development work on plugins (although diff with distributed version would be
- useful).
-
-Setting the spell file in a session only reads the local additions, not the
-normal spell file. (Enno Nagel, 2014 Mar 29)
-
-CTRL-] in Visual mode uses the selected text as a tag. This does not work
-when preceded with CTRL-W. (Patrick Hemmer, 2014 Jun 28)
-
-When typing the first character of a command, e.g. "f", then using a menu, the
-menu item doesn't work. Clear typeahead when using a menu?
-
-Editing an ascii file as ucs-2 or ucs-4 causes display errors.
-(ZyX, 2014 Mar 30)
-
-":Next 1 some-arg" does not complain about trailing argument. Also for
-various other commands. (ZyX, 2014 Mar 30)
-
-patch to skip sort if no line matches the expression.
-(Christian Brabandt, 2014 Jun 25)
-
-Patch to add sortuniq(). (Cade Forester, 2014 Mar 19)
-Or add uniq() instead? Patch by lcd47, but it has problems.
-
-Patch to support sorting on floating point number. (Alex Jakushev, 2010 Oct
-30)
-
-Patch to support expression argument to sort() instead of a function name.
-Yasuhiro Matsumoto, 2013 May 31.
-Or should we add a more general mechanism, like a lambda() function?
-Patch by Yasuhiro Matsumoto, 2014 Sep 16.
-
-Patch to fix display of listchars on the cursorline. (Nayuri Aohime, 2013)
-Update suggested by Yasuhiro Matsumoto, 2014 Nov 25:
-https://gist.github.com/presuku/d3d6b230b9b6dcfc0477
-
-Patch for XDG base directory support. (Jean François Bignolles, 2014 Mar 4)
-Remark on the docs. Should not be a compile time feature. But then what?
-
-Completion of ":e" is ":earlier", should be ":edit". Complete to the matching
-command instead of doing this alphabetically. (Mikel Jorgensen)
-
-Patch to add v:completed_item. (Shougo Matsu, 2013 Nov 29).
-
-Patch to get MSVC version in a nicer way. (Ken Takata, 2014 Jul 24)
-
-Patch to define macros for hardcoded values. (Elias Diem, 2013 Dec 14)
-
-Several syntax file match "^\s*" which may get underlined if that's in the
-highlight group. Add a "\zs" after it?
-
-Patch to fix temp directories for Windows, so that it works without tweaking.
-Issue 28.
-
-Go through more coverity reports.
-
-Patch to add ":undorecover", get as much text out of the undo file as
-possible. (Christian Brabandt, 2014 Mar 12, update Aug 22)
-
-Updated spec ftplugin. (Matěj Cepl, 2013 Oct 16)
-
-Patch to right-align signs. (James Kolb (email james), 2013 Sep 23)
-
-Patch to handle integer overflow. (Aaron Burrow, 2013 Dec 12)
-
-With "$" in 'cpoptions' the popup menu isn't fully drawn. (Matti Niemenmaa,
-2013 Sep 5)
-
-Patch to add "ntab" item in 'listchars' to repeat first character. (Nathaniel
-Braun, pragm, 2013 Oct 13) A better solution 2014 Mar 5.
-
-Undo message is not always properly displayed. Patch by Ken Takata, 2013 oct
-3. Doesn't work properly according to Yukihiro Nakadaira.
-
-/[b-a] gives error E16, should probably be E769.
-
-7 Windows XP: When using "ClearType" for text smoothing, a column of yellow
- pixels remains when typing spaces in front of a "D" ('guifont' set to
- "lucida_console:h8").
-Patch by Thomas Tuegel, also for GTK, 2013 Nov 24
-
-:help gives example for z?, but it does not work. m? and t? do work.
-
-Python: Extended funcrefs: use func_T* structure in place of char_u* function
-names.
-(ZyX, 2013 Jul 15, update Sep 22, 24, 28; Update 2013 Dec 15, 2014 Jan 6)
-Also fixes Bug: E685 error for func_unref(). (ZyX, 2010 Aug 5)
-
-Patch to add funcref to Lua. (Luis Carvalho, 2013 Sep 4)
-With tests: Sep 5.
-
-Patch to fix that on suckless Terminal mousewheel up does not work.
-(Ralph Eastwood, 2013 Nov 25)
-
-Discussion about canonicalization of Hebrew. (Ron Aaron, 2011 April 10)
-
-Checking runtime scripts: Thilo Six, 2012 Jun 6.
-
-When evaluating expression in backticks, autoload doesn't work.
-(Andy Wokula, 2013 Dec 14)
-
-Using <nr>ifoobar<esc> can slow down Vim. Patch by Christian Brabandt, 2013
-Dec 13.
-
-Fold can't be opened after ":move". (Ein Brown)
-Patch from Christian Brabandt doesn't fix it completely.
-
-Patch from Christian Brabandt to preserve upper case marks when wiping out a
-buffer. (2013 Dec 9)
-
-Patch for drag&drop reordering of GUI tab pages reordering.
-(Ken Takata, 2013 Nov 22, second one, also by Masamichi Abe)
-
-Patch to add option that tells whether small deletes go into the numbered
-registers. (Aryeh Leib Taurog, 2013 Nov 18)
-
-Javascript file where indent gets stuck on: GalaxyMaster, 2012 May 3.
-
-The BufUnload event is triggered when re-using the empty buffer.
-(Pokey Rule, 2013 Jul 22)
-Patch by Marcin Szamotulski, 2013 Jul 22.
-
-The CompleteDone autocommand needs some info passed to it:
-- The word that was selected (empty if abandoned complete)
-- Type of completion: tag, omnifunc, user func.
-
-Patch to allow more types in remote_expr(). (Lech Lorens, 2014 Jan 5)
-Doesn't work for string in list. Other way to pass all types of variables
-reliably?
-
-Using ":call foo#d.f()" doesn't autoload the "foo.vim" file.
-That is, calling a dictionary function on an autoloaded dict.
-Works OK for echo, just not for ":call" and ":call call()". (Ted, 2011 Mar
-17)
-Patch by Christian Brabandt, 2013 Mar 23.
-Not 100% sure this is the right solution.
-
-Problem caused by patch 7.3.638: window->open does not update window
-correctly. Issue 91.
-
-Patch to add {lhs} to :mapclear: clear all maps starting with {lhs}.
-(Christian Brabandt, 2013 Dec 9)
-
-Exception caused by argument of return is not caught by try/catch.
-(David Barnett, 2013 Nov 19)
-
-8 'backupdir' and 'directory' should use $TMPDIR, $TMP and/or $TEMP when
- defined.
-Issue 28.
-
-Patch to fix that 'cedit' is recognized after :normal. (Christian Brabandt,
-2013 Mar 19, later message)
-
-Patch to view coverage of the tests. (Nazri Ramliy, 2013 Feb 15)
-
-Patch to add "Q" and "A" responses to interactive :substitute. They are
-carried over when using :global. (Christian Brabandt, 2013 Jun 19)
-
-Bug with 'cursorline' in diff mode. Line being scrolled into view gets
-highlighted as the cursor line. (Alessandro Ivaldi, 2013 Jun 4)
-
-Two highlighting bugs. (ZyX, 2013 Aug 18)
-
-Patch to add the bufferlist() function. (Yegappan Lakshmanan, 2013 May 5)
-May 17: with winlist() and tabpagelist().
-May 19: with local variables.
-May 28: with options
-
-Patch to support 'u' in interactive substitute. (Christian Brabandt, 2012 Sep
-28) With tests: Oct 9.
-
-Patch from Christian Brabandt to make the "buffer" argument for ":sign place"
-optional. (2013 Jul 12)
-
-Dialog is too big on Linux too. (David Fishburn, 2013 Sep 2)
-
-Patch to allow setting w:quickfix_title via setqflist() and setloclist()
-functions. (Christian Brabandt, 2013 May 8, update May 21)
-Patch to add getlocstack() / setlocstack(). (Christian Brabandt, 2013 May 14)
-Second one. Update May 22.
-Update by Daniel Hahler, 2014 Jul 4, Aug 14, Oct 14, Oct 15.
-
-Patch to make fold updates much faster. (Christian Brabandt, 2012 Dec)
-
-Issue 54: document behavior of -complete, also expands arg.
-
-- Add regex for 'paragraphs' and 'sections': 'parare' and 'sectre'. Combine
- the two into a regex for searching. (Ned Konz)
-Patch by Christian Brabandt, 2013 Apr 20, unfinished.
-
-Bug: findfile("any", "file:///tmp;") does not work.
-
-'ff' is wrong for one-line file without EOL. (Issue 77)
-
-Patch to set antialiasing style on Windows. (Ondrej Balaz, 2013 Mar 14)
-Needs a different check for CLEARTYPE_QUALITY.
-
-In the ATTENTION message about an existing swap file, mention the name of the
-process that is running. It might actually be some other program, e.g. after
-a reboot.
-
-Patch to have text objects defined by arbitrary single characters. (Daniel
-Thau, 2013 Nov 20, 2014 Jan 29, 2014 Jan 31)
-Ben Fritz: problem with 'selection' set to "exclusive".
-Updated to current Vim, not quite right yet. (Ben Fritz, 2014 Mar 27)
-
-Patch to select the next or previous text object if there isn't one under the
-cursor. (Daniel Thau, 2013 Nov 20)
-
-patch to add "combine" flag to syntax commands. (so8res, 2012 Dec 6)
-
-Bug caused by patch 7.3.1288? Issue 183.
-I can't reproduce it.
-
-Syntax update problem in one buffer opened in two windows, bottom window is
-not correctly updated. (Paul Harris, 2012 Feb 27)
-
-Patch to add assignments in cscope. (Uli Meis, Estabrooks, 2012 Sep 1)
-Alternate patch by Gary Johnson, Sep 4.
-
-Patch to add getsid(). (Tyru, 2011 Oct 2) Do we want this? Update Oct 4.
-Or use expand('<sid>')?
-
-Patch to make confirm() display colors. (Christian Brabandt, 2012 Nov 9)
-
-Patch to add functions for signs. (Christian Brabandt, 2013 Jan 27)
-
-Do we need some way (option) to show the sign column even when there are no
-signs? Patch by Christian Brabandt, 2013 Aug 22.
-
-Patch to remove flicker from popup menu. (Yasuhiro Matsumoto, 2013 Aug 15)
-
-Patch to add 'completeselect' option. Specifies how to select a candidate in
-insert completion. (Shougo, 2013 May 29)
-Update to add to existing 'completeopt'. 2013 May 30
-
-Problem with refresh:always in completion. (Tyler Wade, 2013 Mar 17)
-
-b:undo_ftplugin cannot call a script-local function. (Boris Danilov, 2013 Jan
-7)
-
-Win32: The Python interface only works with one version of Python, selected at
-compile time. Can this be made to work with version 2.1 and 2.2 dynamically?
-
-Python: Be able to define a Python function that can be called directly from
-Vim script. Requires converting the arguments and return value, like with
-vim.bindeval().
-
-Patch for :tabcloseleft, after closing a tab go to left tab. (William Bowers,
-2012 Aug 4)
-
-Patch to improve equivalence classes in regexp patterns.
-(Christian Brabandt, 2013 Jan 16, update Jan 17)
-
-Patch with suggestions for starting.txt. (Tony Mechelynck, 2012 Oct 24)
-But use Gnome instead of GTK?
-
-Should be possible to enable/disable matchparen per window or buffer.
-Add a check for b:no_match_paren in Highlight_matching_Pair() (Marcin
-Szamotulski, 2012 Nov 8)
-
-Issue 72: 'autochdir' causes problems for :vimgrep.
-
-Session file creation: 'autochdir' causes trouble. Keep it off until after
-loading all files.
-
-Win32: When 'autochdir' is on and 'encoding' is changed, files on the command
-line are opened again, but from the wrong directory. Apply 'autochdir' only
-after starting up?
-
-Patch to add ":ldo" and ":cdo", execute commands over quickfix list and
-location list. (Yegappan Lakshmanan, 2013 Jun 2)
-
-8 "stl" and "stlnc" in 'fillchars' don't work for multi-byte characters.
- Patch by Christian Wellenbrock, 2013 Jul 5.
-
-MS-Windows resizing problems:
-- Windows window on screen positioning: Patch by Yukihiro Nakadaira, 2012 Jun
- 20. Uses getWindowRect() instead of GetWindowPlacement()
-- Win32: When the taskbar is at the top of the screen creating the tabbar
- causes the window to move unnecessarily. (William E. Skeith III, 2012 Jan
- 12) Patch: 2012 Jan 13 Needs more work (2012 Feb 2)
-
-Patch to use Modern UI 2.0 for the Nsis installer. (Guopeng Wen, 2010 Jul 30)
-Latest version: 2011 May 18
-8 Windows install with NSIS: make it possible to do a silent install, see
- http://nsis.sourceforge.net/Docs/Chapter4.html#4.12
- Version from Guopeng Wen that does this (2010 Dec 27)
-Alternative: MSI installer: https://github.com/petrkle/vim-msi/
-Or the one on Issue 279
-
-'iminsert' global value set when using ":setlocal iminsert"? (Wu, 2012 Jun 23)
-
-Patch to append regexp to tag commands to make it possible to select one out
-of many matches. (Cody Cutler, 2013 Mar 28)
-
-Patch to add tagfunc(). Cleaned up by Christian Brabandt, 2013 Jun 22.
-
-Help for 'b:undo_indent'. (Thilo Six, 2012 May 28)
-Also question if examples are correct.
-
-The input map for CTRL-O in mswin.vim causes problems after CTRL-X CTRL-O.
-Suggestion for another map. (Philip Mat, 2012 Jun 18)
-But use "gi" instead of "a". Or use CTRL-\ CTRL-O.
-
-Patch to support user name completion on MS-Windows. (Yasuhiro Matsumoto, 2012
-Aug 16)
-
-When there are no command line arguments ":next" and ":argu" give E163, which
-is confusing. Should say "the argument list is empty".
-
-xterm supports escape sequences to mark a paste operation. Need to be
-enabled. (Bruno Sutic, 2014 Jul 11) How to know the terminal supports this?
-
-Patch to have the fold and sign column and at the last line of the buffer.
-(Marco Hinz, 2014 Sep 25)
-Alternate suggestion: let all columns continue, also the number column.
-
-Patch to add tests for if_xcmdsrv.c., Jul 8, need some more work. (Brian Burns)
-New tests Jul 13. Update Jul 17. Discussion Jul 18.
-
-When running Vim in silent ex mode, an existing swapfile causes Vim to wait
-for a user action without a prompt. (Maarten Billemont, 2012 Feb 3)
-Do give the prompt? Quit with an error?
-
-Patch to list user digraphs. (Christian Brabandt, 2012 Apr 14)
-
-Patch to add digraph() function. (Christian Brabandt, 2013 Aug 22, update Aug
-24)
-
-Patch for input method status. (Hirohito Higashi, 2012 Apr 18)
-
-Update Vim app icon (for Gnome). (Jakub Steiner, 2013 Dec 6)
-
-Patch to use .png icons for the toolbar on MS-Windows. (Martin Gieseking, 2013
-Apr 18)
-
-":cd" doesn't work when current directory path contains "**".
-finddir() has the same problem. (Yukihiro Nakadaira, 2012 Jan 10)
-Requires a rewrite of the file_file_in_path code.
-
-Should use has("browsefilter") in ftplugins. Requires patch 7.3.593.
-
-Update for vim2html.pl. (Tyru, 2013 Feb 22)
-
-Patch to sort functions starting with '<' after others. Omit dict functions,
-they can't be called. (Yasuhiro Matsumoto, 2011 Oct 11)
-
-Patch to pass list to or(), and() and xor(). (Yasuhiro Matsumoto, 2012 Feb 8)
-
-Patch to improve "it" and "at" text object matching. (Christian Brabandt, 2011
-Nov 20)
-
-`] moves to character after insert, instead of the last inserted character.
-(Yukihiro Nakadaira, 2011 Dec 9)
-
-Plugin for Modeleasy. (Massimiliano Tripoli, 2011 Nov 29)
-
-BufWinLeave triggers too late when quitting last window in a tab page. (Lech
-Lorens, 2012 Feb 21)
-
-Patch for 'transparency' option. (Sergiu Dotenco, 2011 Sep 17)
-Only for MS-Windows. No documentation. Do we want this?
-
-Patch to support cursor shape in Cygwin console. (Ben bgold, 2011 Dec 27)
-
-Patch to support UTF-8 for Hangul. (Shawn Y.H. Kim, 2011 May 1)
-Needs more work. Pinged 2012 Jan 4.
-
-Issue 64: when 'incsearch' is on can't paste LF on command line.
-
-On MS-Windows a temp dir with a & init causes system() to fail. (Ben Fritz,
-2012 Jun 19)
-
-'cursorline' is displayed too short when there are concealed characters and
-'list' is set. (Dennis Preiser)
-Patch 7.3.116 was the wrong solution.
-Christian Brabandt has another incomplete patch. (2011 Jul 13)
-
-With concealed text mouse click doesn't put the cursor in the right position.
-(Herb Sitz) Fix by Christian Brabandt, 2011 Jun 16. Doesn't work properly,
-need to make the change in where RET_WIN_BUF_CHARTABSIZE() is called.
-
-Syntax region with 'concealends' and a 'cchar' value, 'conceallevel' set to 2,
-only one of the two ends gets the cchar displayed. (Brett Stahlman, 2010 Aug
-21, Ben Fritz, 2010 Sep 14)
-
-The :syntax cchar value can only be a single character. It would be useful to
-support combining characters. (Charles Campbell)
-
-'cursorline' works on a text line only. Add 'cursorscreenline' for
-highlighting the screen line. (Christian Brabandt, 2012 Mar 31)
-
-Win32: Patch to use task dialogs when available. (Sergiu Dotenco, 2011 Sep 17)
-New feature, requires testing. Made some remarks.
-
-Win32: Patch for alpha-blended icons and toolbar height. (Sergiu Dotenco, 2011
-Sep 17) Asked for feedback from others.
-
-Win32: Cannot cd into a directory that starts with a space. (Andy Wokula, 2012
-Jan 19)
-
-Need to escape $HOME on Windows? (ZyX, 2011 Jul 21, discussion 2013 Jul 4)
-Can't simply use a backslash, \$HOME has a different meaning already.
-Would be possible to use $$HOME where $HOME is to be used.
-
-"2" in 'formatoptions' not working in comments. (Christian Corneliussen, 2011
-Oct 26)
-
-Bug in repeating Visual "u". (Lawrence Kesteloot, 2010 Dec 20)
-
-With "unamedplus" in 'clipboard' pasting in Visual mode causes error for empty
-register. (Michael Seiwald, 2011 Jun 28) I can't reproduce it.
-
-Windows keys not set properly on Windows 7? (cncyber, 2010 Aug 26)
-
-When using a Vim server, a # in the path causes an error message.
-(Jeff Lanzarotta, 2011 Feb 17)
-
-Setting $HOME on MS-Windows is not very well documented. Suggestion by Ben
-Fritz (2011 Oct 27).
-
-Bug: Windows 7 64 bit system freezes when 'clipboard' set to "unnamed" and
-doing ":g/test/d". Putting every delete on the clipboard? (Robert Chan, 2011
-Jun 17)
-
-When there is a ">" in a line that "gq" wraps to the start of the next line,
-then the following line will pick it up as a leader. Should get the leader
-from the first line, not a wrapped line. (Matt Ackeret, 2012 Feb 27)
-
-Using ":break" or something else that stops executing commands inside a
-":finally" does not rethrow a previously uncaught exception. (ZyX, 2010 Oct
-15)
-
-Vim using lots of memory when joining lines. (John Little, 2010 Dec 3)
-
-BT regexp engine: After trying a \@> match and failing, submatches are not
-cleared. See test64.
-
-Changes to manpage plugin. (Elias Toivanen, 2011 Jul 25)
-
-Patch to make "z=" work when 'spell' is off. Does this have nasty side
-effects? (Christian Brabandt, 2012 Aug 5, Update 2013 Aug 12)
-Would also need to do this for spellbadword() and spellsuggest().
-
-Patch for variable tabstops. On github (Christian Brabandt, 2014 May 15)
-Update Aug 16 (email).
-
-On 64 bit MS-Windows "long" is only 32 bits, but we sometimes need to store a
-64 bits value. Change all number options to use nropt_T and define it to the
-right type.
-
-string() can't parse back "inf" and "nan". Fix documentation or fix code?
-(ZyX, 2010 Aug 23)
-
-Make 'formatprg' global-local. (Sung Pae)
-
-When doing "redir => s:foo" in a script and then "redir END" somewhere else
-(e.g. in a function) it can't find s:foo.
-When a script contains "redir => s:foo" but doesn't end redirection, a
-following "redir" command gives an error for not being able to access s:foo.
-(ZyX, 2011 Mar 27)
-
-When setqflist() uses a filename that triggers a BufReadCmd autocommand Vim
-doesn't jump to the correct line with :cfirst. (ZyX, 2011 Sep 18)
-
-Behavior of i" and a" text objects isn't logical. (Ben Fritz, 2013 Nov 19)
-
-7 Make "ga" show the digraph for a character, if it exists.
-Patch from Christian Brabandt, 2011 Aug 19.
-
-maparg() does not show the <script> flag. When temporarily changing a
-mapping, how to restore the script ID?
-
-Bug in try/catch: return with invalid compare throws error that isn't caught.
-(ZyX, 2011 Jan 26)
-
-When setting a local option value from the global value, add a script ID that
-indicates this, so that ":verbose set" can give a hint. Check with options in
-the help file.
-
-After patch 7.3.097 still get E15. (Yukihiro Nakadaira, 2011 Jan 18)
-Also for another example (ZyX, 2011 Jan 24)
-
-Build problem with small features on Mac OS X 10.6. (Rainer, 2011 Jan 24)
-
-"0g@$" puts '] on last byte of multi-byte. (ZyX, 2011 Jan 22)
-
-Patch to addd TextDeletePost and TextYankPost events. (Philippe Vaucher, 2011
-May 24) Update May 26.
-
-Patch for :tabrecently. (Hirokazu Yoshida, 2012 Jan 30)
-
-Problem with "syn sync grouphere". (Gustavo Niemeyer, 2011 Jan 27)
-
-Loading autoload script even when usage is inside "if 0". (Christian Brabandt,
-2010 Dec 18)
-
-With a filler line in diff mode, it isn't displayed in the column with line
-number, but it is in the sign column. Doesn't look right. (ZyX 2011 Jun 5)
-Patch by Christian Brabandt, 2011 Jun 5. Introduces new problems.
-
-Add jump() function. (Marcin Szamotulski, 2013 Aug 29)
-Is this needed? CTRL-O and CTRL-I do the same, just more difficult to use.
-
-8 Add a command to jump to the next character highlighted with "Error".
-Patch by Christian Brabandt, uses ]e [e ]t and [t. 2011 Aug 9.
-
-8 Add an event like CursorHold that is triggered repeatedly, not just once
- after typing something.
-Need for CursorHold that retriggers. Use a key that doesn't do anything, or a
-function that resets did_cursorhold.
-Patch by Christian Brabandt, 2011 May 6.
-
-Add event for when the text scrolls. A bit like CursorMoved. Also a similar
-one for insert mode. Use the event in matchparen to update the highlight if
-the match scrolls into view.
-
-7 Use "++--", "+++--" for different levels instead of "+---" "+----".
-Patch by Christian Brabandt, 2011 Jul 27.
-Update by Ben Fritz, with fix for TOhtml. (2011 Jul 30)
-
-9 Add %F to 'errorformat': file name without spaces. Useful on Unix to
- avoid matching something up to a time 11:22:33.
-Patch by Christian Brabandt, 2011 Jul 27.
-
-Patch to add up to 99 match groups. (Christian Brabandt, 2010 Dec 22)
-Also add named groups: \%{name}(re) and \%{name}g
-
-In the sandbox it's not allowed to do many things, but it's possible to change
-or set variables. Add a way to prevent variables from being changed in the
-sandbox? E.g.: ":protect g:restore_settings".
-
-Win32: tear-off menu does not work when menu language is German. (Markus
-Bossler, 2011 Mar 2) Fixed by 7.3.095?
-
-Version of netbeans.c for use with MacVim. (Kazuki Sakamoto, 2010 Nov 18)
-
-7.3.014 changed how backslash at end of line works, but still get a NUL when
-there is one backslash. (Ray Frush, 2010 Nov 18) What does the original ex
-do?
-
-Searching mixed with Visual mode doesn't redraw properly. (James Vega, 2010 Nov
-22)
-
-New esperanto spell file can't be processed. (Dominique Pelle, 2011 Jan 30)
-- move compflags to separate growarray?
-- instead of a regexp use a hashtable. Expand '?', '*', '+'. What would be
- the maximum repeat for * and +?
-
-"L'Italie" noted as a spell error at start of the sentence. (Dominique Pelle,
-2011 Feb 27)
-
-Editing a file with a ^M with 'ff' set to "mac", opening a help file, then the
-^M is displayed as ^J sometimes. Getting 'ff' value from wrong window/buffer?
-
-'colorcolumn' has higher priority than hlsearch. Should probably be the other
-way around. (Nazri Ramliy, 2013 Feb 19)
-
-When Vim is put in the background (SIGTSTP) and then gets a SIGHUP it doesn't
-exit. It exists as soon as back in the foreground. (Stephen Liang, 2011 Jan
-9) Caused by vim_handle_signal(SIGNAL_BLOCK); in ui.c.
-
-g` not working correctly when using :edit. It works OK when editing a file on
-the command line. (Ingo Karkat, 2011 Jan 25)
-
-Since patch 7.2.46 Yankring plugin has become very slow, eventually make Vim
-crash? (Raiwil, 2010 Nov 17)
-
-Patch to add FoldedLineNr highlighting: different highlighting for the line
-number of a closed fold. (eXerigumo Clanjor, 2013 Jul 15)
-
-Regexp engine performance:
-- Profiling:
- ./vim -u NONE -s ~/vim/test/ruby.vim
- ./vim -u NONE -s ~/vim/test/loop.vim
- ./vim -u NONE -s ~/vim/test/alsa.vim
- ./vim -s ~/vim/test/todo.vim
- ./vim -s ~/vim/test/xml.vim
- Dominique Pelle: xmlSyncDT is particularly slow (Jun 7)
-- More test files from the src/pkg/regexp/testdata directory in the Go repo.
-- Performance tests:
- - Using asciidoc syntax. (Marek Schimara, 2013 Jun 6)
- - ~/vim/text/FeiqCfg.xml (file from Netjune)
- - ~/vim/text/edl.svg (also XML)
- - glts has five tests. (May 25)
- - ~/vim/test/slowsearch
- - ~/vim/test/rgb.vim
- - search for a.*e*exn in the vim executable. Go to last line to use
- 'hlsearch'.
- - Slow combination of folding and PHP syntax highlighting. Script to
- reproduce it. Caused by "syntax sync fromstart" in combination with patch
- 7.2.274. (Christian Brabandt, 2010 May 27) Generally, folding with
- 'foldmethod' set to "syntax" is slow. Do profiling to find out why.
-
-Patch to add 'systemencoding', convert between 'encoding' and this for file
-names, shell commands and the like. (Kikuchan, 2010 Oct 14)
-Assume the system converts between the actual encoding of the filesystem to
-the system encoding (usually utf-8).
-
-Patch to add GUI colors to the terminal, when it supports it. (ZyX, 2013 Jan
-26, update 2013 Dec 14, another 2014 Nov 22)
-
-Problem producing tags file when hebrew.frx is present. It has a BOM.
-Results in E670. (Tony Mechelynck, 2010 May 2)
-
-'beval' option should be global-local.
-
-setpos() does not restore cursor position after :normal. (Tyru, 2010 Aug 11)
-
-7 The 'directory' option supports changing path separators to "%" to make
- file names unique, also support this for 'backupdir'. (Mikolaj Machowski)
- Patch by Christian Brabandt, 2010 Oct 21.
-
-With "tw=55 fo+=a" typing space before ) doesn't work well. (Scott Mcdermott,
-2010 Oct 24)
-
-Patch to add random number generator. (Hong Xu, 2010 Nov 8, update Nov 10)
-Alternative from Christian Brabandt. (2010 Sep 19)
-
-Messages in message.txt are highlighted as examples.
-
-When using cp850 the NBSP (0xff) is not drawn correctly. (Brett Stahlman, 2010
-Oct 22) 'isprint' is set to "@,161-255".
-
-":echo "\x85" =~# '[\u0085]'" returns 1 instead of 0. (ZyX, 2010 Oct 3)
-
-'cindent' not correct when 'list' is set. (Zdravi Korusef, 2010 Apr 15)
-
-C-indenting: A matching { in a comment is ignored, but intermediate { are not
-checked to be in a comment. Implement FM_SKIPCOMM flag of findmatchlimit().
-Issue 46.
-
-Mac with X11: clipboard doesn't work properly. (Raf, 2010 Aug 16)
-
-Using CompilerSet doesn't record where an option was set from. E.g., in the
-gcc compiler plugin. (Gary Johnson, 2010 Dec 13)
-
-":helpgrep" does not put the cursor in the correct column when preceded by
-accented character. (Tony Mechelynck, 2010 Apr 15)
-
-Don't call check_restricted() for histadd(), setbufvar(), settabvar(),
-setwinvar().
-
-Patch for GVimExt to show an icon. (Dominik Riebeling, 2010 Nov 7)
-
-When writing a file > 2Gbyte, the reported number of bytes is negative.
-(Antonio Colombo, 2010 Dec 18)
-
-Patch: Let rare word highlighting overrule good word highlighting.
-(Jakson A. Aquino, 2010 Jul 30, again 2011 Jul 2)
-
-When 'lines' is 25 and 'scrolloff' is 12, "j" scrolls zero or two lines
-instead of one. (Constantin Pan, 2010 Sep 10)
-
-Gui menu edit/paste in block mode insert only inserts in one line (Bjorn
-Winckler, 2011 May 11)
-Requires a map mode for Insert mode started from blockwise Visual mode.
-
-Writing nested List and Dict in viminfo gives error message and can't be read
-back. (Yukihiro Nakadaira, 2010 Nov 13)
-
-Problem with cursor in the wrong column. (SungHyun Nam, 2010 Mar 11)
-Additional info by Dominique Pelle. (also on 2010 Apr 10)
-
-CreateFile and CreateFileW are used without sharing, filewritable() fails when
-the file was already open (e.g. script is being sourced). Add FILE_SHARE_READ|
-FILE_SHARE_WRITE in mch_access()? (Phillippe Vaucher, 2010 Nov 2)
-
-Is ~/bin (literally) in $PATH supposed to work? (Paul, 2010 March 29)
-Looks like only bash can do it. (Yakov Lerner)
-
-Cscope "cs add" stopped working somewhat before 7.2.438. (Gary Johnson, 2010
-Jun 29) Caused by 7.2.433?
-
-I often see pasted text (from Firefox, to Vim in xterm) appear twice.
-Also, Vim in xterm sometimes loses copy/paste ability (probably after running
-an external command).
-
-Jumplist doesn't work properly in Insert mode? (Jean Johner, 2010 Mar 20)
-
-Problem with transparent cmdline. Also: Terminal title is wrong with
-non-ASCII character. (Lily White, 2010 Mar 7)
-
-iconv() doesn't fail on an illegal character, as documented. (Yongwei Wu, 2009
-Nov 15, example Nov 26) Add argument to specify whether iconv() should fail
-or replace with a character and continue?
-
-Add local time at start of --startuptime output.
-Requires configure check for localtime().
-Use format year-month-day hr:min:sec.
-
-Patch to add "combine" to :syntax, combines highlight attributes. (Nate
-Soares, 2012 Dec 3)
-
-Patch to make ":hi link" also take arguments. (Nate Soares, 2012 Dec 4)
-
-Shell not recognized properly if it ends in "csh -f". (James Vega, 2009 Nov 3)
-Find tail? Might have a / in argument. Find space? Might have space in
-path.
-
-Test 51 fails when language set to German. (Marco, 2011 Jan 9)
-Dominique can't reproduce it.
-
-'ambiwidth' should be global-local.
-
-":function f(x) keepjumps" creates a function where every command is executed
-like it has ":keepjumps" before it.
-
-Coverity: ask someone to create new user: Dominique.
-Check if there are new reported defects: http://scan.coverity.com/rung2.html
-
-Patch to support :undo absolute jump to file save number. (Christian Brabandt,
-2010 Nov 5)
-
-Patch to use 'foldnextmax' also for "marker" foldmethod. (Arnaud Lacombe, 2011
-Jan 7)
-
-Bug with 'incsearch' going to wrong line. (Wolfram Kresse, 2009 Aug 17)
-Only with "vim -u NONE".
-
-Problem with editing file in binary mode. (Ingo Krabbe, 2009 Oct 8)
-
-With 'wildmode' set to "longest:full,full" and pressing Tab once the first
-entry in wildmenu is highlighted, that shouldn't happen. (Yuki Watanabe, 2011
-Feb 12)
-
-Display error when 'tabline' that includes a file name with double-width
-characters. (2010 Aug 14, bootleq)
-
-Problem with stop directory in findfile(). (Adam Simpkins, 2009 Aug 26)
-
-Using ']' as the end of a range in a pattern requires double escaping:
- /[@-\\]] (Andy Wokula, 2011 Jun 28)
-
-Syntax priority problem. (Charles Campbell, 2011 Sep 15)
-
-When completion inserts the first match, it may trigger the line to be folded.
-Disable updating folds while completion is active? (Peter Odding, 2010 Jun 9)
-
-When a:base in 'completefunc' starts with a number it's passed as a number,
-not a string. (Sean Ma) Need to add flag to call_func_retlist() to force a
-string value.
-
-Invalid read error in Farsi mode. (Dominique Pelle, 2009 Aug 2)
-
-For running gvim on an USB stick: avoid the OLE registration. Use a command
-line argument -noregister.
-
-When using an expression in 'statusline' leading white space sometimes goes
-missing (but not always). (ZyX, 2010 Nov 1)
-
-When a mapping exists both for insert mode and lang-insert mode, the last one
-doesn't work. (Tyru, 2010 May 6) Or is this intended?
-
-Still a problem with ":make" in the wrong directory. Caused by ":bufdo".
-(Ajit Thakkar, 2009 Jul 1) More information Jul 9, Jul 15.
-Caused by "doautoall syntaxset BufEnter *" in syntax/nosyntax.vim ?
-There also is a BufLeave/BufEnter aucmd to save/restore view.
-Does the patch to save/restore globaldir work?
-
-":bufdo normal gg" while 'hidden' is set leaves buffers without syntax
-highlighting. Don't disable Syntax autocommands then? Or add a flag/modifier
-to avoid changing 'eventignore'?
-
-Patch for displaying 0x200c and 0x200d. (Ali Gholami Rudi, 2009 May 6)
-Probably needs a bit of work.
-
-Patch to add farsi handling to arabic.c (Ali Gholami Rudi, 2009 May 2)
-Added test, updates, June 23.
-Updated for 7.4: http://litcave.rudi.ir/farsi_vim.diff
-With modification for Tatweel character: https://dpaste.de/VmFw
-Remark from Ameretat Reith (2014 Oct 13)
-
-List of encoding aliases. (Takao Fujiwara, 2009 Jul 18)
-Are they all OK? Update Jul 22.
-
-Win32: Improved Makefile for MSVC. (Leonardo Valeri Manera, 2010 Aug 18)
-
-Win32: Expanding 'path' runs into a maximum size limit. (bgold12, 2009 Nov 15)
-
-Win32: Patch for enabling quick edit mode in console. (Craig Barkhouse, 2010
-Sep 1)
-
-Win32: Patch for using .png files for icons. (Charles Peacech, 2012 Feb 5)
-
-Putting a Visual block while 'visualedit' is "all" does not leave the cursor
-on the first character. (John Beckett, 2010 Aug 7)
-
-Setting 'tags' to "tagsdir/*" does not find "tagsdir/tags". (Steven K. Wong,
-2009 Jul 18)
-
-Patch to add "focusonly" to 'scrollopt', so that scrollbind also applies in
-window that doesn't have focus. (Jonathon Mah, 2009 Jan 12)
-Needs more work.
-
-Problem with <script> mappings (Andy Wokula, 2009 Mar 8)
-
-When starting Vim with "gvim -f -u non_existent_file > foo.txt" there are a
-few control characters in the output. (Dale Wiles, 2009 May 28)
-
-'cmdwinheight' is only used in last window when 'winheight' is a large value.
-(Tony Mechelynck, 2009 Apr 15)
-
-Status line containing winnr() isn't updated when splitting the window (Clark
-J. Wang, 2009 Mar 31)
-
-When $VIMRUNTIME is set in .vimrc, need to reload lang files. Already done
-for GTK, how about others? (Ron Aaron, 2010 Apr 10)
-
-Patch for GTK buttons X1Mouse and X2Mouse. (Christian J. Robinson, 2010 Aug 9)
-
-When 'ft' changes redraw custom status line.
-
-":tab split fname" doesn't set the alternate file in the original window,
-because win_valid() always returns FALSE. Below win_new_tabpage() in
-ex_docmd.c.
-
-Space before comma in function definition not allowed: "function x(a , b)"
-Give a more appropriate error message. Add a remark to the docs.
-
-string_convert() should be able to convert between utf-8 and utf-16le. Used
-for GTK clipboard. Avoid requirement for iconv.
-
-Now that colnr_T is int instead of unsigned, more type casts can be removed.
-
-'delcombine' does not work for the command line. (Tony Mechelynck, 2009 Jul
-20)
-
-Add "no_hlsearch" to winsaveview().
-
-Cursorline highlighting combines with Search ('hlsearch') but not with
-SpellBad. (Jim Karsten, 2009 Mar 18)
-
-When 'foldmethod' is "indent", adding an empty line below a fold and then
-indented text, creates a new fold instead of joining it with the previous one.
-(Evan Laforge, 2009 Oct 17)
-
-Bug: When reloading a buffer changed outside of Vim, BufRead autocommands
-are applied to the wrong buffer/window. (Ben Fritz, 2009 Apr 2, May 11)
-Ignore window options when not in the right window?
-Perhaps we need to use a hidden window for applying autocommands to a buffer
-that doesn't have a window.
-
-When using "ab foo bar" and mapping <Tab> to <Esc>, pressing <Tab> after foo
-doesn't trigger the abbreviation like <Esc> would. (Ramana Kumar, 2009 Sep 6)
-
-getbufvar() to get a window-local option value for a buffer that's not
-displayed in a window should return the value that's stored for that buffer.
-
-":he ctrl_u" can be auto-corrected to ":he ctrl-u".
-
-There should be a way after an abbreviation has expanded to go back to what
-was typed. CTRL-G h ? Would also undo last word or line break inserted
-perhaps. And undo CTRL-W. CTRL-G l would redo.
-
-Diff mode out of sync. (Gary Johnson, 2010 Aug 4)
-
-Support a 'systemencoding' option (for Unix). It specifies the encoding of
-file names. (Kikuchan, 2010 Oct 5). Useful on a latin1 or double-byte Asian
-system when 'encoding' is "utf-8".
-
-Win32: completion of file name ":e c:\!test" results in ":e c:\\!test", which
-does not work. (Nieko Maatjes, 2009 Jan 8, Ingo Karkat, 2009 Jan 22)
-
-opening/closing window causes other window with 'winfixheight' to change
-height. Also happens when there is another window in the frame, if it's not
-very high. (Yegappan Lakshmanan, 2010 Jul 22, Michael Peeters, 2010 Jul 22)
-
-Directory wrong in session file, caused by ":lcd" in BufEnter autocommand.
-(Felix Kater, 2009 Mar 3)
-
-Session file generates error upon loading, cause by --remote-silent-tab.
-(7tommm (ytommm) 2010 Nov 24)
-
-Using ~ works OK on 'a' with composing char, but not on 0x0418 with composing
-char 0x0301. (Tony Mechelynck, 2009 Mar 4)
-
-Searching for composing char works, but not when inside []. (ZyX, Benjamin R.
-Haskell, 2010 Aug 24)
-
-This does not work yet: "a\(%C\)" (get composing characters into a submatch).
-
-A function on a dictionary is not profiled. (ZyX, 2010 Dec 25)
-
-Inconsistent: starting with $LANG set to es_ES.utf-8 gives Spanish
-messages, even though locale is not supported. But ":lang messages
-es_ES.utf-8" gives an error and doesn't switch messages. (Dominique Pelle,
-2009 Jan 26)
-
-When $HOME contains special characters, such as a comma, escape them when used
-in an option. (Michael Hordijk, 2009 May 5)
-Turn "esc" argument of expand_env_esc() into string of chars to be escaped.
-
-Should make 'ignorecase' global-local, so that it makes sense setting it from
-a modeline.
-
-Add cscope target to Makefile. (Tony Mechelynck, 2009 Jun 18, replies by
-Sergey Khorev)
-
-Consider making YankRing or something else that keeps a list of yanked text
-part of standard Vim. The "1 to "9 registers are not sufficient.
-
-netrw: dragging status line causes selection of entry. Should check row
-number to be below last visible line.
-
-After doing "su" $HOME can be the old user's home, thus ~root/file is not
-correct. Don't use it in the swap file.
-
-Completion for ":buf" doesn't work properly on Win32 when 'shellslash' is off.
-(Henrik Ohman, 2009, Jan 29)
-
-shellescape() depends on 'shellslash' for quoting. That doesn't work when
-'shellslash' is set but using cmd.exe. (Ben Fritz)
-Use a different option or let it depend on whether 'shell' looks like a
-unix-like shell?
-
-Bug: in Ex mode (after "Q") backslash before line break, when yanked into a
-register and executed, results in <Nul>: instead of line break.
-(Konrad Schwarz, 2010 Apr 16)
-
-Have a look at patch for utf-8 line breaking. (Yongwei Wu, 2008 Mar 1, Mar 23)
-Now at: http://vimgadgets.sourceforge.net/liblinebreak/
-
-Greek sigma character should be lower cased depending on the context. Can we
-make this work? (Dominique Pelle, 2009 Sep 24)
-
-When changing 'encoding' convert all the swap file names, so that we can
-still delete them. Also convert all buffer file names?
-
-"gqip" in Insert mode has an off-by-one error, causing it to reflow text.
-(Raul Coronado, 2009 Nov 2)
-
-Update src/testdir/main.aap.
-
-Something wrong with session that has "cd" commands and "badd", in such a way
-that Vim doesn't find the edited file in the buffer list, causing the
-ATTENTION message? (Tony Mechelynck, 2008 Dec 1)
-Also: swap files are in ~/tmp/ One has relative file name ".mozilla/...".
-
-Add v:motion_force. (Kana Natsuno, 2008 Dec 6)
-Maybe call it v:motiontype.
-
-MS-Windows: editing the first, empty buffer, 'ffs' set to "unix,dos", ":enew"
-doesn't set 'ff' to "unix". (Ben Fritz, 2008 Dec 5) Reusing the old buffer
-probably causes this.
-
-'scrollbind' is not respected when deleting lines or undo. (Milan Vancura,
-2009 Jan 16)
-
-Patch to support strikethrough next to bold and italic. (Christian Brabandt,
-2013 Jul 30) Update from Ken Takata, 2013 Oct 12.
-
-Having "Syntax" in 'eventignore' for :bufdo may cause problems, e.g. for
-":bufdo e" when buffers are open in windows. ex_listdo(eap) could set the
-option only for when jumping to another buffer, not when the command argument
-is executed.
-
-":pedit %" with a BufReadPre autocommand causes the cursor to move to the
-first line. (Ingo Karkat, 2008 Jul 1) Ian Kelling is working on this.
-Similar problem with ":e". (Marc Montu, 2014 Apr 22)
-
-Wildmenu not deleted: "gvim -u NONE", ":set nocp wildmenu cmdheight=3
-laststatus=2", CTRL-D CTRL-H CTRL-H CTRL-H. (A.Politz, 2008 April 1)
-Works OK with Vim in an xterm.
-
-Cursor line moves in other window when using CTRL-W J that doesn't change
-anything. (Dasn, 2009 Apr 7)
-
-On Unix "glob('does not exist~')" returns the string. Without the "~" it
-doesn't. (John Little, 2008 Nov 9)
-Shell expansion returns unexpanded string?
-Don't use shell when "~" is not at the start?
-
-":unlet $VAR" doesn't work.
-
-When using ":e ++enc=foo file" and the file is already loaded with
-'fileencoding' set to "bar", then do_ecmd() uses that buffer, even though the
-fileencoding differs. Reload the buffer in this situation? Need to check for
-the buffer to be unmodified.
-Unfinished patch by Ian Kelling, 2008 Jul 11. Followup Jul 14, need to have
-another look at it.
-
-c.vim: XXX in a comment is colored yellow, but not when it's after "#if 0".
-(Ilya Dogolazky, 2009 Aug 7)
-
-You can type ":w ++bad=x fname", but the ++bad argument is ignored. Give an
-error message? Or is this easy to implement? (Nathan Stratton Treadway, 2008
-Aug 20) This is in ucs2bytes(), search for 0xBF. Using the ++bad argument is
-at the other match for 0xBF.
-
-When adding "-complete=file" to a user command this also changes how the
-argument is processed for <f-args>. (Ivan Tishchenko, 2008 Aug 19)
-
-Win32: associating a type with Vim doesn't take care of space after a
-backslash? (Robert Vibrant, 2008 Jun 5)
-
-When 'rightleft' is set, cursorcolumn isn't highlighted after the end of a
-line. It's also wrong in folds. (Dominique Pelle, 2010 Aug 21)
-
-Using an insert mode expression mapping, cursor is not in the expected
-position. (ZyX, 2010 Aug 29)
-
-After using <Tab> for command line completion after ":ta blah" and getting E33
-(no tags file), further editing the command to e.g., ":echo 'blah'", the
-command is not executed. Fix by Ian Kelling?
-
-":help s/~" jumps to *s/\~*, while ":help s/\~" doesn't find anything. (Tim
-Chase) Fix by Ian Kelling, 2008 Jul 14.
-
-Use "\U12345678" for 32 bit Unicode characters? (Tony Mechelynck, 2009
-Apr 6) Or use "\u(123456)", similar to Perl.
-
-When mapping : to ; and ; to :, @; doesn't work like @: and @: doesn't work
-either. Matt Wozniski: nv_at() calls do_execreg() which uses
-put_in_typebuf(). Char mapped twice?
-
-Despite adding save_subexpr() this still doesn't work properly:
-Regexp: matchlist('12a4aaa', '^\(.\{-}\)\(\%5c\@<=a\+\)\(.\+\)\?')
-Returns ['12a4', 'aaa', '4aaa'], should be ['12a4', 'aaa', '']
-Backreference not cleared when retrying after \@<= fails?
-(Brett Stahlman, 2008 March 8)
-
-Problem with remote_send(). (Charles Campbell, 2008 Aug 12)
-
-ftplugin for help file should set 'isk' to help file value.
-
-Win32: remote editing fails when the current directory name contains "[".
-(Ivan Tishchenko, Liu Yubao) Suggested patch by Chris Lubinski: Avoid
-escaping characters where the backslash is not removed later. Asked Chris for
-an alternate solution, also for src/ex_getln.c.
-This also fails when the file or directory name contains "%". (Thoml, 2008
-July 7)
-Using --remote-silent while the current directory has a # in the name does not
-work, the # needs to be escaped. (Tramblay Bruno, 2012 Sep 15)
-
-When using remote-silent the -R flag is not passed on. (Axel Bender, 2012 May
-31)
-
-Win32: A --remote command that has a directory name starting with a ( doesn't
-work, the backslash is removed, assuming that it escapes the (. (Valery
-Kondakoff, 2009 May 13)
-
-Problem with 'langmap' being used on the rhs of a mapping. (Nikolai Weibull,
-2008 May 14)
-
-Problem with CTRL-F. (Charles Campbell, 2008 March 21)
-Only happens with "gvim -geometry "160x26+4+27" -u NONE -U NONE prop.c".
-'lines' is 54. (2008 March 27)
-
-Problem with pointer wrapping around in getvcol(). (Wolfgang Kroworsch, 2008
-Oct 19) Check for "col" being "MAXCOL" separately?
-
-Unexpectedly inserting a double quote. (Anton Woellert, 2008 Mar 23)
-Works OK when 'cmdheight' is 2.
-
-8 Use a mechanism similar to omni completion to figure out the kind of tab
- for CTRL-] and jump to the appropriate matching tag (if there are
- several).
- Alternative: be able to define a function that takes the tag name and uses
- taglist() to find the right location. With indication of using CTRL-] so
- that the context can be taken into account. (Robert Webb)
-Patch by Christian Brabandt, 2013 May 31.
-
-Test54 should not use shell commands. Make it portable.
-
-The utf class table is missing some entries:
- 0x2212, minus sign
- 0x2217, star
- 0x2500, bar
- 0x26ab, circle
-
-Visual line mode doesn't highlight properly when 'showbreak' is used and the
-line doesn't fit. (Dasn, 2008 May 1)
-
-Mac: After a ":vsplit" the left scrollbar doesn't appear until 'columns' is
-changed or the window is resized.
-
-Mac: Patch for configure: remove arch from ruby link args. (Knezevic, 2008
-Mar 5) Alternative: Kazuki Sakamoto, Mar 7.
-
-C't: On utf-8 system, editing file with umlaut through Gnome results in URL
-with %nn%nn, which is taken as two characters instead of one.
-Try to reproduce at work.
-
-Patch for default choice in file changed dialog. (Bjorn Winckler, 2008 Oct 19)
-Is there a way to list all the files first?
-
-When 'smartcase' is set and using CTRL-L to add to the search pattern it may
-result in no matches. Convert chars to lower case? (Erik Wognsen, 2009 Apr
-16)
-
-Fail to edit file after failed register access. Error flag remains set?
-(Lech Lorens, 2010 Aug 30)
-
-Patch for redo register. (Ben Schmidt, 2007 Oct 19)
-Await response to question to make the register writable.
-
-src/testdir/Make_dos.mak: not all tests are included, e.g., test49, without a
-remark why.
-
-Problem with 'ts' set to 9 and 'showbreak' to ">>>". (Matthew Winn, 2007 Oct
-1)
-
-In the swapfile dialog, add a H(elp) option that gives more info about what
-each choice does. Similar to ":help swap-exists-choices"
-
-try/catch not working for argument of return. (Matt Wozniski, 2008 Sep 15)
-
-try/catch not working when inside a for loop. (ZyX, 2011 Jan 25)
-
-":tab help" always opens a new tab, while ":help" re-uses an existing window.
-Would be more consistent when an existing tab is re-used. (Tony Mechelynck)
-
-Add ":nofold". Range will apply without expanding to closed fold.
-
-Using Aap to build Vim: add remarks about how to set personal preferences.
-Example on http://www.calmar.ws/tmp/aap.html
-
-Syntax highlighting wrong for transparent region. (Doug Kearns, 2007 Feb 26)
-Bug in using a transparent syntax region. (Hanlen in vim-dev maillist, 2007
-Jul 31)
-
-C syntax: {} inside () causes following {} to be highlighted as error.
-(Michalis Giannakidis, 2006 Jun 1)
-
-When 'diffopt' has "context:0" a single deleted line causes two folds to merge
-and mess up syncing. (Austin Jennings, 2008 Jan 31)
-
-Gnome improvements: Edward Catmur, 2007 Jan 7
- Also use Save/Discard for other GUIs
-
-New PHP syntax file, use it? (Peter Hodge)
-
-":echoe" in catch block stops processing, while this doesn't happen outside of
-a catch block. (ZyX, 2011 Jun 2)
-
-'foldcolumn' in modeline applied to wrong window when using a session. (Teemu
-Likonen, March 19)
-
-Test 54 uses shell commands, that doesn't work on non-Unix systems. Use some
-other way to test buffer-local autocommands.
-
-The documentation mentions the priority for ":2match" and ":3match", but it
-appears the last one wins. (John Beckett, 2008 Jul 22) Caused by adding
-matchadd()? Suggested patch by John, 2008 Jul 24.
-
-When 'encoding' is utf-8 the command line is redrawn as a whole on every
-character typed. (Tyler Spivey, 2008 Sep 3) Only redraw cmdline for
-'arabicshape' when there is a character on the command line for which
-(ARABIC_CHAR(u8c)) is TRUE.
-
-Cheng Fang made javacomplete. (2007 Aug 11)
-Asked about latest version: 0.77.1 is on www.vim.org.
-
-Insert mode completion: When editing the text and pressing CTRL-N again goes
-back to originally completed text, edited text is gone. (Peng Yu, 2008 Jul 24)
-Suggestion by Ben Schmidt, 2008 Aug 6.
-
-Problem with compound words? (Bert, 2008 May 6)
-No warning for when flags are defined after they are used in an affix.
-
-Screen redrawing when continuously updating the buffer and resizing the
-terminal. (Yakov Lerner, 2006 Sept 7)
-
-Add option settings to help ftplugin. (David Eggum, 2006 Dec 18)
-
-Autoconf problem: when checking for iconv library we may add -L/usr/local/lib,
-but when compiling further tests -liconv is added without the -L argument,
-that may fail (e.g., sizeof(int)). (Blaine, 2007 Aug 21)
-
-When opening quickfix window, disable spell checking?
-
-Problem with ".add" files when using two languages and restarting Vim. (Raul
-Coronado, 2008 Oct 30)
-
-Popup menu redraw: Instead of first redrawing the text and then drawing the
-popup menu over it, first draw the new popup menu, remember its position and
-size and then redraw the text, skipping the characters under the popup menu.
-This should avoid flicker. Other solution by A.Politz, 2007 Aug 22.
-
-Windows 98: pasting from the clipboard with text from another application has
-a trailing NUL. (Joachim Hofmann) Perhaps the length specified for CF_TEXT
-isn't right?
-
-When a register contains illegal bytes, writing viminfo in utf-8 and reading
-it back doesn't result in utf-8. (Devin Bayer)
-
-Command line completion: Scanning for tags doesn't check for typed key now and
-then? Hangs for about 5 seconds. Appears to be caused by finding include
-files with "foo/**" in 'path'. (Kalisiak, 2006 July 15)
-Additional info: When using the |wildcards| ** globing, vim hangs
-indefinitely on lots of directories. The |file-searching| globing, like in
-":set path=/**" does not hang as often as with globing with |wildcards|, like
-in ":1find /**/file". This is for files that unix "find" can find very
-quickly. Merging the 2 kinds of globing might make this an easier fix. (Ian
-Kelling, 2008 July 4)
-
-When the file name has parenthesis, e.g., "foo (bar).txt", ":!ls '%'" has the
-parenthesis escaped but not the space. That's inconsistent. Either escape
-neither or both. No escaping might be best, because it doesn't depend on
-particularities of the shell. (Zvi Har'El, 2007 Nov 10) (Teemu Likonen, 2008
-Jun 3)
-However, for backwards compatibility escaping might be necessary. Check if
-the user put quotes around the expanded item?
-
-A throw in a function causes missing an endif below the call. (Spiros
-Bousbouras, 2011 May 16)
-
-Error E324 can be given when a cron script has wiped out our temp directory.
-Give a clear error message about this (and tell them not to wipe out /tmp).
-
-Color for cUserLabel should differ from case label, so that a mistake in a
-switch list is noticed:
- switch (i)
- {
- case 1:
- foobar:
- }
-
-Look at http://www.gtk-server.org/ . It has a Vim script implementation.
-
-Netbeans problem. Use "nc -l 127.0.0.1 55555" for the server, then run gvim
-with "gvim -nb:localhost:55555:foo". From nc do: '1:editFile!0 "foo"'. Then
-go to Insert mode and add a few lines. Then backspacing every other time
-moves the cursor instead of deleting. (Chris Kaiser, 2007 Sep 25)
-
-Windows installer should install 32-bit version of right-click handler also on
-64-bit systems. (Brian Cunningham, 2011 Dec 28)
-
-Windows installer could add a "open in new tab of existing Vim" menu entry.
-Gvimext: patch to add "Edit with single Vim &tabbed" menu entry.
-Just have two choices, always using one Vim and selecting between using an
-argument list or opening each file in a separate tab.
-(Erik Falor, 2008 May 21, 2008 Jun 26)
-
-Windows installer: licence text should not use indent, causes bad word wrap.
-(Benjamin Fritz, 2010 Aug 16)
-
-Dos uninstal may delete vim.bat from the wrong directory (e.g., when someone
-makes his own wrapper). Add a magic string with the version number to the
-.bat file and check for it in the uninstaller. E.g.
- # uninstall key: vim7.3*
-
-Changes for Win32 makefile. (Mike Williams, 2007 Jan 22, Alexei Alexandrov,
-2007 Feb 8)
-
-Win32: Can't complete shell command names. Why is setting xp_context in
-set_one_cmd_context() inside #ifndef BACKSLASH_IN_FILENAME?
-
-Win32: Patch for cscope external command. (Mike Williams, 2007 Aug 7)
-
-Win32: XPM support only works with path without spaces. Patch by Mathias
-Michaelis, 2006 Jun 9. Another patch for more path names, 2006 May 31.
-New version: http://members.tcnet.ch/michaelis/vim/patches.zip (also for other
-patches by Mathias, see mail Feb 22)
-
-Win32: compiling with normal features and OLE fails. Patch by Mathias
-Michaelis, 2006 Jun 4.
-
-Win32: after "[I" showing matches, scroll wheel messes up screen. (Tsakiridis,
-2007 Feb 18)
-Patch by Alex Dobrynin, 2007 Jun 3. Also fixes other scroll wheel problems.
-
-Win32: using CTRL-S in Insert mode doesn't remove the "+" from the tab pages
-label. (Tsakiridis, 2007 Feb 18) Patch from Ian Kelling, 2008 Aug 6.
-
-Win32: using "gvim --remote-tab-silent fname" sometimes gives an empty screen
-with the more prompt. Caused by setting the guitablabel? (Thomas Michael
-Engelke, 2007 Dec 20 - 2008 Jan 17)
-
-Win64: Seek error in swap file for a very big file (3 Gbyte). Check storing
-pointer in long and seek offset in 64 bit var.
-Patches from Ken Takata might help (2014 Apr 17)
-
-Win32: patch for fullscreen mode. (Liushaolin, 2008 April 17)
-
-Win32: When 'shell' is bash shellescape() doesn't always do the right thing.
-Depends on 'shellslash', 'shellquote' and 'shellxquote', but shellescape()
-only takes 'shellslash' into account.
-
-Menu item that does "xxd -r" doesn't work when 'fileencoding' is utf-16.
-Check for this and use iconv? (Edward L. Fox, 2007 Sep 12)
-Does the conversion in the other direction work when 'fileencodings' is set
-properly?
-
-Add a few features to xxd. (Vadim Vygonets, 2013 Nov 11)
-Patches: 2013 Nov 19
-1: Add -e: little endian hexdump
-2: Add -o: add offset to displayed position
-3: Change displayed file position width to 8 chars
-
-Cursor displayed in the wrong position when using 'numberwidth'. (James Vega,
-2007 Jun 21)
-
-When $VAR contains a backslash expand('$VAR') removes it. (Teemu Likonen, 2008
-Jun 18)
-
-If the variable "g:x#y#z" exists completion after ":echo g:x#" doesn't work.
-
-Feature request: Command to go to previous tab, like what CTRL-W p does for
-windows. (Adam George)
-
-F1 - F4 in an xterm produce a different escape sequence when used with a
-modifier key. Need to catch three different sequences. Use K_ZF1, like
-K_ZHOME? (Dickey, 2007 Dec 2)
-
-UTF-8: mapping a multi-byte key where the second byte is 0x80 doesn't appear
-to work. (Tony Mechelynck, 2007 March 2)
-
-In debug mode, using CTRL-R = to evaluate a function causes stepping through
-the function. (Hari Krishna Dara, 2006 Jun 28)
-
-C++ indenting wrong with "=". (James Kanze, 2007 Jan 26)
-
-":lockvar" should use copyID to avoid endless loop.
-
-When using --remote-silent and the file name matches 'wildignore' get an E479
-error. without --remote-silent it works fine. (Ben Fritz, 2008 Jun 20)
-
-Gvim: dialog for closing Vim should check if Vim is busy writing a file. Then
-use a different dialog: "busy saving, really quit? yes / no".
-
-":helpgrep" should use the directory from 'helpfile'.
-
-The need_fileinfo flag is messy. Instead make the message right away and put
-it in keep_msg?
-
-Editing a file remotely that matches 'wildignore' results in a "no match"
-error. Should only happen when there are wildcards, not when giving the file
-name literally, and esp. if there is only one name.
-
-Test 61 fails sometimes. This is a timing problem: "sleep 2" sometimes takes
-longer than 2 seconds.
-
-Using ":au CursorMoved * cmd" invokes mch_FullName(), which can be slow.
-Can this be avoided? (Thomas Waba, 2008 Aug 24)
-Also for ":w" without a file name.
-The buffer has the full path in ffname, should pass this to the autocommand.
-
-input() completion should not insert a backslash to escape a space in a file
-name?
-
-Ruby completion is insecure. Can this be fixed?
-
-When 'backupskip' is set from $TEMP special characters need to be escaped.
-(patch by Grembowietz, 2007 Feb 26, not quite right)
-Another problem is that file_pat_to_reg_pat() doesn't recognize "\\", so "\\("
-will be seen as a path separator plus "\(".
-
-gvim d:\path\path\(FILE).xml should not remove the \ before the (.
-This also fails with --remote.
-
-When doing ":quit" the Netbeans "killed" event isn't sent. (Xavier de Gaye,
-2008 Nov 10) call netbeans_file_closed() at the end of buf_freeall(), or in
-all places where buf_freeall() is called?
-
-aucmd_prepbuf() should also use a window in another tab page.
-
-When unloading a buffer in a BufHidden autocommand the hidden flag is reset?
-(Bob Hiestand, 2008 Aug 26, Aug 27)
-
-Substituting an area with a line break with almost the same area does change
-the Visual area. Can this be fixed? (James Vega, 2006 Sept 15)
-
-Spell checking: Add a way to specify punctuation characters. Add the
-superscript numbers by default: 0x2070, 0xb9, 0xb2, 0xb3, 0x2074 - 0x2079.
-
-Spell checking in popup menu: If the only problem is the case of the first
-character, don't offer "ignore" and "add to word list".
-
-Use different pt_br dictionary for spell checking. (Jackson A. Aquino, 2006
-Jun 5)
-
-Use different romanian dictionary for spell checking. (Andrei Popescu, Nov
-2008) Use http://downloads.sourceforge.net/rospell/ro_RO.3.2.zip
-Or the hunspell-ro.3.2.tar.gz file, it also has a iso-8859-2 list.
-
-In a C file with spell checking, in "% integer" "nteger" is seen as an error,
-but "]s" doesn't find it. "nteger" by itself is found. (Ralf Wildenhues, 2008
-Jul 22)
-
-There should be something about spell checking in the user manual.
-
-Spell menu: When using the Popup menu to select a replacement word,
-":spellrepeat" doesn't work. SpellReplace() uses setline(). Can it use "z="
-somehow? Or use a new function.
-
-Mac: Using gvim: netrw window disappears. (Nick Lo, 2006 Jun 21)
-
-Add an option to specify the character to use when a double-width character is
-moved to the next line. Default '>', set to a space to blank it out. Check
-that char is single width when it's set (compare with 'listchars').
-
-The generated vim.bat can avoid the loop for NT. (Carl Zmola, 2006 Sep 3)
-
-When showing a diff between a non-existent file and an existing one, with the
-cursor in the empty buffer, the other buffer only shows the last line. Change
-the "insert" into a change from one line to many? (Yakov Lerner, 2008 May 27)
-
-Add autocommand for when a tabpage is being closed. Also for when a tab page
-has been created.
-
-Using ":make" blocks Vim. Allow running one make in the background (if the
-shell supports it), catch errors in a file and update the error list on the
-fly. A bit like "!make > file&" and repeating ":cf file". ":bgmake",
-background make. ":bgcancel" interrupts it.
-A.Politz may work on this.
-
-These two abbreviations don't give the same result:
- let asdfasdf = "xyz\<Left>"
- cabbr XXX <C-R>=asdfasdf<CR>
- cabbr YYY xyz<Left>
-
-Michael Dietrich: maximized gvim sometimes displays output of external command
-partly. (2006 Dec 7)
-
-In FileChangedShell command it's no longer allowed to switch to another
-buffer. But the changed buffer may differ from the current buffer, how to
-reload it then?
-
-New syntax files for fstab and resolv from Radu Dineiu, David Necas did
-previous version.
-
-For Aap: include a config.arg.example file with hints how to use config.arg.
-
-Command line completion when 'cmdheight' is maximum and 'wildmenu' is set,
-only one buffer line displayed, causes display errors.
-
-Completing with 'wildmenu' and using <Up> and <Down> to move through directory
-tree stops unexpectedly when using ":cd " and entering a directory that
-doesn't contain other directories.
-
-Default for 'background' is wrong when using xterm with 256 colors.
-Table with estimates from Matteo Cavalleri, 2014 Jan 10.
-
-Setting 'background' resets the Normal background color:
- highlight Normal ctermbg=DarkGray
- set background=dark
-This is undesired, 'background' is supposed to tell Vim what the background
-color is, not reset it.
-
-Linux distributions:
-- Suggest compiling xterm with --enable-tcap-query, so that nr of colors is
- known to Vim. 88 colors instead of 16 works better. See ":help
- xfree-xterm".
-- Suggest including bare "vi" and "vim" with X11, syntax, etc.
-
-Completion menu: For a wrapping line, completing a long file name, only the
-start of the path is shown in the menu. Should move the menu to the right to
-show more text of the completions. Shorten the items that don't fit in the
-middle?
-
-When running inside screen it's possible to kill the X server and restart it
-(using pty's the program can keep on running). Vim dies because it loses the
-connection to the X server. Can Vim simply quit using the X server instead of
-dying? Also relevant when running in a console.
-
-Accessing file#var in a function should not need the g: prepended.
-
-When exiting detects a modified buffer, instead of opening the buffer in the
-current tab, use an existing tab, if possible. Like finding a window where
-the buffer is displayed. (Antonios Tsakiridis)
-
-When ":cn" moves to an error in the same line the message isn't shortened.
-Only skip shortening for ":cc"?
-
-Write "making vim work better" for the docs (mostly pointers): *nice*
- - sourcing $VIMRUNTIME/vimrc_example.vim
- - setting 'mouse' to "a"
- - getting colors in xterm
- - compiling Vim with X11, GUI, etc.
-
-Problem with ":call" and dictionary function. Hari Krishna Dara, Charles
-Campbell 2006 Jul 06.
-
-Syntax HL error caused by "containedin". (Peter Hodge, 2006 Oct 6)
-
-A custom completion function in a ":command" cannot be a Funcref. (Andy
-Wokula, 2007 Aug 25)
-
-Problem with using :redir in user command completion function? (Hari Krishna
-Dara, 2006 June 21)
-
-Another resizing problem when setting 'columns' and 'lines' to a very large
-number. (Tony Mechelynck, 2007 Feb 6)
-
-After starting Vim, using '0 to jump somewhere in a file, ":sp" doesn't center
-the cursor line. It works OK after some other commands.
-
-Win32: Is it possible to have both postscript and Win32 printing?
-
-Check: Running Vim in a console and still having connect to the X server for
-copy/paste: is stopping the X server handled gracefully? Should catch the X
-error and stop using the connection to the server.
-
-Problem with 'cdpath' on MS-Windows when a directory is equal to $HOME. (2006
-Jul 26, Gary Johnson)
-
-Using UTF-8 character with ":command" does not work properly. (Matt Wozniski,
-2008 Sep 29)
-
-In the Netbeans interface add a "vimeval" function, so that the other side can
-check the result of has("patch13").
-
-Cursor line at bottom of window instead of halfway through after saving view
-and restoring. Only with 'nowrap'. (Robert Webb, 2008 Aug 25)
-
-Netrw has trouble executing autocommands only for a directory. Add <isdir>
-and <notisdir> to autocommand patterns? Also <isfile>?
-
-Add command modifier that skips wildcard expansion, so that you don't need to
-put backslashes before special chars, only for white space.
-
-Syntax HL: open two windows on the same C code, delete a ")" in one window,
-resulting in highlighted "{" in that window, not in the other.
-
-In mswin.vim: Instead of mapping <C-V> for Insert mode in a complicated way,
-can it be done like ":imap <C-V> <MiddleMouse>" without negative side effects?
-
-When right after "vim file", "M" then CTRL-W v the windows are scrolled
-differently and unexpectedly. Caused by patch 7.2.398?
-
-The magic clipboard format "VimClipboard2" appears in several places. Should
-be only one.
-
-It's difficult to debug numbered functions (function in a Dictionary). Print
-the function name before resolving it to a number?
- let d = {}
- fun! d.foo()
- echo "here"
- endfun
- call d.foo(9)
-
-Add a mark for the other end of the Visual area (VIsual pos). '< and '> are
-only set after Visual moded is ended.
-Also add a variable for the Visual mode. So that this mode and '< '> can be
-used to set what "gv" selects. (Ben Schmidt)
-
-Win32: When running ":make" and 'encoding' differs from the system locale, the
-output should be converted. Esp. when 'encoding' is "utf-8". (Yongwei Wu)
-Should we use 'termencoding' for this?
-
-Win32, NTFS: When editing a specific infostream directly and 'backupcopy' is
-"auto" should detect this situation and work like 'backupcopy' is "yes". File
-name is something like "c:\path\foo.txt:bar", includes a colon. (Alex
-Jakushev, 2008 Feb 1)
-
-printf() uses the field width in bytes. Can it be made character width,
-perhaps with a modifier? What does Posix say?
-
-Small problem displaying diff filler line when opening windows with a script.
-(David Luyer, 2007 Mar 1 ~/Mail/oldmail/mool/in.15872 )
-
-Is it allowed that 'backupext' is empty? Problems when backup is in same dir
-as original file? If it's OK don't compare with 'patchmode'. (Thierry Closen)
-
-Patch for supporting count before CR in quickfix window. (AOYAMA Shotaro, 2007
-Jan 1)
-
-Patch for adding ":lscscope". (Navdeep Parhar, 2007 Apr 26; update 2008 Apr
-23)
-
-":mkview" isn't called with the right buffer argument. Happens when using
-tabs and the autocommand "autocmd BufWinLeave * mkview". (James Vega, 2007
-Jun 18)
-
-xterm should be able to pass focus changes to Vim, so that Vim can check for
-buffers that changed. Perhaps in misc.c, function selectwindow().
-Xterm 224 supports it!
-
-When completing from another file that uses a different encoding completion
-text has the wrong encoding. E.g., when 'encoding' is utf-8 and file is
-latin1. Example from Gombault Damien, 2007 Mar 24.
-
-Is it possible to use "foo#var" instead of "g:foo#var" inside a function?
-
-Syntax HL: When using "nextgroup" and the group has an empty match, there is
-no search at that position for another match. (Lukas Mai, 2008 April 11)
-
-In gvim the backspace key produces a backspace character, but on Linux the
-VERASE key is Delete. Set VERASE to Backspace? (patch by Stephane Chazelas,
-2007 Oct 16)
-
-Create a gvimtutor.1 file and change Makefiles to install it.
-
-When 'encoding' is utf-8 typing text at the end of the line causes previously
-typed characters to be redrawn. Caused by patch 7.1.329. (Tyler Spivey, 2008
-Sep 3, 11)
-
-X11: Putting more than about 262040 characters of text on the clipboard and
-pasting it in another Vim doesn't work. (Dominique Pelle, 2008 Aug 21-23)
-clip_x11_request_selection_cb() is called with zero value and length.
-Also: Get an error message from free() in the process that owns the selection.
-Seems to happen when the selection is requested the second time, but before
-clip_x11_convert_selection_cb() is invoked, thus in X library code.
-
-":vimgrep" does not recognize a recursive symlink. Is it possible to detect
-this, at least for Unix (using device/inode)?
-
-When switching between windows the cursor is often put in the middle.
-Remember the relative position and restore that, just like lnum and col are
-restored. (Luc St-Louis)
-
-Add an option for a minimal text length before inserting a line break for
-'textwidth'. Avoids very short lines when a very long word follows.
-(Kartik Agaram)
-
-
-At next release:
-- Build a huge version by default.
-- Improve plugin handling: Automatic updates, handle dependencies?
- E.g. Vundle: https://github.com/gmarik/vundle
-
-
-More patches:
-- Another patch for Javascript indenting. (Hari Kumar, 2010 Jul 11)
- Needs a few tests.
-- Add 'cscopeignorecase' option. (Liang Wenzhi, 2006 Sept 3)
-- Argument for feedkeys() to prepend to typeahead (Yakov Lerner, 2006 Oct
- 21)
-- Load intl.dll too, not only libintl.dll. (Mike Williams, 2006 May 9, docs
- patch May 10)
-- Extra argument to strtrans() to translate special keys to their name (Eric
- Arnold, 2006 May 22)
-- 'threglookexp' option: only match with first word in thesaurus file.
- (Jakson A. Aquino, 2006 Jun 14)
-- Mac: indicate whether a buffer was modified. (Nicolas Weber, 2006 Jun 30)
-- Allow negative 'nrwidth' for left aligning. (Nathan Laredo, 2006 Aug 16)
-- ml_append_string(): efficiently append to an existing line. (Brad
- Beveridge, 2006 Aug 26) Use in some situations, e.g., when pasting a
- character at a time?
-- recognize hex numbers better. (Mark Manning, 2006 Sep 13)
-- Add <AbbrExpand> key, to expand an abbreviation in a mapping. (Kana
- Natsuno, 2008 Jul 17)
-- Add 'wspara' option, also accept blank lines like empty lines for "{" and
- "}". (Mark Lundquist, 2008 Jul 18)
-- Patch to add CTRL-T to delete part of a path on cmdline. (Adek, 2008 Jul
- 21)
-- Instead of creating a copy of the tutor in all the shell scripts, do it in
- vimtutor.vim. (Jan Minar, 2008 Jul 20)
-- When fsync() fails there is no hint about what went wrong. Patch by Ben
- Schmidt, 2008 Jul 22.
-- testdir/Make_dos_sh.mak for running tests with MingW. (Bill Mccarthy, 2008
- Sep 13)
-- Patch for adding "space" item in 'listchars'. (Jérémie Roquet, 2009 Oct 29,
- Docs patch Oct 30, update David Burgin (glts) 2013 Aug 24, 2014 Oct 10)
-- Replace ccomplete.vim by cppcomplete.vim from www.vim.org? script 1520 by
- Vissale Neang. (Martin Stubenschrott) Asked Vissale to make the scripts
- more friendly for the Vim distribution.
- New version received 2008 Jan 6.
- No maintenance in two years...
-- Patch to open dropped files in new tabs. (Michael Trim, 2010 Aug 3)
-
-Awaiting updated patches:
-9 Mac unicode patch (Da Woon Jung, Eckehard Berns):
- 8 Add patch from Muraoka Taro (Mar 16) to support input method on Mac?
- New patch 2004 Jun 16
- - selecting proportional font breaks display
- - UTF-8 text causes display problems. Font replacement causes this.
- - Command-key mappings do not work. (Alan Schmitt)
- - With 'nopaste' pasting is wrong, with 'paste' Command-V doesn't work.
- (Alan Schmitt)
-9 HTML indenting can be slow. Caused by using searchpair(). Can search()
- be used instead? A.Politz is looking into a solution.
-8 Win32: Add minidump generation. (George Reilly, 2006 Apr 24)
-8 Add ":n" to fnamemodify(): normalize path, remove "../" when possible.
- Aric Blumer has a patch for this. He will update the patch for 6.3.
-7 Completion of network shares, patch by Yasuhiro Matsumoto.
- Update 2004 Sep 6.
- How does this work? Missing comments.
-8 Add a few more command names to the menus. Patch from Jiri Brezina
- (28 feb 2002). Will mess the translations...
-7 ATTENTION dialog choices are more logical when "Delete it" appears
- before "Quit". Patch by Robert Webb, 2004 May 3.
-- Include flipcase patch: ~/vim/patches/wall.flipcase2 ? Make it work
- for multi-byte characters.
-- Win32: add options to print dialog. Patch from Vipin Aravind.
-- Patch to add highlighting for whitespace. (Tom Schumm, 2003 Jul 5)
- use the patch that keeps using HLF_8 if HLF_WS has not
- been given values.
- Add section in help files for these highlight groups?
-8 "fg" and "bg" don't work in an xterm. Get default colors from xterm
- with an ESC sequence.
- xterm can send colors for many things. E.g. for the cursor:
- <Esc>]12;?<Bel>
- Can use this to get the background color and restore the colors on exit.
-7 Add "DefaultFG" and "DefaultBG" for the colors of the menu. (Marcin
- Dalecki has a patch for Motif and Carbon)
-- Add possibility to highlight specific columns (for Fortran). Or put a
- line in between columns (e.g., for 'textwidth').
- Patch to add 'hlcolumn' from Vit Stradal, 2004 May 20.
-8 Add functions:
- gettext() Translate a message. (Patch from Yasuhiro Matsumoto)
- Update 2004 Sep 10
- Another patch from Edward L. Fox (2005 Nov 24)
- Search in 'runtimepath'?
- More docs needed about how to use this.
- How to get the messages into the .po files?
- strchars() Like strlen() and strwidth() but counting characters
- instead of bytes.
- confirm() add "flags" argument, with 'v' for vertical
- layout and 'c' for console dialog. (Haegg)
- Flemming Madsen has a patch for the 'c' flag
- (2003 May 13)
- raisewin() raise gvim window (see HierAssist patch for
- Tcl implementation ~/vim/HierAssist/ )
- taglist() add argument to specify maximum number of matches.
- useful for interactive things or completion.
- col('^') column of first non-white character.
- Can use "len(substitute(getline('.'), '\S.*', '', ''))
- + 1", but that's ugly.
-7 Add patch from Benoit Cerrina to integrate Vim and Perl functions
- better. Now also works for Ruby (2001 Nov 10)
-- Patch from Herculano de Lima Einloft Neto for better formatting of the
- quickfix window (2004 dec 2)
-7 When 'rightleft' is set, the search pattern should be displayed right
- to left as well? See patch of Dec 26. (Nadim Shaikli)
-8 Option to lock all used memory so that it doesn't get swapped to disk
- (uncrypted). Patch by Jason Holt, 2003 May 23. Uses mlock.
-7 Add ! register, for shell commands. (patch from Grenie)
-8 In the gzip plugin, also recognize *.gz.orig, *.gz.bak, etc. Like it's
- done for filetype detection. Patch from Walter Briscoe, 2003 Jul 1.
-7 Add a "-@ filelist" argument: read file names from a file. (David
- Kotchan has a patch for it)
-8 Include a connection to an external program through a pipe? See
- patches from Felbinger for a mathematica interface.
- Or use emacs server kind of thing?
-7 Add ":justify" command. Patch from Vit Stradal 2002 Nov 25.
-- findmatch() should be adjusted for Lisp. See remark at
- get_lisp_indent(). Esp. \( and \) should be skipped. (Dorai Sitaram,
- incomplete patch Mar 18)
-- Patch for "paranoid mode" by Kevin Collins, March 7. Needs much more work.
-
-
-MSDOS and Win32:
-8 Should $USERPROFILE be preferred above $HOMEDRIVE/$HOMEPATH? No, but it's
- a good fallback, thus use:
- $HOME
- $HOMEDRIVE$HOMEPATH
- SHGetSpecialFolderPath(NULL, lpzsPath, CSIDL_APPDATA, FALSE);
- $USERPROFILE
- SHGetSpecialFolderPath(NULL, lpzsPath, CSIDL_COMMON_APPDATA, FALSE);
- $ALLUSERSPROFILE
- $SYSTEMDRIVE\
- C:\
-8 Win32 console: <M-Up> and <M-Down> don't work. (Geddes) We don't have
- special keys for these. Should use modifier + key.
-8 Win32 console: caps-lock makes non-alpha keys work like with shift.
- Should work like in the GUI version.
-8 Environment variables in DOS are not case sensitive. Make a define for
- STRCMP_ENV(), and use it when comparing environment var names.
-8 Setting 'shellslash' has no immediate effect. Change all file names when
- it is set/reset? Or only use it when actually executing a shell command?
-8 When editing a file on a Samba server, case might matter. ":e file"
- followed by ":e FILE" will edit "file" again, even though "FILE" might be
- another one. Set last used name in buflist_new()? Fix do_ecmd(), etc.
-8 When a buffer is editing a file like "ftp://mach/file", which is not going
- to be used like a normal file name, don't change the slashes to
- backslashes. (Ronald Hoellwarth)
-
-
-Win32 console:
-9 When editing a file by its short file name, it should be expanded into its
- long file name, to avoid problems like these: (Mccollister)
- 1) Create a file called ".bashrc" using some other editor.
- 2) Drag that file onto a shortcut or the actual executable.
- 3) Note that the file name is something like BASHRC~1
- 4) Go to File->Save As menu item and type ".bashrc" as the file name.
- 5) Press "Yes" to indicate that I want to overwrite the file.
- 6) Note that the message "File exists (add ! to override)" is displayed
- and the file is not saved.
- Use FindFirstFile() to expand a file name and directory in the path to its
- long name.
-7 Re-install the use of $TERM and support the use of different terminals,
- besides the console.
-8 Use of <altgr> modifier doesn't work? 5.3 was OK. (Garcia-Suarez/Guckes)
-9 Mapping <C-S-Tab> doesn't work correctly. How to see the difference with
- <C-S-i>?
-9 tmpnam() uses file in root of file system: "\asdf". That doesn't work on
- a Netware network drive. Use same function as for Win32 GUI?
-8 In os_win32.h, HAVE_STRICMP and HAVE_STRNICMP are defined only if __GNUC__
- is not defined. Shouldn't that be the other way around?
-7 Use SetConsoleCP() and SetConsoleOutputCP() to implement 'termencoding'?
- Avoids that input and output work differently. Need to be restored when
- exiting.
-
-
-Macintosh:
-7 Loading the Perl library only works on OS/X 10.2 or 10.3, never on both.
- Load the Perl library dynamically see Python sources file dynload_mac
- (Jack)
- dynamic linking: http://developer.apple.com/technotes/tn2002/tn2064.html
-8 inputdialog() doesn't resize when giving more text lines. (David Fishburn,
- 2006 Sept 28)
-8 Define vim_mkdir() for Macintosh.
-8 Define mch_writable() for Macintosh.
-9 When DiskLock is running, using a swap file causes a crash. Appears to be
- a problem with writing a file that starts with a dot. (Giacalone)
-9 In mac_expandpath() check that handling of backslashes is done properly.
-
-
-"Small" problems:
-- Can't disable terminal flow control, to enable the use of CTRL-S and
- CTRL-Q. Add an option for it?
-- When using e_secure in do_one_cmd() mention the command being executed,
- otherwise it's not clear where it comes from.
-- When the quickfix window is open and executing ":echo 'hello'" using the
- Command-line window, the text is immediately removed by the redrawing.
- (Michael Henry, 2008 Nov 1)
- Generic solution: When redrawing while there is a message on the
- cmdline, don't erase the display but draw over the existing text.
- Other solution, redraw after closing the cmdline window, before executing
- the command.
-9 For Turkish vim_tolower() and vim_toupper() also need to use utf_
- functions for characters below 0x80. (Sertacyildiz)
-9 When the last edited file is a help file, using '0 in a new Vim doesn't
- edit the file as a help file. 'filetype' is OK, but 'iskeyword' isn't,
- file isn't readonly, etc.
-8 When an ":edit" is inside a try command and the ATTENTION prompt is used,
- the :catch commands are always executed, also when the file is edited
- normally. Should reset did_emsg and undo side effects. Also make sure
- the ATTENTION message shows up. Servatius Brandt works on this.
-7 Vimtutor leaves escape sequence in terminal. This is the xterm response to
- requesting the version number. (Yasuhiro Matsumoto)
-8 When redirecting and using ":silent" the current column for displaying and
- redirection can be different. Use a separate variable to hold the column
- for redirection.
-7 The messages for "vim --help" and "vim --version" don't use
- 'termencoding'.
-- Could the hit-enter prompt be avoided when a message only overlaps the
- 'showcmd' area? Clear that area when the next cmd is typed.
-8 When 'scrollbind' is set, a window won't scroll horizontally if the cursor
- line is too short. Add a word in 'scrollopt' to allow moving the cursor
- to longer line that is visible. A similar thing is done for the GUI when
- using the horizontal scrollbar.
-7 VisVim can only open one file. Hard to solve: each opened file is passed
- with a separate invocation, would need to use timestamps to know the
- invocations belong together.
-8 When giving a ":bwipeout" command a file-changed dialog may popup for this
- buffer, which is pointless. (Mike Williams)
-8 On MS-Windows ":make" doesn't show output while it is working. Use the
- tee.exe from http://unxutils.sourceforge.net/ ? About 16 Kbyte in the
- UnxUtils.zip archive.
- Alternate one: http://www.pramodx.20m.com/tee_for_win32.htm, but Walter
- Briscoe says it's not as good.
-8 When doing Insert mode completion a mapping cannot recursively call
- edit(), because the completion information is global. Put everything in
- an allocated structure?
-8 Command line completion: buffers "foo.txt" and "../b/foo.txt", completing
- ":buf foo<Tab>" doesn't find the second one. (George V. Reilly)
-7 mb_off2cells() doesn't work correctly on the tail byte of a double-byte
- character. (Yasuhiro Matsumoto) It should return 1 when used on a tail
- byte, like for utf-8. Store second byte of double-byte in ScreenLines2[]
- (like for DBCS_JPNU) and put a zero in the second byte (like for UTF-8).
-7 Inside a function with "perl <<EOF" a line with "$i++" is recognized as an
- ":insert" command, causing the following "endfunction" not to be found.
- Add skipping this perl construction inside function definitions.
-7 When 'ttimeoutlen' is 10 and 'timeoutlen' is 1000, there is a keycode
- "<Esc>a" and a mapping <Esc>x", when typing "<Esc>a" with half a second
- delay should not be interpreted as a keycode. (Hans Ginzel)
-7 ":botright 1 new" twice causes all window heights to be changed. Make the
- bottom window only bigger as much as needed.
-7 The Cygwin and MingW makefiles define "PC", but it's not used anywhere.
- Remove? (Dan Sharp)
-9 User commands use the context of the script they were defined in. This
- causes a "s:var" argument to unexpectedly use a variable in the defining
- script, not the calling script. Add an argument to ":command":
- "-keepcontext". Do replace <SID>, so that a function in the defining
- script can be called.
-8 The Japanese message translations for MS-Windows are called ja.sjis.po,
- but they use encoding cp932. Rename the file and check that it still
- works.
-8 A very long message in confirm() can't be quit. Make this possible with
- CTRL-C.
-8 "gf" always excludes trailing punctuation characters. file_name_in_line()
- is currently fixed to use ".,:;!". Add an option to make this
- configurable?
-8 'hkmap' should probably be global-local.
-9 When "$" is in 'cpoptions' and folding is active, a "C" command changes
- the folds and resets w_lines_valid. The display updating doesn't work
- then. (Pritesh Mistry)
-8 Using ":s" in a function changes the previous replacement string. Save
- "old_sub" in save_search_patterns()?
-8 Should allow multi-byte characters for the delimiter: ":s+a+b+" where "+"
- is a multi-byte character.
-8 When appending to a file and 'patchmode' isn't empty, a backup file is
- always written, even when the original file already exists.
-9 When getting focus while writing a large file, could warn for this file
- being changed outside of Vim. Avoid checking this while the file is being
- written.
-7 The message in bt_dontwrite_msg() could be clearer.
-8 The script ID that is stored with an option and displayed with ":verbose
- set" isn't reset when the option is set internally. For example when
- 'foldlevel' is set from 'foldlevelstart'.
-8 Also store the line number with the script ID and use it for ":verbose",
- so that "set nocompatible" is found when it changes other option values.
- When an option is set indirectly mention the command? E.g. when
- ":diffsplit" sets 'foldmethod'.
-8 In the fileformat dialog, "Cancel" isn't translated. Add a global
- variable for this. (Eduardo Fernandez)
-9 When editing a file with 'readonly' set, there is no check for an existing
- swap file. Then using ":write" (without making any changes) doesn't give
- a warning either. Should check for an existing swap file without creating
- one. Unfinished patch by Ian Kelling, 2008 July 14.
-7 When 'showbreak' is set, the amount of space a Tab occupies changes.
- Should work like 'showbreak' is inserted without changing the Tabs.
-7 When 'mousefocus' is set and switching to another window with a typed
- command, the mouse pointer may be moved to a part of the window that's
- covered by another window and we lose focus. Only move in the y
- direction, not horizontally?
-8 ":hardcopy":
- - Using the cterm_color[] table is wrong when t_colors is > 16.
- - Need to handle unprintable characters.
- - Win32: On a B&W printer syntax highlighting isn't visible. Perform
- dithering to make grey text?
- - Add a flag in 'printoptions' to add an empty page to make the total
- number even. "addempty"? (Mike Williams)
- - Respect 'linebreak'. Perhaps also 'showbreak'?
- - Should interpret CTRL-L as a page break.
- - Grey line numbers are not always readable. Add field in 'printoptions'.
- Default to black when no syntax highlighting.
- - Be able to print a window in diff mode.
- - Be able to specify a colorscheme to use for printing. And a separate
- one for B&W printing (if that can be detected).
-8 In Visual block mode with 'lbr' set, a change command doesn't insert the
- text in following lines where the linebreak changes.
-8 When 'virtualedit' is "block,insert" and encoding is "utf-8", selecting a
- block of one double-wide character, then "d" deletes only half of it.
-8 When 'virtualedit' is set, should "I" in blockwise visual mode also insert
- in lines that don't extend into the block?
-8 With 'virtualedit' set, in Insert mode just after the end of line, CTRL-O
- yh does not yank the last character of the line. (Pavel Papushev)
- Doing "hl" first appears to make it work.
-8 With 'virtualedit' set it's possible to move into the blank area from
- 'linebreak'.
-8 With 'virtualedit' set and 'selection' "exclusive", a Visual selection
- that ends in or after a tab, "d" doesn't delete (part of) the tab.
- (Helmut Stiegler)
-9 When jumping to a tag, the search pattern is put in the history. When
- 'magic' is on, the pattern may not work. Translate the pattern depending
- on p_magic when putting it in the history? Alternative: Store value of
- 'magic' in history. (Margo)
-9 optwin.vim: Restoring a mapping for <Space> or <CR> is not correct for
- ":noremap". Add "mapcmd({string}, {mode})? Use code from ":mkexrc".
-9 incsearch is incorrect for "/that/<Return>/this/;//" (last search pattern
- isn't updated).
-9 Get out-of-memory for ":g/^/,$s//@/" on 1000 lines, this is not handled
- correctly. Get many error messages while redrawing the screen, which
- cause another redraw, etc.
-8 [<C-I> doesn't work when '*' is in 'iskeyword'. find_pattern_in_path()
- must escape special characters in the pattern.
-8 Vim can overwrite a read-only file with ":w!". ":w" can't overwrite an
- existing file, "w!" can, but perhaps not a read-only file? Then use
- ":w!!" for that.
- Or ask for permission to overwrite it (if file can be made writable) and
- restore file to readonly afterwards.
- Overwriting a file for which a swap file exists is similar issue.
-7 X11: Some people prefer to use CLIPBOARD instead of PRIMARY for the normal
- selection. Add an "xclipboard" argument to the 'clipboard' option? (Mark
- Waggoner)
-8 For xterm need to open a connection to the X server to get the window
- title, which can be slow. Can also get the title with "<Esc>[21t", no
- need to use X11 calls. This returns "<Esc>]l{title}<Esc>\".
-6 When the xterm reports the number of colors, a redraw occurs. This is
- annoying on a slow connection. Wait for the xterm to report the number of
- colors before drawing the screen. With a timeout.
-8 When the builtin xterm termcap contains codes that are not wanted, need a
- way to avoid using the builtin termcap.
-8 Xterm sends ^[[H for <Home> and ^[[F for <End> in some mode. Also
- recognize these keys? Mostly useful for xterm simulators, like gnometerm.
- See http://dickey.his.com/xterm/xterm.faq.html#xterm_pc_style.
-8 For xterm also recognize keypad up/down/left/right and insert.
-8 '[ and '] should be set to start/end of line when using a linewise operator
- (e.g., ":w").
-8 CTRL-A can't handle big "long" numbers, they become negative. Check for
- "-" character, if not present, use unsigned long.
-8 Make it possible to disable the special meaning of "#" in the first column
- for ">>".
-8 Add suspending with CTRL-Z at the "more" prompt, and when executing a long
- script in do_cmdline().
-8 When using 'hidden', many swap files will be open. When Vim runs into the
- maximum number of open files, error messages will appear. Detect that
- this problem is present, and close any hidden files that don't have
- changes.
-8 With 'viminfo' set such that the ".viminfo" file is written on a FAT
- filesystem, an illegal file name may be created: ".vim".
-8 For each buffer that is opened, the viminfo file is opened and read to
- check for file marks. This can be slow.
-7 In xterm, recognize both vt100 and vt220 cursor keys. Change
- add_termcode() to not remove an existing entry for a name, when it's
- needed.
- Need a generic solution to recognize different codes for the same key.
-8 Core dump within signal function: gdb doesn't show stack backtrace! Option
- to skip catch_signals()?
-9 Repeating a "cw" with "." doesn't work if the text was pasted from the
- clipboard. (Thomas Jones) It's because the menu/toolbar item exits Insert
- mode and uses "gP". How to fix this without breaking inserting a block of
- text?
-8 In Replace mode pasting from the clipboard (using menu or toolbar) inserts
- all the text. Add ":rmenu"?
-8 Pasting with the mouse in Replace mode inserts the text, instead of
- overwriting, when it is more than one line. Same for using <C-R>.
-9 CTRL-E and CTRL-Y don't work in small window when 'so' is 4 and lines are
- wrapping (Acevedo/in.226). E.g., when using CTRL-E, window height 7,
- window might actually scroll down when last line of buffer is displayed.
- --> Remember if the previous command was "cursor follows screen" or
- "screen follow cursor" and use this in cursupdate().
-7 tilde_replace() can only handle "~/", should also do "~user/".
- Get the list of home directories (from /etc/passwd? Use getpwent()) and
- use some clever algorithm to match a path with that. Find common strings
- in the list?
-8 When dragging status line with mouse, sometimes a jump when first clicking
- on the status line (caused by 'winheight'). Select window on button up,
- instead of on button down.
-8 Dragging the status line doesn't scroll but redraw.
-9 Evaluating 'statusline' in build_stl_str_hl() does not properly check for
- reaching the end of the available buffer.
- Patch to dynamically allocate the buffer for % items. (Eric Arnold, 2006
- May 14)
-8 When performing incremental search, should abort searching as soon as a
- character is typed.
-8 When the value of $MAKE contains a path, configure can't handle this.
- It's an autoconf bug. Remove the path from $MAKE to work around it.
-8 How to set VIMRC_FILE to \"something\" for configure? Why does this not
- work: CFLAGS='-DVIMRC_FILE=\"/mydir/myfile\"' ./configure
-8 The temporary file is sometimes not writable. Check for this, and use an
- alternate name when it isn't. Or add the 'temptemplate' option: template
- for the temp file name ":set temptemplate=/usr/tmp/?????.tmp".
- Also: Win32 version uses Windows temp directory, which might not work for
- cygwin bash.
-7 Get error "*, \+ or \( operand could be empty" for pattern "\(.\)\1\{3}".
- Remember flags for backreferences.
-7 When switching to Daylight Saving Time, Vim complains that a file has been
- changed since last read. Can we use a function that uses GMT?
-7 When completing an environment variable after a '$', check for file names
- that contain a '$' after all have been found.
-8 When "cm" termcap entry is missing, starting gvim shouldn't complain about
- it. (Lohner) Try out with "vt100" entry, cm replaced with cX.
-7 When an include file starts with "../", the check for already visiting
- this file doesn't work. Need to simplify the file name.
-7 The names and comments for the arguments of do_browse() are confusing.
- "dflt" isn't the default file name when "initdir" is not NULL and
- "initdir" is the default path to be used.
-7 When 'scrolloff' is exactly half the window height, "j" causes a scroll of
- two lines at a time. "k" doesn't do this. (Cory T. Echols)
-8 When write_viminfo() is used while there are many orphaned viminfo
- tempfiles writing the viminfo file fails. Give a clear error message so
- that the user knows he has to delete the files.
-7 It's possible to redefine a script-local function with ":func
- <SNR>123_Test()". (Krishna) Disallow this.
-
-
-I can't reproduce these (if you can, let me know how!):
-9 NT 4.0 on NTFS file system: Editing ".bashrc" (drag and drop), file
- disappears. Editing ".xyz" is OK. Also, drag&drop only works for three
- files. (McCollister)
-
-
-Problems that will (probably) not be solved:
-- xterm title: The following scenario may occur (esp. when running the Vim
- test script): Vim 1 sets the title to "file1", then restores the title to
- "xterm" with an ESC sequence when exiting. Vim 2 obtains the old title
- with an X library call, this may result in "file1", because the window
- manager hasn't processed the "xterm" title yet. Can apparently only be
- worked around with a delay.
-- In a terminal with 'mouse' set such that the mouse is active when entering
- a command line, after executing a shell command that scrolls up the
- display and then pressing ":": Selecting text with the mouse works like
- the display wasn't scrolled. Vim doesn't know how much the external
- command scrolled up the display. Use Shift to select text.
-- X windows: When $DISPLAY points to a X server where there is no access
- permission, trying to connect to the X server causes an error message.
- XtOpenDisplay() prints this directly, there is no way to avoid it.
-- Moving the cursor removes color in color-xterm. This is a color-xterm
- problem! color-xterm ver. 6.1 beta 3 and later work properly.
-- In zsh, "gvim&" changes the terminal settings. This is a zsh problem.
- (Jennings)
-- Problem with HPterm under X: old contents of window is lost (Cosentino).
-- Linux: A file with protection r--rw-rw- is seen readonly for others. The
- access() function in GNU libc is probably wrong.
-- MSDOS: When using smartdrive with write-back buffering, writing to a
- readonly floppy will cause problems. How to test for a writable floppy
- first?
-- MSDOS: Both 16 and 32 bit versions: File name expansion doesn't work for
- names that start with a dot. These used to be illegal file names.
-- When doing a CTRL-Z and typing a command for the shell, while Vim is busy
- (e.g. writing a file), the command for the shell is sometimes eaten by Vim,
- because the terminal mode is changed from RAW to CBREAK.
-- An old version of GNU tgoto can't handle the terminfo code for "AF". The
- "%p1" is interpreted as "%p" and "1", causing color not to be working.
- Fix: Change the "%p1" in the "AF" and "AB" terminfo entries to "%p".
- (Benzinger).
-- Win32: All files created on the day of switching from winter to summer
- time cause "changed since editing started" messages. It goes away when
- the file is written again the next day, or the timezone is adjusted.
- Looks like a problem with the Win32 library.
- Rebooting doesn't help. Time stamps look OK in directory. (Penn)
- Is this on FAT (stores wall clock time) or NTFS (stores UTS)?
-- Win32, MS-Windows XP: $HOME uses the wrong drive when the user profiles
- are not on the boot disk. This is caused by a wrong value of $HOMEDRIVE.
- This is a bug in XP, see MSKB article 818134.
-- Win32, MS-Windows: expanding plugin/**/*.vim also picks up
- dir/ctags.vim,v. This is because the short file name is something like
- "ctags~1.vim" and that matches the pattern.
-- When using an xterm that supports the termresponse feature, and the 't_Co'
- termcap option was wrong when Vim started, it will be corrected when the
- termresponse is received. Since the number of colors changes, the
- highlighting needs to be initialized again. This may cause colors defined
- in the vimrc file to be lost.
-- On Windows NT 4.0 the number of files passed to Vim with drag&drop and
- "Edit with Vim" is limited. The maximum command line length is 255 chars.
-
---------------------- extensions and improvements ----------------------
- *extensions-improvements*
-
-Most interesting new features to be added when all bugs have been fixed:
-- Using ":exe edit fname" has escaping problems. Use ":edit ++(fname)".
- Thus use "++=" to give arguments as expressions, comma separated as if
- calling a function.
- With options: ":edit ++(['!', '++enc=abc'], ['+/pat'], fname)".
- Alternative: Make a function for Ex commands: cmd_edit().
-- Add COLUMN NUMBERS to ":" commands ":line1,line2[col1,col2]cmd". Block
- can be selected with CTRL-V. Allow '$' (end of line) for col2.
-- Add DEBUGGER INTERFACE. Implementation for gdb by Xavier de Gaye.
- Should work like an IDE. Try to keep it generic. Now found here:
- http://clewn.sf.net.
- And the idevim plugin/script.
- To be able to start the debugger from inside Vim: For GUI run a program
- with a netbeans connection; for console: start a program that splits the
- terminal, runs the debugger in one window and reconnect Vim I/O to the
- other window.
- Wishes for NetBeans commands:
- - make it possible to have 'defineAnnoType' also handle terminal colors.
- - send 'balloonText' events for the cursor position (using CursorHold ?)
- in terminal mode.
-- ECLIPSE plugin. Problem is: the interface is very complicated. Need to
- implement part in Java and then connect to Vim. Some hints from Alexandru
- Roman, 2004 Dec 15. Should then also work with Oracle Jdeveloper, see JSR
- 198 standard http://www.jcp.org/en/jsr/detail?id=198.
- Eclim does it: http://eclim.sourceforge.net/ (Eric Van Dewoestine)
- Plugin that uses a terminal emulator: http://vimplugin.sf.net
- And another one: http://www.satokar.com/viplugin/index.php
-- STICKY CURSOR: Add a way of scrolling that leaves the cursor where it is.
- Especially when using the scrollbar. Typing a cursor-movement command
- scrolls back to where the cursor is.
-- Scroll commands by screen line. g CTRL-E and g CTRL-Y ? Requires the
- first line to be able to start halfway through.
-8 Add a command to jump to a certain kind of tag. Allow the user to specify
- values for the optional fields. E.g., ":tag size type=m".
- Also allow specifying the file and command, so that the result of
- taglist() can be used.
-- X11: Make it possible to run Vim inside a window of another program.
- This can be done with XReparentWindow(). But how exactly?
-
-
-Documentation:
-8 List of Vim runtime directories. dotvim.txt from Charles Campbell, 2007
- Feb 20.
-8 List of options should mention whether environment variables are expanded
- or not.
-8 Extend usr_27.txt a bit. (Adam Seyfarth)
-7 Add a section on debugging scripts in the user manual.
-9 Make the Reference Manual more precise. For each command mention:
- - change to cursor position and curswant
- - if it can be undone (u/CTRL-R) and redone (.)
- - how it works for folded lines
- - how it works with multi-byte characters
-9 In change.txt, remark about Javadoc isn't right. Right alignment would
- work too.
-8 Spread the windows commands over the other files. For example, ":stag"
- should be with ":tag". Cross-link with tags to avoid too much double
- text.
-8 Add tags for all features, e.g. "gui_running".
-7 MS-Windows: When a wrong command is typed with an ALT key, give a hint to
- look at the help for 'winaltkeys'.
-7 Add a help.vim plugin that maps <Tab> to jump to the next tag in || and
- <C-Tab> (and <S-Tab>) to the previous tag.
- Patch by Balazs Kezes, 2007 Dec 30. Remark from A. Politz.
-- Check text editor compendium for vi and Vim remarks.
-
-
-Help:
-- First try using the ":help" argument literally, before using it as a
- pattern. And then match it as part of a tag.
-- When a help item has multiple matches make it possible to use ":tn" to go
- to the other matches.
-- Support a way to view (and edit) .info files.
-- Default mapping for help files: <Tab> to position cursor on next |:tag|.
-- Implement a "sticky" help window, some help text lines that are always
- displayed in a window with fixed height. (Guckes) Use "~/.vimhelp" file,
- user can edit it to insert his favorite commands, new account can contain a
- default contents.
-- Make 'winminheight' a local option, so that the user can set a minimal
- height for the help window (and other windows).
-- ":help :s^I" should expand to ":help :substitute".
-- Make the help key (<F1>) context sensitive?
-- Learn mode: show short help while typing commands.
-
-
-User Friendlier:
-8 Windows install with install.exe: Use .exe instead of .bat files for
- links, so that command line arguments are passed on unmodified? (Walter
- Briscoe)
-8 Windows install: Be able to associate Vim with a selection of file types?
-8 Windows uninstall: Have uninstal.c delete the vimfiles directories that
- dosinst.c creates. List the contents of the directory (recursively) if
- the user asks for it. Requires an implementation of "rm -rf".
-8 Remember the name of the vimrc file that was used (~/.vimrc, $VIM/_vimrc,
- $HOME/_vimrc, etc.) and add "edit vimrc" to the File menu.
-- Add a way to save local settings and mappings into a new plugin file.
- ":mkplugin <file>"?
-8 Add ":plugininstall" command. Can be used to install a plugin file that
- includes documentation. Let the user select a directory from
- 'runtimepath'.
- " Vim plugin
- <main plugin code>
- " >>> plugin help start <<<
- <plugin docs>
-- Add mappings local to a window: ":map <window> ..."?
-9 Add buffer-local menu. Should offer a choice between removing the menu or
- disabling it. Be careful that tear-offs don't disappear (keep one empty
- item?).
- Alternative: use BufEnter and BufLeave autocommands.
-7 Add the arguments for configure to the ":version" output?
-7 When Vim detects a file is being edited elsewhere and it's a gvim session
- of the same user it should offer a "Raise" button, so that the other gvim
- window can be displayed. (Eduard)
-
-
-Tab pages:
-9 GUI implementation for the tab pages line for other systems.
-7 GUI: Control over the appearance of the text in the labels (bold, color,
- font, etc.)
-8 Make GUI menu in tab pages line configurable. Like the popup menu.
-8 balloons for the tab page labels that are shortened to show the full path.
-7 :tabdup duplicate the tab with all its windows.
-7 Option to put tab line at the left or right? Need an option to specify
- its width. It's like a separate window with ":tabs" output.
-7 Add local variables for each tab page?
-8 Add local options for each tab page? E.g., 'diffopt' could differ between
- tab pages.
-7 Add local highlighting for each tab page?
-7 Add local directory for tab pages? How would this interfere with
- window-local directories?
-
-
-Spell checking:
-- Support more regions? Caolan McNamara argues it's needed for es_XX.
- https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=219777
-- Unicode defines another quote character: 0x2019. Use it as an equivalent
- of a single quote, thus use it as a word character like a quote and match
- with words, replacing the curly quote with a single quote.
-- Could filter &eacute; things for HTML before doing spell checking.
- Similarly for TeX.
-- The Hungarian spell file uses four extra characters in the FOL/UPP/LOW
- items than other spell files with the ISO-8859-2 encoding, that causes
- problem when changing 'spelllang'. There is no obvious way to fix this.
-- Considering Hunspell 1.1.4:
- What does MAXNGRAMSUGS do?
- Is COMPLEXPREFIXES necessary when we have flags for affixes?
-- Support spelling words in CamelCase as if they were two separate words.
- Requires some option to enable it. (Timothy Knox)
-- There is no Finnish spell checking file. For openoffice Voikko is now
- used, which is based on Malaga: http://home.arcor.de/bjoern-beutel/malaga/
- (Teemu Likonen)
-8 ":mkspell" still takes much too long in Hungarian dictionary from
- hunspell. Only solution appears to be to postpone secondary suffixes.
-8 Handle postponed prefix with COMPOUNDPERMITFLAG or COMPOUNDFORBIDFLAG.
- WFP_COMPPERMIT and WFP_COMPFORBID
-8 implement use of <compoptions> in .spl file:
- implement CHECKCOMPOUNDREP: when a compound word seems to be OK apply REP
- items and check if the result is a valid word.
- implement CHECKCOMPOUNDDUP
- implement CHECKCOMPOUNDTRIPLE
- Add CHECKCOMPOUNDCASE: when compounding make leading capital lower case.
- How is it supposed to work?
-- Add a command the repeats ]s and z=, showing the misspelled word in its
- context. Thus to spell-check a whole file.
-- suggestion for "KG" to "kg" when it's keepcase.
-- For flags on affixes: Use a "AFFCOMPSET" flag; means the compound flags of
- the word are not used.
-- Support breakpoint character ? 0xb7 and ignore it? Makes it possible to
- use same wordlist for hyphenation.
-- Compound word is accepted if nr of words is <= COMPOUNDWORDMAX OR nr of
- syllables <= COMPOUNDSYLMAX. Specify using AND in the affix file?
-- NEEDCOMPOUND also used for affix? Or is this called ONLYINCOMPOUND now?
- Or is ONLYINCOMPOUND only for inside a compound, not at start or end?
-- Do we need a flag for the rule that when compounding is done the following
- word doesn't have a capital after a word character, even for Onecap words?
-- New hunspell home page: http://hunspell.sourceforge.net/
- - Version 1.1.0 is out now, look into that.
- - Lots of code depends on LANG, that isn't right. Enable each mechanism
- in the affix file separately.
- - Example with compounding dash is bad, gets in the way of setting
- COMPOUNDMIN and COMPOUNDWORDMAX to a reasonable value.
- - PSEUDOROOT == NEEDAFFIX
- - COMPOUNDROOT -> COMPOUNDED? For a word that already is a compound word
- Or use COMPOUNDED2, COMPOUNDED3, etc.
-- CIRCUMFIX: when a word uses a prefix marked with the CIRCUMFIX flag, then
- the word must also have a suffix marked with the CIRCUMFIX flag. It's a
- bit primitive, since only one flag is used, which doesn't allow matching
- specific prefixes with suffixes.
- Alternative:
- PSFX {flag} {pchop} {padd} {pcond} {schop} {sadd}[/flags] {scond}
- We might not need this at all, you can use the NEEDAFFIX flag and the
- affix which is required.
-- When a suffix has more than one syllable, it may count as a word for
- COMPOUNDWORDMAX.
-- Add flags to count extra syllables in a word. SYLLABLEADD1 SYLLABLEADD2,
- etc.? Or make it possible to specify the syllable count of a word
- directly, e.g., after another slash: /abc/3
-- MORPHO item in affix file: ignore TAB and morphological field after
- word/flags and affix.
-- Implement multiple flags for compound words and CMP item?
- Await comments from other spell checking authors.
-- Also see tklspell: http://tkltrans.sourceforge.net/
-8 Charles Campbell asks for method to add "contained" groups to existing
- syntax items (to add @Spell).
- Add ":syntax contains {pattern} add=@Spell" command? A bit like ":syn
- cluster" but change the contains list directly for matching syntax items.
-- References: MySpell library (in OpenOffice.org).
- http://spellchecker.mozdev.org/source.html
- http://whiteboard.openoffice.org/source/browse/whiteboard/lingucomponent/source/spellcheck/myspell/
- author: Kevin Hendricks <kevin.hendricks@sympatico.ca>
-8 It is currently not possible to mark "can not" as rare, because "can" and
- "not" are good words. Find a way to let "rare" overrule "good"?
-8 Make "en-rare" spell file? Ask Charles Campbell.
-8 The English dictionaries for different regions are not consistent in their
- use of words with a dash.
-7 Insert mode completion mechanism that uses the spell word lists.
-8 Add hl groups to 'spelllang'?
- :set spelllang=en_us,en-rare/SpellRare,en-math/SpellMath
- More complicated: Regions with different languages? E.g., comments
- in English, strings in German (po file).
-
-
-Diff mode:
-9 When making small changes, e.g. deleting a character, update the diff.
- Possibly without running diff.
-9 Instead invoking an external diff program, use builtin code. One can be
- found here: http://www.ioplex.com/~miallen/libmba/dl/src/diff.c
- It's quite big and badly documented though.
-8 Use diff mode to show the changes made in a buffer (compared to the file).
- Use an unnamed buffer, like doing:
- new | set bt=nofile | r # | 0d_ | diffthis | wincmd p | diffthis
- Also show difference with the file when editing started? Should show what
- can be undone. (Tom Popovich)
-7 Add cursor-binding: when moving the cursor in one diff'ed buffer, also
- move it in other diff'ed buffers, so that CTRL-W commands go to the same
- location.
-
-
-Folding:
- (commands still available: zI zJ zK zp zP zq zQ zV zy zY;
- secondary: zB zS zT zZ, z=)
-8 Vertical folds: looks like vertically split windows, but the cursor moves
- through the vertical separator, separator moves when scrolling.
-8 Add "z/" and "z?" for searching in not folded text only.
-9 Add search pattern item to only match in closed or open fold and/or fold
- with certain level. Allows doing ":g/pat/cmd" to work on closed folds.
-8 When a closed fold is displayed open because of 'foldminlines', the
- behavior of commands is still like the fold is closed. How to make the
- user aware of this?
-8 Add an option 'foldskip' with values like 'foldopen' that specifies which
- commands skip over a closed fold.
-8 "H" and "L" count buffer lines instead of window lines. (Servatius Brandt)
-8 Add a way to add fold-plugins. Johannes Zellner has one for VB.
-7 When using manual folding, the undo command should also restore folds.
-- Allow completely hiding a closed fold. E.g., by setting 'foldtext' to an
- empty string. Require showing a character in 'foldcolumn' to avoid the
- missing line goes unnoticed.
- How to implement this?
-- When pressing the down arrow of a scrollbar, a closed fold doesn't scroll
- until after a long time. How to make scrolling with closed folds
- smoother?
-- When creating a session, also store folds for buffers in the buffer list,
- using the wininfo in wi_folds.
-- When currently editing the first file in the argument list the session
- file can contain:
- args version.c main.c
- edit version.c
- Can editing version.c twice be avoided?
-- 'foldmethod' "textobject": fold on sections and paragraph text objects.
-- "zuf": undo change in manual fold. "zUf" redo change in manual fold. How
- to implement this?
-- "zJ" command: add the line or fold below the fold in the fold under the
- cursor.
-- 'foldmethod' "syntax": "fold=3" argument: set fold level for a region or
- match.
-- Apply a new foldlevel to a range of lines. (Steve Litt)
-8 Have some way to restrict commands to not folded text. Also commands like
- searches.
-
-
-Multi-byte characters:
-- When editing a file with both utf-8 and latin1 text Vim always falls back
- to latin1. Add a command to convert the latin1 characters to utf-8?
- :unmix utf-8,latin1 filename
- Would only work when 'encoding' is utf-8.
-9 When the tail byte of a double-byte character is illegal (e.g., a CR), the
- display is messed up (Yasuhiro Matsumoto). Should check for illegal
- double-byte characters and display them differently (display each single
- byte).
-9 'fenc' in modeline problem: add option to reload the file when 'fenc' is
- set to a different value in a modeline? Option can be default on. Could
- it be done with an autocommand?
-8 Add an item in 'fileencodings' to check the first lines of a file for
- the encoding. See Python PEP: http://www.python.org/peps/pep-0263.html.
- To avoid getting a wrong encoding only accept something Emacs-like:
- "-*- coding: enc-na_me.foo -*-" and "-*- coding= enc-na_me.foo -*-"
- Match with "-\*-\s*coding[:=]\s*\([::word::-_.]\+\)\s*-\*-" and use first
- item.
-8 Add an item in 'fileencodings' to check the first line of an XML file for
- the encoding. <?xml version="1.0" encoding="UTF-8"?> Or "charset=UTF-8"?
- For HTML look for "charset=utf-8".
-8 The quickfix file is read without conversion, thus in 'encoding'. Add an
- option to specify the encoding of the errorfile and convert it. Also for
- ":grep" and ":helpgrep".
- More generic solution: support a filter (e.g., by calling a function).
-8 When a file was converted from 'fileencoding' to 'encoding', a tag search
- should also do this on the search pattern. (Andrzej M. Ostruszka)
-8 When filtering changes the encoding 'fileencoding' may not work. E.g.,
- when using xxd and 'fileencoding' is "utf-16". Add an option to set a
- different fileencoding for filter output?
-7 When converting a file fails, mention which byte could not be converted,
- so that the user can fix the problem.
-8 Add configure option to be able to disable using the iconv library. (Udo
- Schweigert)
-9 'aleph' should be set to 1488 for Unicode. (Zvi Har'El)
-8 Should add test for using various commands with multi-byte characters.
-8 'infercase' doesn't work with multi-byte characters.
-8 toupper() function doesn't handle byte count changes.
-7 Searching and composing characters:
- When searching, should order of composing characters be ignored?
- Add a special item to match with a composing character, so that composing
- characters can be manipulated.
-8 Should implement 'delcombine' for command line editing.
-8 Detect overlong UTF-8 sequences and handle them like illegal bytes.
-8 ":s/x/\u\1/" doesn't work, making uppercase isn't done for multi-byte
- characters.
-8 UTF-8: "r" in Visual mode doesn't take composing characters.
-8 UTF-8: When there is a precomposed character in the font, use it instead
- of a character and a composing character. See xterm for an example.
-7 When a character can't be displayed, display its digraph instead.
- 'display' option to specify this.
-7 Use ideas for nl_langinfo() from Markus Kuhn in enc_default():
- (www.cl.cam.ac.uk/~mgk25/ucs/langinfo.c)
-- dbcs_class() only works for Japanese and Korean. Implement this for
- other encodings. The "euc-jp" and "euc-kr" choices might be wrong.
-- Find some way to automatically select the right GUI font or fontset,
- depending on the default value of 'encoding'.
- Irrelevant in the GTK+ 2 GUI so long as UTF-8 is used.
- For Windows, the charset_pairs[] table could be used. But how do we know
- if a font exists?
-- Do keyboard conversion from 'termencoding' to 'encoding' with
- convert_input() for Mac GUI.
-- Add mnemonics from RFC1345 longer than two characters.
- Support CTRL-K _{mnemonic}_
-7 In "-- INSERT (lang) --" show the name of the keymap used instead of
- "lang". (Ilya Dogolazky)
-- Make 'breakat' accept multi-byte characters. Problem: can't use a lookup
- table anymore (breakat_flags[]).
- Simplistic solution: when 'formatoptions' contains "m" also break a line
- at a multi-byte character >= 0x100.
-- Add the possibility to enter mappings which are used whenever normal text
- could be entered. E.g., for "f" command. But not in Normal mode. Sort
- of opposite of 'langmap'. Use ":tmap" command?
-- When breaking a line, take properties of multi-byte characters into
- account. The "linebreak" program from Bruno Haible can do it:
- ftp://ftp.ilog.fr/pub/Users/haible/gnu/linebreak-0.1.tar.gz
- But it's very complicated...
-
-
-Printing:
-7 Implement "undercurl" for printing.
-- Add "page width" to wrap long lines.
-- Win32: use a font dialog for setting 'printfont'. Can reuse the code for
- the 'guifont' dialog, put the common code in a separate function.
-- Add the file timestamp to the page header (with an option). (George
- Reilly)
-- Win32: when 'printfont' is empty use 'guifont'.
-- Unix: Use some dialog box to do the obvious settings (paper size, printer
- name, portrait/landscape, etc).
-- PostScript: Only works for text that can be converted to an 8-bit
- character set. How to support Unicode fully?
-- Allow specifying the paper size, instead of using a standard size. Same
- units as for the margins.
-- Support right-to-left text?
-8 Make the foreground color darkening function preserve the hue of the
- color.
-
-
-Syntax highlighting:
-8 Make ":syn off" use 'runtimepath' instead of $VIMRUNTIME. (Gary Johnson)
- Should do the same for ":syn on" and ":syn manual".
-8 Support "containedin" argument for ":syn include", so that the defined
- cluster can be added to existing syntax items.
-8 C syntax: Don't highlight {} as errors inside () when used like this:
- "({ something })", often used in GCC code.
-7 Add a "startgroup" to a region. Used like "nextgroup" inside the region,
- preferred item at the start of the region. (Charles Campbell)
-8 When editing a new file without a name and giving it a name (by writing
- it) and 'filetype' is not set, detect the filetype. Avoid doing it for
- ":wq file".
-7 For "nextgroup" we have skipwhite, skipnl and skipempty. It would be
- really nice to be able to skip with a pattern. Or skip with a syntax
- group. (Nikolai Weibull, 2007 Feb 27)
-8 Make conversion to HTML faster (Write it in C or pre-compile the script).
-9 There is still a redraw bug somewhere. Probably because a cached state is
- used in a wrong way. I can't reproduce it...
-7 Be able to change only the background highlighting. Useful for Diff* and
- Search highlighting.
-7 When 'number' is set highlight the number of the current line.
- Must be enabled with an option, because it slows down display updating.
-8 Allow the user to add items to the Syntax menu sorted, without having to
- change this for each release.
-8 Add a "matchcontains" for regions: items contained in the start or end
- pattern, but not in the body.
-8 Add a "keepend-contained" argument: Don't change the end of an item this
- one is contained in. Like "keepend" but specified on the contained item,
- instead of the containing item.
-8 cpp.vim: In C++ it's allowed to use {} inside ().
-8 Some syntax files set 'iskeyword'. When switching to another filetype
- this isn't reset. Add a special keyword definition for the syntax rules?
- When this is done, use vim.vim syntax highlighting for help file examples,
- but without ":" in 'iskeyword' for syntax.
- Also need a separate 'iskeyword' for the command line, e.g., in a help
- window ":e /asdf/asdf/" CTRL-W works different.
-8 Add specific syntax item to match with parens/braces that don't have a
- "%" match. :syntax nomatch cMatchError (,{,[,),},] [contained]
-8 Highlight the text between two matching parens (e.g., with a grey
- background) when on one of the parens or in between them.
- Option for the matchparen plugin?
-8 When using a cterm, and no ctermfg or ctermbg are defined, use start/stop
- sequences. Add remark in docs that :if 'term' == "term-name" should be
- used.
-8 Add @spell cluster to String and Comment groups for many languages. Will
- allow spell checking. (Fleiner)
-8 When listing syntax items, try to sort the keywords alphabetically. And
- re-insert the [] if possible.
-8 Make it possible to use color of text for Visual highlight group (like for
- the Cursor).
-8 It would be useful to make the highlight group name an expression. Then
- when there is a match, the expression would be evaluated to find out what
- highlight group to use. Could be used to check if the shell used in a
- password file appears in /etc/shells. (Nikolai Weibull)
- syn match =s:checkShell(v:match) contained 'pattern'
-8 Make it possible to only highlight a sub-expression of a match. Like
- using "\1" in a ":s" command.
-8 Support for deleting syntax items:
- :syn keyword cTodo remove this
- :syn match cTodo remove "pattern"
- :syn region cString remove start="this" end="that"
-8 Add possibility to sync on something else, when the syncing in one way
- doesn't find match. For HTML: When no {script} is found, try looking for
- a '<'. (Fleiner)
-7 Replace the synchronizing method with a state machine specification?
- Should be able to start at any line in the file, search forwards or
- backwards, and use the result of matching a pattern.
-7 Use parsing like awk, so that e.g., a ( without a matching ) can be
- detected.
-8 Make it possible to use "inverted" highlighting, invert the original
- character. For Visual mode. (xterm-selection already does this).
-8 Highlight non-printable characters with "SpecialChar", linked to
- "Special". Display them with the digraph characters, if possible.
-8 Highlight the clipboard-selection with a highlight group.
-8 Be able to reset highlighting to its original (default) values.
-7 Be able to write current highlighting to a file as commands, similar to
- ":mkvimrc".
-8 Improve c.vim:
- - Add check for unterminated strings, with a variable to switch it on:
- "c_strict_ansi".
- - Detect unbalanced "#endif". Requires looking back a long way...
-8 Add an option to restrict the updating of syntax highlighting to the
- current line while in Insert mode.
-8 When guessing value of 'background', the syntax file has already been
- loaded (from the .gvimrc). After changing 'background', load it again?
-8 Add ":syn resync" command, to re-parse the whole file until the current
- display position.
-8 Should support "me" offset for a region start pattern. To be used to
- allow searching for the end pattern inside the match of the end pattern.
- Example: syn region pikeXX start="([^{]" end=")" should work on "()".
-8 When using a regexp for "contains=", should delay matching with it until
- redrawing happens. Set a flag when a group is added, check this flag when
- highlighting starts.
-8 Some terminals can display colors like the GUI. Add some setting to use
- GUI colors for the terminal? With something to define the escape
- sequence.
-7 It's possible for an item to be transparent, so that the colors of an item
- lower on the stack is used. Also do this with highlighting, so that the
- user can set transparent highlighting? E.g. a number in a C comment would
- get the color of a comment, a number in an assignment Normal. (Nikolai
- Weibull)
-7 Add "semitrans": Add highlighting. E.g., make the text bold, but keep the
- colors. And add colors, so that Green+Red becomes Yellow.
- E.g. for this html:
- <B> bold text <I> italic+bold text </B> italic text </I>
-7 CTRL-] checks the highlight group for finding out what the tag is.
-7 Add an explanation how a list of words can be used to highlight misspelled
- words.
-8 Add more command line completion for :syntax.
-8 Add more command line completion for :highlight.
-7 Should find a better way to parse the :syntax and :highlight commands.
- Use tables or lists that can be shared by parsing for execution and
- completion?
-8 Add ColorSchemePost autocommand event, so that scripts can set up their
- highlighting. (Salman Halim)
-7 Add a few sets of colors (e.g. Borland Turbo C one). With a menu to
- select one of the sets.
-8 Add offsets to sub-matches: "\(a*\) *"he=e1-1
- 'e' is end of match 'e1' is end of sub-match 1, 's2' is start of submatch
- 2, etc.
-8 In Insert mode, when there are typeahead characters, postpone the
- highlighting (for "." command).
-8 Syncing on comments isn't 100% correct when / / lines mix with / * and * /.
- For example: What about a line that starts with / / and contains * /?
-8 Ignore / * and * / inside strings, when syncing.
-7 Build a few more syntax files from the file "/usr/share/misc/vgrindefs":
- ISP, LDL, Icon, ratfor. And check "nedit/source/highlight.c".
-6 Add possibility to have background color continue until the right edge of
- the window. Useful for comment blocks and function headings. (Rogall)
-- Make it possible to add "contains" items for all items in a group. Useful
- when extending an already existing syntax file.
-- Add line-continuation pattern for non-syncing items too?
-- Add possibility to highlight the whole line, including the right margin
- (for comment blocks).
-- Add 'hlmatch' option: List of flags:
- 'c': highlight match for character under the cursor.
- 'b': highlight the previous (, and its match.
- 'a': highlight all text from the previous ( until its match.
- Also for {}, <>, etc.?
- 'e': highlight all braces without a match (slow?)
- OR: add an argument "cursor" to the syntax command, which means that the
- region/match/keyword is only highlighted when the cursor is on it.
- (Campbell)
- Or do it like Elvis: define text objects and how to highlight them around
- the cursor. (Iain Truskett)
-7 Make it possible to use all words in the tags files as Keyword.
- Can also be done with a script (but it's slow).
-7 Make it possible to call a ":" command when a match is found. Should
- allow for adding keywords from the text (e.g. variables that are set).
- And allows for sections with different highlighting.
-7 Add highlight group for commandline: "Commandline". Make sure it
- highlights the command line while typing a command, and any output from
- messages. And external commands?
-8 Make a version that works like less, but with highlighting: read stdin for
- text, exit at end of file, don't allow editing, etc. moreim? lessim?
-7 SpecialKey highlighting overrules syntax highlighting. Can't give an
- unprintable char another color. Would be useful for ^M at end of line.
-
-
-Built-in script language:
-8 Make the filename and line number available to script functions, so that
- they can give useful debugging info. The whole call stack would be ideal.
- At least use this for error messages.
-7 Execute a function with standard option values. No need to save and
- restore option values. Especially useful for new options. Problem: how
- to avoid a performance penalty (esp. for string options)?
-8 Add referring to key options with "&t_xx". Both for "echo &t_xx" and
- ":let &t_xx =". Useful for making portable mappings.
-- Add ":let var ?= value", conditional assignment. Patch by Dave Eggum,
- 2006 Dec 11.
-- range for ":exec", pass it on to the executed command. (Webb)
-8 ":{range}source": source the lines from the current file.
- You can already yank lines and use :@" to execute them.
- Most of do_source() would not be used, need a new function.
- It's easy when not doing breakpoints or profiling.
- Requires copying the lines into a list and then creating a function to
- execute lines from the list. Similar to getnextac().
-7 ":include" command: just like ":source" but doesn't start a new scriptID?
- Will be tricky for the list of script names.
-8 Have a look at VSEL. Would it be useful to include? (Bigham)
-8 Add ":fungroup" command, to group function definitions together. When
- encountered, all functions in the group are removed. Suggest using an
- obscure name to avoid name clashes. Require a ":fungroup END" in the same
- sourced file? Assume the group ends at the end of the file. Handle
- nested packages?
- Alternative: Support packages. {package-name}:{function-name}().
- Packages are loaded automatically when first used, from
- $VIMRUNTIME/packages (or use a search path).
-7 Pre-parse or compile Vim scripts into a bytecode.
- 1. Put the bytecode with the original script, with an ":if
- has('bytecode')" around it, so that it's only used with a Vim that
- supports it. Update the code with a command, can be used in an
- autocommand.
- 2. Use a ".vic" file (like Python use .pyc). Create it when writing a
- .vim file. Problem: distribution.
- 3. Use a cache directory for each user. How to recognize which cached
- file belongs to a sourced script?
-7 Add argument to winwidth() to subtract the space taken by 'foldcolumn',
- signs and/or 'number'.
-6 Add ++ and -- operators? They only work on variables (lvals), how to
- implement this?
-8 Add functions:
- has(":command") Check if ":command" works. compare function
- with "ex_ni". E.g. for ":simalt".
- system() With a List argument. Bypasses the shell, use
- exec() directly. (Bob Hiestand)
- escape() Add argument to specify what to escape with.
- modestack() Instead of just the current mode return the
- stack of Insert / CTRL-O / :normal things.
- realname() Get user name (first, last, full)
- user_fullname() patch by Nikolai Weibull, Nov
- 3 2002
- Only add this when also implemented for
- non-Unix systems, otherwise a shell cmd could
- be used.
- get_user_name() gets login name.
- menuprop({name}, {idx}, {what})
- Get menu property of menu {name} item {idx}.
- menuprop("", 1, "name") returns "File".
- menuprop("File", 1, "n") returns "nmenu
- File.Open..." argument.
- Patch by Ilya Sher, 2004 Apr 22
- Return a list of menus and/or a dictionary
- with properties instead.
- mapname({idx}, mode) return the name of the idx'th mapping.
- Patch by Ilya Sher, 2004 Mar 4.
- Return a list instead.
- char2hex() convert char string to hex string.
- base64enc() base 64 encoding
- base64dec() base 64 decoding
- attributes() return file protection flags "drwxrwxrwx"
- filecopy(from, to) Copy a file
- shorten(fname) shorten a file name, like home_replace()
- perl(cmd) call Perl and return string
- inputrl() like input() but right-to-left
- typed() return the characters typed and consumed (to
- find out what happened)
- virtualmode() add argument to obtain whether "$" was used in
- Visual block mode.
- getacp() Win32: get codepage (Glenn Maynard)
- deletebufline() delete line in any buffer
- appendbufline() append line in any buffer
- libcall() Allow more than one argument.
- libcallext() Like libcall(), but using a callback function
- to allow the library to execute a command or
- evaluate an expression.
-7 Make bufname("'0") return the buffer name from mark '0. How to get the
- column and line number? col("'0") currently returns zero.
-8 argc() returns 0 when using "vim -t tag". How to detect that no file was
- specified in any way? To be able to jump to the last edited file.
-8 Pass the command line arguments to Vim scripts in some way. As v:args
- List? Or extra parameter to argv()?
-8 Add command arguments with three dashes, passed on to Vim scripts.
-7 Add optional arguments to user functions:
- :func myFunc(arg1, arg2, arg3 = "blah", arg4 = 17)
-6 User functions: Functions local to buffer "b:func()"?
-8 For Strings add ":let var[{expr}] = {expr}". When past the end of "var"
- just ignore.
-8 The "= register should be writable, if followed by the name of a variable,
- option or environment variable.
-8 ":let &option" should list the value of the option.
-8 ":let Func().foo = value" should work, also when "foo" doesn't exist.
- Also: ":let Func()[foo] = value" should work. Same for a List.
-7 Add synIDlist(), making the whole list of syntax items on the syntax stack
- available as a List.
-8 Add autocommand-event for when a variable is changed:
- :au VarChanged {varname} {commands}
-8 Add "has("gui_capable")", to check if the GUI can be started.
-8 Add possibility to use variables like registers: characterwise (default),
- linewise (when ending in '\n'), blockwise (when ending in '\001'). reg0,
- rega, reg%, etc. Add functions linewise({expr}), blockwise({expr}) and
- charwise({expr}).
-7 Make it possible to do any command on a string variable (make a buffer
- with one line, containing the string). Maybe add an (invisible) scratch
- buffer for this?
- result = scratch(string, command)
- result = apply(string, command)
- result = execute(string, command)
- "command" would use <> notation.
- Does scratch buffer have a number? Or re-use same number?
-7 Add function to generate unique number (date in milliseconds).
-
-
-Robustness:
-6 Add file locking. Lock a file when starting to edit it with flock() or
- fcntl(). This patch has advisory file locking while reading/writing
- the file for Vim 5.4: ~/vim/patches/kahn_file_locking .
- The patch is incomplete (needs support for more systems, autoconf).
- Andy doesn't have time to work on it.
- Disadvantage: Need to find ways to gracefully handle failure to obtain a
- lock. When to release a lock: When buffer is unloaded?
-
-
-Performance:
-7 For string variables up to 3 bytes don't allocate memory, use v_list
- itself as a character array. Use VAR_SSTRING (short string).
-7 Add 'lazysize' option: Above this size Vim doesn't load everything before
- starting to edit a file. Things like 'fileencodings' only work up to this
- size, modelines only work at the top. Useful for large log files where
- you only want to look at the first few pages. Use zero to disable it.
-8 move_lines() copies every line into allocated memory, making reloading a
- buffer a lot slower than re-editing the file. Can the memline be locked
- so that we don't need to make a copy? Or avoid invoking ml_updatechunk(),
- that is taking a lot of time. (Ralf Wildenhues, 2008 Jul 7)
- With a patch, but does it work?
-8 Instead of loading rgb.txt every time a color wasn't recognized load it
- once and keep it in memory. Move the code to a common place to avoid
- repeating it in various system files.
-8 Turn b_syn_ic and b_syn_containedin into b_syn_flags.
-9 Loading menu.vim still takes quite a bit of time. How to make it faster?
-8 in_id_list() takes much time for syntax highlighting. Cache the result?
-7 setpcmark() shifts the jumplist, this takes quite a bit of time when
- jumping around. Instead use an index for the start?
-8 When displaying a space with only foreground highlighting, it's the same
- as a space without attributes. Avoid displaying spaces for the "~" lines
- when starting up in a color terminal.
-8 Profiling shows that in_id_list() is used very often for C code. Can this
- function be improved?
-8 For an existing file, the page size of the swap file is always the
- default, instead of using the block size of the device, because the swap
- file is created only after setting the block size in mf_open(). How can
- this be improved?
-7 C syntax highlighting gets a lot slower after ":set foldmethod=syntax".
- (Charles Campbell) Inserting a "{" is very slow. (dman)
-7 HTML syntax highlighting is slow for long lines. Try displaying
- http://www.theregister.co.uk/content/4/22908.html. (Andre Pang)
-7 Check how performance of loading the wordlist can be improved (adding a
- lot of abbreviations).
-7 MS-DOS console: Add t_DL support, to make scrolling faster.
-7 Compile Ex commands to byte codes. Store byte codes in a vim script file
- at the end, after "compiled:. Make it look like a single comment line
- for old Vim versions. Insert first line "Vim script compiled <timestamp>.
- Only used compiled code when timestamp matches the file stat.
- Add command to compile a vim script and add it to the file in-place.
- Split Ex command executing into a parsing and executing phase.
- Use compiled code for functions, while loops, etc.
-8 When defining autocommands (e.g., from $VIMRUNTIME/filetype.vim), need to
- compare each pattern with all existing patterns. Use a hash code to avoid
- using strcmp() too often?
-7 Include turbo_loader patches, speeding up reading a file?
- Speed up reading a file by reading it into a fixed-size buffer, creating
- the list of indexes in another buffer, and then copying the result into a
- memfile block with two copies. Then read the next block into another
- fixed-size buffer, create the second list of indexes and copy text from
- the two blocks to the memfile block.
-7 do_cmdline(): Avoid that the command line is copied to allocated memory
- and freed again later all the time. For while loops, and for when called
- with an argument that can be messed with.
- Generic solution: Make a struct that contains a pointer and a flag that
- indicates if the pointer should be freed when replaced.
-7 Check that the file size is not more than "sizeof(long)".
-- Further improve finding mappings in maphash[] in vgetorpeek()
-8 Syntax highlighting is slow when deleting lines. Try in
- $VIMRUNTIME/filetype.vim.
-- "out of memory" after deleting (1,$d) and changing (:%s/^/> /) a lot of
- lines (27000) a few times. Memory fragmentation?
-- Have a look at how pdksh does memory allocation (alloc.c). (Dalecki)
-- Do profiling on:
- - :g/pat/normal cmd
- - 1000ii<Esc>
- - deleting 10Mbyte worth of lines (netscape binary)
- - "[i" and "[d" (Yegappan Lakshmanan)
- - ":g/^/m0" on a 450Kbyte file. And the "u".
- - highlighting "~/vim/test/longline.tex", "~/vim/test/scwoop.tcl" and
- "~/vim/test/lockup.pl".
- - loading a syntax file to highlight all words not from a dictionary.
- - editing a Vim script with syntax highlighting on (loading vim.vim).
-7 Screen updating can be further improved by only redrawing lines that were
- changed (and lines after them, when syntax highlighting was used, and it
- changed).
- - On each change, remember start and end of the change.
- - When inserting/deleting lines, remember begin, end, and line count.
-- Use macros/duarte/capicua for profiling. Nvi 1.71 is the fastest!
-- When using a file with one long line (1Mbyte), then do "$hhhh", is still
- very slow. Avoid calling getvcol() for each "h"?
-- Executing a register, e.g. "10000@@" is slow, because ins_typebuf has to
- move the previous commands forward each time. Pass count from
- normal_cmd() down to do_execreg().
-- Repeating insert "1000i-<Esc>" displays --INSERT-- all the time, because of
- the <Esc> at the end. Make this work faster (disable redrawing).
-- Avoid calls to plines() for cursor line, use w_cline_height.
-- After ":set nowrap" remove superfluous redraw with wrong hor. offset if
- cursor is right of the screen.
-8 Make CTRL-C on Unix generate a signal, avoid using select() to check for a
- CTRL-C (it's slow).
-
-
-Code size:
-8 GUI: When NO_CONSOLE is defined, more code can be excluded.
-- Put getline() and cookie in a struct, so only one argument has to be
- passed to do_cmdline() and other functions.
-8 Make a GUI-only version for Unix?
-8 In buf_write _() isn't needed when setting errmsg, do it once when using
- it.
-7 When compiling with a GUI-only version, the code for cterm colors can be
- left out.
-8 When compiled with a GUI-only version, the termcap entries for terminals
- can be removed.
-8 Can the check for libelf in configure.in be removed?
-
-
-Messages:
-8 When using ":q" in a changed file, the error says to "add !". Add the
- command so that beginners understand it: "use :q!".
-8 For 'verbose' level 12 prints commands from source'ed files. How to skip
- lines that aren't executed? Perhaps move the echoing to do_cmdline()?
-8 Use 'report' for ":bdel"? (Krishna) To avoid these messages when using a
- script.
-- Delete message after new command has been entered and have waited for key.
- Perhaps after ten seconds?
-- Make message history available in "msg" variables: msg1, msg2, .. msg9.
-8 When reading from stdin allow suppressing the "reading from stdin"
- message.
-9 Check handling of overwriting of messages and delays:
- Very wrong: errors while redrawing cause endless loop.
- When switching to another file and screen scrolls because of the long
- message and return must be typed, don't scroll the screen back before
- redrawing.
-8 When address range is wrong you only get "Invalid range". Be a bit more
- specific: Negative, beyond last line, reverse range? Include the text.
-8 Make it possible to ignore errors for a moment ('errorignore'?). Another
- option to switch off giving error messages ('errorquiet'?). Also an option
- not to give any messages ('quiet')? Or ":quiet on", ":quiet off".
- Careful: For a severe error (out of memory), and when the user starts
- typing, error messages must be switched back on.
- Also a flag to ignore error messages for shell commands (for mappings).
-- Option to set time for emsg() sleep. Interrupt sleep when key is typed?
- Sleep before second message?
-8 In Ex silent mode or when reading commands from a file, what exactly is
- not printed and what is? Check ":print", ":set all", ":args", ":vers",
- etc. At least there should be no prompt. (Smulders) And don't clear the
- screen when reading commands from stdin. (Kendall)
- --> Make a difference between informative messages, prompts, etc. and
- error messages, printing text, etc.
-8 Window should be redrawn when resizing at the hit-enter prompt.
- Also at the ":tselect" prompt. Find a generic solution for redrawing when
- a prompt is present (with a callback function?).
-
-
-Screen updating:
-7 Add a string to the 'display' option to make CTRL-E and CTRL-Y scroll one
- screen line, also if this means the first line doesn't start with the
- first character (like what happens with a single line that doesn't fit).
-- screen_line():
- - insert/delete character stuff.
- - improve delete rest of line (spaces at end of line).
-- When moving or resizing window, try to avoid a complete redraw (esp. when
- dragging the status line with the mouse).
-- When 'lazyredraw' set, don't echo :ex commands? Need a flag to redraw when
- waiting for a character.
-8 Add a ":refresh [winnr]" command, to force updating a window. Useful from
- an event handler where ":normal" can't be used. Also useful when
- 'lazyredraw' is set in a mapping.
-7 Make 'list' and 'linebreak' work together.
-
-
-Scrolling:
-8 Add "zy" command: scroll horizontally to put the cursor in the middle.
-6 Add option to set the overlap for CTRL-F and CTRL-B. (Garhi)
-- extend 'scrollbind' option: 'scrollopt' words "search", "relative", etc..
- Also 'e'xecute some commands (search, vertical movements) in all bound
- windows.
-7 Add 'scrollbind' feature to make the offset of one window with the next
- one equal to the window height. When editing one file in both windows it
- looks like each window displays a page of the buffer.
-- Allow scrolling by dragging with the mouse (grab a character and move it
- up/down). Like the "hand" in Acrobat reader. Use Alt-LeftMouse for this?
- (Goldfarb)
-- Add command to execute some commands (search, vertical movements) in all
- bound windows.
-- Add 'search' option to 'scrollopt' to allow 'scrollbind' windows to
- be bound by regexp searches
-- Add "z>" and "z<": scroll sideways one screenful. (Campbell)
-- Add option to set the number of lines when not to scroll, instead of the
- fixed number used now (for terminals that scroll slow with a large number
- of lines but not with a single line).
-
-
-Autoconf:
-8 Should use acconfig.h to define prototypes that are used by autoheader.
-8 Some compilers don't give an error for "-OPT:Olimit" but a warning. (Webb)
- Add a check for the warning, so that "Olimit" can be added automatically?
-- Autoconf: Use @datadir@ for the system independent files. Make sure the
- system dependent and system independent files are separated. (Leitner).
-- Add autoconf check for waitpid()/wait4().
-- Remove fcntl() from autoconf, all systems have it?
-- Set default for 'dictionary', add search for dictionary to autoconf.
-
-
-Perl interface:
-8 Rename typemap file to something else?
-7 Make buffers accessed as Perl arrays. (Clark)
-7 Make it possible to compile with non-ANSI C?
-6 Tcl/Tk has the "load" command: load a shared library (.so or .dll).
-
-
-Shared libraries:
-6 Add support for loading shared libraries, and calling functions in it.
- :libload internal-name libname
- :libunload internal-name
- :liblist
- :libcall internal-name function(arg1, arg2, ...)
- :libcall function(arg1, arg2, ...)
- libcall() can have only one integer or String argument at the moment.
-6 Have a look on how Perl handles loading dynamic libraries.
-
-
-Tags:
-9 With ":set tags=./tags,../tags" and a tag appears in both tags files it is
- added twice. Requires figuring out the actual file name for each found
- match. Remove tag_fname from the match and combine it with the fname in
- the match (without expanding or other things that take time). When
- 'tagrelative' is off tag_fname isn't needed at all.
-8 For 'tags' wildcard in the file name is not supported, only in the path.
- This is due to it using |file-searching|. Suboptimal solution would be to
- make the filename or the whole option use |wildcards| globing, better
- would be to merge the 2 kinds of globing. originally (Erik Falor, 2008
- April 18), updated (Ian Kelling, 2008 July 4)
-7 Can CTRL-] (jump to tag) include a following "." and "->" to restrict the
- number of possible matches? Check tags file for an item that has members.
- (Flemming Madsen)
-8 Scope arguments for ":tag", e.g.: ":tag class:cPage open", like Elvis.
-8 When output of ":tselect" is long, getting the more-prompt, should be able
- to type the tag number directly.
-7 Add the possibility to use the "-t {tag}" argument multiple times. Open a
- window for each tag.
-7 Make output of ":tselect" a bit nicer. Use highlighting?
-7 Highlight the "tag 1 of >2" message. New highlight group, or same as "hit
- bottom" search message.
-7 When using ":tag" at the top of the tag stack, should add another entry,
- so CTRL-T can bring you back to where you are now AND to where you were
- before the previous ":tag" command. (Webb)
-- When doing "[^I" or "[^D" add position to tag stack.
-- Add command to put current position to tag stack: ":tpush".
-- Add functions to save and restore the tag stack? Or a command to switch
- to another tag stack? So that you can do something else and come back to
- what you were working on.
-7 When using CTRL-] on someClass::someMethod, separate class from method and
- use ":ta class:someClass someMethod".
- Include C++ tags changes (Bertin). Change "class::func" tag into "func"
- with "class=class"? Docs in oldmail/bertin/in.xxx.
-7 Add ":tagargs", to set values for fields:
- :tagargs class:someclass file:version.c
- :tagargs clear
- These are then the default values (changes the order of priority in tag
- matching).
-7 Support for "gtags" and "global"? With ":rtag" command?
- There is an example for how to do this in Nvi.
- Or do it like Elvis: 'tagprg' and 'tagprgonce' options. (Yamaguchi)
- The Elvis method is far more flexible, do it that way.
-7 Support "col:99" extra field, to position the cursor in that column. With
- a flag in 'cpoptions' to switch it off again.
-7 Better support for jumping to where a function or variable is used. Use
- the id-utils, with a connection to "gid" (Emacs can do it too). Add
- ":idselect", which uses an "ID" database (made by "mkid") like "tselect".
-
-
-Autocommands:
-- Put autocommand event names in a hashtable for faster lookup?
-8 When the SwapExists event is triggered, provide information about the
- swap file, e.g., whether the process is running, file was modified, etc.
- Must be possible to check the situation that it's probably OK to delete
- the swap file. (Marc Merlin)
-8 When all the patterns for an event are "*" there is no need to expand
- buffer names to a full path. This can be slow for NFS.
-7 For autocommand events that trigger multiple times per buffer (e.g.,
- CursorHold), go through the list once and cache the result for a specific
- buffer. Invalidate the cache when adding/deleting autocommands or
- changing the buffer name.
-7 Add TagJump event: do something after jumping to a tag.
-8 Add "TagJumpFile" autocommand: When jumping to another file for a tag.
- Can be used to open "main.c.gz" when "main.c" isn't found.
-8 Use another option than 'updatetime' for the CursorHold event. The two
- things are unrelated for the user (but the implementation is more
- difficult).
-7 Add autocommand event for when a buffer cannot be abandoned. So that the
- user can define the action taking (autowrite, dialog, fail) based on the
- kind of file. (Yakov Lerner) Or is BufLeave sufficient?
-8 Autocommand for when modified files have been found, when getting input
- focus again (e.g., FileChangedFocus).
- Check when: getting focus, jumping to another buffer, ...
-7 Autocommand for when an option is changed. Match buffer name or option
- name?
-8 Autocommands should not change registers. And marks? And the jumplist?
- And anything else? Add a command to save and restore these things.
-8 Add autocommands, user functions and user commands to ":mkvimrc".
-6 Add KeymapChanged event, so that the effects of a different keymap can be
- handled (e.g., other font) (Ron Aaron)
-7 When trying to open a directory, trigger an OpenDirectory event.
-7 Add file type in front of file pattern: <d> for directory, <l> for link,
- <x> for executable, etc. With commas to separate alternatives. The
- autocommand is only executed when both the file type AND the file pattern
- match. (Leonard)
-5 Add option that specifies extensions which are to be discarded from the
- file name. E.g. 'ausuffix', with ".gz,.orig". Such that file.c.gz will
- trigger the "*.c" autocommands. (Belabas)
-7 Add something to break the autocommands for the current event, and for
- what follows. Useful for a "BufWritePre" that wants to avoid writing the
- file.
-8 When editing "tt.gz", which is in DOS format, 'fileformat' stays at
- "unix", thus writing the file changes it. Somehow detect that the read
- command used dos fileformat. Same for 'fileencoding'.
-- Add events to autocommands:
- Error - When an error happens
- NormalEnter - Entering Normal mode
- ReplaceEnter - Entering Replace mode
- CmdEnter - Entering Cmdline mode (with type of cmdline to allow
- different mapping)
- VisualEnter - Entering Visual mode
- *Leave - Leaving a mode (in pair with the above *Enter)
- VimLeaveCheck - Before Vim decides to exit, so that it can be cancelled
- when exiting isn't a good idea.
- CursorHoldC - CursorHold while command-line editing
- WinMoved - when windows have been moved around, e.g, ":wincmd J"
- SearchPost - After doing a search command (e.g. to do "M")
- PreDirChanged/PostDirChanged
- - Before/after ":cd" has been used (for changing the
- window title)
- ShutDown - when the system is about to shut down
- InsertCharPost - user typed a character in Insert mode, after inserting
- the char.
- BufModified - When a buffer becomes modified, or unmodified (for
- putting a [+] in the window title or checking out the
- file from CVS).
- BufFirstChange - When making a change, when 'modified' is set. Can be
- used to do a :preserve for remote files.
- BufChange - after a change was made. Set some variables to indicate
- the position and number of inserted/deleted lines, so
- that marks can be updated. HierAssist has patch to add
- BufChangePre, BufChangePost and RevertBuf. (Shah)
- ViewChanged - triggered when the text scrolls and when the window size
- changes.
- WinResized - After a window has been resized
- WinClose - Just before closing a window
-- Write the file now and then ('autosave'):
- *'autosave'* *'as'* *'noautosave'* *'noas'*
- 'autosave' 'as' number (default 0)
- Automatically write the current buffer to file N seconds after the
- last change has been made and when |'modified'| is still set.
- Default: 0 = do not autosave the buffer.
- Alternative: have 'autosave' use 'updatetime' and 'updatecount' but make
- them save the file itself besides the swapfile.
-
-
-Omni completion:
-- Add a flag to 'complete' to be able to do omni completion with CTRL-N (and
- mix it with other kinds of completion).
-- Ideas from the Vim 7 BOF at SANE:
- - For interpreted languages, use the interpreter to obtain information.
- Should work for Java (Eclipse does this), Python, Tcl, etc.
- Richard Emberson mentioned working on an interface to Java.
- - Check Readline for its completion interface.
-- Ideas from others:
- http://www.wholetomato.com/
- http://www.vim.org/scripts/script.php?script_id=747
- http://sourceforge.net/projects/insenvim
- or http://insenvim.sourceforge.net
- Java, XML, HTML, C++, JSP, SQL, C#
- MS-Windows only, lots of dependencies (e.g. Perl, Internet
- explorer), uses .dll shared libraries.
- For C++ uses $INCLUDE environment var.
- Uses Perl for C++.
- Uses ctags to find the info:
- ctags -f $allTagsFile --fields=+aiKmnsSz --language-force=C++ --C++-kinds=+cefgmnpsut-dlux -u $files
- www.vim.org script 1213 (Java Development Environment) (Fuchuan Wang)
- IComplete: http://www.vim.org/scripts/script.php?script_id=1265
- and http://stud4.tuwien.ac.at/~e0125672/icomplete/
- http://cedet.sourceforge.net/intellisense.shtml (for Emacs)
- Ivan Villanueva has something for Java.
- Emacs: http://www.xref-tech.com/xrefactory/more_c_completion.html
- Completion in .NET framework SharpDevelop: http://www.icsharpcode.net
-- Pre-expand abbreviations, show which abbrevs would match?
-
-
-Insert mode completion/expansion:
-7 When searching in other files the name flash by, too fast to read. Only
- display a name every second or so, like with ":vimgrep".
-7 When expanding file names with an environment variable, add the match with
- the unexpanded var. So $HOME/tm expands to "/home/guy/tmp" and
- "$HOME/tmp"
-8 When there is no word before the cursor but something like "sys." complete
- with "sys.". Works well for C and similar languages.
-9 ^X^L completion doesn't repeat correctly. It uses the first match with
- the last added line, instead of continuing where the last match ended.
- (Webb)
-8 Add option to set different behavior for Insert mode completion:
- - ignore/match case
- - different characters than 'iskeyword'
-8 Add option 'isexpand', containing characters when doing expansion (so that
- "." and "\" can be included, without changing 'iskeyword'). (Goldfarb)
- Also: 'istagword': characters used for CTRL-].
- When 'isexpand' or 'istagword' are empty, use 'iskeyword'.
- Alternative: Use a pattern so that start and end of a keyword can be
- defined, only allow dash in the middle, etc.
-8 Add a command to undo the completion, go back to the original text.
-7 Completion of an abbreviation: Can leave letters out, like what Instant
- text does: www.textware.com
-8 Use the class information in the tags file to do context-sensitive
- completion. After "foo." complete all member functions/variables of
- "foo". Need to search backwards for the class definition of foo.
- Should work for C++ and Java.
- Even more context would be nice: "import java.^N" -> "io", "lang", etc.
-7 When expanding $HOME/dir with ^X^F keep the $HOME (with an option?).
-7 Add CTRL-X command in Insert mode like CTRL-X CTRL-N, that completes WORDS
- instead of words.
-8 Add CTRL-X CTRL-R: complete words from register contents.
-8 Add completion of previously inserted texts (like what CTRL-A does).
- Requires remembering a number of insertions.
-8 Add 'f' flag to 'complete': Expand file names.
- Also apply 'complete' to whole line completion.
-- Add a flag to 'complete' to only scan local header files, not system
- header files. (Andri Moell)
-- Make it possible to search include files in several places. Use the
- 'path' option? Can this be done with the dictionary completion (use
- wildcards in the file name)?
-- Make CTRL-X CTRL-K do a binary search in the dictionary (if it's sorted).
-- Speed up CTRL-X CTRL-K dictionary searching (don't use a regexp?).
-- Set a mark at the position where the match was found (file mark, could
- be in another file).
-- Add CTRL-A command in CTRL-X mode: show all matches.
-- Make CTRL-X CTRL-L use the 'complete' option?
-- Add command in CTRL-X mode to add following words to the completed string
- (e.g. to complete "Pointer->element" with CTRL-X CTRL-P CTRL-W CTRL-W)
-- CTRL-X CTRL-F: Use 'path' to find completions.
-- CTRL-X CTRL-F: Option to use forward slashes on MS-Windows?
-- CTRL-X CTRL-F: Don't replace "$VIM" with the actual value. (Kelly)
-- Allow listing all matches in some way (and picking one from the list).
-
-
-Command line editing:
-7 Add commands (keys) to delete from the cursor to the end of the command
- line.
-8 Custom completion of user commands can't use the standard completion
- functions. Add a hook to invoke a user function that returns the type of
- completion to be done: "file", "tag", "custom", etc.
-- Add flags to 'whichwrap' for command line editing (cursor right at end of
- lines wraps to start of line).
-- Make editing the command line work like Insert mode in a single-line view
- on a buffer that contains the command line history. But this has many
- disadvantages, only implement it when these can be solved. Elvis has run
- into these, see remarks from Steve (~/Mail/oldmail/kirkendall/in.00012).
- - Going back in history and editing a line there would change the history.
- Would still need to keep a copy of the history elsewhere. Like the
- cmdwin does now already.
- - Use CTRL-O to execute one Normal mode command. How to switch to normal
- mode for more commands? <Esc> should cancel the command line. CTRL-T?
- - To allow "/" and "= need to recursively call getcmdline(), overwrite the
- cmdline. But then we are editing a command-line again. How to avoid
- that the user gets confused by the stack of command lines?
- - Use edit() for normal cmdline editing? Would have to integrate
- getcmdline() into edit(). Need to solve conflicts between Insert mode
- and Command-line mode commands. Make it work like Korn shell and tcsh.
- Problems:
- - Insert: completion with 'wildchar'
- - Insert: use cmdline abbreviations
- - Insert: CTRL-D deletes indent instead of listing matches
- - Normal: no CTRL-W commands
- - Normal: no ":" commands?
- - Normal: allow Visual mode only within one line.
- - where to show insert/normal mode message? Change highlighting of
- character in first column?
- - Implementation ideas:
- - Set "curwin" and "curbuf" to the command line window and buffer.
- - curwin->w_topline is always equal to curwin->w_cursor.lnum.
- - never set 'number', no folding, etc. No status line.
- - sync undo after entering a command line?
- - use NV_NOCL flag for commands that are not allowed in Command-line
- Mode.
-
-
-Command line completion:
-8 Change expand_interactively into a flag that is passed as an argument.
-8 With command line completion after '%' and '#', expand current/alternate
- file name, so it can be edited. Also with modifiers, such as "%:h".
-8 When completing command names, either sort them on the long name, or list
- them with the optional part inside [].
-8 Add an option to ignore case when doing interactive completion. So that
- ":e file<Tab>" also lists "Filelist" (sorted after matching case matches).
-7 Completion of ":map x ": fill in the current mapping, so that it can be
- edited. (Sven Guckes)
-- For 'wildmenu': Simplify "../bar" when possible.
-- When using <Up> in wildmenu mode for a submenu, should go back to the
- current menu, not the first one. E.g., ":emenu File.Save<Up>".
-8 When using backtick expansion, the external command may write a greeting
- message. Add an option or commands to remove lines that match a regexp?
-7 When listing matches of files, display the common path separately from the
- file names, if this makes the listing shorter. (Webb)
-- Add command line completion for ":ilist" and friends, show matching
- identifiers (Webb).
-8 Add command line completion for "old value" of a command. ":args <key>"
- would result in the current list of arguments, which you can then edit.
-7 Add command line completion with CTRL-X, just like Insert mode completion.
- Useful for ":s/word/xx/".
-- Add command to go back to the text as it was before completion started.
- Also to be used for <Up> in the command line.
-- Add 'wildlongest' option: Key to use to find longest common match for
- command line completion (default CTRL-L), like 'wildchar'. (Cregut)
- Also: when there are several matches, show them line a CTRL-D.
-
-
-Command line history:
-- Add "KeyWasTyped" flag: It's reset before each command and set when a
- character from the keyboard is consumed. Value is used to decide to put a
- command line in history or not. Put line in history if it didn't
- completely resulted from one mapping.
-- When using ":browse", also put the resulting edit command in the history,
- so that it can be repeated. (Demirel)
-
-
-Insert mode:
-9 When 'autoindent' is set, hitting <CR> twice, while there is text after
- the cursor, doesn't delete the autoindent in the resulting blank line.
- (Rich Wales) This is Vi compatible, but it looks like a bug.
-8 When using CTRL-O in Insert mode, then executing an insert command
- "a" or "i", should we return to Insert mode after <Esc>? (Eggink)
- Perhaps it can be allowed a single time, to be able to do
- "<C-O>10axyz<Esc>". Nesting this further is confusing.
- ":map <F2> 5aabc<Esc>" works only once from Insert mode.
-8 When using CTRL-G CTRL-O do like CTRL-\ CTRL-O, but when returning with
- the cursor in the same position and the text didn't change continue the
- same change, so that "." repeats the whole insert.
-7 Use CTRL-G <count> to repeat what follows. Useful for inserting a
- character multiple times or repeating CTRL-Y.
-- Make 'revins' work in Replace mode.
-9 Can't use multi-byte characters for 'matchpairs'.
-7 Use 'matchpairs' for 'showmatch': When inserting a character check if it
- appears in the rhs of 'matchpairs'.
-- In Insert mode (and command line editing?): Allow undo of the last typed
- character. This is useful for CTRL-U, CTRL-W, delete and backspace, and
- also for characters that wrap to the next line.
- Also: be able to undo CTRL-R (insert register).
- Possibly use 'backspace'="whole" for a mode where at least a <CR> that
- inserts autoindent is undone by a single <BS>.
-- Use CTRL-G in Insert mode for an extra range of commands, like "g" in
- Normal mode.
-- Make 'paste' work without resetting other options, but override their
- value. Avoids problems when changing files and modelines or autocommands
- are used.
-- When typing CTRL-V and a digit higher than 2, only expect two digits.
-- Insert binary numbers with CTRL-V b.
-- Make it possible to undo <BS>, <C-W> and <C-U>. Bash uses CTRL-Y.
-
-
-'cindent', 'smartindent':
-9 Wrapping a variable initialization should have extra indent:
- char * veryLongName =
- "very long string"
- Also check if "cino=+10" is used correctly.
-8 Lisp indenting: "\\" confuses the indenter. (Dorai Sitaram, 2006 May 17)
-8 Why are continuation lines outside of a {} block not indented? E.g.:
- long_type foo =
- value;
-8 Java: Inside an anonymous class, after an "else" or "try" the indent is
- too small. (Vincent Bergbauer)
- Problem of using {} inside (), 'cindent' doesn't work then.
-8 In C++ it's possible to have {} inside (): (Kirshna)
- func(
- new String[] {
- "asdf",
- "asdf"
- }
- );
-8 In C++ a function isn't recognized inside a namespace:
- (Chow Loong Jin)
- namespace {
- int
- func(int arg) {
- }
- }
-6 Add 'cino' flag for this function argument layout: (Spencer Collyer)
- func( arg1
- , arg2
- , arg3
- );
-7 Add separate "(0" option into inside/outside a function (Zellner):
- func(
- int x) // indent like "(4"
- {
- if (a
- && b) // indent like "(0"
-9 Using "{" in a comment: (Helmut Stiegler)
- if (a)
- {
- if (b)
- {
- // {
- }
- } <-- this is indented incorrect
- Problem is that find_start_brace() checks for the matching brace to be in
- a comment, but not braces in between. Requires adding a comment check to
- findmatchlimit().
-- Make smartindenting configurable. Add 'sioptions', e.g. '#' setting the
- indent to 0 should be switched on/off.
-7 Support ANSI style function header, with each argument on its own line.
-- "[p" and "]p" should use 'cindent' code if it's on (only for the first
- line).
-- Add option to 'cindent' to set indent for comments outside of {}?
-- Make a command to line up a comment after a code line with a previous
- comment after a code line. Can 'cindent' do this automatically?
-- When 'cindent'ing a '}', showmatch is done before fixing the indent. It
- looks better when the indent is fixed before the showmatch. (Webb)
-- Add option to make indenting work in comments too (for commented-out
- code), unless the line starts with "*".
-- Don't use 'cindent' when doing formatting with "gq"?
-- When formatting a comment after some text, insert the '*' for the new line
- (indent is correct if 'cindent' is set, but '*' doesn't get inserted).
-8 When 'comments' has both "s1:/*,mb:*,ex:*/" and "s1:(*,mb:*,ex:*)", the
- 'x' flag always uses the first match. Need to continue looking for more
- matches of "*" and remember all characters that could end the comment.
-- For smartindent: When typing 'else' line it up with matching 'if'.
-- 'smartindent': allow patterns in 'cinwords', for e.g. TeX files, where
- lines start with "\item".
-- Support this style of comments (with an option): (Brown)
- /* here is a comment that
- is just autoindented, and
- nothing else */
-- Add words to 'cinwords' to reduce the indent, e.g., "end" or "fi".
-7 Use Tabs for the indent of starting lines, pad with spaces for
- continuation lines. Allows changing 'tabstop' without messing up the
- indents.
- Patch by Lech Lorens, 2010 Mar. Update by James McCoy, 2014 Mar 15.
-
-
-Java:
-8 Can have {} constructs inside parens. Include changes from Steve
- Odendahl?
-8 Recognize "import java.util.Vector" and use $CLASSPATH to find files for
- "[i" commands and friends.
-- For files found with 'include': handle "*" in included name, for Java.
- (Jason)
-- How to make a "package java.util" cause all classes in the package to be
- searched? Also for "import java.util.*". (Mark Brophy)
-
-
-'comments':
-8 When formatting C comments that are after code, the "*" isn't repeated
- like it's done when there is no code. And there is no automatic wrapping.
- Recognize comments that come after code. Should insert the comment leader
- when it's "#" or "//".
- Other way around: when a C command starts with "* 4" the "*" is repeated
- while it should not. Use syntax HL comment recognition?
-7 When using "comments=fg:--", Vim inserts three spaces for a new line.
- When hitting a TAB, these spaces could be removed.
-7 The 'n'esting flag doesn't do the indenting of the last (rightmost) item.
-6 Make strings in 'comments' option a RE, to be able to match more
- complicated things. (Phillipps) Use a special flag to indicate that a
- regexp is used.
-8 Make the 'comments' option with "/* * */" lines only repeat the "*" line
- when there is a "/*" before it? Or include this in 'cindent'?
-
-
-Virtual edit:
-8 Make the horizontal scrollbar work to move the text further left.
-7 Allow specifying it separately for Tabs and beyond end-of-line?
-
-
-Text objects:
-8 Add text object for fold, so that it can be yanked when it's open.
-8 Add test script for text object commands "aw", "iW", etc.
-8 Add text object for part of a CamelHumpedWord and under_scored_word.
- (Scott Graham) "ac" and "au"?
-8 Add a text object for any kind of quoting, also with multi-byte
- characters. Option to specify what quotes are recognized (default: all)
- use "aq" and "iq". Use 'quotepairs' to define pairs of quotes, like
- 'matchpairs'?
-8 Add text object for any kind of parens, also multi-byte ones.
-7 Add text object for current search pattern: "a/" and "i/". Makes it
- possible to turn text highlighted for 'hlsearch' into a Visual area.
-8 Add a way to make an ":omap" for a user-defined text object. Requires
- changing the starting position in oap->start.
-8 Add "gp" and "gP" commands: insert text and make sure there is a single
- space before it, unless at the start of the line, and after it, unless at
- the end of the line or before a ".".
-7 Add objects with backwards extension? Use "I" and "A". Thus "2dAs"
- deletes the current and previous sentence. (Jens Paulus)
-7 Add "g{" and "g}" to move to the first/last character of a paragraph
- (instead of the line just before/after a paragraph as with "{" and "}").
-6 Ignore comment leaders for objects. Make "das" work in reply-email.
-5 Make it possible to use syntax group matches as a text object. For
- example, define a "ccItem" group, then do "da<ccItem>" to delete one.
- Or, maybe just define "dai", delete-an-item, to delete the syntax item the
- cursor is on.
-
-
-Select mode:
-8 In blockwise mode, typed characters are inserted in front of the block,
- backspace deletes a column before the block. (Steve Hall)
-7 Alt-leftmouse starts block mode selection in MS Word.
- See http://vim.wikia.com/wiki/Use_Alt-Mouse_to_select_blockwise.
-7 Add Cmdline-select mode. Like Select mode, but used on the command line.
- - Change gui_send_mouse_event() to pass on mouse events when 'mouse'
- contains 'C' or 'A'.
- - Catch mouse events in ex_getln.c. Also shift-cursor, etc., like in
- normal_cmd().
- - remember start and end of selection in cmdline_info.
- - Typing text replaces the selection.
-
-
-Visual mode:
-8 Support using "." in Visual mode. Use the operator applied to the Visual
- selection, if possible.
-- When dragging the Visual selection with the mouse and 'scrolloff' is zero,
- behave like 'scrolloff' is one, so that the text scrolls when the pointer
- is in the top line.
-- Displaying size of Visual area: use 24-33 column display.
- When selecting multiple lines, up to about a screenful, also count the
- characters.
-8 When using "I" or "A" in Visual block mode, short lines do not get the new
- text. Make it possible to add the text to short lines too, with padding
- where needed.
-7 With a Visual block selected, "2x" deletes a block of double the width,
- "3y" yanks a block of triple width, etc.
-7 When selecting linewise, using "itext" should insert "text" at the start
- of each selected line.
-8 What is "R" supposed to do in Visual mode?
-8 Make Visual mode local to the buffer. Allow changing to another buffer.
- When starting a new Visual selection, remove the Visual selection in any
- other buffer. (Ron Aaron)
-8 Support dragging the Visual area to drop it somewhere else. (Ron Aaron,
- Ben Godfrey)
-7 Support dragging the Visual area to drop it in another program, and
- receive dropped text from another program. (Ben Godfrey)
-7 With blockwise Visual mode and "c", "C", "I", "A", etc., allow the use of
- a <CR>. The entered lines are repeated over the Visual area.
-7 CTRL-V :s should substitute only in the block, not to whole lines. (David
- Young is working on this)
-7 Filtering a block should only apply to the block, not to the whole lines.
- When the number of lines is increased, add lines. When decreased, pad with
- spaces or delete? Use ":`<,`>" on the command line.
-8 After filtering the Visual area, make "gv" select the filtered text?
- Currently "gv" only selects a single line, not useful.
-7 Don't move the cursor when scrolling? Needed when the selection should
- stay the same. Scroll to the cursor at any movement command. With an
- option!
-7 In Visual block mode, need to be able to define a corner on a position
- that doesn't have text? Also: when using the mouse, be able to select
- part of a TAB. Even more: Add a mode where the cursor can be on a screen
- position where there is no text. When typing, add spaces to fill the gap.
- Other solution: Always use curswant, so that you can move the cursor to
- the right column, and then use up/down movements to select the line,
- without changing the column.
-6 ":left" and ":right" should work in Visual block mode.
-7 CTRL-I and CTRL-O should work in Visual mode, but only jump to marks in the
- current buffer.
-7 CTRL-A and CTRL-X should increase/decrease all numbers in the Visual area.
-6 In non-Block mode, "I" should insert the same text in front of each line,
- before the first non-blank, "gI" in column 1.
-6 In non-Block mode, "A" should append the same text after each line.
-6 When in blockwise visual selection (CTRL-V), allow cursor to be placed
- right of the line. Could also allow cursor to be placed anywhere on a TAB
- or other special character.
-6 Add commands to move selected text, without deselecting.
-
-
-More advanced repeating commands:
-- Add "." command for visual mode: redo last visual command (e.g. ":fmt").
-7 Repeating "d:{cmd}" with "." doesn't work. (Benji Fisher) Somehow remember
- the command line so that it can be repeated?
-- Add command to repeat last movement. Including count.
-- Add "." command after operator: repeat last command of same operator. E.g.
- "c." will repeat last change, also when "x" used since then (Webb).
- "y." will repeat last yank.
- "c2." will repeat the last but one change?
- Also: keep history of Normal mode commands, add command to list the history
- and/or pick an older command.
-- History stack for . command? Use "g." command.
-
-
-Mappings and Abbreviations:
-8 When "0" is mapped (it is a movement command) this mapping should not be
- used after typing another number, e.g. "20l". (Charles Campbell)
- Is this possible without disabling the mapping of the following command?
-8 Should mapping <C-A> and <C-S-A> both work?
-7 ":abbr b byte", append "b " to an existing word still expands to "byte".
- This is Vi compatible, but can we avoid it anyway?
-8 To make a mapping work with a prepended "x to select a register, store the
- last _typed_ register name and access it with "&.
-8 Add ":amap", like ":amenu".
-7 Add a mapping that works always, for remapping the keyboard.
-8 Add ":cab!", abbreviations that only apply to Command-line mode and not to
- entering search strings.
-8 Add a flag to ":abbrev" to eat the character that triggers the
- abbreviation. Thus "abb ab xxx" and typing "ab<Space>" inserts "xxx" and
- not the <Space>.
-8 Give a warning when using CTRL-C in the lhs of a mapping. It will never
- (?) work.
-8 Add a way to save a current mapping and restore it later. Use a function
- that returns the mapping command to restore it: mapcmd()? mapcheck() is
- not fool proof. How to handle ambiguous mappings?
-7 Add <0x8f> (hex), <033> (octal) and <123> (decimal) to <> notation?
-7 When someone tries to unmap with a trailing space, and it fails, try
- unmapping without the trailing space. Helps for ":unmap xx | unmap yy".
-6 Context-sensitive abbreviations: Specify syntax group(s) in which the
- abbreviations are to be used.
-- Add mappings that take arguments. Could work like the ":s" command. For
- example, for a mouse escape sequence:
- :mapexp <Esc>{\([0-9]*\),\([0-9]*\); H\1j\2l
-- Add optional <Number> argument for mappings:
- :map <Number>q ^W^W<Number>G
- :map <Number>q<Number>t ^W^W<Number1-1>G<Number2>l
- :map q<Char> :s/<Char>/\u\0/g
- Or implicit:
- :map q <Register>d<Number>$
-- Add command to repeat a whole mapping ("." only repeats the last change in
- a mapping). Also: Repeat a whole insert command, including any mappings
- that it included. Sort-of automatic recording?
-- Include an option (or flag to 'cpoptions') that makes errors in mappings
- not flush the rest of the mapping (like nvi does).
-- Use context sensitiveness of completion to switch abbreviations and
- mappings off for :unab and :unmap.
-6 When using mappings in Insert mode, insert characters for incomplete
- mappings first, then remove them again when a mapping matches. Avoids
- that characters that are the start of some mapping are not shown until you
- hit another character.
-- Add mappings for replace mode: ":rmap". How do we then enter mappings for
- non-replace Insert mode?
-- Add separate mappings for Visual-character/block/line mode?
-- Add 'mapstop' command, to stop recursive mappings.
-- List mappings that have a raw escape sequence both with the name of the key
- for that escape sequence (if there is one) and the sequence itself.
-- List mappings: Once with special keys listed as <>, once with meta chars as
- <M-a>, once with the byte values (octal?). Sort of "spell mapping" command?
-- When entering mappings: Add the possibility to enter meta keys like they
- are displayed, within <>: <M-a>, <~@> or <|a>.
-- Allow multiple arguments to :unmap.
-- Command to show keys that are not used and available for mapping
- ":freekeys".
-- Allow any character except white space in abbreviations lhs (Riehm).
-
-
-Incsearch:
-- Add a limit to the number of lines that are searched for 'incsearch'?
-- When no match is found and the user types more, the screen is redrawn
- anyway. Could skip that. Esp. if the line wraps and the text is scrolled
- up every time.
-- Temporarily open folds to show where the search ends up. Restore the
- folds when going to another line.
-- When incsearch used and hitting return, no need to search again in many
- cases, saves a lot of time in big files. (Slootman wants to work on this?)
- When not using special characters, can continue search from the last match
- (or not at all, when there was no match). See oldmail/webb/in.872.
-- With incsearch, use CTRL-N/CTRL-P to go to next/previous match, some other
- key to copy matched word to search pattern (Alexander Schmid).
-
-
-Searching:
-9 Should have an option for :vimgrep to find lines without a match.
-8 Add "g/" and "gb" to search for a pattern in the Visually selected text?
- "g?" is already used for rot13.
- The vis.vim script has a ":S" command that does something like this.
- Can use "g/" in Normal mode, uses the '< to '> area.
- Use "&/" for searching the text in the Visual area?
-9 Add "v" offset: "/pat/v": search for pattern and start Visual mode on the
- matching text.
-8 Add a modifier to interpret a space like "\_s\+" to make it much easier to
- search for a phrase.
-8 Add a mechanism for recursiveness: "\@(([^()]*\@g[^()]*)\)". \@g stands
- for "go recursive here" and \@( \) marks the recursive part.
- Perl does it this way:
- $paren = qr/ \(( [^()] | (??{ $paren }) )* \) /x;
- Here $paren is evaluated when it's encountered. This is like a regexp
- inside a regexp. In the above terms it would be:
- \@((\([^()]\|\@g\)*)\)
-8 Show the progress every second. Could use the code that checks for CTRL-C
- to find out how much time has passed. Or use SIGALRM. Where to show the
- number?
-8 When using an expression for ":s", set the match position in a v:
- variable. So that you can do ":%s/^/\=v:lnum/" to put a line number
- before each line.
-7 Support for approximate-regexps to find similar words (agrep
- http://www.tgries.de/agrep/ tre: http://laurikari.net/tre/index.html).
-8 Add an item for a big character range, so that one can search for a
- chinese character: \z[234-1234] or \z[XX-YY] or \z[0x23-0x234].
-7 Add an item stack to allow matching (). One side is "push X on
- the stack if previous atom matched". Other side is "match with top of
- stack, pop it when it matches". Use "\@pX" and "\@m"?
- Example: \((\@p).\{-}\@m\)*
-7 Add an option to accept a match at the cursor position. Also for
- search(). (Brett)
-7 Add a flag to "/pat/" to discard an error. Useful to continue a mapping
- when a search fails. Could be "/pat/E" (e is already used for end offset).
-7 Add pattern item to use properties of Unicode characters. In Perl it's
- "\p{L}" for a letter. See Regular Expression Pocket Reference.
-8 Would it be possible to allow ":23,45/pat/flags" to search for "pat" in
- lines 23 to 45? Or does this conflict with Ex range syntax?
-8 Allow identical pairs in 'matchpairs'. Restrict the search to the current
- line.
-7 Allow longer pairs in 'matchpairs'. Use ~/vim/macros/matchit.vim as an
- example.
-8 Make it possible to define the character that "%" checks for in
- #if/#endif. For nmake it's !if/!endif.
-- For "%" command: set hierarchy for which things include other things that
- should be ignored (like "*/" or "#endif" inside /* */).
- Also: use "%" to jump from start to end of syntax region and back.
- Alternative: use matchit.vim
-8 "/:/e+1" gets stuck on a match at the end of the line. Do we care?
-8 A pattern like "\([^a]\+\)\+" takes an awful long time. Recognize that
- the recursive "\+" is meaningless and optimize for it.
- This one is also very slow on "/* some comment */": "^\/\*\(.*[^/]\)*$".
-7 Recognize "[a-z]", "[0-9]", etc. and replace them with the faster "\l" and
- "\d".
-7 Add a way to specify characters in <C-M> or <Key> form. Could be
- \%<C-M>.
-8 Add an argument after ":s/pat/str/" for a range of matches. For example,
- ":s/pat/str/#3-4" to replace only the third and fourth "pat" in a line.
-8 When 'iskeyword' is changed the matches from 'hlsearch' may change. (Benji
- Fisher) redraw if some options are set while 'hlsearch' is set?
-8 Add an option not to use 'hlsearch' highlighting for ":s" and ":g"
- commands. (Kahn) It would work like ":noh" is used after that command.
- Also: An extra flag to do this once, and a flag to keep the existing
- search pattern.
-- Make 'hlsearch' a local/global option, so that it can be disabled in some
- of the windows.
-- Add \%h{group-name}; to search for a specific highlight group.
- Add \%s{syntax-group}; to search for a specific syntax group.
-- Support Perl regexp. Use PCRE (Perl Compatible RE) package. (Shade)
- Or translate the pattern to a Vim one.
- Don't switch on with an option for typed commands/mappings/functions, it's
- too confusing. Use "\@@" in the pattern, to avoid incompatibilities.
-8 Add a way to access the last substitute text, what is used for ":s//~/".
- Can't use the ~ register, it's already used for drag & drop.
-- Remember flags for backreferenced items, so that "*" can be used after it.
- Check with "\(\S\)\1\{3}". (Hemmerling)
-8 Flags that apply to the whole pattern.
- This works for all places where a regexp is used.
- Add "\q" to not store this pattern as the last search pattern?
-- Add flags to search command (also for ":s"?):
- i ignore case
- I use case
- p use Perl regexp syntax (or POSIX?)
- v use Vi regexp syntax
- f forget pattern, don't keep it for "n" command
- F remember pattern, keep it for "n" command
- Perl uses these too:
- e evaluate the right side as an expression (Perl only)
- m multiple line expression (we don't need it)
- o compile only once (Perl only)
- s single line expression (we don't need it)
- x extended regexp (we don't need it)
- When used after ":g" command, backslash needed to avoid confusion with the
- following command.
- Add 'searchflags' for default flags (replaces 'gdefault').
-- Add command to display the last used substitute pattern and last used
- pattern. (Margo) Maybe make it accessible through a register (like "/
- for search string)?
-7 Use T-search algorithm, to speed up searching for strings without special
- characters. See C't article, August 1997.
-- Add 'fuzzycase' option, so that case doesn't matter, and '-' and '_' are
- equivalent (for Unix filenames).
-- Add 'v' flag to search command: enter Visual mode, with the matching text
- as Visual area. (variation on idea from Bertin)
-- Searching: "/this//that/" should find "that" after "this".
-- Add global search commands: Instead of wrapping at the end of the buffer,
- they continue in another buffer. Use flag after search pattern:
- a for the next file in the argument list
- f for file in the buffer list
- w for file edited in a window.
- e.g. "/pat/f". Then "n" and "N" work through files too. "f" flag also for
- ":s/pat/foo/f"??? Then when 'autowrite' and 'hidden' are both not set, ask
- before saving files: "Save modified buffer "/path/file"? (Yes/Hide/No
- Save-all/hide-All/Quit) ".
-- ":s/pat/foo/3": find 3rd match of "pat", like sed. (Thomas Koehler)
-7 When searching with 'n' give message when getting back where the search
- first started. Remember start of search in '/ mark.
-7 Add option that scrolls screen to put cursor in middle of screen after
- search always/when off-screen/never. And after a ":tag" command. Maybe
- specify how many lines below the screen causes a redraw with the cursor in
- the middle (default would be half a screen, zero means always).
-6 Support multiple search buffers, so macros can be made without side
- effects.
-7 From xvim: Allow a newline in search patterns (also for :s, can delete
- newline). Add BOW, EOW, NEWL, NLORANY, NLBUTANY, magic 'n' and 'r', etc.
- [not in xvim:] Add option to switch on matches crossing ONE line boundary.
-7 Add ":iselect", a combination of ":ilist" and ":tselect". (Aaron) (Zellner)
- Also ":dselect".
-
-
-Undo:
-9 ":gundo" command: global undo. Undoes changes spread over multiple files
- in the order they were made. Also ":gredo". Both with a count. Useful
- when tests fail after making changes and you forgot in which files.
-9 After undo/redo, in the message show whether the buffer is modified or
- not.
-8 Use timestamps for undo, so that a version a certain time ago can be found
- and info before some time/date can be flushed. 'undopersist' gives maximum
- time to keep undo: "3h", "1d", "2w", "1y", etc.
-8 Search for pattern in undo tree, showing when it happened and the text
- state, so that you can jump to it.
-8 Undo tree: visually show the tree somehow (Damian Conway)
- Show only the leaves, indicating how many changed from the branch and the
- timestamp?
- Put branch with most recent change on the left, older changes get more
- indent?
-8 See ":e" as a change operation, find the changes and add them to the
- undo info. Also be able to undo the "Reload file" choice for when a file
- was changed outside of Vim.
- Would require doing a diff between the buffer text and the file and
- storing the differences.
- Alternative: before reloading a buffer, store it somewhere. Keep a list
- of about 10 last reloaded buffers.
-- Make it possible to undo all the commands from a mapping, including a
- trailing unfinished command, e.g. for ":map K iX^[r".
-- When accidentally hitting "R" instead of Ctrl-R, further Ctrl-R is not
- possible, even when typing <Esc> immediately. (Grahn) Also for "i", "a",
- etc. Postpone saving for undo until something is really inserted?
-8 When Inserting a lot of text, it can only be undone as a whole. Make undo
- sync points at every line or word. Could recognize the start of a new
- word (white space and then non-white space) and backspacing.
- Can already use CTRL-G u, but that requires remapping a lot of things.
-8 Make undo more memory-efficient: Compare text before and after change,
- only remember the lines that really changed.
-7 Add undo for a range of lines. Can change these back to a previous
- version without changing the rest of the file. Stop doing this when a
- change includes only some of these lines and changes the line count. Need
- to store these undo actions as a separate change that can be undone.
-- For u_save() include the column number. This can be used to set '[ and '].
- And in the future the undo can be made more efficient (Webb).
-- In out-of-memory situations: Free allocated space in undo, and reduce the
- number of undo levels (with confirmation).
-- Instead of [+], give the number of changes since the last write: [+123].
- When undoing to before the last write, change this to a negative number:
- [-99].
-- With undo with simple line delete/insert: optimize screen updating.
-- When executing macro's: Save each line for undo only once.
-- When doing a global substitute, causing almost all lines to be changed,
- undo info becomes very big. Put undo info in swap file??
-
-
-Buffer list:
-7 Command to execute a command in another buffer: ":inbuf {bufname} {cmd}".
- Also for other windows: ":inwin {winnr} {cmd}". How to make sure that
- this works properly for all commands, and still be able to return to the
- current buffer/window? E.g.: ":inbuf xxx only".
-8 Add File.{recent_files} menu entries: Recently edited files.
- Ron Aaron has a plugin for this: mru.vim.
-8 Unix: Check all uses of fnamecmp() and fnamencmp() if they should check
- inode too.
-7 Add another number for a buffer, which is visible for the user. When
- creating a new buffer, use the lowest number not in use (or the highest
- number in use plus one?).
-7 Offer some buffer selection from the command line? Like using ":ls" and
- asking for a buffer number. (Zachmann)
-- When starting to edit a file that is already in the buffer list, use the
- file name argument for the new short file name. (Webb)
-- Add an option to make ":bnext" and ":bprev" wrap around the end of the
- buffer list. Also for ":next" and ":prev"?
-7 Add argument to ":ls" which is a pattern for buffers to list.
- E.g. ":ls *.c". (Thompson)
-7 Add expansion of buffer names, so that "*.c" is expanded to all buffer
- names. Needed for ":bdel *.c", ":bunload *.c", etc.
-8 Support for <afile> where a buffer name is expected.
-8 Some commands don't use line numbers, but buffer numbers. '$'
- should then mean the number of the last buffer. E.g.: "4,$bdel".
-7 Add an option to mostly use slashes in file names. Separately for
- internal use and for when executing an external program?
-8 Some file systems are case-sensitive, some are not. Besides
- 'wildignorecase' there might be more parts inside
- CASE_INSENSITIVE_FILENAME that are useful on Unix.
-
-
-Swap (.swp) files:
-8 If writing to the swap file fails, should try to open one in another
- directory from 'dir'. Useful in case the file system is full and when
- there are short file name problems.
-8 Also use the code to try using a short file name for the backup and swap
- file for the Win32 and Dos 32 bit versions.
-8 When a file is edited by root, add $LOGNAME to know who did su.
-8 When the edited file is a symlink, try to put the swap file in the same
- dir as the actual file. Adjust FullName(). Avoids editing the same file
- twice (e.g. when using quickfix). Also try to make the name of the backup
- file the same as the actual file?
- Use the code for resolve()?
-7 When using 64 bit inode numbers, also store the top 32 bits. Add another
- field for this, using part of bo_fname[], to keep it compatible.
-7 When editing a file on removable media, should put swap file somewhere
- else. Use something like 'r' flag in 'viminfo'. 'diravoid'?
- Also: Be able to specify minimum disk space, skip directory when not
- enough room.
-7 Add a configure check for which directory should be used: /tmp, /var/tmp
- or /var/preserve.
-- Add an option to create a swap file only when making the first change to
- the buffer. (Liang) Or only when the buffer is not read-only.
-- Add option to set "umask" for backup files and swap files (Antwerpen).
- 'backupumask' and 'swapumask'? Or 'umaskback' and 'umaskswap'?
-- When editing a readonly file, don't use a swap file but read parts from the
- original file. Also do this when the file is huge (>'maxmem'). We do
- need to load the file once to count the number of lines? Perhaps keep a
- cached list of which line is where.
-
-
-Viminfo:
-7 Can probably remove the code that checks for a writable viminfo file,
- because we now do the chown() for root, and others can't overwrite someone
- else's viminfo file.
-8 When there is no .viminfo file and someone does "su", runs Vim, a
- root-owned .viminfo file is created. Is there a good way to avoid this?
- Perhaps check the owner of the directory. Only when root?
-8 Add argument to keep the list of buffers when Vim is started with a file
- name. (Schild)
-8 Keep the last used directory of the file browser (File/Open menu).
-8 Remember the last used register for "@@".
-8 Remember the redo buffer, so that "." works after restarting.
-8 Remember a list of last accessed files. To be used in the
- "File.Open Recent" menu. Default is to remember 10 files or so.
- Also remember which files have been read and written. How to display
- this?
-7 Also store the ". register (last inserted text).
-7 Make it possible to store buffer names in viminfo file relative to some
- directory, to make them portable over a network. (Aaron)
-6 Store a snapshot of the currently opened windows. So that when quitting
- Vim, and then starting again (without a file name argument), you see the
- same files in the windows. Use ":mksession" code?
-- Make marks present in .viminfo usable as file marks: Display a list of
- "last visited files" and select one to jump to.
-
-
-Modelines:
-8 Before trying to execute a modeline, check that it looks like one (valid
- option names). If it's very wrong, silently ignore it.
- Ignore a line that starts with "Subject: ".
-- Add an option to whitelist options that are allowed in a modeline. This
- would allow careful users to use modelines, e.g., only allowing
- 'shiftwidth'.
-- Add an option to let modelines only set local options, not global ones
- such as 'encoding'.
-- When an option value is coming from a modeline, do not carry it over to
- another edited file? Would need to remember the value from before the
- modeline setting.
-- Allow setting a variable from a modeline? Only allow using fixed strings,
- no function calls, to avoid a security problem.
-- Allow ":doauto BufRead x.cpp" in modelines, to execute autocommands for
- .cpp files.
-- Support the "abbreviate" command in modelines (Kearns). Careful for
- characters after <Esc>, that is a security leak.
-- Add option setting to ask user if he wants to have the modelines executed
- or not. Same for .exrc in local dir.
-
-
-Sessions:
-8 DOS/Windows: ":mksession" generates a "cd" command where "aa\#bb" means
- directory "#bb" in "aa", but it's used as "aa#bb". (Ronald Hoellwarth)
-7 When there is a "help.txt" window in a session file, restoring that
- session will not get the "LOCAL ADDITIONS" back.
-8 With ":mksession" always store the 'sessionoptions' option, even when
- "options" isn't in it. (St-Amant)
-8 When using ":mksession", also store a command to reset all options to
- their default value, before setting the options that are not at their
- default value.
-7 With ":mksession" also store the tag stack and jump history. (Michal
- Malecki)
-7 Persistent variables: "p:var"; stored in viminfo file and sessions files.
-
-
-Options:
-7 ":with option=value | command": temporarily set an option value and
- restore it after the command has executed.
-8 Make "old" number options that really give a number of effects into string
- options that are a comma separated list. The old number values should
- also be supported.
-8 Add commands to save and restore an option, which also preserves the flag
- that marks if the option was set. Useful to keep the effect of setting
- 'compatible' after ":syntax on" has been used.
-7 There is 'titleold', why is there no 'iconold'? (Chazelas)
-7 Make 'scrolloff' a global-local option, so that it can be different in the
- quickfix window, for example. (Gary Holloway)
- Also do 'sidescrolloff'.
-
-
-External commands:
-8 When filtering text, redirect stderr so that it can't mess up the screen
- and Vim doesn't need to redraw it. Also for ":r !cmd".
-4 Set separate shell for ":sh", piping "range!filter", reading text "r !ls"
- and writing text "w !wc". (Deutsche) Allow arguments for fast start (e.g.
- -f).
-4 Allow direct execution, without using a shell.
-4 Run an external command in the background. But how about I/O in the GUI?
- Careful: don't turn Vim into a shell!
-4 Add feature to disable using a shell or external commands.
-
-
-Multiple Windows:
-7 "vim -oO file ..." use both horizontal and vertical splits.
-8 Add CTRL-W T: go to the top window in the column of the current window.
- And CTRL-W B: go to bottom window.
-7 Use CTRL-W <Tab>, like alt-tab, to switch between buffers. Repeat <Tab>
- to select another buffer (only loaded ones?), <BS> to go back, <Enter> to
- select buffer, <Esc> to go back to original buffer.
-7 Make it possible to edit a new buffer in the preview window. A script can
- then fill it with something. ":popen"?
-7 Add a 'tool' window: behaves like a preview window but there can be
- several. Don't count it in only_one_window(). (Alexei Alexandrov)
-6 Add an option to resize the shell when splitting and/or closing a window.
- ":vsp" would make the shell wider by as many columns as needed for the new
- window. Specify a maximum size (or use the screen size). ":close" would
- shrink the shell by as many columns as come available. (Demirel)
-7 When starting Vim several times, instantiate a Vim server, that allows
- communication between the different Vims. Feels like one Vim running with
- multiple top-level windows. Esp. useful when Vim is started from an IDE
- too. Requires some form of inter process communication.
-- Support a connection to an external viewer. Could call the viewer
- automatically after some seconds of non-activity, or with a command.
- Allow some way of reporting scrolling and cursor positioning in the viewer
- to Vim, so that the link between the viewed and edited text can be made.
-
-
-Marks:
-8 Add ten marks for last changed files: ':0, ':1, etc. One mark per file.
-8 When cursor is first moved because of scrolling, set a mark at this
- position. (Rimon Barr) Use '-.
-8 Add a command to jump to a mark and make the motion inclusive. g'm and g`m?
-8 The '" mark is set to the first line, even when doing ":next" a few times.
- Only set the '" mark when the cursor was really moved in a file.
-8 Make `` and '', which would position the new cursor position in the middle
- of the window, restore the old topline (or relative position) from when
- the mark was set.
-7 Make a list of file marks in a separate window. For listing all buffers,
- matching tags, errors, etc. Normal commands to move around. Add commands
- to jump to the mark (in current window or new window). Start it with
- ":browse marks"?
-6 Add a menu that lists the Marks like ":marks". (Amerige)
-7 For ":jumps", ":tags" and ":marks", for not loaded buffers, remember the
- text at the mark. Highlight the column with the mark.
-7 Highlight each mark in some way (With "Mark" highlight group).
- Or display marks in a separate column, like 'number' does.
-7 Use d"m to delete rectangular area from cursor to mark m (like Vile's \m
- command).
-7 Try to keep marks in the same position when:
- - replacing with a line break, like in ":s/pat/^M/", move marks after the
- line break column to the next line. (Acevedo)
- - inserting/deleting characters in a line.
-5 Include marks for start/end of the current word and section. Useful in
- mappings.
-6 Add "unnamed mark" feature: Like marks for the ":g" command, but place and
- unplace them with commands before doing something with the lines.
- Highlight the marked lines somehow.
-
-
-Digraphs:
-7 Make "ga" show the keymap for a character, if it exists.
- Also show the code of the character after conversion to 'fileencoding'.
-- Use digraph table to tell Vim about the collating sequence of special
- characters?
-8 Add command to remove one or more (all) digraphs. (Brown)
-7 Support different sets of digraphs (depending on the character set?). At
- least Latin1/Unicode, Latin-2, MS-DOS (esp. for Win32).
-
-
-Writing files:
-- In vim_rename(), should lock "from" file when deleting "to" file.
-8 When appending to a file, Vim should also make a backup and a 'patchmode'
- file.
-8 'backupskip' doesn't write a backup file at all, a bit dangerous for some
- applications. Add 'backupelsewhere' to write a backup file in another
- directory? Or add a flag to 'backupdir'?
-6 Add an option to write a new, numbered, backup file each time. Like
- 'patchmode', e.g., 'backupmode'.
-6 Make it possible to write 'patchmode' files to a different directory.
- E.g., ":set patchmode=~/backups/*.orig". (Thomas)
-6 Add an option to prepend something to the backup file name. E.g., "#".
- Or maybe allow a function to modify the backup file name?
-8 Only make a backup when overwriting a file for the first time. Avoids
- losing the original when writing twice. (Slootman)
-7 On non-Unix machines, also overwrite the original file in some situations
- (file system full, it's a link on an NFS partition).
-7 When editing a file, check that it has been change outside of Vim more
- often, not only when writing over it. E.g., at the time the swap file is
- flushed. Or every ten seconds or so (use the time of day, check it before
- waiting for a character to be typed).
-8 When a file was changed since editing started, show this in the status
- line of the window, like "[time]".
- Make it easier to reload all outdated files that don't have changes.
- Automatic and/or with a command.
-
-
-Substitute:
-8 Substitute with hex/unicode number "\%xff" and "\%uabcd". Just like
- "\%uabcd" in search pattern.
-8 Make it easier to replace in all files in the argument list. E.g.:
- ":argsub/oldword/newword/". Works like ":argdo %s/oldword/newword/g|w".
-- :s///p prints the line after a substitution.
-- With :s///c replace \&, ~, etc. when showing the replacement pattern.
-8 With :s///c allow scrolling horizontally when 'nowrap' is effective.
- Also allow a count before the scrolling keys.
-- Add number option to ":s//2": replace second occurrence of string? Or:
- :s///N substitutes N times.
-- Add answers to ":substitute" with 'c' flag, used in a ":global", e.g.:
- ":g/pat1/s/pat2/pat3/cg": 'A' do all remaining replacements, 'Q' don't do
- any replacements, 'u' undo last substitution.
-7 Substitute in a block of text. Use {line}.{column} notation in an Ex
- range, e.g.: ":1.3,$.5s" means to substitute from line 1 column 3 to the
- last line column 5.
-5 Add commands to bookmark lines, display bookmarks, remove bookmarks,
- operate on lines with bookmarks, etc. Like ":global" but with the
- possibility to keep the bookmarks and use them with several commands.
- (Stanislav Sitar)
-
-
-Mouse support:
-8 Add 'o' flag to 'mouse'?
-7 Be able to set a 'mouseshape' for the popup menu.
-8 Add 'mouse' flag, which sets a behavior like Visual mode, but automatic
- yanking at the button-up event. Or like Select mode, but typing gets you
- out of Select mode, instead of replacing the text. (Bhaskar)
-- Using right mouse button to extend a blockwise selection should attach to
- the nearest corner of the rectangle (four possible corners).
-- Precede mouse click by a number to simulate double clicks?!?
-- When mouse click after 'r' command, get character that was pointed to.
-
-
-Argument list:
-6 Add command to put all filenames from the tag files in the argument list.
- When given an argument, only use the files where that argument matches
- (like `grep -l ident`) and jump to the first match.
-6 Add command to form an args list from all the buffers?
-
-
-Registers:
-8 Don't display empty registers with ":display". (Etienne)
-8 Add put command that overwrites existing text. Should also work for
- blocks. Useful to move text around in a table. Works like using "R ^R r"
- for every line.
-6 When yanking into the unnamed registers several times, somehow make the
- previous contents also available (like it's done for deleting). What
- register names to use? g"1, g"2, etc.?
-- When appending to a register, also report the total resulting number of
- lines. Or just say "99 more lines yanked", add the "more".
-- When inserting a register in Insert mode with CTRL-R, don't insert comment
- leader when line wraps?
-- The ":@r" commands should take a range and execute the register for each
- line in the range.
-- Add "P" command to insert contents of unnamed register, move selected text
- to position of previous deleted (to swap foo and bar in " + foo")
-8 Should be able to yank and delete into the "/ register.
- How to take care of the flags (offset, magic)?
-
-
-Debug mode:
-7 Add something to enable debugging when a remote message is received.
-8 Add breakpoints for setting an option
-8 Add breakpoints for assigning to a variable.
-7 Add a watchpoint in the debug mode: An expression that breaks execution
- when evaluating to non-zero. Add the "watchadd expr" command, stop when
- the value of the expression changes. ":watchdel" deletes an item,
- ":watchlist" lists the items. (Charles Campbell)
-7 Store the history from debug mode in viminfo.
-7 Make the debug mode history available with histget() et al.
-
-
-Various improvements:
-7 Add plugins for formatting? Should be able to make a choice depending on
- the language of a file (English/Korean/Japanese/etc.).
- Setting the 'langformat' option to "chinese" would load the
- "format/chinese.vim" plugin.
- The plugin would set 'formatexpr' and define the function being called.
- Edward L. Fox explains how it should be done for most Asian languages.
- (2005 Nov 24)
- Alternative: patch for utf-8 line breaking. (Yongwei Wu, 2008 Feb 23)
-7 [t to move to previous xml/html tag (like "vatov"), ]t to move to next
- ("vatv").
-7 [< to move to previous xml/html tag, e.g., previous <li>. ]< to move to
- next <li>, ]< to next </li>, [< to previous </li>.
-8 Add ":rename" command: rename the file of the current buffer and rename
- the buffer. Buffer may be modified.
-7 Instead of filtering errors with a shell script it should be possible to
- do this with Vim script. A function that filters the raw text that comes
- from the 'makeprg'?
-- Add %b to 'errorformat': buffer number. (Yegappan Lakshmanan / Suresh
- Govindachar)
-7 Add a command that goes back to the position from before jumping to the
- first quickfix location. ":cbefore"?
-7 Allow a window not to have a statusline. Makes it possible to use a
- window as a buffer-tab selection.
-8 Allow non-active windows to have a different statusline. (Yakov Lerner)
-7 Support using ":vert" with User commands. Add expandable items <vert>.
- Do the same for ":browse" and ":confirm"?
- For ":silent" and ":debug" apply to the whole user command.
- More general: need a way to access command modifiers in a user command.
- Assign them to a v: variable?
-7 Add an invisible buffer which can be edited. For use in scripts that want
- to manipulate text without changing the window layout.
-8 Add a command to revert to the saved version of file; undo or redo until
- all changes are gone.
-6 "vim -q -" should read the list of errors from stdin. (Gautam Mudunuri)
-8 Add "--remote-fail": When contacting the server fails, exit Vim.
- Add "--remote-self": When contacting the server fails, do it in this Vim.
- Overrules the default of "--remote-send" to fail and "--remote" to do it
- in this Vim.
-8 When Vim was started without a server, make it possible to start one, as
- if the "--servername" argument was given. ":startserver <name>"?
-8 No address range can be used before the command modifiers. This makes
- them difficult to use in a menu for Visual mode. Accept the range and
- have it apply to the following command.
-8 Add the possibility to set 'fileformats' to force a format and strip other
- CR characters. For example, for "dos" files remove CR characters at the
- end of the line, so that a file with mixed line endings is cleaned up.
- To just not display the CR characters: Add a flag to 'display'?
-7 Some compilers give error messages in which the file name does not have a
- path. Be able to specify that 'path' is used for these files.
-7 Xterm sends <Esc>O3F for <M-End>. Similarly for other <M-Home>, <M-Left>,
- etc. Combinations of Alt, Ctrl and Shift are also possible. Recognize
- these to avoid inserting the raw byte sequence, handle like the key
- without modifier (unless mapped).
-6 Add "gG": like what "gj" is to "j": go to the N'th window line.
-8 Add command like ":normal" that accepts <Key> notation like ":map".
-9 Support ACLs on more systems.
-7 Add ModeMsgVisual, ModeMsgInsert, etc. so that each mode message can be
- highlighted differently.
-7 Add a message area for the user. Set some option to reserve space (above
- the command line?). Use an ":echouser" command to display the message
- (truncated to fit in the space).
-7 Add %s to 'keywordprg': replace with word under the cursor. (Zellner)
-8 Support printing on Unix. Can use "lpansi.c" as an example. (Bookout)
-8 Add put command that replaces the text under it. Esp. for blockwise
- Visual mode.
-7 Enhance termresponse stuff: Add t_CV(?): pattern of term response, use
- regexp: "\e\[[>?][0-9;]*c", but only check just after sending t_RV.
-7 Add "g|" command: move to N'th column from the left margin (after wrapping
- and applying 'leftcol'). Works as "|" like what "g0" is to "0".
-7 Support setting 'equalprg' to a user function name.
-7 Highlight the characters after the end-of-line differently.
-7 When 'whichwrap' contains "l", "$dl" should join lines?
-8 Add an argument to configure to use $CFLAGS and not modify it? (Mooney)
-8 Enabling features is a mix of configure arguments and defines in
- feature.h. How to make this consistent? Feature.h is required for
- non-unix systems. Perhaps let configure define CONF_XXX, and use #ifdef
- CONF_XXX in feature.h? Then what should min-features and max-features do?
-8 Add "g^E" and "g^Y", to scroll a screen-full line up and down.
-6 Add ":timer" command, to set a command to be executed at a certain
- interval, or once after some time has elapsed. (Aaron)
- Perhaps an autocommand event like CursorHold is better?
- Patch to add async functionality. (Geoff Greer, 2013 Sep 1 and later)
-8 Add ":confirm" handling in open_exfile(), for when file already exists.
-8 When quitting with changed files, make the dialog list the changed file
- and allow "write all", "discard all", "write some". The last one would
- then ask "write" or "discard" for each changed file. Patch in HierAssist
- does something like this. (Shah)
-7 Use growarray for replace stack.
-7 Have a look at viH (Hellenic or Greek version of Vim). But a solution
- outside of Vim might be satisfactory (Haritsis).
-3 Make "2d%" work like "d%d%" instead of "d2%"?
-7 "g CTRL-O" jumps back to last used buffer. Skip CTRL-O jumps in the same
- buffer. Make jumplist remember the last ten accessed buffers?
-7 Make it possible to set the size of the jumplist (also to a smaller number
- than the default). (Nikolai Weibull)
-- Add code to disable the CAPS key when going from Insert to Normal mode.
-- Set date/protection/etc. of the patchfile the same as the original file.
-- Use growarray for termcodes[] in term.c
-- Add <window-99>, like <cword> but use filename of 99'th window.
-7 Add a way to change an operator to always work characterwise-inclusive
- (like "v" makes the operator characterwise-exclusive). "x" could be used.
-- Make a set of operations on list of names: expand wildcards, replace home
- dir, append a string, delete a string, etc.
-- Remove using mktemp() and use tmpname() only? Ctags does this.
-- When replacing environment variables, and there is one that is not set,
- turn it into an empty string? Only when expanding options? (Hiebert)
-- Option to set command to be executed instead of producing a beep (e.g. to
- call "play newbeep.au").
-- Add option to show the current function name in the status line. More or
- less what you find with "[[k", like how 'cindent' recognizes a function.
- (Bhatt).
-- "[r" and "]r": like "p" and "P", but replace instead of insert (esp. for
- blockwise registers).
-- Add 'timecheck' option, on by default. Makes it possible to switch off the
- timestamp warning and question. (Dodt).
-- Add an option to set the time after which Vim should check the timestamps
- of the files. Only check when an event occurs (e.g., character typed,
- mouse moved). Useful for non-GUI versions where keyboard focus isn't
- noticeable.
-- Make 'smartcase' work even though 'ic' isn't set (Webb).
-7 When formatting text, allow to break the line at a number of characters.
- Use an option for this: 'breakchars'? Useful for formatting Fortran code.
-- Add flag to 'formatoptions' to be able to format book-style paragraphs
- (first line of paragraph has larger indent, no empty lines between
- paragraphs). Complements the '2' flag. Use '>' flag when larger indent
- starts a new paragraph, use '<' flag when smaller indent starts a new
- paragraph. Both start a new paragraph on any indent change.
-8 The 'a' flag in 'formatoptions' is too dangerous. In some way only do
- auto-formatting in specific regions, e.g. defined by syntax highlighting.
-8 Allow using a trailing space to signal a paragraph that continues on the
- next line (MIME text/plain; format=flowed, RFC 2646). Can be used for
- continuous formatting. Could use 'autoformat' option, which specifies a
- regexp which triggers auto-formatting (for one line).
- ":set autoformat=\\s$".
-- Be able to redefine where a sentence stops. Use a regexp pattern?
-- Support multi-byte characters for sentences. Example from Ben Peterson.
-7 Add command "g)" to go to the end of a sentence, "g(" to go back to the
- end of a sentence. (Servatius Brandt)
-- Be able to redefine where a paragraph starts. For "[[" where the '{' is
- not in column 1.
-6 Add ":cdprev": go back to the previous directory. Need to remember a
- stack of previous directories. We also need ":cdnext".
-7 Should ":cd" for MS-DOS go to $HOME, when it's defined?
-- Make "gq<CR>" work on the last line in the file. Maybe for every operator?
-- Add more redirecting of Ex commands:
- :redir #> bufname
- :redir #>> bufname (append)
-- Give error message when starting :redir: twice or using END when no
- redirection was active.
-- Setting of options, specifically for a buffer or window, with
- ":set window.option" or ":set buffer.option=val". Or use ":buffer.set".
- Also: "buffer.map <F1> quit".
-6 Would it be possible to change the color of the cursor in the Win32
- console? (Klaus Hast)
-- Add :delcr command:
- *:delcr*
- :[range]delcr[!] Check [range] lines (default: whole buffer) for lines
- ending in <CR>. If all lines end in <CR>, or [!] is
- used, remove the <CR> at the end of lines in [range].
- A CTRL-Z at the end of the file is removed. If
- [range] is omitted, or it is the whole file, and all
- lines end in <CR> 'textmode' is set.
-- Should integrate addstar() and file_pat_to_reg_pat().
-- When working over a serial line with 7 bit characters, remove meta
- characters from 'isprint'.
-- Use fchdir() in init_homedir(), like in FullName().
-- In win_update(), when the GUI is active, always use the scrolling area.
- Avoid that the last status line is deleted and needs to be redrawn.
-- That "cTx" fails when the cursor is just after 'x' is Vi compatible, but
- may not be what you expect. Add a flag in 'cpoptions' for this? More
- general: Add an option to allow "c" to work with a null motion.
-- Give better error messages by using errno (strerror()).
-- Give "Usage:" error message when command used with wrong arguments (like
- Nvi).
-- Make 'restorescreen' option also work for xterm (and others), replaces the
- SAVE_XTERM_SCREEN define.
-7 Support for ":winpos" In xterm: report the current window position.
-- Give warning message when using ":set t_xx=asdf" for a termcap code that
- Vim doesn't know about. Add flag in 'shortmess'?
-6 Add ":che <file>", list all the include paths which lead to this file.
-- For a commandline that has several commands (:s, :d, etc.) summarize the
- changes all together instead of for each command (e.g. for the rot13
- macro).
-- Add command like "[I" that also shows the tree of included files.
-- ":set sm^L" results in ":set s", because short names of options are also
- expanded. Is there a better way to do this?
-- Add ":@!" command, to ":@" like what ":source!" is to ":source".
-8 Add ":@:!": repeat last command with forceit set.
-- Add 't_normal': Used whenever t_me, t_se, t_ue or t_Zr is empty.
-- ":cab map test ^V| je", ":cunab map" doesn't work. This is vi compatible!
-- CTRL-W CTRL-E and CTRL-W CTRL-Y should move the current window up or down
- if it is not the first or last window.
-- Include-file-search commands should look in the loaded buffer of a file (if
- there is one) instead of the file itself.
-7 Change 'nrformats' to include the leader for each format. Example:
- nrformats=hex:$,binary:b,octal:0
- Add setting of 'nrformats' to syntax files.
-- 'path' can become very long, don't use NameBuff for expansion.
-- When unhiding a hidden buffer, put the same line at top of the window as
- the one before hiding it. Or: keep the same relative cursor position (so
- many percent down the windows).
-- Make it possible for the 'showbreak' to be displayed at the end of the
- line. Use a comma to separate the part at the end and the start of the
- line? Highlight the linebreak characters, add flag in 'highlight'.
- Make 'showbreak' local to a window.
-- Some string options should be expanded if they have wildcards, e.g.
- 'dictionary' when it is "*.h".
-- Use a specific type for number and boolean options, making it possible to
- change it for specific machines (e.g. when a long is 64 bit).
-- Add option for <Insert> in replace mode going to normal mode. (Nugent)
-- Add a next/previous possibility to "[^I" and friends.
-- Add possibility to change the HOME directory. Use the directory from the
- passwd file? (Antwerpen)
-8 Add commands to push and pop all or individual options. ":setpush tw",
- ":setpop tw", ":setpush all". Maybe pushing/popping all options is
- sufficient. ":setflush" resets the option stack?
- How to handle an aborted mapping? Remember position in tag stack when
- mapping starts, restore it when an error aborts the mapping?
-- "gc": goto character, move absolute character positions forward, also
- counting newlines. "gC" goes backwards (Weigert).
-- When doing CTRL-^, redraw buffer with the same topline. (Demirel) Store
- cursor row and window height to redraw cursor at same percentage of window
- (Webb).
-- Besides remembering the last used line number of a file, also remember the
- column. Use it with CTRL-^ et. al.
-- Check for non-digits when setting a number option (careful when entering
- hex codes like 0xff).
-- Add option to make "." redo the "@r" command, instead of the last command
- executed by it. Also to make "." redo the whole mapping. Basically: redo
- the last TYPED command.
-- Support URL links for ^X^F in Insert mode, like for "gf".
-- Support %name% expansion for "gf" on Windows.
-- Make "gf" work on "file://c:/path/name". "file:/c:/" and "file:///c:/"
- should also work?
-- Add 'urlpath', used like 'path' for when "gf" used on an URL?
-8 When using "gf" on an absolute file name, while editing a remote file
- (starts with scp:// or http://) should prepend the method and machine
- name.
-- When finding an URL or file name, and it doesn't exist, try removing a
- trailing '.'.
-- Add ":path" command modifier. Should work for every command that takes a
- file name argument, to search for the file name in 'path'. Use
- find_file_in_path().
-- Highlight control characters on the screen: Shows the difference between
- CTRL-X and "^" followed by "X" (Colon).
-- Integrate parsing of cmdline command and parsing for expansion.
-- Create a program that can translate a .swp file from any machine into a
- form usable by Vim on the current machine.
-- Add ":noro" command: Reset 'ro' flag for all buffers, except ones that have
- a readonly file. ":noro!" will reset all 'ro' flags.
-- Add a variant of CTRL-V that stops interpretation of more than one
- character. For entering mappings on the command line where a key contains
- several special characters, e.g. a trailing newline.
-- Make '2' option in 'formatoptions' also work inside comments.
-- Add 's' flag to 'formatoptions': Do not break when inside a string. (Dodt)
-- When window size changed (with the mouse) and made too small, set it back
- to the minimal size.
-- Add "]>" and "[<", shift comment at end of line (command; /* comment */).
-- Should not call cursorcmd() for each vgetc() in getcmdline().
-- ":split file1 file2" adds two more windows (Webb).
-- Don't give message "Incomplete last line" when editing binary file.
-- Add ":a", ":i" for preloading of named buffers.
-- When entering text, keep other windows on same buffer updated (when a line
- entered)?
-- Check out how screen does output optimizing. Apparently this is possible
- as an output filter.
-- In dosub() regexec is called twice for the same line. Try to avoid this.
-- Window updating from memline.c: insert/delete/replace line.
-- Optimize ml_append() for speed, esp. for reading a file.
-- V..c should keep indent when 'ai' is set, just like [count]cc.
-- Updatescript() can be done faster with a string instead of a char.
-- Screen updating is inefficient with CTRL-F and CTRL-B when there are long
- lines.
-- Uppercase characters in Ex commands can be made lowercase?
-8 Add option to show characters in text not as "|A" but as decimal ("^129"),
- hex ("\x81") or octal ("\201") or meta (M-x). Nvi has the 'octal' option
- to switch from hex to octal. Vile can show unprintable characters in hex
- or in octal.
-7 Tighter integration with xxd to edit binary files. Make it more
- easy/obvious to use. Command line argument?
-- How does vi detect whether a filter has messed up the screen? Check source.
- After ":w !command" a wait_return?
-- Improve screen updating code for doput() (use s_ins()).
-- With 'p' command on last line: scroll screen up (also for terminals without
- insert line command).
-- Use insert/delete char when terminal supports it.
-- Optimize screen redraw for slow terminals.
-- Optimize "dw" for long row of spaces (say, 30000).
-- Add "-d null" for editing from a script file without displaying.
-- In Insert mode: Remember the characters that were removed with backspace
- and re-insert them one at a time with <key1>, all together with <key2>.
-- Implement 'redraw' option.
-- Add special code to 'sections' option to define something else but '{' or
- '}' as the start of a section (e.g. one shiftwidth to the right).
-7 Allow using Vim in a pipe: "ls | vim -u xxx.vim - | yyy". Only needs
- implementing ":w" to stdout in the buffer that was read from stdin.
- Perhaps writing to stdout will work, since stderr is used for the terminal
- I/O.
-8 Allow opening an unnamed buffer with ":e !cmd" and ":sp !cmd". Vile can
- do it.
-- Add commands like ]] and [[ that do not include the line jumped to.
-- When :unab without matching "from" part and several matching "to" parts,
- delete the entry that was used last, instead of the first in the list.
-- Add text justification option.
-- Set boolean options on/off with ":set paste=off", ":set paste=on".
-- After "inv"ing an option show the value: ":set invpaste" gives "paste is
- off".
-- Check handling of CTRL-V and '\' for ":" commands that do not have TRLBAR.
-- When a file cannot be opened but does exist, give error message.
-- When writing check for file exists but no permission, "Permission denied".
-- If file does not exist, check if directory exists.
-- MSDOS: although t_cv and t_ci are not set, do invert char under cursor.
-- Settings edit mode: make file with ":set opt=xx", edit it, parse it as ex
- commands.
-- ":set -w all": list one option per line.
-- :table command (Webb)
-- Add new operator: clear, make area white (replace with spaces): "g ".
-- Add command to ":read" a file at a certain column (blockwise read?).
-- Add sort of replace mode where case is taken from the old text (Goldfarb).
-- Allow multiple arguments for ":read", read all the files.
-- Support for tabs in specific columns: ":set tabcol=8,20,34,56" (Demirel).
-- Add 'searchdir' option: Directories to search for file name being edited
- (Demirel).
-- Modifier for the put command: Change to linewise, charwise, blockwise, etc.
-- Add commands for saving and restoring options ":set save" "set restore",
- for use in macro's and the like.
-- Keep output from listings in a window, so you can have a look at it while
- working in another window. Put cmdline in a separate window?
-- Add possibility to put output of Ex commands in a buffer or file, e.g. for
- ":set all". ":r :set all"?
-- When the 'equalalways' option is set, creating a new window should not
- result in windows to become bigger. Deleting a window should not result in
- a window to become smaller (Webb).
-- When resizing the whole Vim window, the windows inside should be resized
- proportionally (Webb).
-- Include options directly in option table, no indirect pointers. Use
- mkopttab to make option table?
-- When doing ":w dir", where "dir" is a directory name, write the current
- file into that directory, with the current file name (without the path)?
-- Support for 'dictionary's that are sorted, makes access a lot faster
- (Haritsis).
-- Add "^Vrx" on the command line, replace with contents of register x. Used
- instead of CTRL-R to make repeating possible. (Marinichev)
-- Add "^Vb" on the command line, replace with word before or under the
- cursor?
-- Option to make a .swp file only when a change is made (Templeton).
-- Support mapping for replace mode and "r" command (Vi doesn't do this)?
-5 Add 'ignorefilecase' option: Ignore case when expanding file names.
- ":e ma<Tab>" would also find "Makefile" on Unix.
-8 Sorting of filenames for completion is wrong on systems that ignore
- case of filenames. Add 'ignorefncase' option. When set, case in
- filenames is ignored for sorting them. Patch by Mike Williams:
- ~/vim/patches/ignorefncase. Also change what matches? Or use another
- option name.
-8 Should be able to compile Vim in another directory, with $(srcdir) set to
- where the sources are. Add $(srcdir) in the Makefile in a lot of places.
- (Netherton)
-6 Make it configurable when "J" inserts a space or not. Should not add a
- space after "(", for example.
-5 When inserting spaces after the end-of-line for 'virtualedit', use tabs
- when the user wants this (e.g., add a "tab" field to 'virtualedit').
- (Servatius Brandt)
-
-
-From Elvis:
-- Use "instman.sh" to install manpages?
-- Add ":alias" command.
-- Search patterns:
- \@ match word under cursor.
- but do:
- \@w match the word under the cursor?
- \@W match the WORD under the cursor?
-8 ":window" command:
- :win + next window (up)
- :win ++ idem, wrapping
- :win - previous window (down)
- :win -- idem, wrapping
- :win nr to window number "nr"
- :win name to window editing buffer "name"
-7 ":cc" compiles a single file (default: current one). 'ccprg' option is
- program to use with ":cc". Use ":compile" instead of ":cc"?
-
-
-From xvi:
-- CTRL-_ : swap 8th bit of character.
-- Add egrep-like regex type, like xvi (Ned Konz) or Perl (Emmanuel Mogenet)
-
-
-From vile:
-- When horizontal scrolling, use '>' for lines continuing right of a window.
-- Support putting .swp files in /tmp: Command in rc.local to move .swp files
- from /tmp to some directory before deleting files.
-
-
-Far future and "big" extensions:
-- Instead of using a Makefile and autoconf, use a simple shell script to
- find the C compiler and do everything with C code. Translate something
- like an Aap recipe and configure.in to C. Avoids depending on Python,
- thus will work everywhere. With batch file to find the C compiler it
- would also work on MS-Windows.
-- Make it easy to setup Vim for groups of users: novice vi users, novice
- Vim users, C programmers, xterm users, GUI users,...
-- Change layout of blocks in swap file: Text at the start, with '\n' in
- between lines (just load the file without changes, except for Mac).
- Indexes for lines are from the end of the block backwards. It's the
- current layout mirrored.
-- Make it possible to edit a register, in a window, like a buffer.
-- Add stuff to syntax highlighting to change the text (upper-case keywords,
- set indent, define other highlighting, etc.).
-- Mode to keep C-code formatted all the time (sort of on-line indent).
-- Several top-level windows in one Vim session. Be able to use a different
- font in each top-level window.
-- Allow editing above start and below end of buffer (flag in 'virtualedit').
-- Smart cut/paste: recognize words and adjust spaces before/after them.
-- Add open mode, use it when terminal has no cursor positioning.
-- Special "drawing mode": a line is drawn where the cursor is moved to.
- Backspace deletes along the line (from jvim).
-- Implement ":Bset", set option in all buffers. Also ":Wset", set in all
- windows, ":Aset, set in all arguments and ":Tset", set in all files
- mentioned in the tags file.
- Add buffer/arg range, like in ":2,5B%s/..." (do we really need this???)
- Add search string: "B/*.c/%s/.."? Or ":F/*.c/%s/.."?
-- Support for underlining (underscore-BS-char), bold (char-BS-char) and other
- standout modes switched on/off with , 'overstrike' option (Reiter).
-- Add vertical mode (Paul Jury, Demirel): "5vdw" deletes a word in five
- lines, "3vitextESC" will insert "text" in three lines, etc..
-4 Recognize l, #, p as 'flags' to EX commands:
- :g/RE/#l shall print lines with line numbers and in list format.
- :g/RE/dp shall print lines that are deleted.
- POSIX: Commands where flags shall apply to all lines written: list,
- number, open, print, substitute, visual, &, z. For other commands, flags
- shall apply to the current line after the command completes. Examples:
- :7,10j #l Join the lines 7-10 and print the result in list
-- Allow two or more users to edit the same file at the same time. Changes
- are reflected in each Vim immediately. Could work with local files but
- also over the internet. See http://www.codingmonkeys.de/subethaedit/.
-
-When using "do" or ":diffget" in a buffer with changes in every line an extra
-empty line would appear.
-
-vim:tw=78:sw=4:sts=4:ts=8:ft=help:norl:
-vim: set fo+=n :
diff --git a/runtime/doc/vi_diff.txt b/runtime/doc/vi_diff.txt
index fffb923219..7b61dbe6d7 100644
--- a/runtime/doc/vi_diff.txt
+++ b/runtime/doc/vi_diff.txt
@@ -6,44 +6,14 @@
Differences between Vim and Vi *vi-differences*
-Throughout the help files differences between Vim and Vi/Ex are given in
-curly braces, like "{not in Vi}". This file only lists what has not been
-mentioned in other files and gives an overview.
-
-1. Missing options |missing-options|
-2. Limits |limits|
-3. The most interesting additions |vim-additions|
-4. Other vim features |other-features|
-5. Command-line arguments |cmdline-arguments|
+1. Limits |limits|
+2. The most interesting additions |vim-additions|
==============================================================================
-1. Missing options *missing-options*
-
-These options are in the Unix Vi, but not in Vim.
-
-autoprint (ap) boolean (default on) *'autoprint'* *'ap'*
-beautify (bf) boolean (default off) *'beautify'* *'bf'*
-flash (fl) boolean (default ??) *'flash'* *'fl'*
-graphic (gr) boolean (default off) *'graphic'* *'gr'*
-hardtabs (ht) number (default 8) *'hardtabs'* *'ht'*
- number of spaces that a <Tab> moves on the display
-mesg boolean (default on) *'mesg'*
-novice boolean (default off) *'novice'*
-open boolean (default on) *'open'*
-optimize (op) boolean (default off) *'optimize'* *'op'*
-redraw boolean (default off) *'redraw'*
-slowopen (slow) boolean (default off) *'slowopen'* *'slow'*
-sourceany boolean (default off) *'sourceany'*
-w300 number (default 23) *'w300'*
-w1200 number (default 23) *'w1200'*
-w9600 number (default 23) *'w9600'*
+1. Limits *limits*
-==============================================================================
-2. Limits *limits*
+Vim has only a few limits for the files that can be edited.
-Vim has only a few limits for the files that can be edited {Vi: can not handle
-<Nul> characters and characters above 128, has limited line length, many other
-limits}.
*E340*
Maximum line length 2147483647 characters
Maximum number of lines 2147483647 lines
@@ -83,21 +53,7 @@ don't want a swap file at all, set 'updatecount' to 0, or use the "-n"
argument when starting Vim.
==============================================================================
-3. The most interesting additions *vim-additions*
-
-Vi compatibility. |'compatible'|
- Although Vim is 99% Vi compatible, some things in Vi can be
- considered to be a bug, or at least need improvement. But still, Vim
- starts in a mode which behaves like the "real" Vi as much as possible.
- To make Vim behave a little bit better, try resetting the 'compatible'
- option:
- :set nocompatible
- Or start Vim with the "-N" argument:
- vim -N
- Vim starts with 'nocompatible' automatically if you have a .vimrc
- file. See |startup|.
- The 'cpoptions' option can be used to set Vi compatibility on/off for
- a number of specific items.
+2. The most interesting additions *vim-additions*
Support for different systems.
Vim can be used on:
@@ -418,482 +374,5 @@ Move cursor beyond lines.
screen, also where there is no text. This is useful to edit tables
and figures easily.
-==============================================================================
-5. Other vim features *other-features*
-
-A random collection of nice extra features.
-
-
-When Vim is started with "-s scriptfile", the characters read from
-"scriptfile" are treated as if you typed them. If end of file is reached
-before the editor exits, further characters are read from the console.
-
-The "-w" option can be used to record all typed characters in a script file.
-This file can then be used to redo the editing, possibly on another file or
-after changing some commands in the script file.
-
-The "-o" option opens a window for each argument. "-o4" opens four windows.
-
-Vi requires several termcap entries to be able to work full-screen. Vim only
-requires the "cm" entry (cursor motion).
-
-
-In command mode:
-
-When the 'showcmd' option is set, the command characters are shown in the last
-line of the screen. They are removed when the command is finished.
-
-If the 'ruler' option is set, the current cursor position is shown in the
-last line of the screen.
-
-"U" still works after having moved off the last changed line and after "u".
-
-Characters with the 8th bit set are displayed. The characters between '~' and
-0xa0 are displayed as "~?", "~@", "~A", etc., unless they are included in the
-'isprint' option.
-
-"][" goes to the next ending of a C function ('}' in column 1).
-"[]" goes to the previous ending of a C function ('}' in column 1).
-
-"]f", "[f" and "gf" start editing the file whose name is under the cursor.
-CTRL-W f splits the window and starts editing the file whose name is under
-the cursor.
-
-"*" searches forward for the identifier under the cursor, "#" backward.
-"K" runs the program defined by the 'keywordprg' option, with the identifier
-under the cursor as argument.
-
-"%" can be preceded with a count. The cursor jumps to the line that
-percentage down in the file. The normal "%" function to jump to the matching
-brace skips braces inside quotes.
-
-With the CTRL-] command, the cursor may be in the middle of the identifier.
-
-The used tags are remembered. Commands that can be used with the tag stack
-are CTRL-T, ":pop" and ":tag". ":tags" lists the tag stack.
-
-The 'tags' option can be set to a list of tag file names. Thus multiple
-tag files can be used. For file names that start with "./", the "./" is
-replaced with the path of the current file. This makes it possible to use a
-tags file in the same directory as the file being edited.
-
-Previously used file names are remembered in the alternate file name list.
-CTRL-^ accepts a count, which is an index in this list.
-":files" command shows the list of alternate file names.
-"#<N>" is replaced with the <N>th alternate file name in the list.
-"#<" is replaced with the current file name without extension.
-
-Search patterns have more features. The <NL> character is seen as part of the
-search pattern and the substitute string of ":s". Vi sees it as the end of
-the command.
-
-Searches can put the cursor on the end of a match and may include a character
-offset.
-
-Count added to "~", ":next", ":Next", "n" and "N".
-
-The command ":next!" with 'autowrite' set does not write the file. In vi the
-file was written, but this is considered to be a bug, because one does not
-expect it and the file is not written with ":rewind!".
-
-In Vi when entering a <CR> in replace mode deletes a character only when 'ai'
-is set (but does not show it until you hit <Esc>). Vim always deletes a
-character (and shows it immediately).
-
-Added :wnext command. Same as ":write" followed by ":next".
-
-The ":w!" command always writes, also when the file is write protected. In Vi
-you would have to do ":!chmod +w %:S" and ":set noro".
-
-When 'tildeop' has been set, "~" is an operator (must be followed by a
-movement command).
-
-With the "J" (join) command you can reset the 'joinspaces' option to have only
-one space after a period (Vi inserts two spaces).
-
-"cw" can be used to change white space formed by several characters (Vi is
-confusing: "cw" only changes one space, while "dw" deletes all white space).
-
-"o" and "O" accept a count for repeating the insert (Vi clears a part of
-display).
-
-Flags after Ex commands not supported (no plans to include it).
-
-On non-UNIX systems ":cd" command shows current directory instead of going to
-the home directory (there isn't one). ":pwd" prints the current directory on
-all systems.
-
-After a ":cd" command the file names (in the argument list, opened files)
-still point to the same files. In Vi ":cd" is not allowed in a changed file;
-otherwise the meaning of file names change.
-
-":source!" command reads Vi commands from a file.
-
-":mkexrc" command writes current modified options and mappings to a ".exrc"
-file. ":mkvimrc" writes to a ".vimrc" file.
-
-No check for "tail recursion" with mappings. This allows things like
-":map! foo ^]foo".
-
-When a mapping starts with number, vi loses the count typed before it (e.g.
-when using the mapping ":map g 4G" the command "7g" goes to line 4). This is
-considered a vi bug. Vim concatenates the counts (in the example it becomes
-"74G"), as most people would expect.
-
-The :put! command inserts the contents of a register above the current line.
-
-The "p" and "P" commands of vi cannot be repeated with "." when the putted
-text is less than a line. In Vim they can always be repeated.
-
-":noremap" command can be used to enter a mapping that will not be remapped.
-This is useful to exchange the meaning of two keys. ":cmap", ":cunmap" and
-":cnoremap" can be used for mapping in command-line editing only. ":imap",
-":iunmap" and ":inoremap" can be used for mapping in insert mode only.
-Similar commands exist for abbreviations: ":noreabbrev", ":iabbrev"
-":cabbrev", ":iunabbrev", ":cunabbrev", ":inoreabbrev", ":cnoreabbrev".
-
-In Vi the command ":map foo bar" would remove a previous mapping
-":map bug foo". This is considered a bug, so it is not included in Vim.
-":unmap! foo" does remove ":map! bug foo", because unmapping would be very
-difficult otherwise (this is vi compatible).
-
-The ':' register contains the last command-line.
-The '%' register contains the current file name.
-The '.' register contains the last inserted text.
-
-":dis" command shows the contents of the yank registers.
-
-CTRL-O/CTRL-I can be used to jump to older/newer positions. These are the
-same positions as used with the '' command, but may be in another file. The
-":jumps" command lists the older positions.
-
-If the 'shiftround' option is set, an indent is rounded to a multiple of
-'shiftwidth' with ">" and "<" commands.
-
-The 'scrolljump' option can be set to the minimum number of lines to scroll
-when the cursor gets off the screen. Use this when scrolling is slow.
-
-The 'scrolloff' option can be set to the minimum number of lines to keep
-above and below the cursor. This gives some context to where you are
-editing. When set to a large number the cursor line is always in the middle
-of the window.
-
-Uppercase marks can be used to jump between files. The ":marks" command lists
-all currently set marks. The commands "']" and "`]" jump to the end of the
-previous operator or end of the text inserted with the put command. "'[" and
-"`[" do jump to the start.
-
-The 'highlight' option can be set for the highlight mode to be used for
-several commands.
-
-The CTRL-A (add) and CTRL-X (subtract) commands are new. The count to the
-command (default 1) is added to/subtracted from the number at or after the
-cursor. That number may be decimal, octal (starts with a '0') or hexadecimal
-(starts with '0x'). Very useful in macros.
-
-With the :set command the prefix "inv" can be used to invert boolean options.
-
-In both Vi and Vim you can create a line break with the ":substitute" command
-by using a CTRL-M. For Vi this means you cannot insert a real CTRL-M in the
-text. With Vim you can put a real CTRL-M in the text by preceding it with a
-CTRL-V.
-
-
-In Insert mode:
-
-If the 'revins' option is set, insert happens backwards. This is for typing
-Hebrew. When inserting normal characters the cursor will not be shifted and
-the text moves rightwards. Backspace, CTRL-W and CTRL-U will also work in
-the opposite direction. CTRL-B toggles the 'revins' option. In replace mode
-'revins' has no effect. Only when enabled at compile time.
-
-The backspace key can be used just like CTRL-D to remove auto-indents.
-
-You can backspace, CTRL-U and CTRL-W over line breaks if the 'backspace' (bs)
-option includes "eol". You can backspace over the start of insert if the
-'backspace' option includes "start".
-
-When the 'paste' option is set, a few options are reset and mapping in insert
-mode and abbreviation are disabled. This allows for pasting text in windowing
-systems without unexpected results. When the 'paste' option is reset, the old
-option values are restored.
-
-CTRL-T/CTRL-D always insert/delete an indent in the current line, no matter
-what column the cursor is in.
-
-CTRL-@ (insert previously inserted text) works always (Vi: only when typed as
-first character).
-
-CTRL-A works like CTRL-@ but does not leave insert mode.
-
-CTRL-R {0-9a-z..} can be used to insert the contents of a register.
-
-When the 'smartindent' option is set, C programs will be better auto-indented.
-With 'cindent' even more.
-
-CTRL-Y and CTRL-E can be used to copy a character from above/below the
-current cursor position.
-
-After CTRL-V you can enter a three digit decimal number. This byte value is
-inserted in the text as a single character. Useful for international
-characters that are not on your keyboard.
-
-When the 'expandtab' (et) option is set, a <Tab> is expanded to the
-appropriate number of spaces.
-
-The window always reflects the contents of the buffer (Vi does not do this
-when changing text and in some other cases).
-
-If Vim is compiled with DIGRAPHS defined, digraphs are supported. A set of
-normal digraphs is included. They are shown with the ":digraph" command.
-More can be added with ":digraph {char1}{char2} {number}". A digraph is
-entered with "CTRL-K {char1} {char2}" or "{char1} BS {char2}" (only when
-'digraph' option is set).
-
-When repeating an insert, e.g. "10atest <Esc>" vi would only handle wrapmargin
-for the first insert. Vim does it for all.
-
-A count to the "i" or "a" command is used for all the text. Vi uses the count
-only for one line. "3iabc<NL>def<Esc>" would insert "abcabcabc<NL>def" in Vi
-but "abc<NL>defabc<NL>defabc<NL>def" in Vim.
-
-
-In Command-line mode:
-
-<Esc> terminates the command-line without executing it. In vi the command
-line would be executed, which is not what most people expect (hitting <Esc>
-should always get you back to command mode). To avoid problems with some
-obscure macros, an <Esc> in a macro will execute the command. If you want a
-typed <Esc> to execute the command like vi does you can fix this with
- ":cmap ^V<Esc> ^V<CR>"
-
-General:
-
-The 'ttimeout' option is like 'timeout', but only works for cursor and
-function keys, not for ordinary mapped characters. The 'timeoutlen' option
-gives the number of milliseconds that is waited for. If the 'esckeys' option
-is not set, cursor and function keys that start with <Esc> are not recognized
-in insert mode.
-
-There is an option for each terminal string. Can be used when termcap is not
-supported or to change individual strings.
-
-The 'fileformat' option can be set to select the <EOL>: "dos" <CR><NL>, "unix"
-<NL> or "mac" <CR>.
-When the 'fileformats' option is not empty, Vim tries to detect the type of
-<EOL> automatically. The 'fileformat' option is set accordingly.
-
-On systems that have no job control (older Unix systems and non-Unix systems)
-the CTRL-Z, ":stop" or ":suspend" command starts a new shell.
-
-The 'columns' and 'lines' options are used to set or get the width and height
-of the display.
-
-Option settings are read from the first and last few lines of the file.
-Option 'modelines' determines how many lines are tried (default is 5). Note
-that this is different from the Vi versions that can execute any Ex command
-in a modeline (a major security problem). |trojan-horse|
-
-If the 'insertmode' option is set (e.g. in .exrc), Vim starts in insert mode.
-And it comes back there, when pressing <Esc>.
-
-Undo information is kept in memory. Available memory limits the number and
-size of change that can be undone. This may be a problem with MS-DOS, but is
-almost never one with Unix and Win32.
-
-If the 'backup' or 'writebackup' option is set: Before a file is overwritten,
-a backup file (.bak) is made. If the "backup" option is set it is left
-behind.
-
-Vim creates a file ending in ".swp" to store parts of the file that have been
-changed or that do not fit in memory. This file can be used to recover from
-an aborted editing session with "vim -r file". Using the swap file can be
-switched off by setting the 'updatecount' option to 0 or starting Vim with
-the "-n" option. Use the 'directory' option for placing the .swp file
-somewhere else.
-
-Error messages are shown at least one second (Vi overwrites error messages).
-
-If Vim gives the |hit-enter| prompt, you can hit any key. Characters other
-than <CR>, <NL> and <Space> are interpreted as the (start of) a command. (Vi
-only accepts a command starting with ':').
-
-The contents of the numbered and unnamed registers is remembered when
-changing files.
-
-The "No lines in buffer" message is a normal message instead of an error
-message, since that may cause a mapping to be aborted.
-
-==============================================================================
-5. Command-line arguments *cmdline-arguments*
-
-Different versions of Vi have different command-line arguments. This can be
-confusing. To help you, this section gives an overview of the differences.
-
-Five variants of Vi will be considered here:
- Elvis Elvis version 2.1b
- Nvi Nvi version 1.79
- Posix Posix 1003.2
- Vi Vi version 3.7 (for Sun 4.1.x)
- Vile Vile version 7.4 (incomplete)
- Vim Vim version 5.2
-
-Only Vim is able to accept options in between and after the file names.
-
-+{command} Elvis, Nvi, Posix, Vi, Vim: Same as "-c {command}".
-
-- Nvi, Posix, Vi: Run Ex in batch mode.
- Vim: Read file from stdin (use -s for batch mode).
-
--- Vim: End of options, only file names are following.
-
---cmd {command} Vim: execute {command} before sourcing vimrc files.
-
---echo-wid Vim: GTK+ echoes the Window ID on stdout
-
---help Vim: show help message and exit.
-
---literal Vim: take file names literally, don't expand wildcards.
-
---nofork Vim: same as -f
-
---noplugin[s] Vim: Skip loading plugins.
-
---remote Vim: edit the files in another Vim server
-
---remote-expr {expr} Vim: evaluate {expr} in another Vim server
-
---remote-send {keys} Vim: send {keys} to a Vim server and exit
-
---remote-silent {file} Vim: edit the files in another Vim server if possible
-
---remote-wait Vim: edit the files in another Vim server and wait for it
-
---remote-wait-silent Vim: like --remote-wait, no complaints if not possible
-
---role {role} Vim: GTK+ 2: set role of main window
-
---serverlist Vim: Output a list of Vim servers and exit
-
---servername {name} Vim: Specify Vim server name
-
---socketid {id} Vim: GTK window socket to run Vim in
-
---windowid {id} Vim: Win32 window ID to run Vim in
-
---version Vim: show version message and exit.
-
--? Vile: print usage summary and exit.
-
--a Elvis: Load all specified file names into a window (use -o for
- Vim).
-
--A Vim: Start in Arabic mode (when compiled with Arabic).
-
--b {blksize} Elvis: Use {blksize} blocksize for the session file.
--b Vim: set 'binary' mode.
-
--C Vim: Compatible mode.
-
--c {command} Elvis, Nvi, Posix, Vim: run {command} as an Ex command after
- loading the edit buffer.
- Vim: allow up to 10 "-c" arguments
-
--d Vim: start with 'diff' set. |diff-mode|
-
--D Vim: debug mode.
-
--e Elvis, Nvi, Vim: Start in Ex mode.
-
--E Vim: Start in improved Ex mode |gQ|.
-
--f Vim: Run GUI in foreground.
--f {session} Elvis: Use {session} as the session file.
-
--F Vim: Start in Farsi mode (when compiled with Farsi).
- Nvi: Fast start, don't read the entire file when editing
- starts.
-
--G {gui} Elvis: Use the {gui} as user interface.
-
--g Vim: Start GUI.
--g N Vile: start editing at line N
-
--h Vim: Give help message.
- Vile: edit the help file
-
--H Vim: start Hebrew mode (when compiled with it).
-
--i Elvis: Start each window in Insert mode.
--i {viminfo} Vim: Use {viminfo} for viminfo file.
-
--L Vim: Same as "-r" (also in some versions of Vi).
-
--l Nvi, Vi, Vim: Set 'lisp' and 'showmatch' options.
-
--m Vim: Modifications not allowed to be written, resets 'write'
- option.
-
--M Vim: Modifications not allowed, resets 'modifiable' and the
- 'write' option.
-
--N Vim: No-compatible mode.
-
--n Vim: No swap file used.
-
--nb[args] Vim: open a NetBeans interface connection
-
--O[N] Vim: Like -o, but use vertically split windows.
-
--o[N] Vim: Open [N] windows, or one for each file.
-
--p[N] Vim: Open [N] tab pages, or one for each file.
-
--P {parent-title} Win32 Vim: open Vim inside a parent application window
-
--q {name} Vim: Use {name} for quickfix error file.
--q{name} Vim: Idem.
-
--R Elvis, Nvi, Posix, Vile, Vim: Set the 'readonly' option.
-
--r Elvis, Nvi, Posix, Vi, Vim: Recovery mode.
-
--S Nvi: Set 'secure' option.
--S {script} Vim: source script after starting up.
-
--s Nvi, Posix, Vim: Same as "-" (silent mode), when in Ex mode.
- Elvis: Sets the 'safer' option.
--s {scriptin} Vim: Read from script file {scriptin}; only when not in Ex
- mode.
--s {pattern} Vile: search for {pattern}
-
--t {tag} Elvis, Nvi, Posix, Vi, Vim: Edit the file containing {tag}.
--t{tag} Vim: Idem.
-
--T {term} Vim: Set terminal name to {term}.
-
--u {vimrc} Vim: Read initializations from {vimrc} file.
-
--U {gvimrc} Vim: Read GUI initializations from {gvimrc} file.
-
--v Nvi, Posix, Vi, Vim: Begin in Normal mode (visual mode, in Vi
- terms).
- Vile: View mode, no changes possible.
-
--V Elvis, Vim: Verbose mode.
--V{nr} Vim: Verbose mode with specified level.
-
--w {size} Elvis, Posix, Nvi, Vi, Vim: Set value of 'window' to {size}.
--w{size} Nvi, Vi: Same as "-w {size}".
--w {name} Vim: Write to script file {name} (must start with non-digit).
-
--W {name} Vim: Append to script file {name}.
-
--X Vim: Don't connect to the X server.
-
--Z Vim: restricted mode
-
-@{cmdfile} Vile: use {cmdfile} as startup file.
-
vim:tw=78:ts=8:ft=help:norl:
diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt
index 6cbc2aef59..c6e98bc40c 100644
--- a/runtime/doc/vim_diff.txt
+++ b/runtime/doc/vim_diff.txt
@@ -117,6 +117,7 @@ Additional differences:
|shada-error-handling|
- Vim keeps no timestamps at all, neither in viminfo file nor in the instance
itself.
+- ShaDa file keeps search direction (|v:searchforward|), viminfo does not.
==============================================================================
4. New Features *nvim-features-new*
@@ -194,6 +195,7 @@ Highlight groups:
|hl-VisualNOS|
Other options:
+ 'antialias'
'cpoptions' ('g', 'w', 'H', '*', '-', 'j', and all POSIX flags were removed)
'guioptions' (only the 't' flag was removed)
'guipty'
diff --git a/runtime/ftplugin/shada.vim b/runtime/ftplugin/shada.vim
new file mode 100644
index 0000000000..4f908f4701
--- /dev/null
+++ b/runtime/ftplugin/shada.vim
@@ -0,0 +1,18 @@
+if exists('b:did_ftplugin')
+ finish
+endif
+
+let b:did_ftplugin = 1
+
+function! ShaDaIndent(lnum)
+ if a:lnum == 1 || getline(a:lnum) =~# '\mwith timestamp.*:$'
+ return 0
+ else
+ return shiftwidth()
+ endif
+endfunction
+
+setlocal expandtab tabstop=2 softtabstop=2 shiftwidth=2
+setlocal indentexpr=ShaDaIndent(v:lnum) indentkeys=<:>,o,O
+
+let b:undo_ftplugin = 'setlocal et< ts< sts< sw< indentexpr< indentkeys<'
diff --git a/runtime/optwin.vim b/runtime/optwin.vim
index d1ab204180..09406f260b 100644
--- a/runtime/optwin.vim
+++ b/runtime/optwin.vim
@@ -576,10 +576,6 @@ if has("gui")
endif
call append("$", "guifontwide\tlist of font names to be used for double-wide characters")
call <SID>OptionG("gfw", &gfw)
- if has("mac")
- call append("$", "antialias\tuse smooth, antialiased fonts")
- call <SID>BinOptionG("anti", &anti)
- endif
call append("$", "guioptions\tlist of flags that specify how the GUI works")
call <SID>OptionG("go", &go)
if has("gui_gtk")
diff --git a/runtime/plugin/shada.vim b/runtime/plugin/shada.vim
new file mode 100644
index 0000000000..ae08e01dcb
--- /dev/null
+++ b/runtime/plugin/shada.vim
@@ -0,0 +1,39 @@
+if exists('g:loaded_shada_plugin')
+ finish
+endif
+let g:loaded_shada_plugin = 1
+
+augroup ShaDaCommands
+ autocmd!
+ autocmd BufReadCmd *.shada,*.shada.tmp.[a-z]
+ \ :if !empty(v:cmdarg)|throw '++opt not supported'|endif
+ \ |call setline('.', shada#get_strings(readfile(expand('<afile>'),'b')))
+ \ |setlocal filetype=shada
+ autocmd FileReadCmd *.shada,*.shada.tmp.[a-z]
+ \ :if !empty(v:cmdarg)|throw '++opt not supported'|endif
+ \ |call append("'[", shada#get_strings(readfile(expand('<afile>'), 'b')))
+ autocmd BufWriteCmd *.shada,*.shada.tmp.[a-z]
+ \ :if !empty(v:cmdarg)|throw '++opt not supported'|endif
+ \ |if writefile(shada#get_binstrings(getline(1, '$')),
+ \expand('<afile>'), 'b') == 0
+ \ | let &l:modified = (expand('<afile>') is# bufname(+expand('<abuf>'))
+ \? 0
+ \: stridx(&cpoptions, '+') != -1)
+ \ |endif
+ autocmd FileWriteCmd *.shada,*.shada.tmp.[a-z]
+ \ :if !empty(v:cmdarg)|throw '++opt not supported'|endif
+ \ |call writefile(
+ \shada#get_binstrings(getline(min([line("'["), line("']")]),
+ \max([line("'["), line("']")]))),
+ \expand('<afile>'),
+ \'b')
+ autocmd FileAppendCmd *.shada,*.shada.tmp.[a-z]
+ \ :if !empty(v:cmdarg)|throw '++opt not supported'|endif
+ \ |call writefile(
+ \shada#get_binstrings(getline(min([line("'["), line("']")]),
+ \max([line("'["), line("']")]))),
+ \expand('<afile>'),
+ \'ab')
+ autocmd SourceCmd *.shada,*.shada.tmp.[a-z]
+ \ :execute 'rshada' fnameescape(expand('<afile>'))
+augroup END
diff --git a/runtime/syntax/shada.vim b/runtime/syntax/shada.vim
new file mode 100644
index 0000000000..e5325af5b0
--- /dev/null
+++ b/runtime/syntax/shada.vim
@@ -0,0 +1,125 @@
+if exists("b:current_syntax")
+ finish
+endif
+
+syntax match ShaDaEntryHeader
+ \ '^\u.\{-} with timestamp \d\{4}-\d\d-\d\dT\d\d:\d\d:\d\d:$'
+syntax match ShaDaEntryName '^\u.\{-}\ze with' contained
+ \ containedin=ShaDaEntryHeader
+syntax match ShaDaEntryTimestamp 'timestamp \zs\d\{4}-\d\d-\d\dT\d\d:\d\d:\d\d'
+ \ contained containedin=ShaDaEntryHeader
+syntax match ShaDaEntryTimestampNumber '\d\+' contained
+ \ containedin=ShaDaEntryTimestamp
+
+syntax match ShaDaComment '^\s*#.*$'
+
+syntax region ShaDaEntryMapLong start='^ % Key_* Description_* Value$'
+ \ end='^ %\|^\S'me=s-1 contains=ShaDaComment,ShaDaEntryMapLongEntryStart
+syntax region ShaDaEntryMapShort start='^ % Key_* Value$'
+ \ end='^ %\|^\S'me=s-1 contains=ShaDaComment,ShaDaEntryMapShortEntryStart
+syntax match ShaDaEntryMapHeader '^ % Key_* \(Description_* \)\?Value$'
+ \ contained containedin=ShaDaEntryMapLong,ShaDaEntryMapShort
+syntax match ShaDaEntryMapLongEntryStart '^ + 'hs=e-2,he=e-1
+ \ nextgroup=ShaDaEntryMapLongKey
+syntax match ShaDaEntryMapLongKey '\S\+ \+\ze\S'he=e-2 contained
+ \ nextgroup=ShaDaEntryMapLongDescription
+syntax match ShaDaEntryMapLongDescription '.\{-} \ze\S'he=e-2 contained
+ \ nextgroup=@ShaDaEntryMsgpackValue
+syntax match ShaDaEntryMapShortEntryStart '^ + 'hs=e-2,he=e-1 contained
+ \ nextgroup=ShaDaEntryMapShortKey
+syntax match ShaDaEntryMapShortKey '\S\+ \+\ze\S'he=e-2 contained
+ \ nextgroup=@ShaDaEntryMsgpackValue
+syntax match ShaDaEntryMapBinArrayStart '^ | - 'hs=e-4,he=e-1 contained
+ \ containedin=ShaDaEntryMapLong,ShaDaEntryMapShort
+ \ nextgroup=@ShaDaEntryMsgpackValue
+
+syntax region ShaDaEntryArray start='^ @ Description_* Value$'
+ \ end='^\S'me=s-1 keepend
+ \ contains=ShaDaComment,ShaDaEntryArrayEntryStart,ShaDaEntryArrayHeader
+syntax match ShaDaEntryArrayHeader '^ @ Description_* Value$' contained
+syntax match ShaDaEntryArrayEntryStart '^ - 'hs=e-2,he=e-1
+ \ nextgroup=ShaDaEntryArrayDescription
+syntax match ShaDaEntryArrayDescription '.\{-} \ze\S'he=e-2 contained
+ \ nextgroup=@ShaDaEntryMsgpackValue
+
+syntax match ShaDaEntryRawMsgpack '^ = ' nextgroup=@ShaDaEntryMsgpackValue
+
+syntax cluster ShaDaEntryMsgpackValue
+ \ add=ShaDaMsgpackKeyword,ShaDaMsgpackShaDaKeyword
+ \ add=ShaDaMsgpackInteger,ShaDaMsgpackCharacter,ShaDaMsgpackFloat
+ \ add=ShaDaMsgpackBinaryString,ShaDaMsgpackString,ShaDaMsgpackExt
+ \ add=ShaDaMsgpackArray,ShaDaMsgpackMap
+ \ add=ShaDaMsgpackMultilineArray
+syntax keyword ShaDaMsgpackKeyword contained NIL TRUE FALSE
+syntax keyword ShaDaMsgpackShaDaKeyword contained
+ \ CMD SEARCH EXPR INPUT DEBUG
+ \ CHARACTERWISE LINEWISE BLOCKWISE
+syntax region ShaDaMsgpackBinaryString matchgroup=ShaDaMsgpackStringQuotes
+ \ start='"' skip='\\"' end='"' contained keepend
+syntax match ShaDaMsgpackBinaryStringEscape '\\[\\0n"]'
+ \ contained containedin=ShaDaMsgpackBinaryString
+syntax match ShaDaMsgpackString '=' contained nextgroup=ShaDaMsgpackBinaryString
+syntax match ShaDaMsgpackExt '+(-\?\d\+)' contained
+ \ nextgroup=ShaDaMsgpackBinaryString
+syntax match ShaDaMsgpackExtType '-\?\d\+' contained containedin=ShaDaMsgpackExt
+syntax match ShaDaMsgpackCharacter /'.'/ contained
+syntax match ShaDaMsgpackInteger '-\?\%(0x\x\{,16}\|\d\+\)' contained
+syntax match ShaDaMsgpackFloat '-\?\d\+\.\d\+\%(e[+-]\?\d\+\)\?' contained
+syntax region ShaDaMsgpackArray matchgroup=ShaDaMsgpackArrayBraces
+ \ start='\[' end='\]' contained
+ \ contains=@ShaDaEntryMsgpackValue,ShaDaMsgpackComma
+syntax region ShaDaMsgpackMap matchgroup=ShaDaMsgpackMapBraces
+ \ start='{' end='}' contained
+ \ contains=@ShaDaEntryMsgpackValue,ShaDaMsgpackComma,ShaDaMsgpackColon
+syntax match ShaDaMsgpackComma ',' contained
+syntax match ShaDaMsgpackColon ':' contained
+syntax match ShaDaMsgpackMultilineArray '@' contained
+
+hi def link ShaDaComment Comment
+hi def link ShaDaEntryNumber Number
+hi def link ShaDaEntryTimestamp Operator
+hi def link ShaDaEntryName Keyword
+
+hi def link ShaDaEntryMapHeader PreProc
+
+hi def link ShaDaEntryMapEntryStart Label
+hi def link ShaDaEntryMapLongEntryStart ShaDaEntryMapEntryStart
+hi def link ShaDaEntryMapShortEntryStart ShaDaEntryMapEntryStart
+hi def link ShaDaEntryMapBinArrayStart ShaDaEntryMapEntryStart
+hi def link ShaDaEntryArrayEntryStart ShaDaEntryMapEntryStart
+
+hi def link ShaDaEntryMapKey String
+hi def link ShaDaEntryMapLongKey ShaDaEntryMapKey
+hi def link ShaDaEntryMapShortKey ShaDaEntryMapKey
+
+hi def link ShaDaEntryMapDescription Comment
+hi def link ShaDaEntryMapLongDescription ShaDaEntryMapDescription
+hi def link ShaDaEntryMapShortDescription ShaDaEntryMapDescription
+
+hi def link ShaDaEntryArrayHeader PreProc
+
+hi def link ShaDaEntryArrayDescription ShaDaEntryMapDescription
+
+hi def link ShaDaMsgpackKeyword Keyword
+hi def link ShaDaMsgpackShaDaKeyword ShaDaMsgpackKeyword
+hi def link ShaDaMsgpackCharacter Character
+hi def link ShaDaMsgpackInteger Number
+hi def link ShaDaMsgpackFloat Float
+
+hi def link ShaDaMsgpackBinaryString String
+hi def link ShaDaMsgpackBinaryStringEscape SpecialChar
+hi def link ShaDaMsgpackExtType Typedef
+
+hi def link ShaDaMsgpackStringQuotes Operator
+hi def link ShaDaMsgpackString ShaDaMsgpackStringQuotes
+hi def link ShaDaMsgpackExt ShaDaMsgpackStringQuotes
+
+hi def link ShaDaMsgpackMapBraces Operator
+hi def link ShaDaMsgpackArrayBraces ShaDaMsgpackMapBraces
+
+hi def link ShaDaMsgpackComma Operator
+hi def link ShaDaMsgpackColon ShaDaMsgpackComma
+
+hi def link ShaDaMsgpackMultilineArray Operator
+
+let b:current_syntax = "shada"
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index a8446265d0..b7a86af134 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -1,6 +1,5 @@
// Much of this code was adapted from 'if_py_both.h' from the original
// vim source
-#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 10106bcb1d..fb1aeb7ba8 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
@@ -25,7 +25,6 @@
*/
#include <stdbool.h>
-#include <errno.h>
#include <string.h>
#include <inttypes.h>
@@ -2803,58 +2802,59 @@ void free_titles(void)
# endif
+/// Enumeration specifying the valid numeric bases that can
+/// be used when printing numbers in the status line.
+typedef enum {
+ kNumBaseDecimal = 10,
+ kNumBaseOctal = 8,
+ kNumBaseHexadecimal = 16
+} NumberBase;
-/*
- * Build a string from the status line items in "fmt".
- * Return length of string in screen cells.
- *
- * Normally works for window "wp", except when working for 'tabline' then it
- * is "curwin".
- *
- * Items are drawn interspersed with the text that surrounds it
- * Specials: %-<wid>(xxx%) => group, %= => middle marker, %< => truncation
- * Item: %-<minwid>.<maxwid><itemch> All but <itemch> are optional
- *
- * If maxwidth is not zero, the string will be filled at any middle marker
- * or truncated if too long, fillchar is used for all whitespace.
- */
-int
-build_stl_str_hl (
+
+/// Build a string from the status line items in "fmt".
+/// Return length of string in screen cells.
+///
+/// Normally works for window "wp", except when working for 'tabline' then it
+/// is "curwin".
+///
+/// Items are drawn interspersed with the text that surrounds it
+/// Specials: %-<wid>(xxx%) => group, %= => middle marker, %< => truncation
+/// Item: %-<minwid>.<maxwid><itemch> All but <itemch> are optional
+///
+/// If maxwidth is not zero, the string will be filled at any middle marker
+/// or truncated if too long, fillchar is used for all whitespace.
+///
+/// @param wp The window to build a statusline for
+/// @param out The output buffer to write the statusline to
+/// Note: This should not be NameBuff
+/// @param outlen The length of the output buffer
+/// @param fmt The statusline format string
+/// @param use_sandbox Use a sandboxed environment when evaluating fmt
+/// @param fillchar Character to use when filling empty space in the statusline
+/// @param maxwidth The maximum width to make the statusline
+/// @param hltab HL attributes (can be NULL)
+/// @param tabtab tab page nrs (can be NULL)
+///
+/// @return The final width of the statusline
+int build_stl_str_hl(
win_T *wp,
- char_u *out, /* buffer to write into != NameBuff */
- size_t outlen, /* length of out[] */
+ char_u *out,
+ size_t outlen,
char_u *fmt,
- int use_sandbox, /* "fmt" was set insecurely, use sandbox */
+ int use_sandbox,
int fillchar,
int maxwidth,
- struct stl_hlrec *hltab, /* return: HL attributes (can be NULL) */
- struct stl_hlrec *tabtab /* return: tab page nrs (can be NULL) */
+ struct stl_hlrec *hltab,
+ struct stl_hlrec *tabtab
)
{
- char_u *p;
- char_u *s;
- char_u *t;
- int byteval;
- win_T *o_curwin;
- buf_T *o_curbuf;
- int empty_line;
- colnr_T virtcol;
- long l;
- long n;
- int prevchar_isflag;
- int prevchar_isitem;
- int itemisflag;
- int fillable;
- char_u *str;
- long num;
- int width;
- int itemcnt;
- int curitem;
int groupitem[STL_MAX_ITEM];
- int groupdepth;
struct stl_item {
+ // Where the item starts in the status line output buffer
char_u *start;
+ // The minimum width of the item
int minwid;
+ // The maximum width of the item
int maxwid;
enum {
Normal,
@@ -2866,20 +2866,13 @@ build_stl_str_hl (
Trunc
} type;
} item[STL_MAX_ITEM];
- int minwid;
- int maxwid;
- int zeropad;
- char_u base;
- char_u opt;
+
#define TMPLEN 70
char_u tmp[TMPLEN];
char_u *usefmt = fmt;
- struct stl_hlrec *sp;
- /*
- * When the format starts with "%!" then evaluate it as an expression and
- * use the result as the actual format string.
- */
+ // When the format starts with "%!" then evaluate it as an expression and
+ // use the result as the actual format string.
if (fmt[0] == '%' && fmt[1] == '!') {
usefmt = eval_to_string_safe(fmt + 2, NULL, use_sandbox);
if (usefmt == NULL)
@@ -2888,175 +2881,280 @@ build_stl_str_hl (
if (fillchar == 0)
fillchar = ' ';
- /* Can't handle a multi-byte fill character yet. */
+ // Can't handle a multi-byte fill character yet.
else if (mb_char2len(fillchar) > 1)
fillchar = '-';
- /* Get line & check if empty (cursorpos will show "0-1"). Note that
- * p will become invalid when getting another buffer line. */
- p = ml_get_buf(wp->w_buffer, wp->w_cursor.lnum, FALSE);
- empty_line = (*p == NUL);
+ // Get line & check if empty (cursorpos will show "0-1").
+ char_u *line_ptr = ml_get_buf(wp->w_buffer, wp->w_cursor.lnum, false);
+ bool empty_line = (*line_ptr == NUL);
- /* Get the byte value now, in case we need it below. This is more
- * efficient than making a copy of the line. */
- if (wp->w_cursor.col > (colnr_T)STRLEN(p))
+ // Get the byte value now, in case we need it below. This is more
+ // efficient than making a copy of the line.
+ int byteval;
+ if (wp->w_cursor.col > (colnr_T)STRLEN(line_ptr))
byteval = 0;
else
- byteval = (*mb_ptr2char)(p + wp->w_cursor.col);
-
- groupdepth = 0;
- p = out;
- curitem = 0;
- prevchar_isflag = TRUE;
- prevchar_isitem = FALSE;
- for (s = usefmt; *s; ) {
+ byteval = (*mb_ptr2char)(line_ptr + wp->w_cursor.col);
+
+ int groupdepth = 0;
+
+ int curitem = 0;
+ bool prevchar_isflag = true;
+ bool prevchar_isitem = false;
+
+ // out_p is the current position in the output buffer
+ char_u *out_p = out;
+
+ // out_end_p is the last valid character in the output buffer
+ // Note: The null termination character must occur here or earlier,
+ // so any user-visible characters must occur before here.
+ char_u *out_end_p = (out + outlen) - 1;
+
+
+ // Proceed character by character through the statusline format string
+ // fmt_p is the current positon in the input buffer
+ for (char_u *fmt_p = usefmt; *fmt_p; ) {
if (curitem == STL_MAX_ITEM) {
- /* There are too many items. Add the error code to the statusline
- * to give the user a hint about what went wrong. */
- if (p + 6 < out + outlen) {
- memmove(p, " E541", (size_t)5);
- p += 5;
+ // There are too many items. Add the error code to the statusline
+ // to give the user a hint about what went wrong.
+ if (out_p + 5 < out_end_p) {
+ memmove(out_p, " E541", (size_t)5);
+ out_p += 5;
}
break;
}
- if (*s != NUL && *s != '%')
- prevchar_isflag = prevchar_isitem = FALSE;
+ if (*fmt_p != NUL && *fmt_p != '%') {
+ prevchar_isflag = prevchar_isitem = false;
+ }
- /*
- * Handle up to the next '%' or the end.
- */
- while (*s != NUL && *s != '%' && p + 1 < out + outlen)
- *p++ = *s++;
- if (*s == NUL || p + 1 >= out + outlen)
+ // Copy the formatting verbatim until we reach the end of the string
+ // or find a formatting item (denoted by `%`)
+ // or run out of room in our output buffer.
+ while (*fmt_p != NUL && *fmt_p != '%' && out_p < out_end_p)
+ *out_p++ = *fmt_p++;
+
+ // If we have processed the entire format string or run out of
+ // room in our output buffer, exit the loop.
+ if (*fmt_p == NUL || out_p >= out_end_p)
break;
- /*
- * Handle one '%' item.
- */
- s++;
- if (*s == NUL) /* ignore trailing % */
+ // The rest of this loop will handle a single `%` item.
+ // Note: We increment here to skip over the `%` character we are currently
+ // on so we can process the item's contents.
+ fmt_p++;
+
+ // Ignore `%` at the end of the format string
+ if (*fmt_p == NUL) {
break;
- if (*s == '%') {
- if (p + 1 >= out + outlen)
+ }
+
+ // Two `%` in a row is the escape sequence to print a
+ // single `%` in the output buffer.
+ if (*fmt_p == '%') {
+ // Ignore the character if we're out of room in the output buffer.
+ if (out_p >= out_end_p)
break;
- *p++ = *s++;
- prevchar_isflag = prevchar_isitem = FALSE;
+ *out_p++ = *fmt_p++;
+ prevchar_isflag = prevchar_isitem = false;
continue;
}
- if (*s == STL_MIDDLEMARK) {
- s++;
- if (groupdepth > 0)
+
+ // STL_MIDDLEMARK: Separation place between left and right aligned items.
+ if (*fmt_p == STL_MIDDLEMARK) {
+ fmt_p++;
+ // Ignored when we are inside of a grouping
+ if (groupdepth > 0) {
continue;
+ }
item[curitem].type = Middle;
- item[curitem++].start = p;
+ item[curitem++].start = out_p;
continue;
}
- if (*s == STL_TRUNCMARK) {
- s++;
+
+ // STL_TRUNCMARK: Where to begin truncating if the statusline is too long.
+ if (*fmt_p == STL_TRUNCMARK) {
+ fmt_p++;
item[curitem].type = Trunc;
- item[curitem++].start = p;
+ item[curitem++].start = out_p;
continue;
}
- if (*s == ')') {
- s++;
- if (groupdepth < 1)
+
+ // The end of a grouping
+ if (*fmt_p == ')') {
+ fmt_p++;
+ // Ignore if we are not actually inside a group currently
+ if (groupdepth < 1) {
continue;
+ }
groupdepth--;
- t = item[groupitem[groupdepth]].start;
- *p = NUL;
- l = vim_strsize(t);
+ // Determine how long the group is.
+ // Note: We set the current output position to null
+ // so `vim_strsize` will work.
+ char_u *t = item[groupitem[groupdepth]].start;
+ *out_p = NUL;
+ long group_len = vim_strsize(t);
+
+ // If the group contained internal items
+ // and the group did not have a minimum width,
+ // and if there were no normal items in the group,
+ // move the output pointer back to where the group started.
+ // Note: This erases any non-item characters that were in the group.
+ // Otherwise there would be no reason to do this step.
if (curitem > groupitem[groupdepth] + 1
&& item[groupitem[groupdepth]].minwid == 0) {
- /* remove group if all items are empty */
- for (n = groupitem[groupdepth] + 1; n < curitem; n++)
- if (item[n].type == Normal)
+ bool has_normal_items = false;
+ for (long n = groupitem[groupdepth] + 1; n < curitem; n++) {
+ if (item[n].type == Normal) {
+ has_normal_items = true;
break;
- if (n == curitem) {
- p = t;
- l = 0;
+ }
+ }
+
+ if (!has_normal_items) {
+ out_p = t;
+ group_len = 0;
}
}
- if (l > item[groupitem[groupdepth]].maxwid) {
- /* truncate, remove n bytes of text at the start */
+
+ // If the group is longer than it is allowed to be
+ // truncate by removing bytes from the start of the group text.
+ if (group_len > item[groupitem[groupdepth]].maxwid) {
+ // { Determine the number of bytes to remove
+ long n;
if (has_mbyte) {
/* Find the first character that should be included. */
n = 0;
- while (l >= item[groupitem[groupdepth]].maxwid) {
- l -= ptr2cells(t + n);
+ while (group_len >= item[groupitem[groupdepth]].maxwid) {
+ group_len -= ptr2cells(t + n);
n += (*mb_ptr2len)(t + n);
}
- } else
- n = (long)(p - t) - item[groupitem[groupdepth]].maxwid + 1;
+ } else {
+ n = (long)(out_p - t) - item[groupitem[groupdepth]].maxwid + 1;
+ }
+ // }
+ // Prepend the `<` to indicate that the output was truncated.
*t = '<';
- memmove(t + 1, t + n, (size_t)(p - (t + n)));
- p = p - n + 1;
+
+ // { Move the truncated output
+ memmove(t + 1, t + n, (size_t)(out_p - (t + n)));
+ out_p = out_p - n + 1;
/* Fill up space left over by half a double-wide char. */
- while (++l < item[groupitem[groupdepth]].minwid)
- *p++ = fillchar;
+ while (++group_len < item[groupitem[groupdepth]].minwid)
+ *out_p++ = fillchar;
+ // }
/* correct the start of the items for the truncation */
- for (l = groupitem[groupdepth] + 1; l < curitem; l++) {
- item[l].start -= n;
- if (item[l].start < t)
- item[l].start = t;
+ for (int idx = groupitem[groupdepth] + 1; idx < curitem; idx++) {
+ // Shift everything back by the number of removed bytes
+ item[idx].start -= n;
+
+ // If the item was partially or completely truncated, set its
+ // start to the start of the group
+ if (item[idx].start < t) {
+ item[idx].start = t;
+ }
}
- } else if (abs(item[groupitem[groupdepth]].minwid) > l) {
- /* fill */
- n = item[groupitem[groupdepth]].minwid;
- if (n < 0) {
- /* fill by appending characters */
- n = 0 - n;
- while (l++ < n && p + 1 < out + outlen)
- *p++ = fillchar;
+ // If the group is shorter than the minimum width, add padding characters.
+ } else if (abs(item[groupitem[groupdepth]].minwid) > group_len) {
+ long min_group_width = item[groupitem[groupdepth]].minwid;
+ // If the group is left-aligned, add characters to the right.
+ if (min_group_width < 0) {
+ min_group_width = 0 - min_group_width;
+ while (group_len++ < min_group_width && out_p < out_end_p)
+ *out_p++ = fillchar;
+ // If the group is right-aligned, shift everything to the right and
+ // prepend with filler characters.
} else {
- /* fill by inserting characters */
- memmove(t + n - l, t, (size_t)(p - t));
- l = n - l;
- if (p + l >= out + outlen)
- l = (long)((out + outlen) - p - 1);
- p += l;
- for (n = groupitem[groupdepth] + 1; n < curitem; n++)
- item[n].start += l;
- for (; l > 0; l--)
+ // { Move the group to the right
+ memmove(t + min_group_width - group_len, t, (size_t)(out_p - t));
+ group_len = min_group_width - group_len;
+ if (out_p + group_len >= (out_end_p + 1)) {
+ group_len = (long)(out_end_p - out_p);
+ }
+ out_p += group_len;
+ // }
+
+ // Adjust item start positions
+ for (int n = groupitem[groupdepth] + 1; n < curitem; n++) {
+ item[n].start += group_len;
+ }
+
+ // Prepend the fill characters
+ for (; group_len > 0; group_len--) {
*t++ = fillchar;
+ }
}
}
continue;
}
- minwid = 0;
- maxwid = 9999;
- zeropad = FALSE;
- l = 1;
- if (*s == '0') {
- s++;
- zeropad = TRUE;
+ int minwid = 0;
+ int maxwid = 9999;
+ bool left_align = false;
+
+ // Denotes that numbers should be left-padded with zeros
+ bool zeropad = (*fmt_p == '0');
+ if (zeropad) {
+ fmt_p++;
}
- if (*s == '-') {
- s++;
- l = -1;
+
+ // Denotes that the item should be left-aligned.
+ // This is tracked by using a negative length.
+ if (*fmt_p == '-') {
+ fmt_p++;
+ left_align = true;
}
- if (ascii_isdigit(*s)) {
- minwid = getdigits_int(&s);
+
+ // The first digit group is the item's min width
+ if (ascii_isdigit(*fmt_p)) {
+ minwid = getdigits_int(&fmt_p);
if (minwid < 0) /* overflow */
minwid = 0;
}
- if (*s == STL_USER_HL) {
+
+ // User highlight groups override the min width field
+ // to denote the styling to use.
+ if (*fmt_p == STL_USER_HL) {
item[curitem].type = Highlight;
- item[curitem].start = p;
+ item[curitem].start = out_p;
item[curitem].minwid = minwid > 9 ? 1 : minwid;
- s++;
+ fmt_p++;
curitem++;
continue;
}
- if (*s == STL_TABPAGENR || *s == STL_TABCLOSENR) {
- if (*s == STL_TABCLOSENR) {
+
+ // TABPAGE pairs are used to denote a region that when clicked will
+ // either switch to or close a tab.
+ //
+ // Ex: tabline=%0Ttab\ zero%X
+ // This tabline has a TABPAGENR item with minwid `0`,
+ // which is then closed with a TABCLOSENR item.
+ // Clicking on this region with mouse enabled will switch to tab 0.
+ // Setting the minwid to a different value will switch
+ // to that tab, if it exists
+ //
+ // Ex: tabline=%1Xtab\ one%X
+ // This tabline has a TABCLOSENR item with minwid `1`,
+ // which is then closed with a TABCLOSENR item.
+ // Clicking on this region with mouse enabled will close tab 0.
+ // This is determined by the following formula:
+ // tab to close = (1 - minwid)
+ // This is because for TABPAGENR we use `minwid` = `tab number`.
+ // For TABCLOSENR we store the tab number as a negative value.
+ // Because 0 is a valid TABPAGENR value, we have to
+ // start our numbering at `-1`.
+ // So, `-1` corresponds to us wanting to close tab `0`
+ //
+ // Note: These options are only valid when creating a tabline.
+ if (*fmt_p == STL_TABPAGENR || *fmt_p == STL_TABCLOSENR) {
+ if (*fmt_p == STL_TABCLOSENR) {
if (minwid == 0) {
/* %X ends the close label, go back to the previously
* define tab label nr. */
- for (n = curitem - 1; n >= 0; --n)
+ for (long n = curitem - 1; n >= 0; --n)
if (item[n].type == TabPage && item[n].minwid >= 0) {
minwid = item[n].minwid;
break;
@@ -3066,54 +3164,70 @@ build_stl_str_hl (
minwid = -minwid;
}
item[curitem].type = TabPage;
- item[curitem].start = p;
+ item[curitem].start = out_p;
item[curitem].minwid = minwid;
- s++;
+ fmt_p++;
curitem++;
continue;
}
- if (*s == '.') {
- s++;
- if (ascii_isdigit(*s)) {
- maxwid = getdigits_int(&s);
+
+ // Denotes the end of the minwid
+ // the maxwid may follow immediately after
+ if (*fmt_p == '.') {
+ fmt_p++;
+ if (ascii_isdigit(*fmt_p)) {
+ maxwid = getdigits_int(&fmt_p);
if (maxwid <= 0) /* overflow */
maxwid = 50;
}
}
- minwid = (minwid > 50 ? 50 : minwid) * l;
- if (*s == '(') {
+
+ // Bound the minimum width at 50.
+ // Make the number negative to denote left alignment of the item
+ minwid = (minwid > 50 ? 50 : minwid) * (left_align ? -1 : 1);
+
+ // Denotes the start of a new group
+ if (*fmt_p == '(') {
groupitem[groupdepth++] = curitem;
item[curitem].type = Group;
- item[curitem].start = p;
+ item[curitem].start = out_p;
item[curitem].minwid = minwid;
item[curitem].maxwid = maxwid;
- s++;
+ fmt_p++;
curitem++;
continue;
}
- if (vim_strchr(STL_ALL, *s) == NULL) {
- s++;
+
+ // An invalid item was specified.
+ // Continue processing on the next character of the format string.
+ if (vim_strchr(STL_ALL, *fmt_p) == NULL) {
+ fmt_p++;
continue;
}
- opt = *s++;
-
- /* OK - now for the real work */
- base = 'D';
- itemisflag = FALSE;
- fillable = TRUE;
- num = -1;
- str = NULL;
+
+ // The status line item type
+ char_u opt = *fmt_p++;
+
+ // OK - now for the real work
+ NumberBase base = kNumBaseDecimal;
+ bool itemisflag = false;
+ bool fillable = true;
+ long num = -1;
+ char_u *str = NULL;
switch (opt) {
case STL_FILEPATH:
case STL_FULLPATH:
case STL_FILENAME:
- fillable = FALSE; /* don't change ' ' to fillchar */
- if (buf_spname(wp->w_buffer) != NULL)
+ {
+ // Set fillable to false to that ' ' in the filename will not
+ // get replaced with the fillchar
+ fillable = false;
+ if (buf_spname(wp->w_buffer) != NULL) {
STRLCPY(NameBuff, buf_spname(wp->w_buffer), MAXPATHL);
- else {
- t = (opt == STL_FULLPATH) ? wp->w_buffer->b_ffname
- : wp->w_buffer->b_fname;
- home_replace(wp->w_buffer, t, NameBuff, MAXPATHL, TRUE);
+ } else {
+ char_u *t = (opt == STL_FULLPATH) ? wp->w_buffer->b_ffname
+ : wp->w_buffer->b_fname;
+ home_replace(wp->w_buffer, t, NameBuff, MAXPATHL, true);
}
trans_characters(NameBuff, MAXPATHL);
if (opt != STL_FILENAME)
@@ -3121,42 +3235,59 @@ build_stl_str_hl (
else
str = path_tail(NameBuff);
break;
-
+ }
case STL_VIM_EXPR: /* '{' */
- itemisflag = TRUE;
- t = p;
- while (*s != '}' && *s != NUL && p + 1 < out + outlen)
- *p++ = *s++;
- if (*s != '}') /* missing '}' or out of space */
+ {
+ itemisflag = true;
+
+ // Attempt to copy the expression to evaluate into
+ // the output buffer as a null-terminated string.
+ char_u *t = out_p;
+ while (*fmt_p != '}' && *fmt_p != NUL && out_p < out_end_p)
+ *out_p++ = *fmt_p++;
+ if (*fmt_p != '}') /* missing '}' or out of space */
break;
- s++;
- *p = 0;
- p = t;
+ fmt_p++;
+ *out_p = 0;
+
+ // Move our position in the output buffer
+ // to the beginning of the expression
+ out_p = t;
+ // { Evaluate the expression
+
+ // Store the current buffer number as a string variable
vim_snprintf((char *)tmp, sizeof(tmp), "%d", curbuf->b_fnum);
set_internal_string_var((char_u *)"actual_curbuf", tmp);
- o_curbuf = curbuf;
- o_curwin = curwin;
+ buf_T *o_curbuf = curbuf;
+ win_T *o_curwin = curwin;
curwin = wp;
curbuf = wp->w_buffer;
- str = eval_to_string_safe(p, &t, use_sandbox);
+ // Note: The result stored in `t` is unused.
+ str = eval_to_string_safe(out_p, &t, use_sandbox);
curwin = o_curwin;
curbuf = o_curbuf;
- do_unlet((char_u *)"g:actual_curbuf", TRUE);
+ // Remove the variable we just stored
+ do_unlet((char_u *)"g:actual_curbuf", true);
+
+ // }
+
+ // Check if the evaluated result is a number.
+ // If so, convert the number to an int and free the string.
if (str != NULL && *str != 0) {
if (*skipdigits(str) == NUL) {
num = atoi((char *)str);
xfree(str);
str = NULL;
- itemisflag = FALSE;
+ itemisflag = false;
}
}
break;
-
+ }
case STL_LINE:
num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY)
? 0L : (long)(wp->w_cursor.lnum);
@@ -3173,21 +3304,23 @@ build_stl_str_hl (
case STL_VIRTCOL:
case STL_VIRTCOL_ALT:
- /* In list mode virtcol needs to be recomputed */
- virtcol = wp->w_virtcol;
+ {
+ // In list mode virtcol needs to be recomputed
+ colnr_T virtcol = wp->w_virtcol;
if (wp->w_p_list && lcs_tab1 == NUL) {
wp->w_p_list = FALSE;
getvcol(wp, &wp->w_cursor, NULL, &virtcol, NULL);
wp->w_p_list = TRUE;
}
++virtcol;
- /* Don't display %V if it's the same as %c. */
+ // Don't display %V if it's the same as %c.
if (opt == STL_VIRTCOL_ALT
&& (virtcol == (colnr_T)(!(State & INSERT) && empty_line
? 0 : (int)wp->w_cursor.col + 1)))
break;
num = (long)virtcol;
break;
+ }
case STL_PERCENTAGE:
num = (int)(((long)wp->w_cursor.lnum * 100L) /
@@ -3195,19 +3328,31 @@ build_stl_str_hl (
break;
case STL_ALTPERCENT:
+ // Store the position percentage in our temporary buffer.
+ // Note: We cannot store the value in `num` because
+ // `get_rel_pos` can return a named position. Ex: "Top"
+ get_rel_pos(wp, tmp, TMPLEN);
str = tmp;
- get_rel_pos(wp, str, TMPLEN);
break;
case STL_ARGLISTSTAT:
- fillable = FALSE;
+ fillable = false;
+
+ // Note: This is important because `append_arg_number` starts appending
+ // at the end of the null-terminated string.
+ // Setting the first byte to null means it will place the argument
+ // number string at the beginning of the buffer.
tmp[0] = 0;
- if (append_arg_number(wp, tmp, (int)sizeof(tmp), FALSE))
+
+ // Note: The call will only return true if it actually
+ // appended data to the `tmp` buffer.
+ if (append_arg_number(wp, tmp, (int)sizeof(tmp), false)) {
str = tmp;
+ }
break;
case STL_KEYMAP:
- fillable = FALSE;
+ fillable = false;
if (get_keymap_str(wp, tmp, TMPLEN))
str = tmp;
break;
@@ -3220,16 +3365,17 @@ build_stl_str_hl (
break;
case STL_OFFSET_X:
- base = 'X';
+ base = kNumBaseHexadecimal;
case STL_OFFSET:
- l = ml_find_line_or_offset(wp->w_buffer, wp->w_cursor.lnum, NULL);
+ {
+ long l = ml_find_line_or_offset(wp->w_buffer, wp->w_cursor.lnum, NULL);
num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY) || l < 0 ?
0L : l + 1 + (!(State & INSERT) && empty_line ?
0 : (int)wp->w_cursor.col);
break;
-
+ }
case STL_BYTEVAL_X:
- base = 'X';
+ base = kNumBaseHexadecimal;
case STL_BYTEVAL:
num = byteval;
if (num == NL)
@@ -3240,20 +3386,23 @@ build_stl_str_hl (
case STL_ROFLAG:
case STL_ROFLAG_ALT:
- itemisflag = TRUE;
+ itemisflag = true;
if (wp->w_buffer->b_p_ro)
str = (char_u *)((opt == STL_ROFLAG_ALT) ? ",RO" : _("[RO]"));
break;
case STL_HELPFLAG:
case STL_HELPFLAG_ALT:
- itemisflag = TRUE;
+ itemisflag = true;
if (wp->w_buffer->b_help)
str = (char_u *)((opt == STL_HELPFLAG_ALT) ? ",HLP"
: _("[Help]"));
break;
case STL_FILETYPE:
+ // Copy the filetype if it is not null and the formatted string will fit
+ // in the temporary buffer
+ // (including the brackets and null terminating character)
if (*wp->w_buffer->b_p_ft != NUL
&& STRLEN(wp->w_buffer->b_p_ft) < TMPLEN - 3) {
vim_snprintf((char *)tmp, sizeof(tmp), "[%s]",
@@ -3263,20 +3412,26 @@ build_stl_str_hl (
break;
case STL_FILETYPE_ALT:
- itemisflag = TRUE;
+ {
+ itemisflag = true;
+ // Copy the filetype if it is not null and the formatted string will fit
+ // in the temporary buffer
+ // (including the comma and null terminating character)
if (*wp->w_buffer->b_p_ft != NUL
&& STRLEN(wp->w_buffer->b_p_ft) < TMPLEN - 2) {
vim_snprintf((char *)tmp, sizeof(tmp), ",%s",
wp->w_buffer->b_p_ft);
- for (t = tmp; *t != 0; t++)
+ // Uppercase the file extension
+ for (char_u *t = tmp; *t != 0; t++) {
*t = TOUPPER_LOC(*t);
+ }
str = tmp;
}
break;
-
+ }
case STL_PREVIEWFLAG:
case STL_PREVIEWFLAG_ALT:
- itemisflag = TRUE;
+ itemisflag = true;
if (wp->w_p_pvw)
str = (char_u *)((opt == STL_PREVIEWFLAG_ALT) ? ",PRV"
: _("[Preview]"));
@@ -3291,7 +3446,7 @@ build_stl_str_hl (
case STL_MODIFIED:
case STL_MODIFIED_ALT:
- itemisflag = TRUE;
+ itemisflag = true;
switch ((opt == STL_MODIFIED_ALT)
+ bufIsChanged(wp->w_buffer) * 2
+ (!MODIFIABLE(wp->w_buffer)) * 4) {
@@ -3305,212 +3460,360 @@ build_stl_str_hl (
break;
case STL_HIGHLIGHT:
- t = s;
- while (*s != '#' && *s != NUL)
- ++s;
- if (*s == '#') {
+ {
+ // { The name of the highlight is surrounded by `#`
+ char_u *t = fmt_p;
+ while (*fmt_p != '#' && *fmt_p != NUL) {
+ ++fmt_p;
+ }
+ // }
+
+ // Create a highlight item based on the name
+ if (*fmt_p == '#') {
item[curitem].type = Highlight;
- item[curitem].start = p;
- item[curitem].minwid = -syn_namen2id(t, (int)(s - t));
+ item[curitem].start = out_p;
+ item[curitem].minwid = -syn_namen2id(t, (int)(fmt_p - t));
curitem++;
+ fmt_p++;
}
- if (*s != NUL)
- ++s;
continue;
}
+ }
- item[curitem].start = p;
+ // If we made it this far, the item is normal and starts at
+ // our current position in the output buffer.
+ // Non-normal items would have `continued`.
+ item[curitem].start = out_p;
item[curitem].type = Normal;
+
+ // Copy the item string into the output buffer
if (str != NULL && *str) {
- t = str;
+ // { Skip the leading `,` or ` ` if the item is a flag
+ // and the proper conditions are met
+ char_u *t = str;
if (itemisflag) {
if ((t[0] && t[1])
&& ((!prevchar_isitem && *t == ',')
|| (prevchar_isflag && *t == ' ')))
t++;
- prevchar_isflag = TRUE;
+ prevchar_isflag = true;
+ }
+ // }
+
+ long l = vim_strsize(t);
+
+ // If this item is non-empty, record that the last thing
+ // we put in the output buffer was an item
+ if (l > 0) {
+ prevchar_isitem = true;
}
- l = vim_strsize(t);
- if (l > 0)
- prevchar_isitem = TRUE;
+
+ // If the item is too wide, truncate it from the beginning
if (l > maxwid) {
while (l >= maxwid)
if (has_mbyte) {
l -= ptr2cells(t);
t += (*mb_ptr2len)(t);
- } else
+ } else {
l -= byte2cells(*t++);
- if (p + 1 >= out + outlen)
+ }
+
+ // Early out if there isn't enough room for the truncation marker
+ if (out_p >= out_end_p)
break;
- *p++ = '<';
+
+ // Add the truncation marker
+ *out_p++ = '<';
}
+
+ // If the item is right aligned and not wide enough,
+ // pad with fill characters.
if (minwid > 0) {
- for (; l < minwid && p + 1 < out + outlen; l++) {
- /* Don't put a "-" in front of a digit. */
+ for (; l < minwid && out_p < out_end_p; l++) {
+ // Don't put a "-" in front of a digit.
if (l + 1 == minwid && fillchar == '-' && ascii_isdigit(*t))
- *p++ = ' ';
+ *out_p++ = ' ';
else
- *p++ = fillchar;
+ *out_p++ = fillchar;
}
minwid = 0;
- } else
+ } else {
+ // Note: The negative value denotes a left aligned item.
+ // Here we switch the minimum width back to a positive value.
minwid *= -1;
- while (*t && p + 1 < out + outlen) {
- *p++ = *t++;
- /* Change a space by fillchar, unless fillchar is '-' and a
- * digit follows. */
- if (fillable && p[-1] == ' '
+ }
+
+ // { Copy the string text into the output buffer
+ while (*t && out_p < out_end_p) {
+ *out_p++ = *t++;
+ // Change a space by fillchar, unless fillchar is '-' and a
+ // digit follows.
+ if (fillable && out_p[-1] == ' '
&& (!ascii_isdigit(*t) || fillchar != '-'))
- p[-1] = fillchar;
+ out_p[-1] = fillchar;
+ }
+ // }
+
+ // For left-aligned items, fill any remaining space with the fillchar
+ for (; l < minwid && out_p < out_end_p; l++) {
+ *out_p++ = fillchar;
}
- for (; l < minwid && p + 1 < out + outlen; l++)
- *p++ = fillchar;
- } else if (num >= 0) {
- int nbase = (base == 'D' ? 10 : (base == 'O' ? 8 : 16));
- char_u nstr[20];
- if (p + 20 >= out + outlen)
+ // Otherwise if the item is a number, copy that to the output buffer.
+ } else if (num >= 0) {
+ if (out_p + 20 > out_end_p)
break; /* not sufficient space */
- prevchar_isitem = TRUE;
- t = nstr;
+ prevchar_isitem = true;
+
+ // { Build the formatting string
+ char_u nstr[20];
+ char_u *t = nstr;
if (opt == STL_VIRTCOL_ALT) {
*t++ = '-';
minwid--;
}
*t++ = '%';
- if (zeropad)
+ if (zeropad) {
*t++ = '0';
+ }
+
+ // Note: The `*` means we take the width as one of the arguments
*t++ = '*';
- *t++ = nbase == 16 ? base : (char_u)(nbase == 8 ? 'o' : 'd');
+ *t++ = (char_u) (base == kNumBaseHexadecimal ? 'X'
+ : (base == kNumBaseOctal ? 'o'
+ : 'd'));
*t = 0;
+ // }
+
+ // { Determine how many characters the number will take up when printed
+ // Note: We have to cast the base because the compiler uses
+ // unsigned ints for the enum values.
+ long num_chars = 1;
+ for (long n = num; n >= (int) base; n /= (int) base) {
+ num_chars++;
+ }
- for (n = num, l = 1; n >= nbase; n /= nbase)
- l++;
- if (opt == STL_VIRTCOL_ALT)
- l++;
- if (l > maxwid) {
- l += 2;
- n = l - maxwid;
- while (l-- > maxwid)
- num /= nbase;
+ // VIRTCOL_ALT takes up an extra character because
+ // of the `-` we added above.
+ if (opt == STL_VIRTCOL_ALT) {
+ num_chars++;
+ }
+ // }
+
+ size_t remaining_buf_len = (out_end_p - out_p) + 1;
+
+ // If the number is going to take up too much room
+ // Figure out the approximate number in "scientific" type notation.
+ // Ex: 14532 with maxwid of 4 -> '14>3'
+ if (num_chars > maxwid) {
+ // Add two to the width because the power piece will take
+ // two extra characters
+ num_chars += 2;
+
+ // How many extra characters there are
+ long n = num_chars - maxwid;
+
+ // { Reduce the number by base^n
+ while (num_chars-- > maxwid) {
+ num /= base;
+ }
+ // }
+
+ // { Add the format string for the exponent bit
*t++ = '>';
*t++ = '%';
+ // Use the same base as the first number
*t = t[-3];
*++t = 0;
- vim_snprintf((char *)p, outlen - (p - out), (char *)nstr,
+ // }
+
+ vim_snprintf((char *)out_p, remaining_buf_len, (char *)nstr,
0, num, n);
- } else
- vim_snprintf((char *)p, outlen - (p - out), (char *)nstr,
+ } else {
+ vim_snprintf((char *)out_p, remaining_buf_len, (char *)nstr,
minwid, num);
- p += STRLEN(p);
- } else
+ }
+
+ // Advance the output buffer position to the end of the
+ // number we just printed
+ out_p += STRLEN(out_p);
+
+ // Otherwise, there was nothing to print so mark the item as empty
+ } else {
item[curitem].type = Empty;
+ }
- if (opt == STL_VIM_EXPR)
+ // Only free the string buffer if we allocated it.
+ // Note: This is not needed if `str` is pointing at `tmp`
+ if (opt == STL_VIM_EXPR) {
xfree(str);
+ }
if (num >= 0 || (!itemisflag && str && *str))
- prevchar_isflag = FALSE; /* Item not NULL, but not a flag */
+ prevchar_isflag = false; /* Item not NULL, but not a flag */
+
+ // Item processed, move to the next
curitem++;
}
- *p = NUL;
- itemcnt = curitem;
- if (usefmt != fmt)
+ *out_p = NUL;
+ int itemcnt = curitem;
+
+ // Free the format buffer if we allocated it internally
+ if (usefmt != fmt) {
xfree(usefmt);
+ }
+
+ // We have now processed the entire statusline format string.
+ // What follows is post-processing to handle alignment and
+ // highlighting factors.
- width = vim_strsize(out);
+ int width = vim_strsize(out);
if (maxwidth > 0 && width > maxwidth) {
- /* Result is too long, must truncate somewhere. */
- l = 0;
- if (itemcnt == 0)
- s = out;
- else {
- for (; l < itemcnt; l++)
- if (item[l].type == Trunc) {
- /* Truncate at %< item. */
- s = item[l].start;
+ // Result is too long, must truncate somewhere.
+ int item_idx = 0;
+ char_u *trunc_p;
+
+ // If there are no items, truncate from beginning
+ if (itemcnt == 0) {
+ trunc_p = out;
+
+ // Otherwise, look for the truncation item
+ } else {
+ // Default to truncating at the first item
+ trunc_p = item[0].start;
+ item_idx = 0;
+
+ for (int i = 0; i < itemcnt; i++)
+ if (item[i].type == Trunc) {
+ // Truncate at %< item.
+ trunc_p = item[i].start;
+ item_idx = i;
break;
}
- if (l == itemcnt) {
- /* No %< item, truncate first item. */
- s = item[0].start;
- l = 0;
- }
}
- if (width - vim_strsize(s) >= maxwidth) {
- /* Truncation mark is beyond max length */
+ // If the truncation point we found is beyond the maximum
+ // length of the string, truncate the end of the string.
+ if (width - vim_strsize(trunc_p) >= maxwidth) {
+ // If we are using a multi-byte encoding, walk from the beginning of the
+ // string to find the last character that will fit.
if (has_mbyte) {
- s = out;
+ trunc_p = out;
width = 0;
for (;; ) {
- width += ptr2cells(s);
+ width += ptr2cells(trunc_p);
if (width >= maxwidth)
break;
- s += (*mb_ptr2len)(s);
+
+ // Note: Only advance the pointer if the next
+ // character will fit in the available output space
+ trunc_p += (*mb_ptr2len)(trunc_p);
}
- /* Fill up for half a double-wide character. */
- while (++width < maxwidth)
- *s++ = fillchar;
- } else
- s = out + maxwidth - 1;
- for (l = 0; l < itemcnt; l++)
- if (item[l].start > s)
+
+ // Otherwise put the truncation point at the end, leaving enough room
+ // for a single-character truncation marker
+ } else {
+ trunc_p = out + maxwidth - 1;
+ }
+
+ // Ignore any items in the statusline that occur after
+ // the truncation point
+ for (int i = 0; i < itemcnt; i++) {
+ if (item[i].start > trunc_p) {
+ itemcnt = i;
break;
- itemcnt = l;
- *s++ = '>';
- *s = 0;
+ }
+ }
+
+ // Truncate the output
+ *trunc_p++ = '>';
+ *trunc_p = 0;
+
+ // Truncate at the truncation point we found
} else {
+ // { Determine how many bytes to remove
+ long trunc_len;
if (has_mbyte) {
- n = 0;
+ trunc_len = 0;
while (width >= maxwidth) {
- width -= ptr2cells(s + n);
- n += (*mb_ptr2len)(s + n);
+ width -= ptr2cells(trunc_p + trunc_len);
+ trunc_len += (*mb_ptr2len)(trunc_p + trunc_len);
}
- } else
- n = width - maxwidth + 1;
- p = s + n;
- STRMOVE(s + 1, p);
- *s = '<';
+ } else {
+ // Truncate an extra character so we can insert our `<`.
+ trunc_len = (width - maxwidth) + 1;
+ }
+ // }
- /* Fill up for half a double-wide character. */
+ // { Truncate the string
+ char_u *trunc_end_p = trunc_p + trunc_len;
+ STRMOVE(trunc_p + 1, trunc_end_p);
+
+ // 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);
+
+ // Fill up for half a double-wide character.
while (++width < maxwidth) {
- s = s + STRLEN(s);
- *s++ = fillchar;
- *s = NUL;
+ *trunc_p++ = fillchar;
+ *trunc_p = NUL;
}
-
- --n; /* count the '<' */
- for (; l < itemcnt; l++) {
- if (item[l].start - n >= s)
- item[l].start -= n;
- else
- item[l].start = s;
+ // }
+
+ // { Change the start point for items based on
+ // their position relative to our truncation point
+
+ // Note: The offset is one less than the truncation length because
+ // the truncation marker `<` is not counted.
+ long item_offset = trunc_len - 1;
+
+ for (int i = item_idx; i < itemcnt; i++) {
+ // Items starting at or after the end of the truncated section need
+ // to be moved backwards.
+ if (item[i].start >= trunc_end_p) {
+ item[i].start -= item_offset;
+ // Anything inside the truncated area is set to start
+ // at the `<` truncation character.
+ } else {
+ item[i].start = trunc_p;
+ }
}
+ // }
}
width = maxwidth;
- } else if (width < maxwidth && STRLEN(out) + maxwidth - width + 1 <
- outlen) {
- /* Apply STL_MIDDLE if any */
- for (l = 0; l < itemcnt; l++)
- if (item[l].type == Middle)
+
+ // If there is room left in our statusline, and room left in our buffer,
+ // add characters at the middle marker (if there is one) to
+ // fill up the available space.
+ } else if (width < maxwidth
+ && STRLEN(out) + maxwidth - width + 1 < outlen) {
+ for (int item_idx = 0; item_idx < itemcnt; item_idx++) {
+ if (item[item_idx].type == Middle) {
+ // Move the statusline to make room for the middle characters
+ char_u *middle_end = item[item_idx].start + (maxwidth - width);
+ STRMOVE(middle_end, item[item_idx].start);
+
+ // Fill the middle section with our fill character
+ for (char_u *s = item[item_idx].start; s < middle_end; s++)
+ *s = fillchar;
+
+ // Adjust the offset of any items after the middle
+ for (item_idx++; item_idx < itemcnt; item_idx++)
+ item[item_idx].start += maxwidth - width;
+
+ width = maxwidth;
break;
- if (l < itemcnt) {
- p = item[l].start + maxwidth - width;
- STRMOVE(p, item[l].start);
- for (s = item[l].start; s < p; s++)
- *s = fillchar;
- for (l++; l < itemcnt; l++)
- item[l].start += maxwidth - width;
- width = maxwidth;
+ }
}
}
- /* Store the info about highlighting. */
+ // Store the info about highlighting.
if (hltab != NULL) {
- sp = hltab;
- for (l = 0; l < itemcnt; l++) {
+ struct stl_hlrec *sp = hltab;
+ for (long l = 0; l < itemcnt; l++) {
if (item[l].type == Highlight) {
sp->start = item[l].start;
sp->userhl = item[l].minwid;
@@ -3521,10 +3824,10 @@ build_stl_str_hl (
sp->userhl = 0;
}
- /* Store the info about tab pages labels. */
+ // Store the info about tab pages labels.
if (tabtab != NULL) {
- sp = tabtab;
- for (l = 0; l < itemcnt; l++) {
+ struct stl_hlrec *sp = tabtab;
+ for (long l = 0; l < itemcnt; l++) {
if (item[l].type == TabPage) {
sp->start = item[l].start;
sp->userhl = item[l].minwid;
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index 6e2b3056e4..d311588ab4 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -2,7 +2,6 @@
///
/// Code for diff'ing two, three or four buffers.
-#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index abd16e57ae..08b587df8a 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
@@ -11,7 +11,6 @@
*/
#include <assert.h>
-#include <errno.h>
#include <string.h>
#include <inttypes.h>
#include <stdbool.h>
@@ -977,6 +976,14 @@ static int insert_handle_key(InsertState *s)
queue_process_events(loop.events);
break;
+ case K_FOCUSGAINED: // Neovim has been given focus
+ apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf);
+ break;
+
+ case K_FOCUSLOST: // Neovim has lost focus
+ apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf);
+ break;
+
case K_HOME: // <Home>
case K_KHOME:
case K_S_HOME:
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 9581b81456..cec7c91c03 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -4,7 +4,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
@@ -12,7 +12,6 @@
*/
#include <assert.h>
-#include <errno.h>
#include <inttypes.h>
#include <stdarg.h>
#include <string.h>
diff --git a/src/nvim/event/socket.c b/src/nvim/event/socket.c
index 347e464d25..93cc592683 100644
--- a/src/nvim/event/socket.c
+++ b/src/nvim/event/socket.c
@@ -97,7 +97,7 @@ int socket_watcher_start(SocketWatcher *watcher, int backlog, socket_cb cb)
result = uv_listen(watcher->stream, backlog, connection_cb);
}
- assert(result <= 0); // libuv should have returned -errno or zero.
+ assert(result <= 0); // libuv should return negative error code or zero.
if (result < 0) {
if (result == -EACCES) {
// Libuv converts ENOENT to EACCES for Windows compatibility, but if
diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c
index 376eb9fce7..71582ab357 100644
--- a/src/nvim/event/stream.c
+++ b/src/nvim/event/stream.c
@@ -13,7 +13,7 @@
/// Sets the stream associated with `fd` to "blocking" mode.
///
-/// @return `0` on success, or `-errno` on failure.
+/// @return `0` on success, or libuv error code on failure.
int stream_set_blocking(int fd, bool blocking)
{
// Private loop to avoid conflict with existing watcher(s):
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index c4fffcda71..f69910eb99 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
@@ -11,7 +11,6 @@
*/
#include <assert.h>
-#include <errno.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua
index 79b53b9fb5..b7a3505c99 100644
--- a/src/nvim/ex_cmds.lua
+++ b/src/nvim/ex_cmds.lua
@@ -989,13 +989,13 @@ return {
command='gui',
flags=bit.bor(BANG, FILES, EDITCMD, ARGOPT, TRLBAR, CMDWIN),
addr_type=ADDR_LINES,
- func='ex_gui',
+ func='ex_nogui',
},
{
command='gvim',
flags=bit.bor(BANG, FILES, EDITCMD, ARGOPT, TRLBAR, CMDWIN),
addr_type=ADDR_LINES,
- func='ex_gui',
+ func='ex_nogui',
},
{
command='help',
@@ -1013,7 +1013,7 @@ return {
command='helpfind',
flags=bit.bor(EXTRA, NOTRLCOM),
addr_type=ADDR_LINES,
- func='ex_helpfind',
+ func='ex_ni',
},
{
command='helpgrep',
@@ -1643,19 +1643,19 @@ return {
command='nbkey',
flags=bit.bor(EXTRA, NOTADR, NEEDARG),
addr_type=ADDR_LINES,
- func='ex_nbkey',
+ func='ex_ni',
},
{
command='nbclose',
flags=bit.bor(TRLBAR, CMDWIN),
addr_type=ADDR_LINES,
- func='ex_nbclose',
+ func='ex_ni',
},
{
command='nbstart',
flags=bit.bor(WORD1, TRLBAR, CMDWIN),
addr_type=ADDR_LINES,
- func='ex_nbstart',
+ func='ex_ni',
},
{
command='new',
@@ -1859,7 +1859,7 @@ return {
command='popup',
flags=bit.bor(NEEDARG, EXTRA, BANG, TRLBAR, NOTRLCOM, CMDWIN),
addr_type=ADDR_LINES,
- func='ex_popup',
+ func='ex_ni',
},
{
command='ppop',
@@ -1883,13 +1883,13 @@ return {
command='promptfind',
flags=bit.bor(EXTRA, NOTRLCOM, CMDWIN),
addr_type=ADDR_LINES,
- func='gui_mch_find_dialog',
+ func='ex_ni',
},
{
command='promptrepl',
flags=bit.bor(EXTRA, NOTRLCOM, CMDWIN),
addr_type=ADDR_LINES,
- func='gui_mch_replace_dialog',
+ func='ex_ni',
},
{
command='profile',
@@ -2303,7 +2303,7 @@ return {
command='simalt',
flags=bit.bor(NEEDARG, WORD1, TRLBAR, CMDWIN),
addr_type=ADDR_LINES,
- func='ex_simalt',
+ func='ex_ni',
},
{
command='sign',
@@ -3029,7 +3029,7 @@ return {
command='wsverb',
flags=bit.bor(EXTRA, NOTADR, NEEDARG),
addr_type=ADDR_LINES,
- func='ex_wsverb',
+ func='ex_ni',
},
{
command='wshada',
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index a632a3cce4..bb629fad76 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
@@ -11,7 +11,6 @@
*/
#include <assert.h>
-#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 7b5e3939f2..b50c7330d3 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
@@ -14,7 +14,6 @@
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
-#include <errno.h>
#include <inttypes.h>
#include "nvim/vim.h"
@@ -80,6 +79,9 @@
static int quitmore = 0;
static int ex_pressedreturn = FALSE;
+/* whether ":lcd" was produced for a session */
+static int did_lcd;
+
typedef struct ucmd {
char_u *uc_name; /* The command name */
uint32_t uc_argt; /* The argument type */
@@ -144,23 +146,9 @@ struct dbg_stuff {
# include "ex_docmd.c.generated.h"
#endif
-# define ex_gui ex_nogui
-# define ex_popup ex_ni
-# define ex_simalt ex_ni
-# define gui_mch_find_dialog ex_ni
-# define gui_mch_replace_dialog ex_ni
-# define ex_helpfind ex_ni
-static int did_lcd; /* whether ":lcd" was produced for a session */
#ifndef HAVE_WORKING_LIBINTL
# define ex_language ex_ni
#endif
-# define ex_wsverb ex_ni
-# define ex_nbclose ex_ni
-# define ex_nbkey ex_ni
-# define ex_nbstart ex_ni
-
-
-
/*
* Declare cmdnames[].
diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c
index bea1aecb58..773005e72b 100644
--- a/src/nvim/ex_eval.c
+++ b/src/nvim/ex_eval.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 52292128d8..c9a324b49f 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
@@ -11,7 +11,6 @@
*/
#include <assert.h>
-#include <errno.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
@@ -1448,6 +1447,14 @@ static int command_line_handle_key(CommandLineState *s)
}
return command_line_not_changed(s);
+ case K_FOCUSGAINED: // Neovim has been given focus
+ apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf);
+ return command_line_not_changed(s);
+
+ case K_FOCUSLOST: // Neovim has lost focus
+ apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf);
+ return command_line_not_changed(s);
+
default:
// Normal character with no special meaning. Just set mod_mask
// to 0x0 so that typing Shift-Space in the GUI doesn't enter
diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c
index fbff7d2417..4f345158cf 100644
--- a/src/nvim/file_search.c
+++ b/src/nvim/file_search.c
@@ -45,7 +45,6 @@
*/
#include <assert.h>
-#include <errno.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index a7472b40e2..4aa4d4c399 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
@@ -535,11 +535,7 @@ readfile (
if (!newfile) {
return FAIL;
}
- if (perm < 0
-#ifdef ENOENT
- && errno == ENOENT
-#endif
- ) {
+ if (perm == UV_ENOENT) {
/*
* Set the 'new-file' flag, so that when the file has
* been created by someone else, a ":w" will complain.
@@ -582,11 +578,11 @@ readfile (
return OK; /* a new file is not an error */
} else {
filemess(curbuf, sfname, (char_u *)(
-# ifdef EFBIG
- (errno == EFBIG) ? _("[File too big]") :
-# endif
-# ifdef EOVERFLOW
- (errno == EOVERFLOW) ? _("[File too big]") :
+ (fd == UV_EFBIG) ? _("[File too big]") :
+# if defined(UNIX) && defined(EOVERFLOW)
+ // libuv only returns -errno in Unix and in Windows open() does not
+ // set EOVERFLOW
+ (fd == -EOVERFLOW) ? _("[File too big]") :
# endif
_("[Permission Denied]")), 0);
curbuf->b_p_ro = TRUE; /* must use "w!" now */
diff --git a/src/nvim/fold.c b/src/nvim/fold.c
index b52938075c..29921bc816 100644
--- a/src/nvim/fold.c
+++ b/src/nvim/fold.c
@@ -4,7 +4,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index b77a030158..3692fa27aa 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c
index 819015a85d..9f7431ee7d 100644
--- a/src/nvim/hardcopy.c
+++ b/src/nvim/hardcopy.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
@@ -11,7 +11,6 @@
*/
#include <assert.h>
-#include <errno.h>
#include <string.h>
#include <inttypes.h>
#include <stdint.h>
diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c
index e5cbb58608..578ae5de1e 100644
--- a/src/nvim/if_cscope.c
+++ b/src/nvim/if_cscope.c
@@ -5,7 +5,7 @@
* The basic idea/structure of cscope for Vim was borrowed from Nvi. There
* might be a few lines of code that look similar to what Nvi has.
*
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
#include <stdbool.h>
diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c
index 9d656276ec..85380ba173 100644
--- a/src/nvim/keymap.c
+++ b/src/nvim/keymap.c
@@ -284,6 +284,8 @@ static struct key_name_entry {
{K_SNR, (char_u *)"SNR"},
{K_PLUG, (char_u *)"Plug"},
{K_PASTE, (char_u *)"Paste"},
+ {K_FOCUSGAINED, (char_u *)"FocusGained"},
+ {K_FOCUSLOST, (char_u *)"FocusLost"},
{0, NULL}
};
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 83fe32cccb..203aeb8d69 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -3,12 +3,11 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
#define EXTERN
#include <assert.h>
-#include <errno.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index 0432ec5cef..38a76a45e6 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
@@ -11,7 +11,6 @@
*/
#include <assert.h>
-#include <errno.h>
#include <inttypes.h>
#include <string.h>
#include <limits.h>
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index 087d2e677c..fc7199e3a6 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -4,7 +4,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
* mbyte.c: Code specifically for handling multi-byte characters.
@@ -71,7 +71,6 @@
* some commands, like ":menutrans"
*/
-#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
diff --git a/src/nvim/memfile.c b/src/nvim/memfile.c
index b6a341d5e8..b2783736e1 100644
--- a/src/nvim/memfile.c
+++ b/src/nvim/memfile.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/// An abstraction to handle blocks of memory which can be stored in a file.
@@ -44,7 +44,6 @@
/// mf_fullname() make file name full path (use before first :cd)
#include <assert.h>
-#include <errno.h>
#include <inttypes.h>
#include <limits.h>
#include <string.h>
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index 85f545f960..e822a58273 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/* for debugging */
diff --git a/src/nvim/memory.c b/src/nvim/memory.c
index 6d386f3599..8db47b79c1 100644
--- a/src/nvim/memory.c
+++ b/src/nvim/memory.c
@@ -1,7 +1,6 @@
// Various routines dealing with allocation and deallocation of memory.
#include <assert.h>
-#include <errno.h>
#include <inttypes.h>
#include <string.h>
#include <stdbool.h>
diff --git a/src/nvim/menu.c b/src/nvim/menu.c
index 9857b8a778..3859ba5ec8 100644
--- a/src/nvim/menu.c
+++ b/src/nvim/menu.c
@@ -4,7 +4,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 5f06506a31..52e2a286c3 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
@@ -11,7 +11,6 @@
*/
#include <assert.h>
-#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdarg.h>
diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c
index 5097255880..0ba6929686 100644
--- a/src/nvim/misc1.c
+++ b/src/nvim/misc1.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
@@ -11,7 +11,6 @@
*/
#include <assert.h>
-#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
diff --git a/src/nvim/misc2.c b/src/nvim/misc2.c
index d9bc35470f..d72a8f17e0 100644
--- a/src/nvim/misc2.c
+++ b/src/nvim/misc2.c
@@ -3,14 +3,13 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
* misc2.c: Various functions.
*/
#include <assert.h>
-#include <errno.h>
#include <inttypes.h>
#include <string.h>
diff --git a/src/nvim/move.c b/src/nvim/move.c
index 3831004703..b44d3f2fd9 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
* move.c: Functions for moving the cursor and scrolling text.
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index d6bc416c91..a0d2c7903d 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
* normal.c: Contains the main routine for processing characters in command
@@ -12,7 +12,6 @@
*/
#include <assert.h>
-#include <errno.h>
#include <inttypes.h>
#include <string.h>
#include <stdbool.h>
@@ -349,6 +348,8 @@ static const struct nv_cmd {
{K_F8, farsi_fkey, 0, 0},
{K_F9, farsi_fkey, 0, 0},
{K_EVENT, nv_event, NV_KEEPREG, 0},
+ {K_FOCUSGAINED, nv_focusgained, NV_KEEPREG, 0},
+ {K_FOCUSLOST, nv_focuslost, NV_KEEPREG, 0},
};
/* Number of commands in nv_cmds[]. */
@@ -7715,6 +7716,18 @@ static void nv_event(cmdarg_T *cap)
cap->retval |= CA_COMMAND_BUSY; // don't call edit() now
}
+/// Trigger FocusGained event.
+static void nv_focusgained(cmdarg_T *cap)
+{
+ apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf);
+}
+
+/// Trigger FocusLost event.
+static void nv_focuslost(cmdarg_T *cap)
+{
+ apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf);
+}
+
/*
* Return TRUE when 'mousemodel' is set to "popup" or "popup_setpos".
*/
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 3fd2c0b773..6693ca23c8 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
diff --git a/src/nvim/option.c b/src/nvim/option.c
index cc4df28837..8b4aab88a3 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
@@ -30,7 +30,6 @@
#define IN_OPTION_C
#include <assert.h>
-#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdint.h>
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index 633eabab60..b22e994efe 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -51,15 +51,6 @@ return {
defaults={if_true={vi=224}}
},
{
- full_name='antialias', abbreviation='anti',
- type='bool', scope={'global'},
- vi_def=true,
- vim=true,
- redraw={'everything'},
- enable_if=false,
- defaults={if_true={vi=false, vim=false}}
- },
- {
full_name='arabic', abbreviation='arab',
type='bool', scope={'window'},
vi_def=true,
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index 3fb00eb24e..d59b66e773 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -185,13 +185,13 @@ static bool is_executable_in_path(const char_u *name, char_u **abspath)
/// Opens or creates a file and returns a non-negative integer representing
/// the lowest-numbered unused file descriptor, for use in subsequent system
-/// calls (read, write, lseek, fcntl, etc.). If the operation fails, `-errno`
-/// is returned, and no file is created or modified.
+/// calls (read, write, lseek, fcntl, etc.). If the operation fails, a libuv
+/// error code is returned, and no file is created or modified.
///
/// @param flags Bitwise OR of flags defined in <fcntl.h>
/// @param mode Permissions for the newly-created file (IGNORED if 'flags' is
/// not `O_CREAT` or `O_TMPFILE`), subject to the current umask
-/// @return file descriptor, or negative `errno` on failure
+/// @return file descriptor, or libuv error code on failure
int os_open(const char* path, int flags, int mode)
FUNC_ATTR_NONNULL_ALL
{
@@ -204,28 +204,29 @@ int os_open(const char* path, int flags, int mode)
/// Get stat information for a file.
///
-/// @return OK on success, FAIL if a failure occurred.
-static bool os_stat(const char *name, uv_stat_t *statbuf)
+/// @return libuv return code.
+static int os_stat(const char *name, uv_stat_t *statbuf)
FUNC_ATTR_NONNULL_ALL
{
uv_fs_t request;
int result = uv_fs_stat(&fs_loop, &request, name, NULL);
*statbuf = request.statbuf;
uv_fs_req_cleanup(&request);
- return (result == kLibuvSuccess);
+ return result;
}
/// Get the file permissions for a given file.
///
-/// @return `-1` when `name` doesn't exist.
+/// @return libuv error code on error.
int32_t os_getperm(const char_u *name)
FUNC_ATTR_NONNULL_ALL
{
uv_stat_t statbuf;
- if (os_stat((char *)name, &statbuf)) {
+ int stat_result = os_stat((char *)name, &statbuf);
+ if (stat_result == kLibuvSuccess) {
return (int32_t)statbuf.st_mode;
} else {
- return -1;
+ return stat_result;
}
}
@@ -270,7 +271,7 @@ bool os_file_exists(const char_u *name)
FUNC_ATTR_NONNULL_ALL
{
uv_stat_t statbuf;
- return os_stat((char *)name, &statbuf);
+ return os_stat((char *)name, &statbuf) == kLibuvSuccess;
}
/// Check if a file is readable.
@@ -322,7 +323,7 @@ int os_rename(const char_u *path, const char_u *new_path)
/// Make a directory.
///
-/// @return `0` for success, -errno for failure.
+/// @return `0` for success, libuv error code for failure.
int os_mkdir(const char *path, int32_t mode)
FUNC_ATTR_NONNULL_ALL
{
@@ -342,7 +343,7 @@ int os_mkdir(const char *path, int32_t mode)
/// failed to create. I.e. it will contain dir or any
/// of the higher level directories.
///
-/// @return `0` for success, -errno for failure.
+/// @return `0` for success, libuv error code for failure.
int os_mkdir_recurse(const char *const dir, int32_t mode,
char **const failed_dir)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
@@ -470,7 +471,7 @@ int os_remove(const char *path)
bool os_fileinfo(const char *path, FileInfo *file_info)
FUNC_ATTR_NONNULL_ALL
{
- return os_stat(path, &(file_info->stat));
+ return os_stat(path, &(file_info->stat)) == kLibuvSuccess;
}
/// Get the file information for a given path without following links
@@ -572,7 +573,7 @@ bool os_fileid(const char *path, FileID *file_id)
FUNC_ATTR_NONNULL_ALL
{
uv_stat_t statbuf;
- if (os_stat(path, &statbuf)) {
+ if (os_stat(path, &statbuf) == kLibuvSuccess) {
file_id->inode = statbuf.st_ino;
file_id->device_id = statbuf.st_dev;
return true;
diff --git a/src/nvim/os/fs_defs.h b/src/nvim/os/fs_defs.h
index df1031b721..52b2841514 100644
--- a/src/nvim/os/fs_defs.h
+++ b/src/nvim/os/fs_defs.h
@@ -21,9 +21,9 @@ typedef struct {
uv_dirent_t ent; ///< @private The entry information.
} Directory;
-/// Function to convert -errno error to char * error description
+/// Function to convert libuv error to char * error description
///
-/// -errno errors are returned by a number of os functions.
+/// negative libuv error codes are returned by a number of os functions.
#define os_strerror uv_strerror
#endif // NVIM_OS_FS_DEFS_H
diff --git a/src/nvim/os/os_defs.h b/src/nvim/os/os_defs.h
index 3d56115401..55a2d5513e 100644
--- a/src/nvim/os/os_defs.h
+++ b/src/nvim/os/os_defs.h
@@ -103,9 +103,9 @@
# include <strings.h>
#endif
-/// Function to convert -errno error to char * error description
+/// Function to convert libuv error to char * error description
///
-/// -errno errors are returned by a number of os functions.
+/// negative libuv error codes are returned by a number of os functions.
#define os_strerror uv_strerror
#endif // NVIM_OS_OS_DEFS_H
diff --git a/src/nvim/os/win_defs.h b/src/nvim/os/win_defs.h
index d614582250..bfd431c9c6 100644
--- a/src/nvim/os/win_defs.h
+++ b/src/nvim/os/win_defs.h
@@ -28,7 +28,9 @@
# endif
#endif
+#ifdef _MSC_VER
typedef SSIZE_T ssize_t;
+#endif
#ifndef SSIZE_MAX
# ifdef _WIN64
diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c
index 828ccd556d..ddb799f23d 100644
--- a/src/nvim/os_unix.c
+++ b/src/nvim/os_unix.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
diff --git a/src/nvim/path.c b/src/nvim/path.c
index eaca85ed40..a14ba38508 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.c
@@ -1,6 +1,5 @@
#include <assert.h>
-#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stdlib.h>
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 4d53238381..8be010c560 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
@@ -11,7 +11,6 @@
*/
#include <assert.h>
-#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 0c4cf30602..bea09fd804 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
@@ -87,7 +87,6 @@
*/
#include <assert.h>
-#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
diff --git a/src/nvim/search.c b/src/nvim/search.c
index a44b0e00c7..89c96fe31e 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -3,14 +3,13 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
* search.c: code for normal mode searching commands
*/
#include <assert.h>
-#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
@@ -4623,6 +4622,7 @@ void set_search_pattern(const SearchPattern pat)
{
free_spat(&spats[0]);
memcpy(&(spats[0]), &pat, sizeof(spats[0]));
+ set_vv_searchforward();
}
/// Set last substitute pattern
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index f8643fe655..e21c6f17fe 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -43,6 +43,7 @@
#include "nvim/path.h"
#include "nvim/fileio.h"
#include "nvim/strings.h"
+#include "nvim/quickfix.h"
#include "nvim/lib/khash.h"
#include "nvim/lib/kvec.h"
@@ -98,6 +99,7 @@ KHASH_SET_INIT_STR(strset)
#define SEARCH_KEY_HIGHLIGHTED "sh"
#define SEARCH_KEY_OFFSET "so"
#define SEARCH_KEY_PAT "sp"
+#define SEARCH_KEY_BACKWARD "sb"
#define REG_KEY_TYPE "rt"
#define REG_KEY_WIDTH "rw"
@@ -263,6 +265,7 @@ typedef struct {
bool is_last_used;
bool is_substitute_pattern;
bool highlighted;
+ bool search_backward;
char *pat;
dict_T *additional_data;
} search_pattern;
@@ -455,6 +458,7 @@ static const ShadaEntry sd_default_values[] = {
.is_last_used = true,
.is_substitute_pattern = false,
.highlighted = false,
+ .search_backward = false,
.pat = NULL,
.additional_data = NULL),
DEF_SDE(SubString, sub_string, .sub = NULL, .additional_elements = NULL),
@@ -812,7 +816,7 @@ static ShaDaReadResult sd_reader_skip(ShaDaReadDef *const sd_reader,
///
/// All arguments are passed to os_open().
///
-/// @return file descriptor or -errno on failure.
+/// @return file descriptor or libuv error on failure.
static int open_file(const char *const fname, const int flags, const int mode)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
@@ -822,15 +826,15 @@ open_file_start:
fd = os_open(fname, flags, mode);
if (fd < 0) {
- if (-fd == ENOENT) {
+ if (fd == UV_ENOENT) {
return fd;
}
- if (-fd == ENOMEM && !did_try_to_free) {
+ if (fd == UV_ENOMEM && !did_try_to_free) {
try_to_free_memory();
did_try_to_free = true;
goto open_file_start;
}
- if (-fd != EEXIST) {
+ if (fd != UV_EEXIST) {
emsg3(_(SERR "System error while opening ShaDa file %s: %s"),
fname, os_strerror(fd));
}
@@ -844,7 +848,7 @@ open_file_start:
/// @param[in] fname File name to open.
/// @param[out] sd_reader Location where reader structure will be saved.
///
-/// @return -errno in case of error, 0 otherwise.
+/// @return libuv error in case of error, 0 otherwise.
static int open_shada_file_for_reading(const char *const fname,
ShaDaReadDef *sd_reader)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
@@ -962,7 +966,7 @@ static int shada_read_file(const char *const file, const int flags)
}
if (of_ret != 0) {
- if (-of_ret == ENOENT && (flags & kShaDaMissingError)) {
+ if (of_ret == UV_ENOENT && (flags & kShaDaMissingError)) {
emsg3(_(SERR "System error while opening ShaDa file %s for reading: %s"),
fname, os_strerror(of_ret));
}
@@ -1338,6 +1342,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
.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,
@@ -1754,6 +1759,7 @@ static bool shada_pack_entry(msgpack_packer *const packer,
+ ONE_IF_NOT_DEFAULT(entry, search_pattern.is_substitute_pattern)
+ ONE_IF_NOT_DEFAULT(entry, search_pattern.highlighted)
+ ONE_IF_NOT_DEFAULT(entry, search_pattern.offset)
+ + ONE_IF_NOT_DEFAULT(entry, search_pattern.search_backward)
// finally, additional data:
+ (size_t) (
entry.data.search_pattern.additional_data
@@ -1780,6 +1786,7 @@ static bool shada_pack_entry(msgpack_packer *const packer,
PACK_BOOL(entry, SEARCH_KEY_PLACE_CURSOR_AT_END, place_cursor_at_end);
PACK_BOOL(entry, SEARCH_KEY_IS_SUBSTITUTE_PATTERN, is_substitute_pattern);
PACK_BOOL(entry, SEARCH_KEY_HIGHLIGHTED, highlighted);
+ PACK_BOOL(entry, SEARCH_KEY_BACKWARD, search_backward);
if (!CHECK_DEFAULT(entry, search_pattern.offset)) {
PACK_STATIC_STR(SEARCH_KEY_OFFSET);
msgpack_pack_int64(spacker, entry.data.search_pattern.offset);
@@ -2478,8 +2485,11 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
// Write buffer list
if (find_shada_parameter('%') != NULL) {
size_t buf_count = 0;
+#define IGNORE_BUF(buf)\
+ (buf->b_ffname == NULL || !buf->b_p_bl || bt_quickfix(buf) \
+ || in_bufset(&removable_bufs, buf))
FOR_ALL_BUFFERS(buf) {
- if (buf->b_ffname != NULL && !in_bufset(&removable_bufs, buf)) {
+ if (!IGNORE_BUF(buf)) {
buf_count++;
}
}
@@ -2497,7 +2507,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
};
size_t i = 0;
FOR_ALL_BUFFERS(buf) {
- if (buf->b_ffname == NULL || in_bufset(&removable_bufs, buf)) {
+ if (IGNORE_BUF(buf)) {
continue;
}
buflist_entry.data.buffer_list.buffers[i] = (struct buffer_list_buffer) {
@@ -2513,6 +2523,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
goto shada_write_exit;
}
xfree(buflist_entry.data.buffer_list.buffers);
+#undef IGNORE_BUF
}
// Write some of the variables
@@ -2581,6 +2592,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
&& search_highlighted), \
.pat = (char *) pat.pat, \
.additional_data = pat.additional_data, \
+ .search_backward = (!is_sub && pat.off.dir == '?'), \
} \
} \
} \
@@ -2957,9 +2969,9 @@ shada_write_file_open:
fd = (intptr_t) open_file(tempname, O_CREAT|O_WRONLY|O_NOFOLLOW|O_EXCL,
perm);
if (fd < 0) {
- if (-fd == EEXIST
+ if (fd == UV_EEXIST
#ifdef ELOOP
- || -fd == ELOOP
+ || fd == UV_ELOOP
#endif
) {
// File already exists, try another name
@@ -3633,6 +3645,9 @@ shada_read_next_item_start:
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
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 7d9257141a..a5b66ad220 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -2,7 +2,7 @@
//
// Do ":help uganda" in Vim to read copying and usage conditions.
// Do ":help credits" in Vim to see a list of people who contributed.
-// See README.txt for an overview of the Vim source code.
+// See README.md for an overview of the Vim source code.
// spell.c: code for spell checking
//
@@ -285,7 +285,6 @@
// few bytes as possible, see offset2bytes())
#include <assert.h>
-#include <errno.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
diff --git a/src/nvim/strings.c b/src/nvim/strings.c
index 9ffa5c6a76..4bd394cb44 100644
--- a/src/nvim/strings.c
+++ b/src/nvim/strings.c
@@ -1,5 +1,4 @@
-#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index d0491ab42b..f65b21a40b 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
@@ -12,7 +12,6 @@
#include <assert.h>
#include <ctype.h>
-#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
diff --git a/src/nvim/tag.c b/src/nvim/tag.c
index b0d1a17c89..1b3fda8aca 100644
--- a/src/nvim/tag.c
+++ b/src/nvim/tag.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
@@ -11,7 +11,6 @@
*/
#include <assert.h>
-#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index 119ee2c5b3..adf3f725a2 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -402,6 +402,14 @@ static int terminal_execute(VimState *state, int key)
TerminalState *s = (TerminalState *)state;
switch (key) {
+ case K_FOCUSGAINED: // Neovim has been given focus
+ apply_autocmds(EVENT_FOCUSGAINED, NULL, NULL, false, curbuf);
+ break;
+
+ case K_FOCUSLOST: // Neovim has lost focus
+ apply_autocmds(EVENT_FOCUSLOST, NULL, NULL, false, curbuf);
+ break;
+
case K_LEFTMOUSE:
case K_LEFTDRAG:
case K_LEFTRELEASE:
diff --git a/src/nvim/terminal.h b/src/nvim/terminal.h
index 6e0b062fbd..25e609fb68 100644
--- a/src/nvim/terminal.h
+++ b/src/nvim/terminal.h
@@ -18,15 +18,6 @@ typedef struct {
terminal_close_cb close_cb;
} TerminalOptions;
-#define TERMINAL_OPTIONS_INIT ((TerminalOptions) { \
- .data = NULL, \
- .width = 80, \
- .height = 24, \
- .write_cb = NULL, \
- .resize_cb = NULL, \
- .close_cb = NULL \
- })
-
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "terminal.h.generated.h"
#endif
diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c
index 654b857301..b41e4d2fba 100644
--- a/src/nvim/tui/input.c
+++ b/src/nvim/tui/input.c
@@ -10,6 +10,8 @@
#include "nvim/event/rstream.h"
#define PASTETOGGLE_KEY "<Paste>"
+#define FOCUSGAINED_KEY "<FocusGained>"
+#define FOCUSLOST_KEY "<FocusLost>"
#define KEY_BUFFER_SIZE 0xfff
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -252,6 +254,32 @@ static void timer_cb(TimeWatcher *watcher, void *data)
flush_input(data, true);
}
+/// Handle focus events.
+///
+/// If the upcoming sequence of bytes in the input stream matches either the
+/// escape code for focus gained `<ESC>[I` or focus lost `<ESC>[O` then consume
+/// that sequence and push the appropriate event into the input queue
+///
+/// @param input the input stream
+/// @return true iff handle_focus_event consumed some input
+static bool handle_focus_event(TermInput *input)
+{
+ if (rbuffer_size(input->read_stream.buffer) > 2
+ && (!rbuffer_cmp(input->read_stream.buffer, "\x1b[I", 3)
+ || !rbuffer_cmp(input->read_stream.buffer, "\x1b[O", 3))) {
+ // Advance past the sequence
+ bool focus_gained = *rbuffer_get(input->read_stream.buffer, 2) == 'I';
+ rbuffer_consumed(input->read_stream.buffer, 3);
+ if (focus_gained) {
+ enqueue_input(input, FOCUSGAINED_KEY, sizeof(FOCUSGAINED_KEY) - 1);
+ } else {
+ enqueue_input(input, FOCUSLOST_KEY, sizeof(FOCUSLOST_KEY) - 1);
+ }
+ return true;
+ }
+ return false;
+}
+
static bool handle_bracketed_paste(TermInput *input)
{
if (rbuffer_size(input->read_stream.buffer) > 5 &&
@@ -314,7 +342,9 @@ static void read_cb(Stream *stream, RBuffer *buf, size_t c, void *data,
}
do {
- if (handle_bracketed_paste(input) || handle_forced_escape(input)) {
+ if (handle_focus_event(input)
+ || handle_bracketed_paste(input)
+ || handle_forced_escape(input)) {
continue;
}
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 02efa1f8df..7f7d138358 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -66,6 +66,7 @@ typedef struct {
int enable_bracketed_paste, disable_bracketed_paste;
int enter_insert_mode, enter_replace_mode, exit_insert_mode;
int set_rgb_foreground, set_rgb_background;
+ int enable_focus_reporting, disable_focus_reporting;
} unibi_ext;
} TUIData;
@@ -120,6 +121,8 @@ static void terminfo_start(UI *ui)
data->unibi_ext.enter_insert_mode = -1;
data->unibi_ext.enter_replace_mode = -1;
data->unibi_ext.exit_insert_mode = -1;
+ data->unibi_ext.enable_focus_reporting = -1;
+ data->unibi_ext.disable_focus_reporting = -1;
data->out_fd = 1;
data->out_isatty = os_isatty(data->out_fd);
// setup unibilium
@@ -135,6 +138,8 @@ static void terminfo_start(UI *ui)
unibi_out(ui, unibi_clear_screen);
// Enable bracketed paste
unibi_out(ui, data->unibi_ext.enable_bracketed_paste);
+ // Enable focus reporting
+ unibi_out(ui, data->unibi_ext.enable_focus_reporting);
uv_loop_init(&data->write_loop);
if (data->out_isatty) {
uv_tty_init(&data->write_loop, &data->output_handle.tty, data->out_fd, 0);
@@ -157,6 +162,8 @@ static void terminfo_stop(UI *ui)
unibi_out(ui, unibi_exit_ca_mode);
// Disable bracketed paste
unibi_out(ui, data->unibi_ext.disable_bracketed_paste);
+ // Disable focus reporting
+ unibi_out(ui, data->unibi_ext.disable_focus_reporting);
flush_buf(ui);
uv_tty_reset_mode();
uv_close((uv_handle_t *)&data->output_handle, NULL);
@@ -807,6 +814,11 @@ static void fix_terminfo(TUIData *data)
data->unibi_ext.disable_bracketed_paste = (int)unibi_add_ext_str(ut, NULL,
"\x1b[?2004l");
+ data->unibi_ext.enable_focus_reporting = (int)unibi_add_ext_str(ut, NULL,
+ "\x1b[?1004h");
+ data->unibi_ext.disable_focus_reporting = (int)unibi_add_ext_str(ut, NULL,
+ "\x1b[?1004l");
+
#define XTERM_SETAF \
"\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m"
#define XTERM_SETAB \
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index b0c49cbf8e..6c87f01746 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -3,7 +3,7 @@
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
/*
@@ -83,7 +83,6 @@
#include <assert.h>
#include <inttypes.h>
#include <limits.h>
-#include <errno.h>
#include <stdbool.h>
#include <string.h>
diff --git a/src/nvim/version.c b/src/nvim/version.c
index f5e43878e4..d5bbd734f4 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -74,86 +74,92 @@ static char *features[] = {
// clang-format off
static int included_patches[] = {
+ // 922,
+ // 921 NA
+ // 920 NA
+ // 919 NA
+ // 918 NA
+ // 917 NA
916,
// 915,
// 914,
- // 913,
+ // 913 NA
// 912,
- // 911,
- // 910,
+ // 911 NA
+ // 910 NA
// 909,
- // 908,
- // 907,
- // 906,
+ // 908 NA
+ // 907 NA
+ // 906 NA
// 905,
// 904,
// 903,
- // 902,
+ // 902 NA
// 901,
- // 900,
- // 899,
+ // 900 NA
+ // 899 NA
// 898,
// 897,
// 896,
// 895,
- // 894,
+ // 894 NA
// 893,
// 892,
// 891,
- // 890,
+ // 890 NA
// 889,
// 888,
// 887,
- // 886,
+ // 886 NA
// 885,
- // 884,
+ // 884 NA
// 883,
// 882,
// 881,
- // 880,
+ // 880 NA
// 879,
// 878,
// 877,
- // 876,
- // 875,
- // 874,
+ // 876 NA
+ // 875 NA
+ // 874 NA
// 873,
- // 872,
+ // 872 NA
// 871,
// 870,
- // 869,
+ // 869 NA
// 868,
- // 867,
+ // 867 NA
// 866,
// 865,
// 864,
// 863,
- // 862,
- // 861,
+ // 862 NA
+ // 861 NA
// 860,
// 859,
// 858,
// 857,
// 856,
- // 855,
+ // 855 NA
// 854,
// 853,
- // 852,
- // 851,
- // 850,
- 849,
+ // 852 NA
+ // 851 NA
+ // 850 NA
+ 849,
// 848,
// 847,
- // 846,
+ // 846 NA
// 845,
// 844,
// 843,
// 842,
// 841,
- // 840,
+ // 840 NA
// 839,
// 838,
- // 837,
+ // 837 NA
836,
// 835,
// 834,
@@ -161,7 +167,7 @@ static int included_patches[] = {
// 832,
// 831,
// 830,
- // 829,
+ // 829 NA
// 828,
// 827,
826,
@@ -181,14 +187,14 @@ static int included_patches[] = {
// 812,
// 811,
// 810,
- // 809,
+ 809,
// 808,
// 807,
// 806,
// 805,
// 804,
// 803,
- // 802,
+ 802,
// 801,
// 800,
799,
@@ -218,35 +224,35 @@ static int included_patches[] = {
775,
774,
773,
- // 772,
+ // 772 NA
// 771,
- // 770,
+ // 770 NA
// 769,
// 768,
// 767,
- // 766,
+ // 766 NA
// 765,
// 764,
- // 763,
- // 762,
- // 761,
+ // 763 NA
+ // 762 NA
+ // 761 NA
// 760,
- // 759,
+ // 759 NA
// 758,
- // 757,
- // 756,
+ // 757 NA
+ // 756 NA
// 755,
// 754,
// 753,
// 752,
- // 751,
- // 750,
+ // 751 NA
+ // 750 NA
// 749,
// 748,
// 747,
// 746,
// 745,
- // 744,
+ // 744 NA
// 743,
// 742,
// 741,
@@ -338,7 +344,7 @@ static int included_patches[] = {
// 655,
// 654,
653,
- // 652,
+ // 652 NA
651,
// 650 NA
// 649,
diff --git a/src/nvim/window.c b/src/nvim/window.c
index b71b2cb603..8ac50b2731 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -3,10 +3,9 @@
*
* Do ":help uganda" in Vim to read a list of people who contributed.
* Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
+ * See README.md for an overview of the Vim source code.
*/
-#include <errno.h>
#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
diff --git a/test/.luacheckrc b/test/.luacheckrc
new file mode 100644
index 0000000000..92e19d40e8
--- /dev/null
+++ b/test/.luacheckrc
@@ -0,0 +1,13 @@
+-- vim: ft=lua tw=80
+
+-- Don't report globals from luajit or busted (e.g. jit.os or describe).
+std = '+luajit +busted'
+
+-- One can't test these files properly; assume correctness.
+exclude_files = { '*/preload.lua' }
+
+-- Don't report unused self arguments of methods.
+self = false
+
+-- Rerun tests only if their modification time changed.
+cache = true
diff --git a/test/benchmark/bench_re_freeze_spec.lua b/test/benchmark/bench_re_freeze_spec.lua
index 7242f43c8e..d40d9f9ece 100644
--- a/test/benchmark/bench_re_freeze_spec.lua
+++ b/test/benchmark/bench_re_freeze_spec.lua
@@ -1,7 +1,7 @@
-- Test for benchmarking RE engine.
local helpers = require('test.functional.helpers')
-local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local insert, source = helpers.insert, helpers.source
local clear, execute, wait = helpers.clear, helpers.execute, helpers.wait
-- Temporary file for gathering benchmarking results for each regexp engine.
diff --git a/test/functional/api/menu_spec.lua b/test/functional/api/menu_spec.lua
index 34d23ca098..5b414fb559 100644
--- a/test/functional/api/menu_spec.lua
+++ b/test/functional/api/menu_spec.lua
@@ -19,7 +19,7 @@ describe("update_menu notification", function()
screen:detach()
end)
- function expect_sent(expected)
+ local function expect_sent(expected)
screen:wait(function()
if screen.update_menu ~= expected then
if expected then
diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua
index 4c7122a549..a3ac864f79 100644
--- a/test/functional/api/server_requests_spec.lua
+++ b/test/functional/api/server_requests_spec.lua
@@ -95,13 +95,13 @@ describe('server -> client', function()
eq('notified!', eval('rpcrequest('..cid..', "notify")'))
end
- local function on_request(method, args)
+ local function on_request(method)
eq('notify', method)
eq(1, eval('rpcnotify('..cid..', "notification")'))
return 'notified!'
end
- local function on_notification(method, args)
+ local function on_notification(method)
eq('notification', method)
if notified == expected then
stop()
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index eb4804f141..cba0b7533b 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -180,6 +180,8 @@ describe('vim_* functions', function()
end)
describe('err_write', function()
+ local screen
+
before_each(function()
clear()
screen = Screen.new(40, 8)
diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua
index 456252522d..17aacafe9b 100644
--- a/test/functional/api/window_spec.lua
+++ b/test/functional/api/window_spec.lua
@@ -1,9 +1,9 @@
-- Sanity checks for window_* API calls via msgpack-rpc
local helpers = require('test.functional.helpers')
-local clear, nvim, buffer, curbuf, curbuf_contents, window, curwin, eq, neq,
- ok, feed, rawfeed, insert, eval = helpers.clear, helpers.nvim, helpers.buffer, helpers.curbuf,
+local clear, nvim, curbuf, curbuf_contents, window, curwin, eq, neq,
+ ok, feed, insert, eval = helpers.clear, helpers.nvim, helpers.curbuf,
helpers.curbuf_contents, helpers.window, helpers.curwin, helpers.eq,
- helpers.neq, helpers.ok, helpers.feed, helpers.rawfeed, helpers.insert, helpers.eval
+ helpers.neq, helpers.ok, helpers.feed, helpers.insert, helpers.eval
local wait = helpers.wait
-- check if str is visible at the beginning of some line
@@ -54,7 +54,7 @@ describe('window_* functions', function()
insert("prologue")
feed('100o<esc>')
insert("epilogue")
- win = curwin()
+ local win = curwin()
feed('gg')
wait() -- let nvim process the 'gg' command
diff --git a/test/functional/autocmd/tabclose_spec.lua b/test/functional/autocmd/tabclose_spec.lua
index 847362e3de..bf609d1846 100644
--- a/test/functional/autocmd/tabclose_spec.lua
+++ b/test/functional/autocmd/tabclose_spec.lua
@@ -1,7 +1,5 @@
local helpers = require('test.functional.helpers')
-local clear, nvim, buffer, curbuf, curwin, eq, neq, ok =
- helpers.clear, helpers.nvim, helpers.buffer, helpers.curbuf, helpers.curwin,
- helpers.eq, helpers.neq, helpers.ok
+local clear, nvim, eq = helpers.clear, helpers.nvim, helpers.eq
describe('TabClosed', function()
describe('au TabClosed', function()
@@ -20,7 +18,6 @@ describe('TabClosed', function()
end)
describe('with NR as <afile>', function()
it('matches when closing a tab whose index is NR', function()
- tmp_path = nvim('eval', 'tempname()')
nvim('command', 'au! TabClosed 2 echom "tabclosed:match"')
repeat
nvim('command', 'tabnew')
diff --git a/test/functional/autocmd/tabnew_spec.lua b/test/functional/autocmd/tabnew_spec.lua
index d80644cd92..5ab504889b 100644
--- a/test/functional/autocmd/tabnew_spec.lua
+++ b/test/functional/autocmd/tabnew_spec.lua
@@ -1,7 +1,5 @@
local helpers = require('test.functional.helpers')
-local clear, nvim, buffer, curbuf, curwin, eq, neq, ok =
- helpers.clear, helpers.nvim, helpers.buffer, helpers.curbuf, helpers.curwin,
- helpers.eq, helpers.neq, helpers.ok
+local clear, nvim, eq = helpers.clear, helpers.nvim, helpers.eq
describe('TabNew', function()
setup(clear)
@@ -15,7 +13,7 @@ describe('TabNew', function()
end)
describe('with FILE as <afile>', function()
it('matches when opening a new tab for FILE', function()
- tmp_path = nvim('eval', 'tempname()')
+ local tmp_path = nvim('eval', 'tempname()')
nvim('command', 'au! TabNew '..tmp_path..' echom "tabnew:match"')
eq("\ntabnew:4:3\ntabnew:match\n\""..tmp_path.."\" [New File]", nvim('command_output', 'tabnew '..tmp_path))
end)
diff --git a/test/functional/autocmd/tabnewentered_spec.lua b/test/functional/autocmd/tabnewentered_spec.lua
index f220c15ef7..64b9a22f41 100644
--- a/test/functional/autocmd/tabnewentered_spec.lua
+++ b/test/functional/autocmd/tabnewentered_spec.lua
@@ -1,7 +1,5 @@
local helpers = require('test.functional.helpers')
-local clear, nvim, buffer, curbuf, curwin, eq, neq, ok =
- helpers.clear, helpers.nvim, helpers.buffer, helpers.curbuf, helpers.curwin,
- helpers.eq, helpers.neq, helpers.ok
+local clear, nvim, eq = helpers.clear, helpers.nvim, helpers.eq
describe('TabNewEntered', function()
describe('au TabNewEntered', function()
@@ -15,7 +13,7 @@ describe('TabNewEntered', function()
end)
describe('with FILE as <afile>', function()
it('matches when opening a new tab for FILE', function()
- tmp_path = nvim('eval', 'tempname()')
+ local tmp_path = nvim('eval', 'tempname()')
nvim('command', 'au! TabNewEntered '..tmp_path..' echom "tabnewentered:match"')
eq("\n\""..tmp_path.."\" [New File]\ntabnewentered:4:4\ntabnewentered:match", nvim('command_output', 'tabnew '..tmp_path))
end)
diff --git a/test/functional/autocmd/termclose_spec.lua b/test/functional/autocmd/termclose_spec.lua
index 265d857a42..0961340e61 100644
--- a/test/functional/autocmd/termclose_spec.lua
+++ b/test/functional/autocmd/termclose_spec.lua
@@ -1,11 +1,11 @@
local helpers = require('test.functional.helpers')
local Screen = require('test.functional.ui.screen')
-local clear, eval, execute, feed, nvim, nvim_dir = helpers.clear, helpers.eval,
+local clear, execute, feed, nvim, nvim_dir = helpers.clear,
helpers.execute, helpers.feed, helpers.nvim, helpers.nvim_dir
-local wait = helpers.wait
describe('TermClose event', function()
+ local screen
before_each(function()
clear()
nvim('set_option', 'shell', nvim_dir .. '/shell-test')
diff --git a/test/functional/clipboard/clipboard_provider_spec.lua b/test/functional/clipboard/clipboard_provider_spec.lua
index 98b8d2dd45..898ec556a2 100644
--- a/test/functional/clipboard/clipboard_provider_spec.lua
+++ b/test/functional/clipboard/clipboard_provider_spec.lua
@@ -4,7 +4,6 @@ local helpers = require('test.functional.helpers')
local Screen = require('test.functional.ui.screen')
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
local execute, expect, eq, eval = helpers.execute, helpers.expect, helpers.eq, helpers.eval
-local nvim, run, stop, restart = helpers.nvim, helpers.run, helpers.stop, helpers.restart
local function basic_register_test(noblock)
insert("some words")
diff --git a/test/functional/eval/glob_spec.lua b/test/functional/eval/glob_spec.lua
index f99a9e7d0e..c6bba46424 100644
--- a/test/functional/eval/glob_spec.lua
+++ b/test/functional/eval/glob_spec.lua
@@ -1,3 +1,4 @@
+local lfs = require('lfs')
local helpers = require('test.functional.helpers')
local clear, execute, eval, eq = helpers.clear, helpers.execute, helpers.eval, helpers.eq
diff --git a/test/functional/eval/msgpack_functions_spec.lua b/test/functional/eval/msgpack_functions_spec.lua
index 9a7b630f64..da42fc9d26 100644
--- a/test/functional/eval/msgpack_functions_spec.lua
+++ b/test/functional/eval/msgpack_functions_spec.lua
@@ -1,7 +1,7 @@
local helpers = require('test.functional.helpers')
-local clear, feed, execute = helpers.clear, helpers.feed, helpers.execute
-local eval, eq, neq = helpers.eval, helpers.eq, helpers.neq
-local execute, source = helpers.execute, helpers.source
+local clear = helpers.clear
+local eval, eq = helpers.eval, helpers.eq
+local execute = helpers.execute
local nvim = helpers.nvim
local exc_exec = helpers.exc_exec
@@ -454,9 +454,9 @@ describe('msgpackparse() function', function()
it('msgpackparse(systemlist(...)) does not segfault. #3135', function()
local cmd = "sort(keys(msgpackparse(systemlist('"
..helpers.nvim_prog.." --api-info'))[0]))"
- local api_info = eval(cmd)
- api_info = eval(cmd) -- do it again (try to force segfault)
- api_info = eval(cmd) -- do it again
+ eval(cmd)
+ eval(cmd) -- do it again (try to force segfault)
+ local api_info = eval(cmd) -- do it again
eq({'error_types', 'functions', 'types'}, api_info)
end)
diff --git a/test/functional/ex_cmds/grep_spec.lua b/test/functional/ex_cmds/grep_spec.lua
index 9c792099c1..f3ff0a3817 100644
--- a/test/functional/ex_cmds/grep_spec.lua
+++ b/test/functional/ex_cmds/grep_spec.lua
@@ -1,7 +1,6 @@
local helpers = require('test.functional.helpers')
-local clear, execute, nvim, feed, eq, ok, eval =
- helpers.clear, helpers.execute, helpers.nvim, helpers.feed,
- helpers.eq, helpers.ok, helpers.eval
+local clear, execute, feed, ok, eval =
+ helpers.clear, helpers.execute, helpers.feed, helpers.ok, helpers.eval
describe(':grep', function()
before_each(clear)
diff --git a/test/functional/ex_cmds/oldfiles_spec.lua b/test/functional/ex_cmds/oldfiles_spec.lua
index d54e43f6cb..dac6757a97 100644
--- a/test/functional/ex_cmds/oldfiles_spec.lua
+++ b/test/functional/ex_cmds/oldfiles_spec.lua
@@ -2,8 +2,8 @@ local Screen = require('test.functional.ui.screen')
local helpers = require('test.functional.helpers')
local buf, eq, execute = helpers.curbufmeths, helpers.eq, helpers.execute
-local feed, nvim, nvim_prog = helpers.feed, helpers.nvim, helpers.nvim_prog
-local set_session, spawn = helpers.set_session, helpers.spawn
+local feed, nvim_prog = helpers.feed, helpers.nvim_prog
+local ok, set_session, spawn = helpers.ok, helpers.set_session, helpers.spawn
local shada_file = 'test.shada'
@@ -11,9 +11,6 @@ local shada_file = 'test.shada'
-- helpers.clear() uses "-i NONE", which is not useful for this test.
--
local function _clear()
- if session then
- session:exit(0)
- end
set_session(spawn({nvim_prog,
'-u', 'NONE',
'--cmd', 'set noswapfile undodir=. directory=. viewdir=. backupdir=.',
@@ -32,19 +29,18 @@ describe(':oldfiles', function()
end
it('shows most recently used files', function()
- screen = Screen.new(100, 5)
+ local screen = Screen.new(100, 5)
screen:attach()
execute('edit testfile1')
- local filename1 = buf.get_name()
execute('edit testfile2')
- local filename2 = buf.get_name()
execute('wshada ' .. shada_file)
execute('rshada! ' .. shada_file)
+ local oldfiles = helpers.meths.get_vvar('oldfiles')
execute('oldfiles')
screen:expect([[
testfile2 |
- 1: ]].. add_padding(filename1) ..[[ |
- 2: ]].. add_padding(filename2) ..[[ |
+ 1: ]].. add_padding(oldfiles[1]) ..[[ |
+ 2: ]].. add_padding(oldfiles[2]) ..[[ |
|
Press ENTER or type command to continue^ |
]])
@@ -53,15 +49,27 @@ end)
describe(':oldfiles!', function()
local filename
+ local filename2
+ local oldfiles
before_each(function()
_clear()
execute('edit testfile1')
- execute('edit testfile2')
filename = buf.get_name()
+ execute('edit testfile2')
+ filename2 = buf.get_name()
execute('wshada ' .. shada_file)
_clear()
execute('rshada! ' .. shada_file)
+
+ -- Ensure v:oldfiles isn't busted. Since things happen so fast,
+ -- the ordering of v:oldfiles is unstable (it uses qsort() under-the-hood).
+ -- Let's verify the contents and the length of v:oldfiles before moving on.
+ oldfiles = helpers.meths.get_vvar('oldfiles')
+ eq(2, #oldfiles)
+ ok(filename == oldfiles[1] or filename == oldfiles[2])
+ ok(filename2 == oldfiles[1] or filename2 == oldfiles[2])
+
execute('oldfiles!')
end)
@@ -71,7 +79,7 @@ describe(':oldfiles!', function()
it('provides a prompt and edits the chosen file', function()
feed('2<cr>')
- eq(filename, buf.get_name())
+ eq(oldfiles[2], buf.get_name())
end)
it('provides a prompt and does nothing on <cr>', function()
diff --git a/test/functional/ex_cmds/profile_spec.lua b/test/functional/ex_cmds/profile_spec.lua
index 721669e73b..744b22621f 100644
--- a/test/functional/ex_cmds/profile_spec.lua
+++ b/test/functional/ex_cmds/profile_spec.lua
@@ -1,5 +1,5 @@
require('os')
-require('lfs')
+local lfs = require('lfs')
local helpers = require('test.functional.helpers')
local eval = helpers.eval
diff --git a/test/functional/ex_cmds/quit_spec.lua b/test/functional/ex_cmds/quit_spec.lua
index 3cd8e19617..a8156228d3 100644
--- a/test/functional/ex_cmds/quit_spec.lua
+++ b/test/functional/ex_cmds/quit_spec.lua
@@ -1,5 +1,5 @@
local helpers = require('test.functional.helpers')
-local execute, eq, clear = helpers.execute, helpers.eq, helpers.clear
+local clear = helpers.clear
describe(':qa', function()
before_each(function()
diff --git a/test/functional/ex_cmds/recover_spec.lua b/test/functional/ex_cmds/recover_spec.lua
index 6749cfaf40..e1d01f6896 100644
--- a/test/functional/ex_cmds/recover_spec.lua
+++ b/test/functional/ex_cmds/recover_spec.lua
@@ -1,6 +1,7 @@
-- Tests for :recover
local helpers = require('test.functional.helpers')
+local lfs = require('lfs')
local execute, eq, clear, eval, feed, expect, source =
helpers.execute, helpers.eq, helpers.clear, helpers.eval, helpers.feed,
helpers.expect, helpers.source
diff --git a/test/functional/ex_cmds/sign_spec.lua b/test/functional/ex_cmds/sign_spec.lua
index be213cd0d9..c50704504d 100644
--- a/test/functional/ex_cmds/sign_spec.lua
+++ b/test/functional/ex_cmds/sign_spec.lua
@@ -1,7 +1,5 @@
local helpers = require('test.functional.helpers')
-local clear, nvim, buffer, curbuf, curwin, eq, ok =
- helpers.clear, helpers.nvim, helpers.buffer, helpers.curbuf, helpers.curwin,
- helpers.eq, helpers.ok
+local clear, nvim, eq = helpers.clear, helpers.nvim, helpers.eq
describe('sign', function()
before_each(clear)
diff --git a/test/functional/ex_cmds/wviminfo_spec.lua b/test/functional/ex_cmds/wviminfo_spec.lua
index b6b9185cf2..207d94124f 100644
--- a/test/functional/ex_cmds/wviminfo_spec.lua
+++ b/test/functional/ex_cmds/wviminfo_spec.lua
@@ -1,6 +1,6 @@
local helpers, lfs = require('test.functional.helpers'), require('lfs')
-local clear, execute, eq, neq, spawn, nvim_prog, set_session, wait, write_file
- = helpers.clear, helpers.execute, helpers.eq, helpers.neq, helpers.spawn,
+local execute, eq, neq, spawn, nvim_prog, set_session, wait, write_file
+ = helpers.execute, helpers.eq, helpers.neq, helpers.spawn,
helpers.nvim_prog, helpers.set_session, helpers.wait, helpers.write_file
describe(':wshada', function()
@@ -13,7 +13,7 @@ describe(':wshada', function()
end
-- Override the default session because we need 'swapfile' for these tests.
- local session = spawn({nvim_prog, '-u', 'NONE', '-i', '/dev/null', '--embed',
+ session = spawn({nvim_prog, '-u', 'NONE', '-i', '/dev/null', '--embed',
'--cmd', 'set swapfile'})
set_session(session)
diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua
index 8a85f187cf..9562457c8e 100644
--- a/test/functional/helpers.lua
+++ b/test/functional/helpers.lua
@@ -1,4 +1,5 @@
require('coxpcall')
+local lfs = require('lfs')
local assert = require('luassert')
local Loop = require('nvim.loop')
local MsgpackStream = require('nvim.msgpack_stream')
@@ -55,7 +56,7 @@ if prepend_argv then
nvim_argv = new_nvim_argv
end
-local session, loop_running, loop_stopped, last_error
+local session, loop_running, last_error
local function set_session(s)
session = s
@@ -79,7 +80,7 @@ local function next_message()
end
local function call_and_stop_on_error(...)
- local status, result = copcall(...)
+ local status, result = copcall(...) -- luacheck: ignore
if not status then
session:stop()
last_error = result
@@ -109,7 +110,6 @@ local function run(request_cb, notification_cb, setup_cb, timeout)
end
end
- loop_stopped = false
loop_running = true
session:run(on_request, on_notification, on_setup, timeout)
loop_running = false
@@ -121,7 +121,6 @@ local function run(request_cb, notification_cb, setup_cb, timeout)
end
local function stop()
- loop_stopped = true
session:stop()
end
@@ -197,9 +196,9 @@ local function spawn(argv, merge)
local loop = Loop.new()
local msgpack_stream = MsgpackStream.new(loop)
local async_session = AsyncSession.new(msgpack_stream)
- local session = Session.new(async_session)
+ local sess = Session.new(async_session)
loop:spawn(merge and merge_args(prepend_argv, argv) or argv)
- return session
+ return sess
end
local function clear(extra_cmd)
@@ -332,14 +331,14 @@ local function rmdir(path)
if file == '.' or file == '..' then
goto continue
end
- ret, err = os.remove(path..'/'..file)
+ local ret, err = os.remove(path..'/'..file)
if not ret then
error('os.remove: '..err)
return nil
end
::continue::
end
- ret, err = os.remove(path)
+ local ret, err = os.remove(path)
if not ret then
error('os.remove: '..err)
end
@@ -371,15 +370,15 @@ local function redir_exec(cmd)
end
local function create_callindex(func)
- local tbl = {}
- setmetatable(tbl, {
+ local table = {}
+ setmetatable(table, {
__index = function(tbl, arg1)
- ret = function(...) return func(arg1, ...) end
+ local ret = function(...) return func(arg1, ...) end
tbl[arg1] = ret
return ret
end,
})
- return tbl
+ return table
end
local funcs = create_callindex(nvim_call)
diff --git a/test/functional/job/job_spec.lua b/test/functional/job/job_spec.lua
index bdaf2a7ec6..0915ab0955 100644
--- a/test/functional/job/job_spec.lua
+++ b/test/functional/job/job_spec.lua
@@ -1,11 +1,11 @@
local helpers = require('test.functional.helpers')
-local clear, eq, eval, execute, expect, feed, insert, neq, next_msg, nvim,
- nvim_dir, ok, run, session, source, stop, wait, write_file = helpers.clear,
- helpers.eq, helpers.eval, helpers.execute, helpers.expect, helpers.feed,
+local clear, eq, eval, execute, feed, insert, neq, next_msg, nvim,
+ nvim_dir, ok, source, write_file = helpers.clear,
+ helpers.eq, helpers.eval, helpers.execute, helpers.feed,
helpers.insert, helpers.neq, helpers.next_message, helpers.nvim,
- helpers.nvim_dir, helpers.ok, helpers.run, helpers.session, helpers.source,
- helpers.stop, helpers.wait, helpers.write_file
+ helpers.nvim_dir, helpers.ok, helpers.source,
+ helpers.write_file
local Screen = require('test.functional.ui.screen')
@@ -370,7 +370,7 @@ describe('jobs', function()
describe('running tty-test program', function()
local function next_chunk()
- local rv = ''
+ local rv
while true do
local msg = next_msg()
local data = msg[3][2]
diff --git a/test/functional/legacy/003_cindent_spec.lua b/test/functional/legacy/003_cindent_spec.lua
index 1857721563..39de3e8280 100644
--- a/test/functional/legacy/003_cindent_spec.lua
+++ b/test/functional/legacy/003_cindent_spec.lua
@@ -4,7 +4,7 @@
-- in the original test. These have been converted to "it" test cases here.
local helpers = require('test.functional.helpers')
-local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local feed, insert = helpers.feed, helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
-- Inserts text as usual, and additionally positions the cursor on line 1 and
diff --git a/test/functional/legacy/009_bufleave_autocommand_spec.lua b/test/functional/legacy/009_bufleave_autocommand_spec.lua
index 0fc1b5b657..8c18639c8f 100644
--- a/test/functional/legacy/009_bufleave_autocommand_spec.lua
+++ b/test/functional/legacy/009_bufleave_autocommand_spec.lua
@@ -1,7 +1,7 @@
-- Test for Bufleave autocommand that deletes the buffer we are about to edit.
local helpers = require('test.functional.helpers')
-local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local clear, insert = helpers.clear, helpers.insert
local execute, expect = helpers.execute, helpers.expect
describe('BufLeave autocommand', function()
diff --git a/test/functional/legacy/015_alignment_spec.lua b/test/functional/legacy/015_alignment_spec.lua
index e71f9d1c90..3b19f4ff42 100644
--- a/test/functional/legacy/015_alignment_spec.lua
+++ b/test/functional/legacy/015_alignment_spec.lua
@@ -3,7 +3,7 @@
-- Also test undo after ":%s" and formatting.
local helpers = require('test.functional.helpers')
-local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local feed, insert = helpers.feed, helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
describe('alignment', function()
diff --git a/test/functional/legacy/022_line_ending_spec.lua b/test/functional/legacy/022_line_ending_spec.lua
index 4b897a7c95..a841378a82 100644
--- a/test/functional/legacy/022_line_ending_spec.lua
+++ b/test/functional/legacy/022_line_ending_spec.lua
@@ -1,7 +1,7 @@
-- Tests for file with some lines ending in CTRL-M, some not
local helpers = require('test.functional.helpers')
-local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local clear, feed = helpers.clear, helpers.feed
local execute, expect = helpers.execute, helpers.expect
describe('line ending', function()
diff --git a/test/functional/legacy/023_edit_arguments_spec.lua b/test/functional/legacy/023_edit_arguments_spec.lua
index e68af9758d..15b30bfa3a 100644
--- a/test/functional/legacy/023_edit_arguments_spec.lua
+++ b/test/functional/legacy/023_edit_arguments_spec.lua
@@ -1,7 +1,7 @@
-- Tests for complicated + argument to :edit command
local helpers = require('test.functional.helpers')
-local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local clear, insert = helpers.clear, helpers.insert
local execute, expect = helpers.execute, helpers.expect
describe(':edit', function()
diff --git a/test/functional/legacy/026_execute_while_if_spec.lua b/test/functional/legacy/026_execute_while_if_spec.lua
index ffe37819de..f17bb79702 100644
--- a/test/functional/legacy/026_execute_while_if_spec.lua
+++ b/test/functional/legacy/026_execute_while_if_spec.lua
@@ -1,7 +1,7 @@
-- Test for :execute, :while and :if
local helpers = require('test.functional.helpers')
-local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local clear = helpers.clear
local execute, expect = helpers.execute, helpers.expect
local source = helpers.source
diff --git a/test/functional/legacy/027_expand_file_names_spec.lua b/test/functional/legacy/027_expand_file_names_spec.lua
index d31f29d38a..4778d16d43 100644
--- a/test/functional/legacy/027_expand_file_names_spec.lua
+++ b/test/functional/legacy/027_expand_file_names_spec.lua
@@ -1,10 +1,10 @@
-- Test for expanding file names
local helpers = require('test.functional.helpers')
-local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
-local execute, expect = helpers.execute, helpers.expect
+local clear, feed = helpers.clear, helpers.feed
+local execute = helpers.execute
local curbuf_contents = helpers.curbuf_contents
-local eq, eval = helpers.eq, helpers.eval
+local eq = helpers.eq
describe('expand file name', function()
setup(clear)
diff --git a/test/functional/legacy/029_join_spec.lua b/test/functional/legacy/029_join_spec.lua
index eafa50d88c..25a072ad6e 100644
--- a/test/functional/legacy/029_join_spec.lua
+++ b/test/functional/legacy/029_join_spec.lua
@@ -1,7 +1,7 @@
-- Test for joining lines with marks in them (and with 'joinspaces' set/reset)
local helpers = require('test.functional.helpers')
-local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local feed, insert = helpers.feed, helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
describe('joining lines', function()
diff --git a/test/functional/legacy/031_close_commands_spec.lua b/test/functional/legacy/031_close_commands_spec.lua
index 78e71b5fb1..3597cba12a 100644
--- a/test/functional/legacy/031_close_commands_spec.lua
+++ b/test/functional/legacy/031_close_commands_spec.lua
@@ -10,7 +10,7 @@
-- :edit
local helpers = require('test.functional.helpers')
-local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local feed, insert = helpers.feed, helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
describe('Commands that close windows and/or buffers', function()
diff --git a/test/functional/legacy/038_virtual_replace_spec.lua b/test/functional/legacy/038_virtual_replace_spec.lua
index 94503bd42a..10d42f0cea 100644
--- a/test/functional/legacy/038_virtual_replace_spec.lua
+++ b/test/functional/legacy/038_virtual_replace_spec.lua
@@ -1,7 +1,7 @@
-- Test Virtual replace mode.
local helpers = require('test.functional.helpers')
-local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local feed = helpers.feed
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
describe('Virtual replace mode', function()
diff --git a/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua b/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua
index efe61aa354..1359b45228 100644
--- a/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua
+++ b/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua
@@ -4,7 +4,7 @@
-- This test contains both "test44" and "test99" from the old test suite.
local helpers = require('test.functional.helpers')
-local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local feed, insert = helpers.feed, helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
-- Runs the test protocol with the given 'regexpengine' setting. In the old test
diff --git a/test/functional/legacy/046_multi_line_regexps_spec.lua b/test/functional/legacy/046_multi_line_regexps_spec.lua
index f8a6143b18..b17ab42fe3 100644
--- a/test/functional/legacy/046_multi_line_regexps_spec.lua
+++ b/test/functional/legacy/046_multi_line_regexps_spec.lua
@@ -3,7 +3,7 @@
local helpers = require('test.functional.helpers')
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
-local execute, expect = helpers.execute, helpers.expect
+local expect = helpers.expect
describe('multi-line regexp', function()
setup(clear)
diff --git a/test/functional/legacy/051_highlight_spec.lua b/test/functional/legacy/051_highlight_spec.lua
index 620df97aac..94c42b73e5 100644
--- a/test/functional/legacy/051_highlight_spec.lua
+++ b/test/functional/legacy/051_highlight_spec.lua
@@ -3,7 +3,7 @@
local Screen = require('test.functional.ui.screen')
local helpers = require('test.functional.helpers')
-local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local clear, feed = helpers.clear, helpers.feed
local execute, expect = helpers.execute, helpers.expect
local wait = helpers.wait
diff --git a/test/functional/legacy/056_script_local_function_spec.lua b/test/functional/legacy/056_script_local_function_spec.lua
index 147391ceb1..dec88e8001 100644
--- a/test/functional/legacy/056_script_local_function_spec.lua
+++ b/test/functional/legacy/056_script_local_function_spec.lua
@@ -3,7 +3,7 @@
local helpers = require('test.functional.helpers')
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
-local execute, expect = helpers.execute, helpers.expect
+local expect = helpers.expect
describe('source function', function()
setup(clear)
diff --git a/test/functional/legacy/060_exists_and_has_functions_spec.lua b/test/functional/legacy/060_exists_and_has_functions_spec.lua
index e9b79b490d..7f44b35a4e 100644
--- a/test/functional/legacy/060_exists_and_has_functions_spec.lua
+++ b/test/functional/legacy/060_exists_and_has_functions_spec.lua
@@ -1,8 +1,8 @@
-- Tests for the exists() and has() functions.
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
+local source = helpers.source
+local clear, expect = helpers.clear, helpers.expect
local write_file = helpers.write_file
describe('exists() and has() functions', function()
diff --git a/test/functional/legacy/061_undo_tree_spec.lua b/test/functional/legacy/061_undo_tree_spec.lua
index 8cc2a371bb..ceb114b2a7 100644
--- a/test/functional/legacy/061_undo_tree_spec.lua
+++ b/test/functional/legacy/061_undo_tree_spec.lua
@@ -1,8 +1,8 @@
-- Tests for undo tree and :earlier and :later.
local helpers = require('test.functional.helpers')
-local feed, insert, source, eq, eval, clear, execute, expect, wait, write_file
- = helpers.feed, helpers.insert, helpers.source, helpers.eq, helpers.eval,
+local feed, source, eq, eval, clear, execute, expect, wait, write_file =
+ helpers.feed, helpers.source, helpers.eq, helpers.eval,
helpers.clear, helpers.execute, helpers.expect, helpers.wait,
helpers.write_file
@@ -97,9 +97,8 @@ describe('undo tree:', function()
-- Retry up to 3 times. pcall() is _not_ used for the final attempt, so
-- that failure messages can bubble up.
- local success, result = false, ''
- for i = 1, 2 do
- success, result = pcall(test_earlier_later)
+ for _ = 1, 2 do
+ local success = pcall(test_earlier_later)
if success then
return
end
diff --git a/test/functional/legacy/063_match_and_matchadd_spec.lua b/test/functional/legacy/063_match_and_matchadd_spec.lua
index d819db7812..a354d4d328 100644
--- a/test/functional/legacy/063_match_and_matchadd_spec.lua
+++ b/test/functional/legacy/063_match_and_matchadd_spec.lua
@@ -2,10 +2,9 @@
local helpers = require('test.functional.helpers')
local Screen = require('test.functional.ui.screen')
-local feed, insert, source = helpers.feed, helpers.insert, helpers.source
-local eval, clear, execute, expect = helpers.eval, helpers.clear, helpers.execute
-local expect, eq, neq = helpers.expect, helpers.eq, helpers.neq
-local command = helpers.command
+local feed, insert = helpers.feed, helpers.insert
+local eval, clear, execute = helpers.eval, helpers.clear, helpers.execute
+local eq, neq = helpers.eq, helpers.neq
describe('063: Test for ":match", "matchadd()" and related functions', function()
setup(clear)
@@ -86,7 +85,7 @@ describe('063: Test for ":match", "matchadd()" and related functions', function(
execute("2match MyGroup2 /HUMPPA/")
execute("3match MyGroup3 /VIM/")
execute("let ml = getmatches()")
- ml = eval("ml")
+ local ml = eval("ml")
execute("call clearmatches()")
execute("call setmatches(ml)")
eq(ml, eval('getmatches()'))
diff --git a/test/functional/legacy/065_float_and_logic_operators_spec.lua b/test/functional/legacy/065_float_and_logic_operators_spec.lua
index 5cdb0b7f58..e78b230956 100644
--- a/test/functional/legacy/065_float_and_logic_operators_spec.lua
+++ b/test/functional/legacy/065_float_and_logic_operators_spec.lua
@@ -1,7 +1,7 @@
-- Test for floating point and logical operators.
local helpers = require('test.functional.helpers')
-local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local insert, source = helpers.insert, helpers.source
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
describe('floating point and logical operators', function()
diff --git a/test/functional/legacy/067_augroup_exists_spec.lua b/test/functional/legacy/067_augroup_exists_spec.lua
index 6d89ad6d55..dc4c9c7eeb 100644
--- a/test/functional/legacy/067_augroup_exists_spec.lua
+++ b/test/functional/legacy/067_augroup_exists_spec.lua
@@ -2,7 +2,7 @@
-- autocommands.
local helpers = require('test.functional.helpers')
-local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local clear = helpers.clear
local execute, expect = helpers.execute, helpers.expect
describe('augroup when calling exists()', function()
diff --git a/test/functional/legacy/072_undo_file_spec.lua b/test/functional/legacy/072_undo_file_spec.lua
index ce9129ff43..efcc2f2cc3 100644
--- a/test/functional/legacy/072_undo_file_spec.lua
+++ b/test/functional/legacy/072_undo_file_spec.lua
@@ -3,7 +3,7 @@
-- undo-able pieces. Do that by setting 'undolevels'.
local helpers = require('test.functional.helpers')
-local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local feed, insert = helpers.feed, helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
describe('72', function()
diff --git a/test/functional/legacy/074_global_var_in_viminfo_spec.lua b/test/functional/legacy/074_global_var_in_viminfo_spec.lua
index 2428b7f74d..49c4827613 100644
--- a/test/functional/legacy/074_global_var_in_viminfo_spec.lua
+++ b/test/functional/legacy/074_global_var_in_viminfo_spec.lua
@@ -13,7 +13,7 @@ describe('storing global variables in ShaDa files', function()
end)
it('is working', function()
- local nvim2 = helpers.spawn({helpers.nvim_prog, '-u', 'NONE',
+ local nvim2 = spawn({helpers.nvim_prog, '-u', 'NONE',
'-i', 'Xviminfo', '--embed'})
helpers.set_session(nvim2)
diff --git a/test/functional/legacy/075_maparg_spec.lua b/test/functional/legacy/075_maparg_spec.lua
index 418abb14d4..82965f5cb2 100644
--- a/test/functional/legacy/075_maparg_spec.lua
+++ b/test/functional/legacy/075_maparg_spec.lua
@@ -2,7 +2,7 @@
-- Also test utf8 map with a 0x80 byte.
local helpers = require('test.functional.helpers')
-local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local clear, feed = helpers.clear, helpers.feed
local execute, expect = helpers.execute, helpers.expect
describe('maparg()', function()
diff --git a/test/functional/legacy/077_mf_hash_grow_spec.lua b/test/functional/legacy/077_mf_hash_grow_spec.lua
index 825f08e968..029fe98fe9 100644
--- a/test/functional/legacy/077_mf_hash_grow_spec.lua
+++ b/test/functional/legacy/077_mf_hash_grow_spec.lua
@@ -7,7 +7,7 @@
-- If it isn't available then the test will be skipped.
local helpers = require('test.functional.helpers')
-local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local feed = helpers.feed
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
describe('mf_hash_grow()', function()
diff --git a/test/functional/legacy/078_swapfile_recover_spec.lua b/test/functional/legacy/078_swapfile_recover_spec.lua
index 33115c1317..e48fddaac1 100644
--- a/test/functional/legacy/078_swapfile_recover_spec.lua
+++ b/test/functional/legacy/078_swapfile_recover_spec.lua
@@ -4,9 +4,7 @@
-- pointer blocks.
local helpers = require('test.functional.helpers')
-local feed, insert, source = helpers.feed, helpers.insert, helpers.source
-local clear, execute, expect, source = helpers.clear, helpers.execute, helpers.expect, helpers.source
-local eval = helpers.eval
+local clear, expect, source = helpers.clear, helpers.expect, helpers.source
describe('78', function()
setup(clear)
diff --git a/test/functional/legacy/080_substitute_spec.lua b/test/functional/legacy/080_substitute_spec.lua
index 89ef7a713c..96082364e0 100644
--- a/test/functional/legacy/080_substitute_spec.lua
+++ b/test/functional/legacy/080_substitute_spec.lua
@@ -3,7 +3,7 @@
-- Test for *:s%* on :substitute.
local helpers = require('test.functional.helpers')
-local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local feed, insert = helpers.feed, helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
local eq, eval = helpers.eq, helpers.eval
diff --git a/test/functional/legacy/082_string_comparison_spec.lua b/test/functional/legacy/082_string_comparison_spec.lua
index 1615828ca0..933c6c8fa3 100644
--- a/test/functional/legacy/082_string_comparison_spec.lua
+++ b/test/functional/legacy/082_string_comparison_spec.lua
@@ -2,7 +2,7 @@
-- Also test "g~ap".
local helpers = require('test.functional.helpers')
-local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local feed, source = helpers.feed, helpers.source
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
describe('case-insensitive string comparison in UTF-8', function()
diff --git a/test/functional/legacy/084_curswant_spec.lua b/test/functional/legacy/084_curswant_spec.lua
index 55df5d3e73..946dd5e501 100644
--- a/test/functional/legacy/084_curswant_spec.lua
+++ b/test/functional/legacy/084_curswant_spec.lua
@@ -1,8 +1,8 @@
-- Tests for curswant not changing when setting an option.
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
+local insert, source = helpers.insert, helpers.source
+local clear, expect = helpers.clear, helpers.expect
describe('curswant', function()
setup(clear)
diff --git a/test/functional/legacy/089_number_relnumber_findfile_spec.lua b/test/functional/legacy/089_number_relnumber_findfile_spec.lua
index 1f8e49cc81..f72ebf3f72 100644
--- a/test/functional/legacy/089_number_relnumber_findfile_spec.lua
+++ b/test/functional/legacy/089_number_relnumber_findfile_spec.lua
@@ -4,7 +4,7 @@
local helpers = require('test.functional.helpers')
local feed = helpers.feed
-local clear, execute, expect, source = helpers.clear, helpers.execute, helpers.expect, helpers.source
+local clear, expect, source = helpers.clear, helpers.expect, helpers.source
describe("setting 'number' and 'relativenumber'", function()
setup(clear)
diff --git a/test/functional/legacy/090_sha256_spec.lua b/test/functional/legacy/090_sha256_spec.lua
index 35fbd5752e..95e50063a1 100644
--- a/test/functional/legacy/090_sha256_spec.lua
+++ b/test/functional/legacy/090_sha256_spec.lua
@@ -1,8 +1,8 @@
-- Tests for sha256() function.
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
+local insert, source = helpers.insert, helpers.source
+local clear, expect = helpers.clear, helpers.expect
describe('sha256()', function()
setup(clear)
diff --git a/test/functional/legacy/091_context_variables_spec.lua b/test/functional/legacy/091_context_variables_spec.lua
index bb9c32b84f..ffeb0c657e 100644
--- a/test/functional/legacy/091_context_variables_spec.lua
+++ b/test/functional/legacy/091_context_variables_spec.lua
@@ -1,8 +1,8 @@
-- Tests for getbufvar(), getwinvar(), gettabvar() and gettabwinvar().
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
+local insert, source = helpers.insert, helpers.source
+local clear, expect = helpers.clear, helpers.expect
describe('context variables', function()
setup(clear)
diff --git a/test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua b/test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua
index e0cc39dc40..f76ba25d7a 100644
--- a/test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua
+++ b/test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua
@@ -4,7 +4,7 @@
-- Same as legacy test 93 but using UTF-8 file encoding.
local helpers = require('test.functional.helpers')
-local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local feed, insert = helpers.feed, helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
describe('store cursor position in session file in UTF-8', function()
diff --git a/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua b/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua
index 659e716721..bf3af1a827 100644
--- a/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua
+++ b/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua
@@ -4,7 +4,7 @@
-- Same as legacy test 92 but using Latin-1 file encoding.
local helpers = require('test.functional.helpers')
-local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local feed, insert = helpers.feed, helpers.insert
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
describe('store cursor position in session file in Latin-1', function()
diff --git a/test/functional/legacy/095_regexp_multibyte_spec.lua b/test/functional/legacy/095_regexp_multibyte_spec.lua
index 559222e2ff..a80a247612 100644
--- a/test/functional/legacy/095_regexp_multibyte_spec.lua
+++ b/test/functional/legacy/095_regexp_multibyte_spec.lua
@@ -4,8 +4,8 @@
-- actually tried.
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
+local insert, source = helpers.insert, helpers.source
+local clear, expect = helpers.clear, helpers.expect
describe('regex with multi-byte', function()
setup(clear)
diff --git a/test/functional/legacy/096_location_list_spec.lua b/test/functional/legacy/096_location_list_spec.lua
index 2ccfd3530d..6e2f22ea33 100644
--- a/test/functional/legacy/096_location_list_spec.lua
+++ b/test/functional/legacy/096_location_list_spec.lua
@@ -7,7 +7,7 @@
-- it belongs to.
local helpers = require('test.functional.helpers')
-local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local source = helpers.source
local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
describe('location list', function()
diff --git a/test/functional/legacy/097_glob_path_spec.lua b/test/functional/legacy/097_glob_path_spec.lua
index 84f26478ac..5c467fbb20 100644
--- a/test/functional/legacy/097_glob_path_spec.lua
+++ b/test/functional/legacy/097_glob_path_spec.lua
@@ -3,7 +3,7 @@
-- characters.
local helpers = require('test.functional.helpers')
-local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local clear = helpers.clear
local execute, expect = helpers.execute, helpers.expect
describe('glob() and globpath()', function()
diff --git a/test/functional/legacy/098_scrollbind_spec.lua b/test/functional/legacy/098_scrollbind_spec.lua
index 7b2059e38b..6850e373ab 100644
--- a/test/functional/legacy/098_scrollbind_spec.lua
+++ b/test/functional/legacy/098_scrollbind_spec.lua
@@ -1,8 +1,8 @@
-- Test for 'scrollbind' causing an unexpected scroll of one of the windows.
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
+local source = helpers.source
+local clear, expect = helpers.clear, helpers.expect
describe('scrollbind', function()
setup(clear)
diff --git a/test/functional/legacy/100_undo_level_spec.lua b/test/functional/legacy/100_undo_level_spec.lua
index 9143d9e540..3bf72341d6 100644
--- a/test/functional/legacy/100_undo_level_spec.lua
+++ b/test/functional/legacy/100_undo_level_spec.lua
@@ -1,8 +1,8 @@
-- Tests for 'undolevel' setting being global-local
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
+local source = helpers.source
+local clear, expect = helpers.clear, helpers.expect
describe('undolevel', function()
setup(clear)
diff --git a/test/functional/legacy/101_hlsearch_spec.lua b/test/functional/legacy/101_hlsearch_spec.lua
index 4b8b1cef50..335d275c2a 100644
--- a/test/functional/legacy/101_hlsearch_spec.lua
+++ b/test/functional/legacy/101_hlsearch_spec.lua
@@ -1,9 +1,8 @@
-- Test for v:hlsearch
local helpers = require('test.functional.helpers')
-local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local clear, feed = helpers.clear, helpers.feed
local execute, expect = helpers.execute, helpers.expect
-local eval = helpers.eval
describe('v:hlsearch', function()
setup(clear)
diff --git a/test/functional/legacy/102_fnameescape_spec.lua b/test/functional/legacy/102_fnameescape_spec.lua
index 251ce68430..a3b0313d7a 100644
--- a/test/functional/legacy/102_fnameescape_spec.lua
+++ b/test/functional/legacy/102_fnameescape_spec.lua
@@ -1,7 +1,7 @@
-- Test if fnameescape is correct for special chars like!
local helpers = require('test.functional.helpers')
-local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local clear = helpers.clear
local execute, expect = helpers.execute, helpers.expect
describe('fnameescape', function()
diff --git a/test/functional/legacy/103_visual_mode_reset_spec.lua b/test/functional/legacy/103_visual_mode_reset_spec.lua
index 6b2f3bc1b6..c1407ef10a 100644
--- a/test/functional/legacy/103_visual_mode_reset_spec.lua
+++ b/test/functional/legacy/103_visual_mode_reset_spec.lua
@@ -1,8 +1,8 @@
-- Test for visual mode not being reset causing E315 error.
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
+local feed, source = helpers.feed, helpers.source
+local clear, expect = helpers.clear, helpers.expect
describe('E315 error', function()
setup(clear)
diff --git a/test/functional/legacy/105_filename_modifiers_spec.lua b/test/functional/legacy/105_filename_modifiers_spec.lua
index 3b417a88eb..3413667022 100644
--- a/test/functional/legacy/105_filename_modifiers_spec.lua
+++ b/test/functional/legacy/105_filename_modifiers_spec.lua
@@ -1,7 +1,7 @@
-- Test filename modifiers.
local helpers = require('test.functional.helpers')
-local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local clear = helpers.clear
local execute, expect = helpers.execute, helpers.expect
describe('filename modifiers', function()
diff --git a/test/functional/legacy/106_errorformat_spec.lua b/test/functional/legacy/106_errorformat_spec.lua
index 5b6037f928..5958f1aa7b 100644
--- a/test/functional/legacy/106_errorformat_spec.lua
+++ b/test/functional/legacy/106_errorformat_spec.lua
@@ -1,7 +1,7 @@
-- Tests for errorformat.
local helpers = require('test.functional.helpers')
-local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local clear = helpers.clear
local execute, expect = helpers.execute, helpers.expect
describe('errorformat', function()
diff --git a/test/functional/legacy/107_adjust_window_and_contents_spec.lua b/test/functional/legacy/107_adjust_window_and_contents_spec.lua
index f6ea7e5a6c..7a6de3d748 100644
--- a/test/functional/legacy/107_adjust_window_and_contents_spec.lua
+++ b/test/functional/legacy/107_adjust_window_and_contents_spec.lua
@@ -2,8 +2,8 @@
local helpers = require('test.functional.helpers')
local Screen = require('test.functional.ui.screen')
-local feed, insert, source = helpers.feed, helpers.insert, helpers.source
-local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
+local insert = helpers.insert
+local clear, execute = helpers.clear, helpers.execute
describe('107', function()
setup(clear)
diff --git a/test/functional/legacy/listlbr_utf8_spec.lua b/test/functional/legacy/listlbr_utf8_spec.lua
index 15d12ac4af..69e7b87a21 100644
--- a/test/functional/legacy/listlbr_utf8_spec.lua
+++ b/test/functional/legacy/listlbr_utf8_spec.lua
@@ -1,8 +1,8 @@
-- Test for linebreak and list option in utf-8 mode
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
+local source = helpers.source
+local clear, expect = helpers.clear, helpers.expect
describe('linebreak', function()
setup(clear)
diff --git a/test/functional/legacy/nested_function_spec.lua b/test/functional/legacy/nested_function_spec.lua
index 87371c8294..fac3b03191 100644
--- a/test/functional/legacy/nested_function_spec.lua
+++ b/test/functional/legacy/nested_function_spec.lua
@@ -1,7 +1,7 @@
-- Tests for nested function.
local helpers = require('test.functional.helpers')
-local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local clear, insert = helpers.clear, helpers.insert
local execute, expect, source = helpers.execute, helpers.expect, helpers.source
describe('test_nested_function', function()
diff --git a/test/functional/legacy/qf_title_spec.lua b/test/functional/legacy/qf_title_spec.lua
index aa005117be..01c781cc05 100644
--- a/test/functional/legacy/qf_title_spec.lua
+++ b/test/functional/legacy/qf_title_spec.lua
@@ -1,8 +1,8 @@
-- Tests for quickfix window's title
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
+local insert, source = helpers.insert, helpers.source
+local clear, expect = helpers.clear, helpers.expect
describe('qf_title', function()
setup(clear)
diff --git a/test/functional/legacy/signs_spec.lua b/test/functional/legacy/signs_spec.lua
index 89b2bf3b73..5a834c39e3 100644
--- a/test/functional/legacy/signs_spec.lua
+++ b/test/functional/legacy/signs_spec.lua
@@ -1,7 +1,6 @@
-- Tests for signs
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('signs', function()
diff --git a/test/functional/legacy/writefile_spec.lua b/test/functional/legacy/writefile_spec.lua
index e7a260bcd9..efdfc1d09f 100644
--- a/test/functional/legacy/writefile_spec.lua
+++ b/test/functional/legacy/writefile_spec.lua
@@ -1,7 +1,6 @@
-- Tests for writefile()
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('writefile', function()
diff --git a/test/functional/normal/K_spec.lua b/test/functional/normal/K_spec.lua
index dbda6dcb93..df6b429f50 100644
--- a/test/functional/normal/K_spec.lua
+++ b/test/functional/normal/K_spec.lua
@@ -1,7 +1,6 @@
local helpers = require('test.functional.helpers')
-local execute, eq, clear, eval, feed, ok =
- helpers.execute, helpers.eq, helpers.clear, helpers.eval,
- helpers.feed, helpers.ok
+local eq, clear, eval, feed =
+ helpers.eq, helpers.clear, helpers.eval, helpers.feed
describe('K', function()
local test_file = 'K_spec_out'
diff --git a/test/functional/plugin/helpers.lua b/test/functional/plugin/helpers.lua
new file mode 100644
index 0000000000..cc76794267
--- /dev/null
+++ b/test/functional/plugin/helpers.lua
@@ -0,0 +1,41 @@
+local paths = require('test.config.paths')
+
+local helpers = require('test.functional.helpers')
+local spawn, set_session, nvim_prog, merge_args =
+ helpers.spawn, helpers.set_session, helpers.nvim_prog, helpers.merge_args
+
+local additional_cmd = ''
+
+local function nvim_argv(shada_file)
+ local rtp_value = ('\'%s/runtime\''):format(
+ paths.test_source_path:gsub('\'', '\'\''))
+ local nvim_args = {nvim_prog, '-u', 'NORC', '-i', shada_file or 'NONE', '-N',
+ '--cmd', 'set shortmess+=I background=light noswapfile',
+ '--cmd', 'let &runtimepath=' .. rtp_value,
+ '--cmd', additional_cmd,
+ '--embed'}
+ if helpers.prepend_argv then
+ return merge_args(helpers.prepend_argv, nvim_args)
+ else
+ return nvim_args
+ end
+end
+
+local session = nil
+
+local reset = function(...)
+ if session then
+ session:exit(0)
+ end
+ session = spawn(nvim_argv(...))
+ set_session(session)
+end
+
+local set_additional_cmd = function(s)
+ additional_cmd = s
+end
+
+return {
+ reset=reset,
+ set_additional_cmd=set_additional_cmd,
+}
diff --git a/test/functional/plugin/msgpack_spec.lua b/test/functional/plugin/msgpack_spec.lua
new file mode 100644
index 0000000000..18ff0f5156
--- /dev/null
+++ b/test/functional/plugin/msgpack_spec.lua
@@ -0,0 +1,699 @@
+local helpers = require('test.functional.helpers')
+local eq, nvim_eval, nvim_command, exc_exec =
+ helpers.eq, helpers.eval, helpers.command, helpers.exc_exec
+
+local plugin_helpers = require('test.functional.plugin.helpers')
+local reset = plugin_helpers.reset
+
+describe('In autoload/msgpack.vim', function()
+ before_each(reset)
+
+ local sp = function(typ, val)
+ return ('{"_TYPE": v:msgpack_types.%s, "_VAL": %s}'):format(typ, val)
+ end
+ local mapsp = function(...)
+ local val = ''
+ for i=1,(select('#', ...)/2) do
+ val = ('%s[%s,%s],'):format(val, select(i * 2 - 1, ...),
+ select(i * 2, ...))
+ end
+ return sp('map', '[' .. val .. ']')
+ end
+
+ local nan = -(1.0/0.0-1.0/0.0)
+ local minus_nan = 1.0/0.0-1.0/0.0
+ local inf = 1.0/0.0
+ local minus_inf = -(1.0/0.0)
+ local has_minus_nan = tostring(nan) ~= tostring(minus_nan)
+
+ describe('function msgpack#equal', function()
+ local msgpack_eq = function(expected, a, b)
+ eq(expected, nvim_eval(('msgpack#equal(%s, %s)'):format(a, b)))
+ if a ~= b then
+ eq(expected, nvim_eval(('msgpack#equal(%s, %s)'):format(b, a)))
+ end
+ end
+ it('compares raw integers correctly', function()
+ msgpack_eq(1, '1', '1')
+ msgpack_eq(0, '1', '0')
+ end)
+ it('compares integer specials correctly', function()
+ msgpack_eq(1, sp('integer', '[-1, 1, 0, 0]'),
+ sp('integer', '[-1, 1, 0, 0]'))
+ msgpack_eq(0, sp('integer', '[-1, 1, 0, 0]'),
+ sp('integer', '[ 1, 1, 0, 0]'))
+ end)
+ it('compares integer specials with raw integer correctly', function()
+ msgpack_eq(1, sp('integer', '[-1, 0, 0, 1]'), '-1')
+ msgpack_eq(0, sp('integer', '[-1, 0, 0, 1]'), '1')
+ msgpack_eq(0, sp('integer', '[ 1, 0, 0, 1]'), '-1')
+ msgpack_eq(1, sp('integer', '[ 1, 0, 0, 1]'), '1')
+ end)
+ it('compares integer with float correctly', function()
+ msgpack_eq(0, '0', '0.0')
+ end)
+ it('compares raw binaries correctly', function()
+ msgpack_eq(1, '"abc\\ndef"', '"abc\\ndef"')
+ msgpack_eq(0, '"abc\\ndef"', '"abc\\nghi"')
+ end)
+ it('compares binary specials correctly', function()
+ msgpack_eq(1, sp('binary', '["abc\\n", "def"]'),
+ sp('binary', '["abc\\n", "def"]'))
+ msgpack_eq(0, sp('binary', '["abc", "def"]'),
+ sp('binary', '["abc\\n", "def"]'))
+ end)
+ it('compares binary specials with raw binaries correctly', function()
+ msgpack_eq(1, sp('binary', '["abc", "def"]'), '"abc\\ndef"')
+ msgpack_eq(0, sp('binary', '["abc", "def"]'), '"abcdef"')
+ end)
+ it('compares string specials correctly', function()
+ msgpack_eq(1, sp('string', '["abc\\n", "def"]'),
+ sp('string', '["abc\\n", "def"]'))
+ msgpack_eq(0, sp('string', '["abc", "def"]'),
+ sp('string', '["abc\\n", "def"]'))
+ end)
+ it('compares string specials with binary correctly', function()
+ msgpack_eq(0, sp('string', '["abc\\n", "def"]'),
+ sp('binary', '["abc\\n", "def"]'))
+ msgpack_eq(0, sp('string', '["abc", "def"]'), '"abc\\ndef"')
+ msgpack_eq(0, sp('binary', '["abc\\n", "def"]'),
+ sp('string', '["abc\\n", "def"]'))
+ msgpack_eq(0, '"abc\\ndef"', sp('string', '["abc", "def"]'))
+ end)
+ it('compares ext specials correctly', function()
+ msgpack_eq(1, sp('ext', '[1, ["", "ac"]]'), sp('ext', '[1, ["", "ac"]]'))
+ msgpack_eq(0, sp('ext', '[2, ["", "ac"]]'), sp('ext', '[1, ["", "ac"]]'))
+ msgpack_eq(0, sp('ext', '[1, ["", "ac"]]'), sp('ext', '[1, ["", "abc"]]'))
+ end)
+ it('compares raw maps correctly', function()
+ msgpack_eq(1, '{"a": 1, "b": 2}', '{"b": 2, "a": 1}')
+ msgpack_eq(1, '{}', '{}')
+ msgpack_eq(0, '{}', '{"a": 1}')
+ msgpack_eq(0, '{"a": 2}', '{"a": 1}')
+ msgpack_eq(0, '{"a": 1}', '{"b": 1}')
+ msgpack_eq(0, '{"a": 1}', '{"a": 1, "b": 1}')
+ msgpack_eq(0, '{"a": 1, "b": 1}', '{"b": 1}')
+ end)
+ it('compares map specials correctly', function()
+ msgpack_eq(1, mapsp(), mapsp())
+ msgpack_eq(1, mapsp(sp('binary', '[""]'), '""'),
+ mapsp(sp('binary', '[""]'), '""'))
+ msgpack_eq(1, mapsp(mapsp('1', '1'), mapsp('1', '1')),
+ mapsp(mapsp('1', '1'), mapsp('1', '1')))
+ msgpack_eq(0, mapsp(), mapsp('1', '1'))
+ msgpack_eq(0, mapsp(sp('binary', '["a"]'), '""'),
+ mapsp(sp('binary', '[""]'), '""'))
+ msgpack_eq(0, mapsp(sp('binary', '[""]'), '"a"'),
+ mapsp(sp('binary', '[""]'), '""'))
+ msgpack_eq(0, mapsp(sp('binary', '["a"]'), '"a"'),
+ mapsp(sp('binary', '[""]'), '""'))
+ msgpack_eq(0, mapsp(mapsp('1', '1'), mapsp('1', '1')),
+ mapsp(sp('binary', '[""]'), mapsp('1', '1')))
+ msgpack_eq(0, mapsp(mapsp('1', '1'), mapsp('1', '1')),
+ mapsp(mapsp('2', '1'), mapsp('1', '1')))
+ msgpack_eq(0, mapsp(mapsp('1', '1'), mapsp('1', '1')),
+ mapsp(mapsp('1', '2'), mapsp('1', '1')))
+ msgpack_eq(0, mapsp(mapsp('1', '1'), mapsp('1', '1')),
+ mapsp(mapsp('1', '1'), mapsp('2', '1')))
+ msgpack_eq(0, mapsp(mapsp('1', '1'), mapsp('1', '1')),
+ mapsp(mapsp('1', '1'), mapsp('1', '2')))
+ msgpack_eq(1, mapsp(mapsp('2', '1'), mapsp('1', '1'),
+ mapsp('1', '1'), mapsp('1', '1')),
+ mapsp(mapsp('1', '1'), mapsp('1', '1'),
+ mapsp('2', '1'), mapsp('1', '1')))
+ end)
+ it('compares map specials with raw maps correctly', function()
+ msgpack_eq(1, mapsp(), '{}')
+ msgpack_eq(1, mapsp(sp('string', '["1"]'), '1'), '{"1": 1}')
+ msgpack_eq(1, mapsp(sp('string', '["1"]'), sp('integer', '[1, 0, 0, 1]')),
+ '{"1": 1}')
+ msgpack_eq(0, mapsp(sp('integer', '[1, 0, 0, 1]'), sp('string', '["1"]')),
+ '{1: "1"}')
+ msgpack_eq(0, mapsp('"1"', sp('integer', '[1, 0, 0, 1]')),
+ '{"1": 1}')
+ msgpack_eq(0,
+ mapsp(sp('string', '["1"]'), '1', sp('string', '["2"]'), '2'),
+ '{"1": 1}')
+ msgpack_eq(0, mapsp(sp('string', '["1"]'), '1'), '{"1": 1, "2": 2}')
+ end)
+ it('compares raw arrays correctly', function()
+ msgpack_eq(1, '[]', '[]')
+ msgpack_eq(0, '[]', '[1]')
+ msgpack_eq(1, '[1]', '[1]')
+ msgpack_eq(1, '[[[1]]]', '[[[1]]]')
+ msgpack_eq(0, '[[[2]]]', '[[[1]]]')
+ end)
+ it('compares array specials correctly', function()
+ msgpack_eq(1, sp('array', '[]'), sp('array', '[]'))
+ msgpack_eq(0, sp('array', '[]'), sp('array', '[1]'))
+ msgpack_eq(1, sp('array', '[1]'), sp('array', '[1]'))
+ msgpack_eq(1, sp('array', '[[[1]]]'), sp('array', '[[[1]]]'))
+ msgpack_eq(0, sp('array', '[[[1]]]'), sp('array', '[[[2]]]'))
+ end)
+ it('compares array specials with raw arrays correctly', function()
+ msgpack_eq(1, sp('array', '[]'), '[]')
+ msgpack_eq(0, sp('array', '[]'), '[1]')
+ msgpack_eq(1, sp('array', '[1]'), '[1]')
+ msgpack_eq(1, sp('array', '[[[1]]]'), '[[[1]]]')
+ msgpack_eq(0, sp('array', '[[[1]]]'), '[[[2]]]')
+ end)
+ it('compares raw floats correctly', function()
+ msgpack_eq(1, '0.0', '0.0')
+ msgpack_eq(1, '(1.0/0.0-1.0/0.0)', '(1.0/0.0-1.0/0.0)')
+ if has_minus_nan then
+ msgpack_eq(0, '(1.0/0.0-1.0/0.0)', '-(1.0/0.0-1.0/0.0)')
+ end
+ msgpack_eq(1, '-(1.0/0.0-1.0/0.0)', '-(1.0/0.0-1.0/0.0)')
+ msgpack_eq(1, '1.0/0.0', '1.0/0.0')
+ msgpack_eq(1, '-(1.0/0.0)', '-(1.0/0.0)')
+ msgpack_eq(1, '0.0', '0.0')
+ msgpack_eq(0, '0.0', '1.0')
+ msgpack_eq(0, '0.0', '(1.0/0.0-1.0/0.0)')
+ msgpack_eq(0, '0.0', '1.0/0.0')
+ msgpack_eq(0, '0.0', '-(1.0/0.0)')
+ msgpack_eq(0, '1.0/0.0', '-(1.0/0.0)')
+ msgpack_eq(0, '(1.0/0.0-1.0/0.0)', '-(1.0/0.0)')
+ msgpack_eq(0, '(1.0/0.0-1.0/0.0)', '1.0/0.0')
+ end)
+ it('compares float specials with raw floats correctly', function()
+ msgpack_eq(1, sp('float', '0.0'), '0.0')
+ msgpack_eq(1, sp('float', '(1.0/0.0-1.0/0.0)'), '(1.0/0.0-1.0/0.0)')
+ if has_minus_nan then
+ msgpack_eq(0, sp('float', '(1.0/0.0-1.0/0.0)'), '-(1.0/0.0-1.0/0.0)')
+ msgpack_eq(0, sp('float', '-(1.0/0.0-1.0/0.0)'), '(1.0/0.0-1.0/0.0)')
+ end
+ msgpack_eq(1, sp('float', '-(1.0/0.0-1.0/0.0)'), '-(1.0/0.0-1.0/0.0)')
+ msgpack_eq(1, sp('float', '1.0/0.0'), '1.0/0.0')
+ msgpack_eq(1, sp('float', '-(1.0/0.0)'), '-(1.0/0.0)')
+ msgpack_eq(1, sp('float', '0.0'), '0.0')
+ msgpack_eq(0, sp('float', '0.0'), '1.0')
+ msgpack_eq(0, sp('float', '0.0'), '(1.0/0.0-1.0/0.0)')
+ msgpack_eq(0, sp('float', '0.0'), '1.0/0.0')
+ msgpack_eq(0, sp('float', '0.0'), '-(1.0/0.0)')
+ msgpack_eq(0, sp('float', '1.0/0.0'), '-(1.0/0.0)')
+ msgpack_eq(0, sp('float', '(1.0/0.0-1.0/0.0)'), '-(1.0/0.0)')
+ msgpack_eq(0, sp('float', '(1.0/0.0-1.0/0.0)'), '1.0/0.0')
+ end)
+ it('compares float specials correctly', function()
+ msgpack_eq(1, sp('float', '0.0'), sp('float', '0.0'))
+ msgpack_eq(1, sp('float', '(1.0/0.0-1.0/0.0)'),
+ sp('float', '(1.0/0.0-1.0/0.0)'))
+ msgpack_eq(1, sp('float', '1.0/0.0'), sp('float', '1.0/0.0'))
+ msgpack_eq(1, sp('float', '-(1.0/0.0)'), sp('float', '-(1.0/0.0)'))
+ msgpack_eq(1, sp('float', '0.0'), sp('float', '0.0'))
+ msgpack_eq(0, sp('float', '0.0'), sp('float', '1.0'))
+ msgpack_eq(0, sp('float', '0.0'), sp('float', '(1.0/0.0-1.0/0.0)'))
+ msgpack_eq(0, sp('float', '0.0'), sp('float', '1.0/0.0'))
+ msgpack_eq(0, sp('float', '0.0'), sp('float', '-(1.0/0.0)'))
+ msgpack_eq(0, sp('float', '1.0/0.0'), sp('float', '-(1.0/0.0)'))
+ msgpack_eq(0, sp('float', '(1.0/0.0-1.0/0.0)'), sp('float', '-(1.0/0.0)'))
+ if has_minus_nan then
+ msgpack_eq(0, sp('float', '(1.0/0.0-1.0/0.0)'),
+ sp('float', '-(1.0/0.0-1.0/0.0)'))
+ end
+ msgpack_eq(1, sp('float', '-(1.0/0.0-1.0/0.0)'),
+ sp('float', '-(1.0/0.0-1.0/0.0)'))
+ msgpack_eq(0, sp('float', '(1.0/0.0-1.0/0.0)'), sp('float', '1.0/0.0'))
+ end)
+ it('compares boolean specials correctly', function()
+ msgpack_eq(1, sp('boolean', '1'), sp('boolean', '1'))
+ msgpack_eq(0, sp('boolean', '1'), sp('boolean', '0'))
+ end)
+ it('compares nil specials correctly', function()
+ msgpack_eq(1, sp('nil', '1'), sp('nil', '0'))
+ end)
+ it('compares nil, boolean and integer values with each other correctly',
+ function()
+ msgpack_eq(0, sp('boolean', '1'), '1')
+ msgpack_eq(0, sp('boolean', '1'), sp('nil', '0'))
+ msgpack_eq(0, sp('boolean', '1'), sp('nil', '1'))
+ msgpack_eq(0, sp('boolean', '0'), sp('nil', '0'))
+ msgpack_eq(0, sp('boolean', '0'), '0')
+ msgpack_eq(0, sp('boolean', '0'), sp('integer', '[1, 0, 0, 0]'))
+ msgpack_eq(0, sp('boolean', '0'), sp('integer', '[1, 0, 0, 1]'))
+ msgpack_eq(0, sp('boolean', '1'), sp('integer', '[1, 0, 0, 1]'))
+ msgpack_eq(0, sp('nil', '0'), sp('integer', '[1, 0, 0, 0]'))
+ msgpack_eq(0, sp('nil', '0'), '0')
+ end)
+ end)
+
+ describe('function msgpack#is_int', function()
+ it('works', function()
+ eq(1, nvim_eval('msgpack#is_int(1)'))
+ eq(1, nvim_eval('msgpack#is_int(-1)'))
+ eq(1, nvim_eval(('msgpack#is_int(%s)'):format(
+ sp('integer', '[1, 0, 0, 1]'))))
+ eq(1, nvim_eval(('msgpack#is_int(%s)'):format(
+ sp('integer', '[-1, 0, 0, 1]'))))
+ eq(0, nvim_eval(('msgpack#is_int(%s)'):format(
+ sp('float', '0.0'))))
+ eq(0, nvim_eval(('msgpack#is_int(%s)'):format(
+ sp('boolean', '0'))))
+ eq(0, nvim_eval(('msgpack#is_int(%s)'):format(
+ sp('nil', '0'))))
+ eq(0, nvim_eval('msgpack#is_int("")'))
+ end)
+ end)
+
+ describe('function msgpack#is_uint', function()
+ it('works', function()
+ eq(1, nvim_eval('msgpack#is_uint(1)'))
+ eq(0, nvim_eval('msgpack#is_uint(-1)'))
+ eq(1, nvim_eval(('msgpack#is_uint(%s)'):format(
+ sp('integer', '[1, 0, 0, 1]'))))
+ eq(0, nvim_eval(('msgpack#is_uint(%s)'):format(
+ sp('integer', '[-1, 0, 0, 1]'))))
+ eq(0, nvim_eval(('msgpack#is_uint(%s)'):format(
+ sp('float', '0.0'))))
+ eq(0, nvim_eval(('msgpack#is_uint(%s)'):format(
+ sp('boolean', '0'))))
+ eq(0, nvim_eval(('msgpack#is_uint(%s)'):format(
+ sp('nil', '0'))))
+ eq(0, nvim_eval('msgpack#is_uint("")'))
+ end)
+ end)
+
+ describe('function msgpack#strftime', function()
+ it('works', function()
+ local epoch = os.date('%Y-%m-%dT%H:%M:%S', 0)
+ eq(epoch, nvim_eval('msgpack#strftime("%Y-%m-%dT%H:%M:%S", 0)'))
+ eq(epoch, nvim_eval(
+ ('msgpack#strftime("%%Y-%%m-%%dT%%H:%%M:%%S", %s)'):format(sp(
+ 'integer', '[1, 0, 0, 0]'))))
+ end)
+ end)
+
+ describe('function msgpack#strptime', function()
+ it('works', function()
+ for _, v in ipairs({0, 10, 100000, 204, 1000000000}) do
+ local time = os.date('%Y-%m-%dT%H:%M:%S', v)
+ eq(v, nvim_eval('msgpack#strptime("%Y-%m-%dT%H:%M:%S", '
+ .. '"' .. time .. '")'))
+ end
+ end)
+ end)
+
+ describe('function msgpack#type', function()
+ local type_eq = function(expected, val)
+ eq(expected, nvim_eval(('msgpack#type(%s)'):format(val)))
+ end
+
+ it('works for special dictionaries', function()
+ type_eq('string', sp('string', '[""]'))
+ type_eq('binary', sp('binary', '[""]'))
+ type_eq('ext', sp('ext', '[1, [""]]'))
+ type_eq('array', sp('array', '[]'))
+ type_eq('map', sp('map', '[]'))
+ type_eq('integer', sp('integer', '[1, 0, 0, 0]'))
+ type_eq('float', sp('float', '0.0'))
+ type_eq('boolean', sp('boolean', '0'))
+ type_eq('nil', sp('nil', '0'))
+ end)
+
+ it('works for regular values', function()
+ type_eq('binary', '""')
+ type_eq('array', '[]')
+ type_eq('map', '{}')
+ type_eq('integer', '1')
+ type_eq('float', '0.0')
+ type_eq('float', '(1.0/0.0)')
+ type_eq('float', '-(1.0/0.0)')
+ type_eq('float', '(1.0/0.0-1.0/0.0)')
+ end)
+ end)
+
+ describe('function msgpack#special_type', function()
+ local sp_type_eq = function(expected, val)
+ eq(expected, nvim_eval(('msgpack#special_type(%s)'):format(val)))
+ end
+
+ it('works for special dictionaries', function()
+ sp_type_eq('string', sp('string', '[""]'))
+ sp_type_eq('binary', sp('binary', '[""]'))
+ sp_type_eq('ext', sp('ext', '[1, [""]]'))
+ sp_type_eq('array', sp('array', '[]'))
+ sp_type_eq('map', sp('map', '[]'))
+ sp_type_eq('integer', sp('integer', '[1, 0, 0, 0]'))
+ sp_type_eq('float', sp('float', '0.0'))
+ sp_type_eq('boolean', sp('boolean', '0'))
+ sp_type_eq('nil', sp('nil', '0'))
+ end)
+
+ it('works for regular values', function()
+ sp_type_eq(0, '""')
+ sp_type_eq(0, '[]')
+ sp_type_eq(0, '{}')
+ sp_type_eq(0, '1')
+ sp_type_eq(0, '0.0')
+ sp_type_eq(0, '(1.0/0.0)')
+ sp_type_eq(0, '-(1.0/0.0)')
+ sp_type_eq(0, '(1.0/0.0-1.0/0.0)')
+ end)
+ end)
+
+ describe('function msgpack#string', function()
+ local string_eq = function(expected, val)
+ eq(expected, nvim_eval(('msgpack#string(%s)'):format(val)))
+ end
+
+ it('works for special dictionaries', function()
+ string_eq('=""', sp('string', '[""]'))
+ string_eq('="\\n"', sp('string', '["", ""]'))
+ string_eq('="ab\\0c\\nde"', sp('string', '["ab\\nc", "de"]'))
+ string_eq('""', sp('binary', '[""]'))
+ string_eq('"\\n"', sp('binary', '["", ""]'))
+ string_eq('"ab\\0c\\nde"', sp('binary', '["ab\\nc", "de"]'))
+ string_eq('+(2)""', sp('ext', '[2, [""]]'))
+ string_eq('+(2)"\\n"', sp('ext', '[2, ["", ""]]'))
+ string_eq('+(2)"ab\\0c\\nde"', sp('ext', '[2, ["ab\\nc", "de"]]'))
+ string_eq('[]', sp('array', '[]'))
+ string_eq('[[[[{}]]]]', sp('array', '[[[[{}]]]]'))
+ string_eq('{}', sp('map', '[]'))
+ string_eq('{2: 10}', sp('map', '[[2, 10]]'))
+ string_eq('{{1: 1}: {1: 1}, {2: 1}: {1: 1}}',
+ mapsp(mapsp('2', '1'), mapsp('1', '1'),
+ mapsp('1', '1'), mapsp('1', '1')))
+ string_eq('{{1: 1}: {1: 1}, {2: 1}: {1: 1}}',
+ mapsp(mapsp('1', '1'), mapsp('1', '1'),
+ mapsp('2', '1'), mapsp('1', '1')))
+ string_eq('{[1, 2, {{1: 2}: 1}]: [1, 2, {{1: 2}: 1}]}',
+ mapsp(('[1, 2, %s]'):format(mapsp(mapsp('1', '2'), '1')),
+ ('[1, 2, %s]'):format(mapsp(mapsp('1', '2'), '1'))))
+ string_eq('0x0000000000000000', sp('integer', '[1, 0, 0, 0]'))
+ string_eq('-0x0000000100000000', sp('integer', '[-1, 0, 2, 0]'))
+ string_eq('0x123456789abcdef0',
+ sp('integer', '[ 1, 0, 610839793, 448585456]'))
+ string_eq('-0x123456789abcdef0',
+ sp('integer', '[-1, 0, 610839793, 448585456]'))
+ string_eq('0xf23456789abcdef0',
+ sp('integer', '[ 1, 3, 1684581617, 448585456]'))
+ string_eq('-0x723456789abcdef0',
+ sp('integer', '[-1, 1, 1684581617, 448585456]'))
+ string_eq('0.0', sp('float', '0.0'))
+ string_eq('inf', sp('float', '(1.0/0.0)'))
+ string_eq('-inf', sp('float', '-(1.0/0.0)'))
+ if has_minus_nan then
+ string_eq('-nan', sp('float', '(1.0/0.0-1.0/0.0)'))
+ end
+ string_eq('nan', sp('float', '-(1.0/0.0-1.0/0.0)'))
+ string_eq('FALSE', sp('boolean', '0'))
+ string_eq('TRUE', sp('boolean', '1'))
+ string_eq('NIL', sp('nil', '0'))
+ end)
+
+ it('works for regular values', function()
+ string_eq('""', '""')
+ string_eq('"\\n"', '"\\n"')
+ string_eq('[]', '[]')
+ string_eq('[[[{}]]]', '[[[{}]]]')
+ string_eq('{}', '{}')
+ string_eq('{="2": 10}', '{2: 10}')
+ string_eq('{="2": [{}]}', '{2: [{}]}')
+ string_eq('1', '1')
+ string_eq('0.0', '0.0')
+ string_eq('inf', '(1.0/0.0)')
+ string_eq('-inf', '-(1.0/0.0)')
+ if has_minus_nan then
+ string_eq('-nan', '(1.0/0.0-1.0/0.0)')
+ end
+ string_eq('nan', '-(1.0/0.0-1.0/0.0)')
+ end)
+ end)
+
+ describe('function msgpack#deepcopy', function()
+ it('works for special dictionaries', function()
+ nvim_command('let sparr = ' .. sp('array', '[[[]]]'))
+ nvim_command('let spmap = ' .. mapsp('"abc"', '[[]]'))
+ nvim_command('let spint = ' .. sp('integer', '[1, 0, 0, 0]'))
+ nvim_command('let spflt = ' .. sp('float', '1.0'))
+ nvim_command('let spext = ' .. sp('ext', '[2, ["abc", "def"]]'))
+ nvim_command('let spstr = ' .. sp('string', '["abc", "def"]'))
+ nvim_command('let spbin = ' .. sp('binary', '["abc", "def"]'))
+ nvim_command('let spbln = ' .. sp('boolean', '0'))
+ nvim_command('let spnil = ' .. sp('nil', '0'))
+
+ nvim_command('let sparr2 = msgpack#deepcopy(sparr)')
+ nvim_command('let spmap2 = msgpack#deepcopy(spmap)')
+ nvim_command('let spint2 = msgpack#deepcopy(spint)')
+ nvim_command('let spflt2 = msgpack#deepcopy(spflt)')
+ nvim_command('let spext2 = msgpack#deepcopy(spext)')
+ nvim_command('let spstr2 = msgpack#deepcopy(spstr)')
+ nvim_command('let spbin2 = msgpack#deepcopy(spbin)')
+ nvim_command('let spbln2 = msgpack#deepcopy(spbln)')
+ nvim_command('let spnil2 = msgpack#deepcopy(spnil)')
+
+ eq('array', nvim_eval('msgpack#type(sparr2)'))
+ eq('map', nvim_eval('msgpack#type(spmap2)'))
+ eq('integer', nvim_eval('msgpack#type(spint2)'))
+ eq('float', nvim_eval('msgpack#type(spflt2)'))
+ eq('ext', nvim_eval('msgpack#type(spext2)'))
+ eq('string', nvim_eval('msgpack#type(spstr2)'))
+ eq('binary', nvim_eval('msgpack#type(spbin2)'))
+ eq('boolean', nvim_eval('msgpack#type(spbln2)'))
+ eq('nil', nvim_eval('msgpack#type(spnil2)'))
+
+ nvim_command('call add(sparr._VAL, 0)')
+ nvim_command('call add(sparr._VAL[0], 0)')
+ nvim_command('call add(sparr._VAL[0][0], 0)')
+ nvim_command('call add(spmap._VAL, [0, 0])')
+ nvim_command('call add(spmap._VAL[0][1], 0)')
+ nvim_command('call add(spmap._VAL[0][1][0], 0)')
+ nvim_command('let spint._VAL[1] = 1')
+ nvim_command('let spflt._VAL = 0.0')
+ nvim_command('let spext._VAL[0] = 3')
+ nvim_command('let spext._VAL[1][0] = "gh"')
+ nvim_command('let spstr._VAL[0] = "gh"')
+ nvim_command('let spbin._VAL[0] = "gh"')
+ nvim_command('let spbln._VAL = 1')
+ nvim_command('let spnil._VAL = 1')
+
+ eq({_TYPE={}, _VAL={{{}}}}, nvim_eval('sparr2'))
+ eq({_TYPE={}, _VAL={{'abc', {{}}}}}, nvim_eval('spmap2'))
+ eq({_TYPE={}, _VAL={1, 0, 0, 0}}, nvim_eval('spint2'))
+ eq({_TYPE={}, _VAL=1.0}, nvim_eval('spflt2'))
+ eq({_TYPE={}, _VAL={2, {'abc', 'def'}}}, nvim_eval('spext2'))
+ eq({_TYPE={}, _VAL={'abc', 'def'}}, nvim_eval('spstr2'))
+ eq({_TYPE={}, _VAL={'abc', 'def'}}, nvim_eval('spbin2'))
+ eq({_TYPE={}, _VAL=0}, nvim_eval('spbln2'))
+ eq({_TYPE={}, _VAL=0}, nvim_eval('spnil2'))
+
+ nvim_command('let sparr._TYPE = []')
+ nvim_command('let spmap._TYPE = []')
+ nvim_command('let spint._TYPE = []')
+ nvim_command('let spflt._TYPE = []')
+ nvim_command('let spext._TYPE = []')
+ nvim_command('let spstr._TYPE = []')
+ nvim_command('let spbin._TYPE = []')
+ nvim_command('let spbln._TYPE = []')
+ nvim_command('let spnil._TYPE = []')
+
+ eq('array', nvim_eval('msgpack#special_type(sparr2)'))
+ eq('map', nvim_eval('msgpack#special_type(spmap2)'))
+ eq('integer', nvim_eval('msgpack#special_type(spint2)'))
+ eq('float', nvim_eval('msgpack#special_type(spflt2)'))
+ eq('ext', nvim_eval('msgpack#special_type(spext2)'))
+ eq('string', nvim_eval('msgpack#special_type(spstr2)'))
+ eq('binary', nvim_eval('msgpack#special_type(spbin2)'))
+ eq('boolean', nvim_eval('msgpack#special_type(spbln2)'))
+ eq('nil', nvim_eval('msgpack#special_type(spnil2)'))
+ end)
+
+ it('works for regular values', function()
+ nvim_command('let arr = [[[]]]')
+ nvim_command('let map = {1: {}}')
+ nvim_command('let int = 1')
+ nvim_command('let flt = 2.0')
+ nvim_command('let bin = "abc"')
+
+ nvim_command('let arr2 = msgpack#deepcopy(arr)')
+ nvim_command('let map2 = msgpack#deepcopy(map)')
+ nvim_command('let int2 = msgpack#deepcopy(int)')
+ nvim_command('let flt2 = msgpack#deepcopy(flt)')
+ nvim_command('let bin2 = msgpack#deepcopy(bin)')
+
+ eq('array', nvim_eval('msgpack#type(arr2)'))
+ eq('map', nvim_eval('msgpack#type(map2)'))
+ eq('integer', nvim_eval('msgpack#type(int2)'))
+ eq('float', nvim_eval('msgpack#type(flt2)'))
+ eq('binary', nvim_eval('msgpack#type(bin2)'))
+
+ nvim_command('call add(arr, 0)')
+ nvim_command('call add(arr[0], 0)')
+ nvim_command('call add(arr[0][0], 0)')
+ nvim_command('let map.a = 1')
+ nvim_command('let map.1.a = 1')
+ nvim_command('let int = 2')
+ nvim_command('let flt = 3.0')
+ nvim_command('let bin = ""')
+
+ eq({{{}}}, nvim_eval('arr2'))
+ eq({['1']={}}, nvim_eval('map2'))
+ eq(1, nvim_eval('int2'))
+ eq(2.0, nvim_eval('flt2'))
+ eq('abc', nvim_eval('bin2'))
+ end)
+ end)
+
+ describe('function msgpack#eval', function()
+ local eval_eq = function(expected_type, expected_val, str, ...)
+ nvim_command(('let g:__val = msgpack#eval(\'%s\', %s)'):format(str:gsub(
+ '\'', '\'\''), select(1, ...) or '{}'))
+ eq(expected_type, nvim_eval('msgpack#type(g:__val)'))
+ local expected_val_full = expected_val
+ if (not (({float=true, integer=true})[expected_type]
+ and type(expected_val) ~= 'table')
+ and expected_type ~= 'array') then
+ expected_val_full = {_TYPE={}, _VAL=expected_val_full}
+ end
+ if expected_val_full == expected_val_full then
+ eq(expected_val_full, nvim_eval('g:__val'))
+ else
+ eq(tostring(expected_val_full), tostring(nvim_eval('g:__val')))
+ end
+ nvim_command('unlet g:__val')
+ end
+
+ it('correctly loads binary strings', function()
+ eval_eq('binary', {'abcdef'}, '"abcdef"')
+ eval_eq('binary', {'abc', 'def'}, '"abc\\ndef"')
+ eval_eq('binary', {'abc\ndef'}, '"abc\\0def"')
+ eval_eq('binary', {'\nabc\ndef\n'}, '"\\0abc\\0def\\0"')
+ eval_eq('binary', {'abc\n\n\ndef'}, '"abc\\0\\0\\0def"')
+ eval_eq('binary', {'abc\n', '\ndef'}, '"abc\\0\\n\\0def"')
+ eval_eq('binary', {'abc', '', '', 'def'}, '"abc\\n\\n\\ndef"')
+ eval_eq('binary', {'abc', '', '', 'def', ''}, '"abc\\n\\n\\ndef\\n"')
+ eval_eq('binary', {'', 'abc', '', '', 'def'}, '"\\nabc\\n\\n\\ndef"')
+ eval_eq('binary', {''}, '""')
+ eval_eq('binary', {'"'}, '"\\""')
+ end)
+
+ it('correctly loads strings', function()
+ eval_eq('string', {'abcdef'}, '="abcdef"')
+ eval_eq('string', {'abc', 'def'}, '="abc\\ndef"')
+ eval_eq('string', {'abc\ndef'}, '="abc\\0def"')
+ eval_eq('string', {'\nabc\ndef\n'}, '="\\0abc\\0def\\0"')
+ eval_eq('string', {'abc\n\n\ndef'}, '="abc\\0\\0\\0def"')
+ eval_eq('string', {'abc\n', '\ndef'}, '="abc\\0\\n\\0def"')
+ eval_eq('string', {'abc', '', '', 'def'}, '="abc\\n\\n\\ndef"')
+ eval_eq('string', {'abc', '', '', 'def', ''}, '="abc\\n\\n\\ndef\\n"')
+ eval_eq('string', {'', 'abc', '', '', 'def'}, '="\\nabc\\n\\n\\ndef"')
+ eval_eq('string', {''}, '=""')
+ eval_eq('string', {'"'}, '="\\""')
+ end)
+
+ it('correctly loads ext values', function()
+ eval_eq('ext', {0, {'abcdef'}}, '+(0)"abcdef"')
+ eval_eq('ext', {0, {'abc', 'def'}}, '+(0)"abc\\ndef"')
+ eval_eq('ext', {0, {'abc\ndef'}}, '+(0)"abc\\0def"')
+ eval_eq('ext', {0, {'\nabc\ndef\n'}}, '+(0)"\\0abc\\0def\\0"')
+ eval_eq('ext', {0, {'abc\n\n\ndef'}}, '+(0)"abc\\0\\0\\0def"')
+ eval_eq('ext', {0, {'abc\n', '\ndef'}}, '+(0)"abc\\0\\n\\0def"')
+ eval_eq('ext', {0, {'abc', '', '', 'def'}}, '+(0)"abc\\n\\n\\ndef"')
+ eval_eq('ext', {0, {'abc', '', '', 'def', ''}},
+ '+(0)"abc\\n\\n\\ndef\\n"')
+ eval_eq('ext', {0, {'', 'abc', '', '', 'def'}},
+ '+(0)"\\nabc\\n\\n\\ndef"')
+ eval_eq('ext', {0, {''}}, '+(0)""')
+ eval_eq('ext', {0, {'"'}}, '+(0)"\\""')
+
+ eval_eq('ext', {-1, {'abcdef'}}, '+(-1)"abcdef"')
+ eval_eq('ext', {-1, {'abc', 'def'}}, '+(-1)"abc\\ndef"')
+ eval_eq('ext', {-1, {'abc\ndef'}}, '+(-1)"abc\\0def"')
+ eval_eq('ext', {-1, {'\nabc\ndef\n'}}, '+(-1)"\\0abc\\0def\\0"')
+ eval_eq('ext', {-1, {'abc\n\n\ndef'}}, '+(-1)"abc\\0\\0\\0def"')
+ eval_eq('ext', {-1, {'abc\n', '\ndef'}}, '+(-1)"abc\\0\\n\\0def"')
+ eval_eq('ext', {-1, {'abc', '', '', 'def'}}, '+(-1)"abc\\n\\n\\ndef"')
+ eval_eq('ext', {-1, {'abc', '', '', 'def', ''}},
+ '+(-1)"abc\\n\\n\\ndef\\n"')
+ eval_eq('ext', {-1, {'', 'abc', '', '', 'def'}},
+ '+(-1)"\\nabc\\n\\n\\ndef"')
+ eval_eq('ext', {-1, {''}}, '+(-1)""')
+ eval_eq('ext', {-1, {'"'}}, '+(-1)"\\""')
+ end)
+
+ it('correctly loads floats', function()
+ eval_eq('float', inf, 'inf')
+ eval_eq('float', minus_inf, '-inf')
+ eval_eq('float', nan, 'nan')
+ eval_eq('float', minus_nan, '-nan')
+ eval_eq('float', 1.0e10, '1.0e10')
+ eval_eq('float', 1.0e10, '1.0e+10')
+ eval_eq('float', -1.0e10, '-1.0e+10')
+ eval_eq('float', 1.0, '1.0')
+ eval_eq('float', -1.0, '-1.0')
+ eval_eq('float', 1.0e-10, '1.0e-10')
+ eval_eq('float', -1.0e-10, '-1.0e-10')
+ end)
+
+ it('correctly loads integers', function()
+ eval_eq('integer', 10, '10')
+ eval_eq('integer', -10, '-10')
+ eval_eq('integer', { 1, 0, 610839793, 448585456}, ' 0x123456789ABCDEF0')
+ eval_eq('integer', {-1, 0, 610839793, 448585456}, '-0x123456789ABCDEF0')
+ eval_eq('integer', { 1, 3, 1684581617, 448585456}, ' 0xF23456789ABCDEF0')
+ eval_eq('integer', {-1, 1, 1684581617, 448585456}, '-0x723456789ABCDEF0')
+ eval_eq('integer', { 1, 0, 0, 0x100}, '0x100')
+ eval_eq('integer', {-1, 0, 0, 0x100}, '-0x100')
+
+ eval_eq('integer', ('a'):byte(), '\'a\'')
+ eval_eq('integer', 0xAB, '\'«\'')
+ end)
+
+ it('correctly loads constants', function()
+ eval_eq('boolean', 1, 'TRUE')
+ eval_eq('boolean', 0, 'FALSE')
+ eval_eq('nil', 0, 'NIL')
+ eval_eq('nil', 0, 'NIL', '{"NIL": 1, "nan": 2, "T": 3}')
+ eval_eq('float', nan, 'nan',
+ '{"NIL": "1", "nan": "2", "T": "3"}')
+ eval_eq('integer', 3, 'T', '{"NIL": "1", "nan": "2", "T": "3"}')
+ eval_eq('integer', {1, 0, 0, 0}, 'T',
+ ('{"NIL": "1", "nan": "2", "T": \'%s\'}'):format(
+ sp('integer', '[1, 0, 0, 0]')))
+ end)
+
+ it('correctly loads maps', function()
+ eval_eq('map', {}, '{}')
+ eval_eq('map', {{{_TYPE={}, _VAL={{1, 2}}}, {_TYPE={}, _VAL={{3, 4}}}}},
+ '{{1: 2}: {3: 4}}')
+ eval_eq('map', {{{_TYPE={}, _VAL={{1, 2}}}, {_TYPE={}, _VAL={{3, 4}}}},
+ {1, 2}},
+ '{{1: 2}: {3: 4}, 1: 2}')
+ end)
+
+ it('correctly loads arrays', function()
+ eval_eq('array', {}, '[]')
+ eval_eq('array', {1}, '[1]')
+ eval_eq('array', {{_TYPE={}, _VAL=1}}, '[TRUE]')
+ eval_eq('array', {{{_TYPE={}, _VAL={{1, 2}}}}, {_TYPE={}, _VAL={{3, 4}}}},
+ '[[{1: 2}], {3: 4}]')
+ end)
+
+ it('errors out when needed', function()
+ eq('empty:Parsed string is empty',
+ exc_exec('call msgpack#eval("", {})'))
+ eq('unknown:Invalid non-space character: ^',
+ exc_exec('call msgpack#eval("^", {})'))
+ eq('char-invalid:Invalid integer character literal format: \'\'',
+ exc_exec('call msgpack#eval("\'\'", {})'))
+ eq('char-invalid:Invalid integer character literal format: \'ab\'',
+ exc_exec('call msgpack#eval("\'ab\'", {})'))
+ eq('char-invalid:Invalid integer character literal format: \'',
+ exc_exec('call msgpack#eval("\'", {})'))
+ eq('"-invalid:Invalid string: "',
+ exc_exec('call msgpack#eval("\\"", {})'))
+ eq('"-invalid:Invalid string: ="',
+ exc_exec('call msgpack#eval("=\\"", {})'))
+ eq('"-invalid:Invalid string: +(0)"',
+ exc_exec('call msgpack#eval("+(0)\\"", {})'))
+ eq('0.-nodigits:Decimal dot must be followed by digit(s): .e1',
+ exc_exec('call msgpack#eval("0.e1", {})'))
+ eq('0x-long:Must have at most 16 hex digits: FEDCBA98765432100',
+ exc_exec('call msgpack#eval("0xFEDCBA98765432100", {})'))
+ eq('0x-empty:Must have number after 0x: ',
+ exc_exec('call msgpack#eval("0x", {})'))
+ eq('name-unknown:Unknown name FOO: FOO',
+ exc_exec('call msgpack#eval("FOO", {})'))
+ end)
+ end)
+end)
diff --git a/test/functional/plugin/shada_spec.lua b/test/functional/plugin/shada_spec.lua
new file mode 100644
index 0000000000..020bb11bbc
--- /dev/null
+++ b/test/functional/plugin/shada_spec.lua
@@ -0,0 +1,2845 @@
+local helpers = require('test.functional.helpers')
+local eq, nvim_eval, nvim_command, nvim, exc_exec, funcs, nvim_feed, curbuf =
+ helpers.eq, helpers.eval, helpers.command, helpers.nvim, helpers.exc_exec,
+ helpers.funcs, helpers.feed, helpers.curbuf
+local neq = helpers.neq
+
+local msgpack = require('MessagePack')
+
+local plugin_helpers = require('test.functional.plugin.helpers')
+local reset = plugin_helpers.reset
+
+local shada_helpers = require('test.functional.shada.helpers')
+local get_shada_rw = shada_helpers.get_shada_rw
+
+local mpack_eq = function(expected, mpack_result)
+ local mpack_keys = {'type', 'timestamp', 'length', 'value'}
+
+ local unpacker = msgpack.unpacker(mpack_result)
+ local actual = {}
+ local cur
+ local i = 0
+ while true do
+ local off, val = unpacker()
+ if not off then break end
+ if i % 4 == 0 then
+ cur = {}
+ actual[#actual + 1] = cur
+ end
+ local key = mpack_keys[(i % 4) + 1]
+ if key ~= 'length' then
+ if key == 'timestamp' and math.abs(val - os.time()) < 2 then
+ val = 'current'
+ end
+ cur[key] = val
+ end
+ i = i + 1
+ end
+ eq(expected, actual)
+end
+
+local wshada, _, fname = get_shada_rw('Xtest-functional-plugin-shada.shada')
+
+local wshada_tmp, _, fname_tmp =
+ get_shada_rw('Xtest-functional-plugin-shada.shada.tmp.f')
+
+describe('In autoload/shada.vim', function()
+ local epoch = os.date('%Y-%m-%dT%H:%M:%S', 0)
+ before_each(function()
+ reset()
+ nvim_command([[
+ function ModifyVal(val)
+ if type(a:val) == type([])
+ if len(a:val) == 2 && type(a:val[0]) == type('') && a:val[0][0] is# '!' && has_key(v:msgpack_types, a:val[0][1:])
+ return {'_TYPE': v:msgpack_types[ a:val[0][1:] ], '_VAL': a:val[1]}
+ else
+ return map(copy(a:val), 'ModifyVal(v:val)')
+ endif
+ elseif type(a:val) == type({})
+ let keys = sort(keys(a:val))
+ let ret = {'_TYPE': v:msgpack_types.map, '_VAL': []}
+ for key in keys
+ let k = {'_TYPE': v:msgpack_types.string, '_VAL': split(key, "\n", 1)}
+ let v = ModifyVal(a:val[key])
+ call add(ret._VAL, [k, v])
+ unlet v
+ endfor
+ return ret
+ elseif type(a:val) == type('')
+ return {'_TYPE': v:msgpack_types.binary, '_VAL': split(a:val, "\n", 1)}
+ else
+ return a:val
+ endif
+ endfunction
+ ]])
+ end)
+
+ local sp = function(typ, val)
+ return ('{"_TYPE": v:msgpack_types.%s, "_VAL": %s}'):format(typ, val)
+ end
+
+ local st_meta = {
+ __pairs=function(table)
+ local ret = {}
+ local next_key = nil
+ local num_keys = 0
+ while true do
+ next_key = next(table, next_key)
+ if next_key == nil then
+ break
+ end
+ num_keys = num_keys + 1
+ ret[num_keys] = {next_key, table[next_key]}
+ end
+ table.sort(ret, function(a, b)
+ return a[1] < b[1]
+ end)
+ local state = {i=0}
+ return (function(state_, _)
+ state_.i = state_.i + 1
+ if ret[state_.i] then
+ return table.unpack(ret[state_.i])
+ end
+ end), state
+ end
+ }
+
+ local st = function(table)
+ return setmetatable(table, st_meta)
+ end
+
+ describe('function shada#mpack_to_sd', function()
+ local mpack2sd = function(arg)
+ return ('shada#mpack_to_sd(%s)'):format(arg)
+ end
+
+ it('works', function()
+ eq({}, nvim_eval(mpack2sd('[]')))
+ eq({{type=1, timestamp=5, length=1, data=7}},
+ nvim_eval(mpack2sd('[1, 5, 1, 7]')))
+ eq({{type=1, timestamp=5, length=1, data=7},
+ {type=1, timestamp=10, length=1, data=5}},
+ nvim_eval(mpack2sd('[1, 5, 1, 7, 1, 10, 1, 5]')))
+ eq('zero-uint:Entry 1 has type element which is zero',
+ exc_exec('call ' .. mpack2sd('[0, 5, 1, 7]')))
+ eq('zero-uint:Entry 1 has type element which is zero',
+ exc_exec('call ' .. mpack2sd(('[%s, 5, 1, 7]'):format(
+ sp('integer', '[1, 0, 0, 0]')))))
+ eq('not-uint:Entry 1 has timestamp element which is not an unsigned integer',
+ exc_exec('call ' .. mpack2sd('[1, -1, 1, 7]')))
+ eq('not-uint:Entry 1 has length element which is not an unsigned integer',
+ exc_exec('call ' .. mpack2sd('[1, 1, -1, 7]')))
+ eq('not-uint:Entry 1 has type element which is not an unsigned integer',
+ exc_exec('call ' .. mpack2sd('["", 1, -1, 7]')))
+ end)
+ end)
+
+ describe('function shada#sd_to_strings', function()
+ local sd2strings_eq = function(expected, arg)
+ if type(arg) == 'table' then
+ eq(expected, funcs['shada#sd_to_strings'](arg))
+ else
+ eq(expected, nvim_eval(('shada#sd_to_strings(%s)'):format(arg)))
+ end
+ end
+
+ it('works with empty input', function()
+ sd2strings_eq({}, '[]')
+ end)
+
+ it('works with unknown items', function()
+ sd2strings_eq({
+ 'Unknown (0x64) with timestamp ' .. epoch .. ':',
+ ' = 100'
+ }, {{type=100, timestamp=0, length=1, data=100}})
+
+ sd2strings_eq({
+ 'Unknown (0x4000001180000006) with timestamp ' .. epoch .. ':',
+ ' = 100'
+ }, ('[{"type": %s, "timestamp": 0, "length": 1, "data": 100}]'):format(
+ sp('integer', '[1, 1, 35, 6]')
+ ))
+ end)
+
+ it('works with multiple unknown items', function()
+ sd2strings_eq({
+ 'Unknown (0x64) with timestamp ' .. epoch .. ':',
+ ' = 100',
+ 'Unknown (0x65) with timestamp ' .. epoch .. ':',
+ ' = 500',
+ }, {{type=100, timestamp=0, length=1, data=100},
+ {type=101, timestamp=0, length=1, data=500}})
+ end)
+
+ it('works with header items', function()
+ sd2strings_eq({
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key______ Value',
+ ' + generator "test"',
+ }, {{type=1, timestamp=0, data={generator='test'}}})
+ sd2strings_eq({
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + a 1',
+ ' + b 2',
+ ' + c column 3',
+ ' + d 4',
+ }, {{type=1, timestamp=0, data=st({a=1, b=2, c=3, d=4})}})
+ sd2strings_eq({
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Value',
+ ' + t "test"',
+ }, {{type=1, timestamp=0, data={t='test'}}})
+ sd2strings_eq({
+ 'Header with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ }, {{type=1, timestamp=0, data={1, 2, 3}}})
+ end)
+
+ it('processes standard keys correctly, even in header', function()
+ sd2strings_eq({
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' + c column 0',
+ ' + f file name "/tmp/foo"',
+ ' + l line number 10',
+ ' + n name \'@\'',
+ ' + rc contents ["abc", "def"]',
+ ' + rt type CHARACTERWISE',
+ ' + rw block width 10',
+ ' + sb search backward TRUE',
+ ' + sc smartcase value FALSE',
+ ' + se place cursor at end TRUE',
+ ' + sh v:hlsearch value TRUE',
+ ' + sl has line offset FALSE',
+ ' + sm magic value TRUE',
+ ' + so offset value 10',
+ ' + sp pattern "100"',
+ ' + ss is :s pattern TRUE',
+ ' + su is last used FALSE',
+ }, ([[ [{'type': 1, 'timestamp': 0, 'data': {
+ 'sm': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'sc': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ 'sl': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ 'se': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'sb': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'so': 10,
+ 'su': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ 'ss': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'sh': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'sp': '100',
+ 'rt': 0,
+ 'rw': 10,
+ 'rc': ['abc', 'def'],
+ 'n': 0x40,
+ 'l': 10,
+ 'c': 0,
+ 'f': '/tmp/foo',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Description____ Value',
+ ' # Expected integer',
+ ' + c column "abc"',
+ ' # Expected no NUL bytes',
+ ' + f file name "abc\\0def"',
+ ' # Value is negative',
+ ' + l line number -10',
+ ' # Value is negative',
+ ' + n name -64',
+ ' # Expected array value',
+ ' + rc contents "10"',
+ ' # Unexpected enum value: expected one of '
+ .. '0 (CHARACTERWISE), 1 (LINEWISE), 2 (BLOCKWISE)',
+ ' + rt type 10',
+ ' # Expected boolean',
+ ' + sc smartcase value NIL',
+ ' # Expected boolean',
+ ' + sm magic value "TRUE"',
+ ' # Expected integer',
+ ' + so offset value "TRUE"',
+ ' # Expected binary string',
+ ' + sp pattern ="abc"',
+ }, ([[ [{'type': 1, 'timestamp': 0, 'data': {
+ 'sm': 'TRUE',
+ 'sc': {'_TYPE': v:msgpack_types.nil, '_VAL': 0},
+ 'so': 'TRUE',
+ 'sp': {'_TYPE': v:msgpack_types.string, '_VAL': ["abc"]},
+ 'rt': 10,
+ 'rc': '10',
+ 'n': -0x40,
+ 'l': -10,
+ 'c': 'abc',
+ 'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc\ndef"]},
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected no NUL bytes',
+ ' + f file name "abc\\0def"',
+ ' # Expected array of binary strings',
+ ' + rc contents ["abc", ="abc"]',
+ ' # Expected integer',
+ ' + rt type "ABC"',
+ }, ([[ [{'type': 1, 'timestamp': 0, 'data': {
+ 'rt': 'ABC',
+ 'rc': ["abc", {'_TYPE': v:msgpack_types.string, '_VAL': ["abc"]}],
+ 'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc\ndef"]},
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected no NUL bytes',
+ ' + rc contents ["abc", "a\\nd\\0"]',
+ }, ([[ [{'type': 1, 'timestamp': 0, 'data': {
+ 'rc': ["abc", {'_TYPE': v:msgpack_types.binary, '_VAL': ["a", "d\n"]}],
+ }}] ]]):gsub('\n', ''))
+ end)
+
+ it('works with search pattern items', function()
+ sd2strings_eq({
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ }, {{type=2, timestamp=0, data={1, 2, 3}}})
+ sd2strings_eq({
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' + sp pattern "abc"',
+ ' + sh v:hlsearch value FALSE',
+ ' + ss is :s pattern FALSE',
+ ' + sb search backward FALSE',
+ ' + sm magic value TRUE',
+ ' + sc smartcase value FALSE',
+ ' + sl has line offset FALSE',
+ ' + se place cursor at end FALSE',
+ ' + so offset value 0',
+ ' + su is last used TRUE',
+ }, ([[ [{'type': 2, 'timestamp': 0, 'data': {
+ 'sp': 'abc',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' + sp pattern "abc"',
+ ' + sh v:hlsearch value FALSE',
+ ' + ss is :s pattern FALSE',
+ ' + sb search backward FALSE',
+ ' + sm magic value TRUE',
+ ' + sc smartcase value FALSE',
+ ' + sl has line offset FALSE',
+ ' + se place cursor at end FALSE',
+ ' + so offset value 0',
+ ' + su is last used TRUE',
+ ' + sX NIL',
+ ' + sY NIL',
+ ' + sZ NIL',
+ }, ([[ [{'type': 2, 'timestamp': 0, 'data': {
+ 'sp': 'abc',
+ 'sZ': {'_TYPE': v:msgpack_types.nil, '_VAL': 0},
+ 'sY': {'_TYPE': v:msgpack_types.nil, '_VAL': 0},
+ 'sX': {'_TYPE': v:msgpack_types.nil, '_VAL': 0},
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' + sp pattern "abc"',
+ ' + sh v:hlsearch value FALSE',
+ ' + ss is :s pattern FALSE',
+ ' + sb search backward FALSE',
+ ' + sm magic value TRUE',
+ ' + sc smartcase value FALSE',
+ ' + sl has line offset FALSE',
+ ' + se place cursor at end FALSE',
+ ' + so offset value 0',
+ ' + su is last used TRUE',
+ }, ([[ [{'type': 2, 'timestamp': 0, 'data': {
+ 'sp': 'abc',
+ 'sh': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ 'ss': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ 'sb': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ 'sm': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'sc': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ 'sl': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ 'se': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ 'so': 0,
+ 'su': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' # Required key missing: sp',
+ ' + sh v:hlsearch value FALSE',
+ ' + ss is :s pattern FALSE',
+ ' + sb search backward FALSE',
+ ' + sm magic value TRUE',
+ ' + sc smartcase value FALSE',
+ ' + sl has line offset FALSE',
+ ' + se place cursor at end FALSE',
+ ' + so offset value 0',
+ ' + su is last used TRUE',
+ }, ([[ [{'type': 2, 'timestamp': 0, 'data': {
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' + sp pattern ""',
+ ' + sh v:hlsearch value TRUE',
+ ' + ss is :s pattern TRUE',
+ ' + sb search backward TRUE',
+ ' + sm magic value FALSE',
+ ' + sc smartcase value TRUE',
+ ' + sl has line offset TRUE',
+ ' + se place cursor at end TRUE',
+ ' + so offset value -10',
+ ' + su is last used FALSE',
+ }, ([[ [{'type': 2, 'timestamp': 0, 'data': {
+ 'sp': '',
+ 'sh': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'ss': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'sb': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'sm': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ 'sc': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'sl': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'se': {'_TYPE': v:msgpack_types.boolean, '_VAL': 1},
+ 'so': -10,
+ 'su': {'_TYPE': v:msgpack_types.boolean, '_VAL': 0},
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' # Expected binary string',
+ ' + sp pattern 0',
+ ' # Expected boolean',
+ ' + sh v:hlsearch value 0',
+ ' # Expected boolean',
+ ' + ss is :s pattern 0',
+ ' # Expected boolean',
+ ' + sb search backward 0',
+ ' # Expected boolean',
+ ' + sm magic value 0',
+ ' # Expected boolean',
+ ' + sc smartcase value 0',
+ ' # Expected boolean',
+ ' + sl has line offset 0',
+ ' # Expected boolean',
+ ' + se place cursor at end 0',
+ ' # Expected integer',
+ ' + so offset value ""',
+ ' # Expected boolean',
+ ' + su is last used 0',
+ }, ([[ [{'type': 2, 'timestamp': 0, 'data': {
+ 'sp': 0,
+ 'sh': 0,
+ 'ss': 0,
+ 'sb': 0,
+ 'sm': 0,
+ 'sc': 0,
+ 'sl': 0,
+ 'se': 0,
+ 'so': '',
+ 'su': 0,
+ }}] ]]):gsub('\n', ''))
+ end)
+
+ it('works with replacement string items', function()
+ sd2strings_eq({
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: map instead of array',
+ ' = {="a": [10]}',
+ }, {{type=3, timestamp=0, data={a={10}}}})
+ sd2strings_eq({
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' # Expected more elements in list'
+ }, ([[ [{'type': 3, 'timestamp': 0, 'data': [
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' # Expected binary string',
+ ' - :s replacement string 0',
+ }, ([[ [{'type': 3, 'timestamp': 0, 'data': [
+ 0,
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' # Expected no NUL bytes',
+ ' - :s replacement string "abc\\0def"',
+ }, ([[ [{'type': 3, 'timestamp': 0, 'data': [
+ {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc\ndef"]},
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' - :s replacement string "abc\\ndef"',
+ }, ([[ [{'type': 3, 'timestamp': 0, 'data': [
+ {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc", "def"]},
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' - :s replacement string "abc\\ndef"',
+ ' - 0',
+ }, ([[ [{'type': 3, 'timestamp': 0, 'data': [
+ {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc", "def"]},
+ 0,
+ ]}] ]]):gsub('\n', ''))
+ end)
+
+ it('works with history entry items', function()
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: map instead of array',
+ ' = {="a": [10]}',
+ }, {{type=4, timestamp=0, data={a={10}}}})
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' # Expected more elements in list'
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' # Expected integer',
+ ' - history type ""',
+ ' # Expected more elements in list'
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ '',
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' # Unexpected enum value: expected one of 0 (CMD), 1 (SEARCH), '
+ .. '2 (EXPR), 3 (INPUT), 4 (DEBUG)',
+ ' - history type 5',
+ ' - contents ""',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 5,
+ ''
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' # Unexpected enum value: expected one of 0 (CMD), 1 (SEARCH), '
+ .. '2 (EXPR), 3 (INPUT), 4 (DEBUG)',
+ ' - history type 5',
+ ' - contents ""',
+ ' - 32',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 5,
+ '',
+ 0x20
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type CMD',
+ ' - contents ""',
+ ' - 32',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 0,
+ '',
+ 0x20
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type SEARCH',
+ ' - contents ""',
+ ' - separator \' \'',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 1,
+ '',
+ 0x20
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type SEARCH',
+ ' - contents ""',
+ ' # Expected more elements in list',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 1,
+ '',
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type EXPR',
+ ' - contents ""',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 2,
+ '',
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type INPUT',
+ ' - contents ""',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 3,
+ '',
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type DEBUG',
+ ' - contents ""',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 4,
+ '',
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type DEBUG',
+ ' # Expected binary string',
+ ' - contents 10',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 4,
+ 10,
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type DEBUG',
+ ' # Expected no NUL bytes',
+ ' - contents "abc\\0def"',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 4,
+ {'_TYPE': v:msgpack_types.binary, '_VAL': ["abc\ndef"]},
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type SEARCH',
+ ' - contents "abc"',
+ ' # Expected integer',
+ ' - separator ""',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 1,
+ 'abc',
+ '',
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type SEARCH',
+ ' - contents "abc"',
+ ' # Value is negative',
+ ' - separator -1',
+ }, ([[ [{'type': 4, 'timestamp': 0, 'data': [
+ 1,
+ 'abc',
+ -1,
+ ]}] ]]):gsub('\n', ''))
+ end)
+
+ it('works with register items', function()
+ sd2strings_eq({
+ 'Register with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ }, {{type=5, timestamp=0, data={1, 2, 3}}})
+ sd2strings_eq({
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: n',
+ ' # Required key missing: rc',
+ ' + rw block width 0',
+ ' + rt type CHARACTERWISE',
+ }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' # Required key missing: rc',
+ ' + rw block width 0',
+ ' + rt type CHARACTERWISE',
+ }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
+ 'n': 0x20,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' + rc contents ["abc", "def"]',
+ ' + rw block width 0',
+ ' + rt type CHARACTERWISE',
+ }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
+ 'n': 0x20,
+ 'rc': ["abc", "def"],
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' + rc contents @',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' + rw block width 0',
+ ' + rt type CHARACTERWISE',
+ }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
+ 'n': 0x20,
+ 'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'],
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' + rc contents @',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' + rw block width 0',
+ ' + rt type CHARACTERWISE',
+ }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
+ 'n': 0x20,
+ 'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'],
+ 'rw': 0,
+ 'rt': 0,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' + rc contents @',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' + rw block width 5',
+ ' + rt type LINEWISE',
+ }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
+ 'n': 0x20,
+ 'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'],
+ 'rw': 5,
+ 'rt': 1,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' + rc contents @',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' # Expected integer',
+ ' + rw block width ""',
+ ' + rt type BLOCKWISE',
+ }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
+ 'n': 0x20,
+ 'rc': ['abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'],
+ 'rw': "",
+ 'rt': 2,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' # Expected array value',
+ ' + rc contents 0',
+ ' # Value is negative',
+ ' + rw block width -1',
+ ' # Unexpected enum value: expected one of 0 (CHARACTERWISE), '
+ .. '1 (LINEWISE), 2 (BLOCKWISE)',
+ ' + rt type 10',
+ }, ([[ [{'type': 5, 'timestamp': 0, 'data': {
+ 'n': 0x20,
+ 'rc': 0,
+ 'rw': -1,
+ 'rt': 10,
+ }}] ]]):gsub('\n', ''))
+ end)
+
+ it('works with variable items', function()
+ sd2strings_eq({
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: map instead of array',
+ ' = {="a": [10]}',
+ }, {{type=6, timestamp=0, data={a={10}}}})
+ sd2strings_eq({
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' @ Description Value',
+ ' # Expected more elements in list'
+ }, ([[ [{'type': 6, 'timestamp': 0, 'data': [
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' @ Description Value',
+ ' # Expected binary string',
+ ' - name 1',
+ ' # Expected more elements in list',
+ }, ([[ [{'type': 6, 'timestamp': 0, 'data': [
+ 1
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' @ Description Value',
+ ' # Expected no NUL bytes',
+ ' - name "\\0"',
+ ' # Expected more elements in list',
+ }, ([[ [{'type': 6, 'timestamp': 0, 'data': [
+ {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]},
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' @ Description Value',
+ ' - name "foo"',
+ ' # Expected more elements in list',
+ }, ([[ [{'type': 6, 'timestamp': 0, 'data': [
+ {'_TYPE': v:msgpack_types.binary, '_VAL': ["foo"]},
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' @ Description Value',
+ ' - name "foo"',
+ ' - value NIL',
+ }, ([[ [{'type': 6, 'timestamp': 0, 'data': [
+ {'_TYPE': v:msgpack_types.binary, '_VAL': ["foo"]},
+ {'_TYPE': v:msgpack_types.nil, '_VAL': ["foo"]},
+ ]}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' @ Description Value',
+ ' - name "foo"',
+ ' - value NIL',
+ ' - NIL',
+ }, ([[ [{'type': 6, 'timestamp': 0, 'data': [
+ {'_TYPE': v:msgpack_types.binary, '_VAL': ["foo"]},
+ {'_TYPE': v:msgpack_types.nil, '_VAL': ["foo"]},
+ {'_TYPE': v:msgpack_types.nil, '_VAL': ["foo"]},
+ ]}] ]]):gsub('\n', ''))
+ end)
+
+ it('works with global mark items', function()
+ sd2strings_eq({
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ }, {{type=7, timestamp=0, data={1, 2, 3}}})
+ sd2strings_eq({
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: n',
+ ' # Required key missing: f',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 7, 'timestamp': 0, 'data': {
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected integer',
+ ' + n name "foo"',
+ ' # Required key missing: f',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 7, 'timestamp': 0, 'data': {
+ 'n': 'foo',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: n',
+ ' + f file name "foo"',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 7, 'timestamp': 0, 'data': {
+ 'f': 'foo',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Value is negative',
+ ' + n name -10',
+ ' # Expected no NUL bytes',
+ ' + f file name "\\0"',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 7, 'timestamp': 0, 'data': {
+ 'n': -10,
+ 'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]},
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name 20',
+ ' + f file name "foo"',
+ ' # Value is negative',
+ ' + l line number -10',
+ ' # Value is negative',
+ ' + c column -10',
+ }, ([[ [{'type': 7, 'timestamp': 0, 'data': {
+ 'n': 20,
+ 'f': 'foo',
+ 'l': -10,
+ 'c': -10,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name 20',
+ ' + f file name "foo"',
+ ' # Expected integer',
+ ' + l line number "FOO"',
+ ' # Expected integer',
+ ' + c column "foo"',
+ ' + mX 10',
+ }, ([[ [{'type': 7, 'timestamp': 0, 'data': {
+ 'n': 20,
+ 'f': 'foo',
+ 'l': 'FOO',
+ 'c': 'foo',
+ 'mX': 10,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name "foo"',
+ ' + l line number 2',
+ ' + c column 200',
+ ' + mX 10',
+ ' + mYYYYYYYYYY 10',
+ }, ([[ [{'type': 7, 'timestamp': 0, 'data': {
+ 'n': char2nr('A'),
+ 'f': 'foo',
+ 'l': 2,
+ 'c': 200,
+ 'mX': 10,
+ 'mYYYYYYYYYY': 10,
+ }}] ]]):gsub('\n', ''))
+ end)
+
+ it('works with jump items', function()
+ sd2strings_eq({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ }, {{type=8, timestamp=0, data={1, 2, 3}}})
+ sd2strings_eq({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 8, 'timestamp': 0, 'data': {
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' + l line number 1',
+ ' + c column 0',
+ ' # Expected integer',
+ ' + n name "foo"',
+ }, ([[ [{'type': 8, 'timestamp': 0, 'data': {
+ 'n': 'foo',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "foo"',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 8, 'timestamp': 0, 'data': {
+ 'f': 'foo',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected no NUL bytes',
+ ' + f file name "\\0"',
+ ' + l line number 1',
+ ' + c column 0',
+ ' # Value is negative',
+ ' + n name -10',
+ }, ([[ [{'type': 8, 'timestamp': 0, 'data': {
+ 'n': -10,
+ 'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]},
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "foo"',
+ ' # Value is negative',
+ ' + l line number -10',
+ ' # Value is negative',
+ ' + c column -10',
+ }, ([[ [{'type': 8, 'timestamp': 0, 'data': {
+ 'f': 'foo',
+ 'l': -10,
+ 'c': -10,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "foo"',
+ ' # Expected integer',
+ ' + l line number "FOO"',
+ ' # Expected integer',
+ ' + c column "foo"',
+ ' + mX 10',
+ }, ([[ [{'type': 8, 'timestamp': 0, 'data': {
+ 'f': 'foo',
+ 'l': 'FOO',
+ 'c': 'foo',
+ 'mX': 10,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + f file name "foo"',
+ ' + l line number 2',
+ ' + c column 200',
+ ' + mX 10',
+ ' + mYYYYYYYYYY 10',
+ ' + n name \' \'',
+ }, ([[ [{'type': 8, 'timestamp': 0, 'data': {
+ 'n': 0x20,
+ 'f': 'foo',
+ 'l': 2,
+ 'c': 200,
+ 'mX': 10,
+ 'mYYYYYYYYYY': 10,
+ }}] ]]):gsub('\n', ''))
+ end)
+
+ it('works with buffer list items', function()
+ sd2strings_eq({
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: map instead of array',
+ ' = {="a": [10]}',
+ }, {{type=9, timestamp=0, data={a={10}}}})
+ sd2strings_eq({
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' # Expected array of maps',
+ ' = [[], []]',
+ }, {{type=9, timestamp=0, data={{}, {}}}})
+ sd2strings_eq({
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' # Expected array of maps',
+ ' = [{="a": 10}, []]',
+ }, {{type=9, timestamp=0, data={{a=10}, {}}}})
+ sd2strings_eq({
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' + l line number 1',
+ ' + c column 0',
+ ' + a 10',
+ }, {{type=9, timestamp=0, data={{a=10}}}})
+ sd2strings_eq({
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' # Expected integer',
+ ' + l line number "10"',
+ ' # Expected integer',
+ ' + c column "10"',
+ ' + a 10',
+ }, {{type=9, timestamp=0, data={{l='10', c='10', a=10}}}})
+ sd2strings_eq({
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' + l line number 10',
+ ' + c column 10',
+ ' + a 10',
+ }, {{type=9, timestamp=0, data={{l=10, c=10, a=10}}}})
+ sd2strings_eq({
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' # Value is negative',
+ ' + l line number -10',
+ ' # Value is negative',
+ ' + c column -10',
+ }, {{type=9, timestamp=0, data={{l=-10, c=-10}}}})
+ sd2strings_eq({
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "abc"',
+ ' + l line number 1',
+ ' + c column 0',
+ }, {{type=9, timestamp=0, data={{f='abc'}}}})
+ sd2strings_eq({
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected binary string',
+ ' + f file name 10',
+ ' + l line number 1',
+ ' + c column 0',
+ '',
+ ' % Key Description Value',
+ ' # Expected binary string',
+ ' + f file name 20',
+ ' + l line number 1',
+ ' + c column 0',
+ }, {{type=9, timestamp=0, data={{f=10}, {f=20}}}})
+ sd2strings_eq({
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected binary string',
+ ' + f file name 10',
+ ' + l line number 1',
+ ' + c column 0',
+ '',
+ ' % Key Description Value',
+ ' # Expected no NUL bytes',
+ ' + f file name "\\0"',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 9, 'timestamp': 0, 'data': [
+ {'f': 10},
+ {'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]}},
+ ]}] ]]):gsub('\n', ''))
+ end)
+
+ it('works with local mark items', function()
+ sd2strings_eq({
+ 'Local mark with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ }, {{type=10, timestamp=0, data={1, 2, 3}}})
+ sd2strings_eq({
+ 'Local mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' + n name \'"\'',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 10, 'timestamp': 0, 'data': {
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Local mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' # Expected integer',
+ ' + n name "foo"',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 10, 'timestamp': 0, 'data': {
+ 'n': 'foo',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Local mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "foo"',
+ ' + n name \'"\'',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 10, 'timestamp': 0, 'data': {
+ 'f': 'foo',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Local mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected no NUL bytes',
+ ' + f file name "\\0"',
+ ' # Value is negative',
+ ' + n name -10',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 10, 'timestamp': 0, 'data': {
+ 'n': -10,
+ 'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]},
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Local mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "foo"',
+ ' + n name 20',
+ ' # Value is negative',
+ ' + l line number -10',
+ ' # Value is negative',
+ ' + c column -10',
+ }, ([[ [{'type': 10, 'timestamp': 0, 'data': {
+ 'n': 20,
+ 'f': 'foo',
+ 'l': -10,
+ 'c': -10,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Local mark with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "foo"',
+ ' + n name 20',
+ ' # Expected integer',
+ ' + l line number "FOO"',
+ ' # Expected integer',
+ ' + c column "foo"',
+ ' + mX 10',
+ }, ([[ [{'type': 10, 'timestamp': 0, 'data': {
+ 'n': 20,
+ 'f': 'foo',
+ 'l': 'FOO',
+ 'c': 'foo',
+ 'mX': 10,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Local mark with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + f file name "foo"',
+ ' + n name \'a\'',
+ ' + l line number 2',
+ ' + c column 200',
+ ' + mX 10',
+ ' + mYYYYYYYYYY 10',
+ }, ([[ [{'type': 10, 'timestamp': 0, 'data': {
+ 'n': char2nr('a'),
+ 'f': 'foo',
+ 'l': 2,
+ 'c': 200,
+ 'mX': 10,
+ 'mYYYYYYYYYY': 10,
+ }}] ]]):gsub('\n', ''))
+ end)
+
+ it('works with change items', function()
+ sd2strings_eq({
+ 'Change with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ }, {{type=11, timestamp=0, data={1, 2, 3}}})
+ sd2strings_eq({
+ 'Change with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 11, 'timestamp': 0, 'data': {
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Change with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' + l line number 1',
+ ' + c column 0',
+ ' # Expected integer',
+ ' + n name "foo"',
+ }, ([[ [{'type': 11, 'timestamp': 0, 'data': {
+ 'n': 'foo',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Change with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "foo"',
+ ' + l line number 1',
+ ' + c column 0',
+ }, ([[ [{'type': 11, 'timestamp': 0, 'data': {
+ 'f': 'foo',
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Change with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected no NUL bytes',
+ ' + f file name "\\0"',
+ ' + l line number 1',
+ ' + c column 0',
+ ' # Value is negative',
+ ' + n name -10',
+ }, ([[ [{'type': 11, 'timestamp': 0, 'data': {
+ 'n': -10,
+ 'f': {'_TYPE': v:msgpack_types.binary, '_VAL': ["\n"]},
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Change with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "foo"',
+ ' # Value is negative',
+ ' + l line number -10',
+ ' # Value is negative',
+ ' + c column -10',
+ }, ([[ [{'type': 11, 'timestamp': 0, 'data': {
+ 'f': 'foo',
+ 'l': -10,
+ 'c': -10,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Change with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "foo"',
+ ' # Expected integer',
+ ' + l line number "FOO"',
+ ' # Expected integer',
+ ' + c column "foo"',
+ ' + mX 10',
+ }, ([[ [{'type': 11, 'timestamp': 0, 'data': {
+ 'f': 'foo',
+ 'l': 'FOO',
+ 'c': 'foo',
+ 'mX': 10,
+ }}] ]]):gsub('\n', ''))
+ sd2strings_eq({
+ 'Change with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + f file name "foo"',
+ ' + l line number 2',
+ ' + c column 200',
+ ' + mX 10',
+ ' + mYYYYYYYYYY 10',
+ ' + n name \' \'',
+ }, ([[ [{'type': 11, 'timestamp': 0, 'data': {
+ 'n': 0x20,
+ 'f': 'foo',
+ 'l': 2,
+ 'c': 200,
+ 'mX': 10,
+ 'mYYYYYYYYYY': 10,
+ }}] ]]):gsub('\n', ''))
+ end)
+ end)
+
+ describe('function shada#get_strings', function()
+ it('works', function()
+ eq({
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Value',
+ }, nvim_eval('shada#get_strings(msgpackdump([1, 0, 0, {}]))'))
+ end)
+ end)
+
+ describe('function shada#strings_to_sd', function()
+
+ local strings2sd_eq = function(expected, input)
+ nvim('set_var', '__input', input)
+ nvim_command('let g:__actual = map(shada#strings_to_sd(g:__input), '
+ .. '"filter(v:val, \\"v:key[0] isnot# \'_\' '
+ .. '&& v:key isnot# \'length\'\\")")')
+ -- print()
+ if type(expected) == 'table' then
+ nvim('set_var', '__expected', expected)
+ nvim_command('let g:__expected = ModifyVal(g:__expected)')
+ expected = 'g:__expected'
+ -- print(nvim_eval('msgpack#string(g:__expected)'))
+ end
+ -- print(nvim_eval('msgpack#string(g:__actual)'))
+ eq(1, nvim_eval(('msgpack#equal(%s, g:__actual)'):format(expected)))
+ if type(expected) == 'table' then
+ nvim_command('unlet g:__expected')
+ end
+ nvim_command('unlet g:__input')
+ nvim_command('unlet g:__actual')
+ end
+
+ assert:set_parameter('TableFormatLevel', 100)
+
+ it('works with multiple items', function()
+ strings2sd_eq({{
+ type=11, timestamp=0, data={
+ f='foo',
+ l=2,
+ c=200,
+ mX=10,
+ mYYYYYYYYYY=10,
+ n=(' '):byte(),
+ }
+ }, {
+ type=1, timestamp=0, data={
+ c='abc',
+ f={'!binary', {'abc\ndef'}},
+ l=-10,
+ n=-64,
+ rc='10',
+ rt=10,
+ sc={'!nil', 0},
+ sm='TRUE',
+ so='TRUE',
+ sp={'!string', {'abc'}},
+ }
+ }}, {
+ 'Change with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + f file name "foo"',
+ ' + l line number 2',
+ ' + c column 200',
+ ' + mX 10',
+ ' + mYYYYYYYYYY 10',
+ ' + n name \' \'',
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Description____ Value',
+ ' # Expected integer',
+ ' + c column "abc"',
+ ' # Expected no NUL bytes',
+ ' + f file name "abc\\0def"',
+ ' # Value is negative',
+ ' + l line number -10',
+ ' # Value is negative',
+ ' + n name -64',
+ ' # Expected array value',
+ ' + rc contents "10"',
+ ' # Unexpected enum value: expected one of '
+ .. '0 (CHARACTERWISE), 1 (LINEWISE), 2 (BLOCKWISE)',
+ ' + rt type 10',
+ ' # Expected boolean',
+ ' + sc smartcase value NIL',
+ ' # Expected boolean',
+ ' + sm magic value "TRUE"',
+ ' # Expected integer',
+ ' + so offset value "TRUE"',
+ ' # Expected binary string',
+ ' + sp pattern ="abc"',
+ })
+ end)
+
+ it('works with empty list', function()
+ strings2sd_eq({}, {})
+ end)
+
+ it('works with header items', function()
+ strings2sd_eq({{type=1, timestamp=0, data={
+ generator='test',
+ }}}, {
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key______ Value',
+ ' + generator "test"',
+ })
+ strings2sd_eq({{type=1, timestamp=0, data={
+ 1, 2, 3,
+ }}}, {
+ 'Header with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ })
+ strings2sd_eq({{type=1, timestamp=0, data={
+ a=1, b=2, c=3, d=4,
+ }}}, {
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + a 1',
+ ' + b 2',
+ ' + c column 3',
+ ' + d 4',
+ })
+ strings2sd_eq({{type=1, timestamp=0, data={
+ c='abc',
+ f={'!binary', {'abc\ndef'}},
+ l=-10,
+ n=-64,
+ rc='10',
+ rt=10,
+ sc={'!nil', 0},
+ sm='TRUE',
+ so='TRUE',
+ sp={'!string', {'abc'}},
+ }}}, {
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Description____ Value',
+ ' # Expected integer',
+ ' + c column "abc"',
+ ' # Expected no NUL bytes',
+ ' + f file name "abc\\0def"',
+ ' # Value is negative',
+ ' + l line number -10',
+ ' # Value is negative',
+ ' + n name -64',
+ ' # Expected array value',
+ ' + rc contents "10"',
+ ' # Unexpected enum value: expected one of '
+ .. '0 (CHARACTERWISE), 1 (LINEWISE), 2 (BLOCKWISE)',
+ ' + rt type 10',
+ ' # Expected boolean',
+ ' + sc smartcase value NIL',
+ ' # Expected boolean',
+ ' + sm magic value "TRUE"',
+ ' # Expected integer',
+ ' + so offset value "TRUE"',
+ ' # Expected binary string',
+ ' + sp pattern ="abc"',
+ })
+ end)
+
+ it('works with search pattern items', function()
+ strings2sd_eq({{type=2, timestamp=0, data={
+ 1, 2, 3
+ }}}, {
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ })
+ strings2sd_eq({{type=2, timestamp=0, data={
+ sp='abc',
+ }}}, {
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' + sp pattern "abc"',
+ ' + sh v:hlsearch value FALSE',
+ ' + ss is :s pattern FALSE',
+ ' + sm magic value TRUE',
+ ' + sc smartcase value FALSE',
+ ' + sl has line offset FALSE',
+ ' + se place cursor at end FALSE',
+ ' + so offset value 0',
+ ' + su is last used TRUE',
+ })
+ strings2sd_eq({{type=2, timestamp=0, data={
+ sp='abc',
+ sX={'!nil', 0},
+ sY={'!nil', 0},
+ sZ={'!nil', 0},
+ }}}, {
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' + sp pattern "abc"',
+ ' + sh v:hlsearch value FALSE',
+ ' + ss is :s pattern FALSE',
+ ' + sm magic value TRUE',
+ ' + sc smartcase value FALSE',
+ ' + sl has line offset FALSE',
+ ' + se place cursor at end FALSE',
+ ' + so offset value 0',
+ ' + su is last used TRUE',
+ ' + sX NIL',
+ ' + sY NIL',
+ ' + sZ NIL',
+ })
+ strings2sd_eq({{type=2, timestamp=0, data={'!map', {
+ }}}}, {
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' # Required key missing: sp',
+ ' + sh v:hlsearch value FALSE',
+ ' + ss is :s pattern FALSE',
+ ' + sm magic value TRUE',
+ ' + sc smartcase value FALSE',
+ ' + sl has line offset FALSE',
+ ' + se place cursor at end FALSE',
+ ' + so offset value 0',
+ ' + su is last used TRUE',
+ })
+ strings2sd_eq({{type=2, timestamp=0, data={
+ sp='',
+ sh={'!boolean', 1},
+ ss={'!boolean', 1},
+ sc={'!boolean', 1},
+ sl={'!boolean', 1},
+ se={'!boolean', 1},
+ sm={'!boolean', 0},
+ su={'!boolean', 0},
+ so=-10,
+ }}}, {
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' + sp pattern ""',
+ ' + sh v:hlsearch value TRUE',
+ ' + ss is :s pattern TRUE',
+ ' + sm magic value FALSE',
+ ' + sc smartcase value TRUE',
+ ' + sl has line offset TRUE',
+ ' + se place cursor at end TRUE',
+ ' + so offset value -10',
+ ' + su is last used FALSE',
+ })
+ strings2sd_eq({{type=2, timestamp=0, data={
+ sp=0,
+ sh=0,
+ ss=0,
+ sc=0,
+ sl=0,
+ se=0,
+ sm=0,
+ su=0,
+ so='',
+ }}}, {
+ 'Search pattern with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' # Expected binary string',
+ ' + sp pattern 0',
+ ' # Expected boolean',
+ ' + sh v:hlsearch value 0',
+ ' # Expected boolean',
+ ' + ss is :s pattern 0',
+ ' # Expected boolean',
+ ' + sm magic value 0',
+ ' # Expected boolean',
+ ' + sc smartcase value 0',
+ ' # Expected boolean',
+ ' + sl has line offset 0',
+ ' # Expected boolean',
+ ' + se place cursor at end 0',
+ ' # Expected integer',
+ ' + so offset value ""',
+ ' # Expected boolean',
+ ' + su is last used 0',
+ })
+ end)
+
+ it('works with replacement string items', function()
+ strings2sd_eq({{type=3, timestamp=0, data={
+ a={10}
+ }}}, {
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: map instead of array',
+ ' = {="a": [10]}',
+ })
+ strings2sd_eq({{type=3, timestamp=0, data={
+ }}}, {
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' # Expected more elements in list'
+ })
+ strings2sd_eq({{type=3, timestamp=0, data={
+ 0
+ }}}, {
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' # Expected binary string',
+ ' - :s replacement string 0',
+ })
+ strings2sd_eq({{type=3, timestamp=0, data={
+ 'abc\ndef', 0,
+ }}}, {
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' - :s replacement string "abc\\ndef"',
+ ' - 0',
+ })
+ strings2sd_eq({{type=3, timestamp=0, data={
+ 'abc\ndef',
+ }}}, {
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' - :s replacement string "abc\\ndef"',
+ })
+ end)
+
+ it('works with history entry items', function()
+ strings2sd_eq({{type=4, timestamp=0, data={
+ a={10},
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: map instead of array',
+ ' = {="a": [10]}',
+ })
+ strings2sd_eq({{type=4, timestamp=0, data={
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' # Expected more elements in list'
+ })
+ strings2sd_eq({{type=4, timestamp=0, data={
+ '',
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' # Expected integer',
+ ' - history type ""',
+ ' # Expected more elements in list'
+ })
+ strings2sd_eq({{type=4, timestamp=0, data={
+ 5, '',
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' # Unexpected enum value: expected one of 0 (CMD), 1 (SEARCH), '
+ .. '2 (EXPR), 3 (INPUT), 4 (DEBUG)',
+ ' - history type 5',
+ ' - contents ""',
+ })
+ strings2sd_eq({{type=4, timestamp=0, data={
+ 5, '', 32,
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' # Unexpected enum value: expected one of 0 (CMD), 1 (SEARCH), '
+ .. '2 (EXPR), 3 (INPUT), 4 (DEBUG)',
+ ' - history type 5',
+ ' - contents ""',
+ ' - 32',
+ })
+ strings2sd_eq({{type=4, timestamp=0, data={
+ 0, '', 32,
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type CMD',
+ ' - contents ""',
+ ' - 32',
+ })
+ strings2sd_eq({{type=4, timestamp=0, data={
+ 1, '', 32,
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type SEARCH',
+ ' - contents ""',
+ ' - separator \' \'',
+ })
+ strings2sd_eq({{type=4, timestamp=0, data={
+ 1, '',
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type SEARCH',
+ ' - contents ""',
+ ' # Expected more elements in list',
+ })
+ strings2sd_eq({{type=4, timestamp=0, data={
+ 2, '',
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type EXPR',
+ ' - contents ""',
+ })
+ strings2sd_eq({{type=4, timestamp=0, data={
+ 3, ''
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type INPUT',
+ ' - contents ""',
+ })
+ strings2sd_eq({{type=4, timestamp=0, data={
+ 4, ''
+ }}}, {
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type DEBUG',
+ ' - contents ""',
+ })
+ end)
+
+ it('works with register items', function()
+ strings2sd_eq({{type=5, timestamp=0, data={
+ 1, 2, 3
+ }}}, {
+ 'Register with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ })
+ strings2sd_eq({{type=5, timestamp=0, data={'!map', {
+ }}}}, {
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: n',
+ ' # Required key missing: rc',
+ ' + rw block width 0',
+ ' + rt type CHARACTERWISE',
+ })
+ strings2sd_eq({{type=5, timestamp=0, data={
+ n=(' '):byte()
+ }}}, {
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' # Required key missing: rc',
+ ' + rw block width 0',
+ ' + rt type CHARACTERWISE',
+ })
+ strings2sd_eq({{type=5, timestamp=0, data={
+ n=(' '):byte(), rc={'abc', 'def'}
+ }}}, {
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' + rc contents ["abc", "def"]',
+ ' + rw block width 0',
+ ' + rt type CHARACTERWISE',
+ })
+ strings2sd_eq({{type=5, timestamp=0, data={
+ n=(' '):byte(),
+ rc={'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'},
+ }}}, {
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' + rc contents @',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' + rw block width 0',
+ ' + rt type CHARACTERWISE',
+ })
+ strings2sd_eq({{type=5, timestamp=0, data={
+ n=(' '):byte(),
+ rc={'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'},
+ rw=5,
+ rt=1,
+ }}}, {
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' + rc contents @',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' + rw block width 5',
+ ' + rt type LINEWISE',
+ })
+ strings2sd_eq({{type=5, timestamp=0, data={
+ n=(' '):byte(),
+ rc={'abcdefghijklmnopqrstuvwxyz', 'abcdefghijklmnopqrstuvwxyz'},
+ rw=5,
+ rt=2,
+ }}}, {
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' + rc contents @',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' + rw block width 5',
+ ' + rt type BLOCKWISE',
+ })
+ strings2sd_eq({{type=5, timestamp=0, data={
+ n=(' '):byte(),
+ rc=0,
+ rw=-1,
+ rt=10,
+ }}}, {
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' # Expected array value',
+ ' + rc contents 0',
+ ' # Value is negative',
+ ' + rw block width -1',
+ ' # Unexpected enum value: expected one of 0 (CHARACTERWISE), '
+ .. '1 (LINEWISE), 2 (BLOCKWISE)',
+ ' + rt type 10',
+ })
+ end)
+
+ it('works with variable items', function()
+ strings2sd_eq({{type=6, timestamp=0, data={
+ a={10}
+ }}}, {
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: map instead of array',
+ ' = {="a": [10]}',
+ })
+ strings2sd_eq({{type=6, timestamp=0, data={
+ }}}, {
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' @ Description Value',
+ ' # Expected more elements in list'
+ })
+ strings2sd_eq({{type=6, timestamp=0, data={
+ 'foo',
+ }}}, {
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' @ Description Value',
+ ' - name "foo"',
+ ' # Expected more elements in list',
+ })
+ strings2sd_eq({{type=6, timestamp=0, data={
+ 'foo', {'!nil', 0},
+ }}}, {
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' @ Description Value',
+ ' - name "foo"',
+ ' - value NIL',
+ })
+ strings2sd_eq({{type=6, timestamp=0, data={
+ 'foo', {'!nil', 0}, {'!nil', 0}
+ }}}, {
+ 'Variable with timestamp ' .. epoch .. ':',
+ ' @ Description Value',
+ ' - name "foo"',
+ ' - value NIL',
+ ' - NIL',
+ })
+ end)
+
+ it('works with global mark items', function()
+ strings2sd_eq({{type=7, timestamp=0, data={
+ 1, 2, 3
+ }}}, {
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ })
+ strings2sd_eq({{type=7, timestamp=0, data={
+ n=('A'):byte(), f='foo', l=2, c=200, mX=10, mYYYYYYYYYY=10,
+ }}}, {
+ 'Global mark with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name "foo"',
+ ' + l line number 2',
+ ' + c column 200',
+ ' + mX 10',
+ ' + mYYYYYYYYYY 10',
+ })
+ end)
+
+ it('works with jump items', function()
+ strings2sd_eq({{type=8, timestamp=0, data={
+ 1, 2, 3
+ }}}, {
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ })
+ strings2sd_eq({{type=8, timestamp=0, data={
+ n=('A'):byte(), f='foo', l=2, c=200, mX=10, mYYYYYYYYYY=10,
+ }}}, {
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name "foo"',
+ ' + l line number 2',
+ ' + c column 200',
+ ' + mX 10',
+ ' + mYYYYYYYYYY 10',
+ })
+ end)
+
+ it('works with buffer list items', function()
+ strings2sd_eq({{type=9, timestamp=0, data={
+ a={10}
+ }}}, {
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: map instead of array',
+ ' = {="a": [10]}',
+ })
+ strings2sd_eq({{type=9, timestamp=0, data={
+ {a=10}, {}
+ }}}, {
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' # Expected array of maps',
+ ' = [{="a": 10}, []]',
+ })
+ strings2sd_eq({{type=9, timestamp=0, data={
+ {a=10},
+ }}}, {
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' + l line number 1',
+ ' + c column 0',
+ ' + a 10',
+ })
+ strings2sd_eq({{type=9, timestamp=0, data={
+ {l='10', c='10', a=10},
+ }}}, {
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' # Expected integer',
+ ' + l line number "10"',
+ ' # Expected integer',
+ ' + c column "10"',
+ ' + a 10',
+ })
+ strings2sd_eq({{type=9, timestamp=0, data={
+ {l=10, c=10, a=10},
+ }}}, {
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' + l line number 10',
+ ' + c column 10',
+ ' + a 10',
+ })
+ strings2sd_eq({{type=9, timestamp=0, data={
+ {l=-10, c=-10},
+ }}}, {
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Required key missing: f',
+ ' # Value is negative',
+ ' + l line number -10',
+ ' # Value is negative',
+ ' + c column -10',
+ })
+ strings2sd_eq({{type=9, timestamp=0, data={
+ {f='abc'},
+ }}}, {
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + f file name "abc"',
+ ' + l line number 1',
+ ' + c column 0',
+ })
+ strings2sd_eq({{type=9, timestamp=0, data={
+ {f=10}, {f=20},
+ }}}, {
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected binary string',
+ ' + f file name 10',
+ ' + l line number 1',
+ ' + c column 0',
+ '',
+ ' % Key Description Value',
+ ' # Expected binary string',
+ ' + f file name 20',
+ ' + l line number 1',
+ ' + c column 0',
+ })
+ strings2sd_eq({{type=9, timestamp=0, data={
+ {f=10}, {f={'!binary', {'\n'}}},
+ }}}, {
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected binary string',
+ ' + f file name 10',
+ ' + l line number 1',
+ ' + c column 0',
+ '',
+ ' % Key Description Value',
+ ' # Expected no NUL bytes',
+ ' + f file name "\\0"',
+ ' + l line number 1',
+ ' + c column 0',
+ })
+ end)
+
+ it('works with local mark items', function()
+ strings2sd_eq({{type=10, timestamp=0, data={
+ 1, 2, 3
+ }}}, {
+ 'Local mark with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ })
+ strings2sd_eq({{type=10, timestamp=0, data={
+ n=('A'):byte(), f='foo', l=2, c=200, mX=10, mYYYYYYYYYY=10,
+ }}}, {
+ 'Local mark with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name "foo"',
+ ' + l line number 2',
+ ' + c column 200',
+ ' + mX 10',
+ ' + mYYYYYYYYYY 10',
+ })
+ end)
+
+ it('works with change items', function()
+ strings2sd_eq({{type=11, timestamp=0, data={
+ 1, 2, 3
+ }}}, {
+ 'Change with timestamp ' .. epoch .. ':',
+ ' # Unexpected type: array instead of map',
+ ' = [1, 2, 3]',
+ })
+ strings2sd_eq({{type=11, timestamp=0, data={
+ n=('A'):byte(), f='foo', l=2, c=200, mX=10, mYYYYYYYYYY=10,
+ }}}, {
+ 'Change with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name "foo"',
+ ' + l line number 2',
+ ' + c column 200',
+ ' + mX 10',
+ ' + mYYYYYYYYYY 10',
+ })
+ end)
+ end)
+
+ describe('function shada#get_binstrings', function()
+ local getbstrings_eq = function(expected, input)
+ local result = funcs['shada#get_binstrings'](input)
+ for i, s in ipairs(result) do
+ result[i] = s:gsub('\n', '\0')
+ end
+ local mpack_result = table.concat(result, '\n')
+ return mpack_eq(expected, mpack_result)
+ end
+
+ it('works', function()
+ getbstrings_eq({{timestamp='current', type=1, value={
+ generator='shada.vim',
+ version=704,
+ }}}, {})
+ getbstrings_eq({
+ {timestamp='current', type=1, value={
+ generator='shada.vim', version=704
+ }},
+ {timestamp=0, type=1, value={generator='test'}}
+ }, {
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key______ Value',
+ ' + generator "test"',
+ })
+ nvim('set_var', 'shada#add_own_header', 1)
+ getbstrings_eq({{timestamp='current', type=1, value={
+ generator='shada.vim',
+ version=704,
+ }}}, {})
+ getbstrings_eq({
+ {timestamp='current', type=1, value={
+ generator='shada.vim', version=704
+ }},
+ {timestamp=0, type=1, value={generator='test'}}
+ }, {
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key______ Value',
+ ' + generator "test"',
+ })
+ nvim('set_var', 'shada#add_own_header', 0)
+ getbstrings_eq({}, {})
+ getbstrings_eq({{timestamp=0, type=1, value={generator='test'}}}, {
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key______ Value',
+ ' + generator "test"',
+ })
+ nvim('set_var', 'shada#keep_old_header', 0)
+ getbstrings_eq({}, {
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key______ Value',
+ ' + generator "test"',
+ })
+ getbstrings_eq({
+ {type=3, timestamp=0, value={'abc\ndef'}},
+ {type=3, timestamp=0, value={'abc\ndef'}},
+ {type=3, timestamp=0, value={'abc\ndef'}},
+ }, {
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' - :s replacement string "abc\\ndef"',
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' - :s replacement string "abc\\ndef"',
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' - :s replacement string "abc\\ndef"',
+ })
+ end)
+ end)
+end)
+
+describe('In plugin/shada.vim', function()
+ local epoch = os.date('%Y-%m-%dT%H:%M:%S', 0)
+ before_each(function()
+ reset()
+ os.remove(fname)
+ os.remove(fname .. '.tst')
+ os.remove(fname_tmp)
+ end)
+
+ local shada_eq = function(expected, fname_)
+ local fd = io.open(fname_)
+ local mpack_result = fd:read('*a')
+ fd:close()
+ mpack_eq(expected, mpack_result)
+ end
+
+ describe('event BufReadCmd', function()
+ it('works', function()
+ wshada('\004\000\009\147\000\196\002ab\196\001a')
+ wshada_tmp('\004\000\009\147\000\196\002ab\196\001b')
+ nvim_command('edit ' .. fname)
+ eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type CMD',
+ ' - contents "ab"',
+ ' - "a"',
+ }, nvim_eval('getline(1, "$")'))
+ eq(false, curbuf('get_option', 'modified'))
+ eq('shada', curbuf('get_option', 'filetype'))
+ nvim_command('edit ' .. fname_tmp)
+ eq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type CMD',
+ ' - contents "ab"',
+ ' - "b"',
+ }, nvim_eval('getline(1, "$")'))
+ eq(false, curbuf('get_option', 'modified'))
+ eq('shada', curbuf('get_option', 'filetype'))
+ eq('++opt not supported', exc_exec('edit ++enc=latin1 ' .. fname))
+ neq({
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type CMD',
+ ' - contents "ab"',
+ ' - "a"',
+ }, nvim_eval('getline(1, "$")'))
+ neq(true, curbuf('get_option', 'modified'))
+ end)
+ end)
+
+ describe('event FileReadCmd', function()
+ it('works', function()
+ wshada('\004\000\009\147\000\196\002ab\196\001a')
+ wshada_tmp('\004\000\009\147\000\196\002ab\196\001b')
+ nvim_command('$read ' .. fname)
+ eq({
+ '',
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type CMD',
+ ' - contents "ab"',
+ ' - "a"',
+ }, nvim_eval('getline(1, "$")'))
+ eq(true, curbuf('get_option', 'modified'))
+ neq('shada', curbuf('get_option', 'filetype'))
+ nvim_command('1,$read ' .. fname_tmp)
+ eq({
+ '',
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type CMD',
+ ' - contents "ab"',
+ ' - "a"',
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type CMD',
+ ' - contents "ab"',
+ ' - "b"',
+ }, nvim_eval('getline(1, "$")'))
+ eq(true, curbuf('get_option', 'modified'))
+ neq('shada', curbuf('get_option', 'filetype'))
+ curbuf('set_option', 'modified', false)
+ eq('++opt not supported', exc_exec('$read ++enc=latin1 ' .. fname))
+ eq({
+ '',
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type CMD',
+ ' - contents "ab"',
+ ' - "a"',
+ 'History entry with timestamp ' .. epoch .. ':',
+ ' @ Description_ Value',
+ ' - history type CMD',
+ ' - contents "ab"',
+ ' - "b"',
+ }, nvim_eval('getline(1, "$")'))
+ neq(true, curbuf('get_option', 'modified'))
+ end)
+ end)
+
+ describe('event BufWriteCmd', function()
+ it('works', function()
+ nvim('set_var', 'shada#add_own_header', 0)
+ curbuf('set_line_slice', 0, 0, true, true, {
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ })
+ nvim_command('w ' .. fname .. '.tst')
+ nvim_command('w ' .. fname)
+ nvim_command('w ' .. fname_tmp)
+ eq('++opt not supported', exc_exec('w! ++enc=latin1 ' .. fname))
+ eq(table.concat({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ }, '\n') .. '\n', io.open(fname .. '.tst'):read('*a'))
+ shada_eq({{
+ timestamp=0,
+ type=8,
+ value={c=-200, f={'foo'}, l=2, n=('A'):byte()},
+ }, {
+ timestamp=0,
+ type=8,
+ value={c=-200, f={'foo'}, l=2, n=('A'):byte()},
+ }}, fname)
+ shada_eq({{
+ timestamp=0,
+ type=8,
+ value={c=-200, f={'foo'}, l=2, n=('A'):byte()},
+ }, {
+ timestamp=0,
+ type=8,
+ value={c=-200, f={'foo'}, l=2, n=('A'):byte()},
+ }}, fname_tmp)
+ end)
+ end)
+
+ describe('event FileWriteCmd', function()
+ it('works', function()
+ nvim('set_var', 'shada#add_own_header', 0)
+ curbuf('set_line_slice', 0, 0, true, true, {
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ })
+ nvim_command('1,3w ' .. fname .. '.tst')
+ nvim_command('1,3w ' .. fname)
+ nvim_command('1,3w ' .. fname_tmp)
+ eq('++opt not supported', exc_exec('1,3w! ++enc=latin1 ' .. fname))
+ eq(table.concat({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ }, '\n') .. '\n', io.open(fname .. '.tst'):read('*a'))
+ shada_eq({{
+ timestamp=0,
+ type=8,
+ value={n=('A'):byte()},
+ }}, fname)
+ shada_eq({{
+ timestamp=0,
+ type=8,
+ value={n=('A'):byte()},
+ }}, fname_tmp)
+ end)
+ end)
+
+ describe('event FileAppendCmd', function()
+ it('works', function()
+ nvim('set_var', 'shada#add_own_header', 0)
+ curbuf('set_line_slice', 0, 0, true, true, {
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ })
+ funcs.writefile({''}, fname .. '.tst', 'b')
+ funcs.writefile({''}, fname, 'b')
+ funcs.writefile({''}, fname_tmp, 'b')
+ nvim_command('1,3w >> ' .. fname .. '.tst')
+ nvim_command('1,3w >> ' .. fname)
+ nvim_command('1,3w >> ' .. fname_tmp)
+ nvim_command('w >> ' .. fname .. '.tst')
+ nvim_command('w >> ' .. fname)
+ nvim_command('w >> ' .. fname_tmp)
+ eq('++opt not supported', exc_exec('1,3w! ++enc=latin1 >> ' .. fname))
+ eq(table.concat({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ }, '\n') .. '\n', io.open(fname .. '.tst'):read('*a'))
+ shada_eq({{
+ timestamp=0,
+ type=8,
+ value={n=('A'):byte()},
+ }, {
+ timestamp=0,
+ type=8,
+ value={c=-200, f={'foo'}, l=2, n=('A'):byte()},
+ }, {
+ timestamp=0,
+ type=8,
+ value={c=-200, f={'foo'}, l=2, n=('A'):byte()},
+ }}, fname)
+ shada_eq({{
+ timestamp=0,
+ type=8,
+ value={n=('A'):byte()},
+ }, {
+ timestamp=0,
+ type=8,
+ value={c=-200, f={'foo'}, l=2, n=('A'):byte()},
+ }, {
+ timestamp=0,
+ type=8,
+ value={c=-200, f={'foo'}, l=2, n=('A'):byte()},
+ }}, fname_tmp)
+ end)
+ end)
+
+ describe('event SourceCmd', function()
+ before_each(function()
+ reset(fname)
+ end)
+ it('works', function()
+ wshada('\004\000\006\146\000\196\002ab')
+ wshada_tmp('\004\001\006\146\000\196\002bc')
+ eq(0, exc_exec('source ' .. fname))
+ eq(0, exc_exec('source ' .. fname_tmp))
+ eq('bc', funcs.histget(':', -1))
+ eq('ab', funcs.histget(':', -2))
+ end)
+ end)
+end)
+
+describe('ftplugin/shada.vim', function()
+ local epoch = os.date('%Y-%m-%dT%H:%M:%S', 0)
+ before_each(reset)
+
+ it('sets indentexpr correctly', function()
+ nvim_command('filetype plugin indent on')
+ nvim_command('setlocal filetype=shada')
+ funcs.setline(1, {
+ 'Jump with timestamp ' .. epoch .. ':',
+ '% Key________ Description Value',
+ '+ n name \'A\'',
+ '+ f file name "foo"',
+ '+ l line number 2',
+ '+ c column 200',
+ '+ mX 10',
+ '+ mYYYYYYYYYY 10',
+ 'Register with timestamp ' .. epoch .. ':',
+ '% Key Description Value',
+ '+ n name \' \'',
+ '+ rc contents @',
+ '| - "abcdefghijklmnopqrstuvwxyz"',
+ '| - "abcdefghijklmnopqrstuvwxyz"',
+ '+ rw block width 0',
+ '+ rt type CHARACTERWISE',
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' - :s replacement string "abc\\ndef"',
+ ' Buffer list with timestamp ' .. epoch .. ':',
+ ' # Expected array of maps',
+ '= [{="a": 10}, []]',
+ ' Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected binary string',
+ '+ f file name 10',
+ ' + l line number 1',
+ ' + c column 0',
+ '',
+ ' % Key Description Value',
+ ' # Expected binary string',
+ ' + f file name 20',
+ '+ l line number 1',
+ ' + c column 0',
+ })
+ nvim_command('normal! gg=G')
+ eq({
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name "foo"',
+ ' + l line number 2',
+ ' + c column 200',
+ ' + mX 10',
+ ' + mYYYYYYYYYY 10',
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + n name \' \'',
+ ' + rc contents @',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' | - "abcdefghijklmnopqrstuvwxyz"',
+ ' + rw block width 0',
+ ' + rt type CHARACTERWISE',
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' - :s replacement string "abc\\ndef"',
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' # Expected array of maps',
+ ' = [{="a": 10}, []]',
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' # Expected binary string',
+ ' + f file name 10',
+ ' + l line number 1',
+ ' + c column 0',
+ '',
+ ' % Key Description Value',
+ ' # Expected binary string',
+ ' + f file name 20',
+ ' + l line number 1',
+ ' + c column 0',
+ }, funcs.getline(1, funcs.line('$')))
+ end)
+
+ it('sets options correctly', function()
+ nvim_command('filetype plugin indent on')
+ nvim_command('setlocal filetype=shada')
+ eq(true, curbuf('get_option', 'expandtab'))
+ eq(2, curbuf('get_option', 'tabstop'))
+ eq(2, curbuf('get_option', 'softtabstop'))
+ eq(2, curbuf('get_option', 'shiftwidth'))
+ end)
+
+ it('sets indentkeys correctly', function()
+ nvim_command('filetype plugin indent on')
+ nvim_command('setlocal filetype=shada')
+ funcs.setline(1, ' Replacement with timestamp ' .. epoch)
+ nvim_feed('ggA:\027')
+ eq('Replacement with timestamp ' .. epoch .. ':', curbuf('get_line', 0))
+ nvim_feed('o-\027')
+ eq(' -', curbuf('get_line', 1))
+ nvim_feed('ggO+\027')
+ eq('+', curbuf('get_line', 0))
+ nvim_feed('GO*\027')
+ eq(' *', curbuf('get_line', 2))
+ nvim_feed('ggO /\027')
+ eq(' /', curbuf('get_line', 0))
+ nvim_feed('ggOx\027')
+ eq('x', curbuf('get_line', 0))
+ end)
+end)
+
+describe('syntax/shada.vim', function()
+ local epoch = os.date('%Y-%m-%dT%H:%M:%S', 0)
+ before_each(reset)
+
+ it('works', function()
+ nvim_command('syntax on')
+ nvim_command('setlocal syntax=shada')
+ curbuf('set_line_slice', 0, 0, true, true, {
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Value',
+ ' + t "test"',
+ 'Jump with timestamp ' .. epoch .. ':',
+ ' % Key________ Description Value',
+ ' + n name \'A\'',
+ ' + f file name ["foo"]',
+ ' + l line number 2',
+ ' + c column -200',
+ 'Register with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ ' + rc contents @',
+ ' | - {"abcdefghijklmnopqrstuvwxyz": 1.0}',
+ ' + rt type CHARACTERWISE',
+ ' + rt type LINEWISE',
+ ' + rt type BLOCKWISE',
+ 'Replacement string with timestamp ' .. epoch .. ':',
+ ' @ Description__________ Value',
+ ' - :s replacement string CMD',
+ ' - :s replacement string SEARCH',
+ ' - :s replacement string EXPR',
+ ' - :s replacement string INPUT',
+ ' - :s replacement string DEBUG',
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' # Expected array of maps',
+ ' = [{="a": +(10)"ac\\0df\\ngi\\"tt\\.", TRUE: FALSE}, [NIL, +(-10)""]]',
+ 'Buffer list with timestamp ' .. epoch .. ':',
+ ' % Key Description Value',
+ '',
+ ' % Key Description Value',
+ 'Header with timestamp ' .. epoch .. ':',
+ ' % Key Description________ Value',
+ ' + se place cursor at end TRUE',
+ })
+ nvim_command([[
+ function GetSyntax()
+ let lines = []
+ for l in range(1, line('$'))
+ let columns = []
+ let line = getline(l)
+ for c in range(1, col([l, '$']) - 1)
+ let synstack = map(synstack(l, c), 'synIDattr(v:val, "name")')
+ if !empty(columns) && columns[-1][0] ==# synstack
+ let columns[-1][1] .= line[c - 1]
+ else
+ call add(columns, [ synstack, line[c - 1] ])
+ endif
+ endfor
+ call add(lines, columns)
+ endfor
+ return lines
+ endfunction
+ ]])
+ local hname = function(s) return {{'ShaDaEntryHeader', 'ShaDaEntryName'},
+ s} end
+ local h = function(s) return {{'ShaDaEntryHeader'}, s} end
+ local htsnum = function(s) return {
+ {'ShaDaEntryHeader', 'ShaDaEntryTimestamp', 'ShaDaEntryTimestampNumber'},
+ s
+ } end
+ local synhtssep = function(s)
+ return {{'ShaDaEntryHeader', 'ShaDaEntryTimestamp'}, s}
+ end
+ local synepoch = {
+ year = htsnum(os.date('%Y', 0)),
+ month = htsnum(os.date('%m', 0)),
+ day = htsnum(os.date('%d', 0)),
+ hour = htsnum(os.date('%H', 0)),
+ minute = htsnum(os.date('%M', 0)),
+ second = htsnum(os.date('%S', 0)),
+ }
+ local msh = function(s) return {{'ShaDaEntryMapShort',
+ 'ShaDaEntryMapHeader'}, s} end
+ local mlh = function(s) return {{'ShaDaEntryMapLong',
+ 'ShaDaEntryMapHeader'}, s} end
+ local ah = function(s) return {{'ShaDaEntryArray',
+ 'ShaDaEntryArrayHeader'}, s} end
+ -- luacheck: ignore
+ local mses = function(s) return {{'ShaDaEntryMapShort',
+ 'ShaDaEntryMapShortEntryStart'}, s} end
+ local mles = function(s) return {{'ShaDaEntryMapLong',
+ 'ShaDaEntryMapLongEntryStart'}, s} end
+ local act = funcs.GetSyntax()
+ local ms = function(syn)
+ return {
+ {'ShaDaEntryMap' .. syn, 'ShaDaEntryMap' .. syn .. 'EntryStart'}, ' + '
+ }
+ end
+ local as = function()
+ return {{'ShaDaEntryArray', 'ShaDaEntryArrayEntryStart'}, ' - '}
+ end
+ local ad = function(s) return {{'ShaDaEntryArray',
+ 'ShaDaEntryArrayDescription'}, s} end
+ local mbas = function(syn)
+ return {
+ {'ShaDaEntryMap' .. syn, 'ShaDaEntryMapBinArrayStart'},
+ ' | - '
+ }
+ end
+ local msk = function(s) return {{'ShaDaEntryMapShort',
+ 'ShaDaEntryMapShortKey'}, s} end
+ local mlk = function(s) return {{'ShaDaEntryMapLong',
+ 'ShaDaEntryMapLongKey'}, s} end
+ local mld = function(s) return {{'ShaDaEntryMapLong',
+ 'ShaDaEntryMapLongDescription'}, s} end
+ local c = function(s) return {{'ShaDaComment'}, s} end
+ local exp = {
+ {
+ hname('Header'), h(' with timestamp '),
+ synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'),
+ synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'),
+ synepoch.minute, synhtssep(':'), synepoch.second, h(':'),
+ },
+ {
+ msh(' % Key Value'),
+ },
+ {
+ ms('Short'), msk('t '),
+ {{'ShaDaEntryMapShort', 'ShaDaMsgpackBinaryString',
+ 'ShaDaMsgpackStringQuotes'}, '"'},
+ {{'ShaDaEntryMapShort', 'ShaDaMsgpackBinaryString'}, 'test'},
+ {{'ShaDaEntryMapShort', 'ShaDaMsgpackStringQuotes'}, '"'},
+ },
+ {
+ hname('Jump'), h(' with timestamp '),
+ synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'),
+ synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'),
+ synepoch.minute, synhtssep(':'), synepoch.second, h(':'),
+ },
+ {
+ mlh(' % Key________ Description Value'),
+ },
+ {
+ ms('Long'), mlk('n '), mld('name '),
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackCharacter'}, '\'A\''},
+ },
+ {
+ ms('Long'), mlk('f '), mld('file name '),
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackArray',
+ 'ShaDaMsgpackArrayBraces'}, '['},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackArray', 'ShaDaMsgpackBinaryString',
+ 'ShaDaMsgpackStringQuotes'}, '"'},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackArray', 'ShaDaMsgpackBinaryString'},
+ 'foo'},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackArray', 'ShaDaMsgpackStringQuotes'},
+ '"'},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackArrayBraces'}, ']'},
+ },
+ {
+ ms('Long'), mlk('l '), mld('line number '),
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackInteger'}, '2'},
+ },
+ {
+ ms('Long'), mlk('c '), mld('column '),
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackInteger'}, '-200'},
+ },
+ {
+ hname('Register'), h(' with timestamp '),
+ synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'),
+ synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'),
+ synepoch.minute, synhtssep(':'), synepoch.second, h(':'),
+ },
+ {
+ mlh(' % Key Description Value'),
+ },
+ {
+ ms('Long'), mlk('rc '), mld('contents '),
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackMultilineArray'}, '@'},
+ },
+ {
+ mbas('Long'),
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackMapBraces'},
+ '{'},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString',
+ 'ShaDaMsgpackStringQuotes'}, '"'},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString'},
+ 'abcdefghijklmnopqrstuvwxyz'},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackStringQuotes'},
+ '"'},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackColon'}, ':'},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap'}, ' '},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackMap', 'ShaDaMsgpackFloat'}, '1.0'},
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackMapBraces'}, '}'},
+ },
+ {
+ ms('Long'), mlk('rt '), mld('type '),
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackShaDaKeyword'}, 'CHARACTERWISE'},
+ },
+ {
+ ms('Long'), mlk('rt '), mld('type '),
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackShaDaKeyword'}, 'LINEWISE'},
+ },
+ {
+ ms('Long'), mlk('rt '), mld('type '),
+ {{'ShaDaEntryMapLong', 'ShaDaMsgpackShaDaKeyword'}, 'BLOCKWISE'},
+ },
+ {
+ hname('Replacement string'), h(' with timestamp '),
+ synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'),
+ synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'),
+ synepoch.minute, synhtssep(':'), synepoch.second, h(':'),
+ },
+ {
+ ah(' @ Description__________ Value'),
+ },
+ {
+ as(), ad(':s replacement string '),
+ {{'ShaDaEntryArray', 'ShaDaMsgpackShaDaKeyword'}, 'CMD'},
+ },
+ {
+ as(), ad(':s replacement string '),
+ {{'ShaDaEntryArray', 'ShaDaMsgpackShaDaKeyword'}, 'SEARCH'},
+ },
+ {
+ as(), ad(':s replacement string '),
+ {{'ShaDaEntryArray', 'ShaDaMsgpackShaDaKeyword'}, 'EXPR'},
+ },
+ {
+ as(), ad(':s replacement string '),
+ {{'ShaDaEntryArray', 'ShaDaMsgpackShaDaKeyword'}, 'INPUT'},
+ },
+ {
+ {{'ShaDaEntryArrayEntryStart'}, ' - '},
+ {{'ShaDaEntryArrayDescription'}, ':s replacement string '},
+ {{'ShaDaMsgpackShaDaKeyword'}, 'DEBUG'},
+ },
+ {
+ hname('Buffer list'), h(' with timestamp '),
+ synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'),
+ synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'),
+ synepoch.minute, synhtssep(':'), synepoch.second, h(':'),
+ },
+ {
+ c(' # Expected array of maps'),
+ },
+ {
+ {{'ShaDaEntryRawMsgpack'}, ' = '},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArrayBraces'}, '['},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackMapBraces'},
+ '{'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackString'}, '='},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString',
+ 'ShaDaMsgpackStringQuotes'}, '"'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString'},
+ 'a'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackStringQuotes'},
+ '"'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackColon'}, ':'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap'}, ' '},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackExt'}, '+('},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackExt',
+ 'ShaDaMsgpackExtType'}, '10'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackExt'}, ')'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString',
+ 'ShaDaMsgpackStringQuotes'}, '"'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString'},
+ 'ac'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString',
+ 'ShaDaMsgpackBinaryStringEscape'},
+ '\\0'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString'},
+ 'df'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString',
+ 'ShaDaMsgpackBinaryStringEscape'},
+ '\\n'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString'},
+ 'gi'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString',
+ 'ShaDaMsgpackBinaryStringEscape'},
+ '\\"'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackBinaryString'},
+ 'tt\\.'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackStringQuotes'},
+ '"'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackComma'}, ','},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap'}, ' '},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackKeyword'},
+ 'TRUE'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackColon'}, ':'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap'}, ' '},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMap', 'ShaDaMsgpackKeyword'},
+ 'FALSE'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackMapBraces'}, '}'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackComma'}, ','},
+ {{'ShaDaMsgpackArray'}, ' '},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackArrayBraces'},
+ '['},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackKeyword'},
+ 'NIL'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackComma'}, ','},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray'}, ' '},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackExt'}, '+('},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackExt',
+ 'ShaDaMsgpackExtType'}, '-10'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackExt'}, ')'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackBinaryString',
+ 'ShaDaMsgpackStringQuotes'}, '"'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArray', 'ShaDaMsgpackStringQuotes'},
+ '"'},
+ {{'ShaDaMsgpackArray', 'ShaDaMsgpackArrayBraces'}, ']'},
+ {{'ShaDaMsgpackArrayBraces'}, ']'},
+ },
+ {
+ hname('Buffer list'), h(' with timestamp '),
+ synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'),
+ synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'),
+ synepoch.minute, synhtssep(':'), synepoch.second, h(':'),
+ },
+ {
+ mlh(' % Key Description Value'),
+ },
+ {
+ },
+ {
+ mlh(' % Key Description Value'),
+ },
+ {
+ hname('Header'), h(' with timestamp '),
+ synepoch.year, synhtssep('-'), synepoch.month, synhtssep('-'),
+ synepoch.day, synhtssep('T'), synepoch.hour, synhtssep(':'),
+ synepoch.minute, synhtssep(':'), synepoch.second, h(':'),
+ },
+ {
+ mlh(' % Key Description________ Value'),
+ },
+ {
+ {{'ShaDaEntryMapLongEntryStart'}, ' + '},
+ {{'ShaDaEntryMapLongKey'}, 'se '},
+ {{'ShaDaEntryMapLongDescription'}, 'place cursor at end '},
+ {{'ShaDaMsgpackKeyword'}, 'TRUE'},
+ },
+ }
+ eq(exp, act)
+ end)
+end)
diff --git a/test/functional/provider/define_spec.lua b/test/functional/provider/define_spec.lua
index 9b97ed84d9..6e8a3b89cd 100644
--- a/test/functional/provider/define_spec.lua
+++ b/test/functional/provider/define_spec.lua
@@ -1,7 +1,7 @@
local helpers = require('test.functional.helpers')
local eval, command, nvim = helpers.eval, helpers.command, helpers.nvim
local eq, run, stop = helpers.eq, helpers.run, helpers.stop
-local clear, feed = helpers.clear, helpers.feed
+local clear = helpers.clear
local function get_prefix(sync)
@@ -12,8 +12,8 @@ local function get_prefix(sync)
end
-local function call(fn, args)
- command('call '..fn..'('..args..')')
+local function call(fn, arguments)
+ command('call '..fn..'('..arguments..')')
end
@@ -87,9 +87,9 @@ local function command_specs_for(fn, sync, first_arg_factory, init)
command('RpcCommand arg1 arg2 arg3')
end
- local function handler(method, args)
+ local function handler(method, arguments)
eq('test-handler', method)
- eq({'arg1', 'arg2', 'arg3'}, args[1])
+ eq({'arg1', 'arg2', 'arg3'}, arguments[1])
return ''
end
@@ -104,9 +104,9 @@ local function command_specs_for(fn, sync, first_arg_factory, init)
command('1,1RpcCommand')
end
- local function handler(method, args)
+ local function handler(method, arguments)
eq('test-handler', method)
- eq({1, 1}, args[1])
+ eq({1, 1}, arguments[1])
return ''
end
@@ -121,10 +121,10 @@ local function command_specs_for(fn, sync, first_arg_factory, init)
command('1,1RpcCommand arg')
end
- local function handler(method, args)
+ local function handler(method, arguments)
eq('test-handler', method)
- eq({'arg'}, args[1])
- eq({1, 1}, args[2])
+ eq({'arg'}, arguments[1])
+ eq({1, 1}, arguments[2])
return ''
end
@@ -139,10 +139,10 @@ local function command_specs_for(fn, sync, first_arg_factory, init)
command('5RpcCommand arg')
end
- local function handler(method, args)
+ local function handler(method, arguments)
eq('test-handler', method)
- eq({'arg'}, args[1])
- eq(5, args[2])
+ eq({'arg'}, arguments[1])
+ eq(5, arguments[2])
return ''
end
@@ -157,11 +157,11 @@ local function command_specs_for(fn, sync, first_arg_factory, init)
command('5RpcCommand! arg')
end
- local function handler(method, args)
+ local function handler(method, arguments)
eq('test-handler', method)
- eq({'arg'}, args[1])
- eq(5, args[2])
- eq(1, args[3])
+ eq({'arg'}, arguments[1])
+ eq(5, arguments[2])
+ eq(1, arguments[3])
return ''
end
@@ -177,12 +177,12 @@ local function command_specs_for(fn, sync, first_arg_factory, init)
command('5RpcCommand! b arg')
end
- local function handler(method, args)
+ local function handler(method, arguments)
eq('test-handler', method)
- eq({'arg'}, args[1])
- eq(5, args[2])
- eq(1, args[3])
- eq('b', args[4])
+ eq({'arg'}, arguments[1])
+ eq(5, arguments[2])
+ eq(1, arguments[3])
+ eq('b', arguments[4])
return ''
end
@@ -199,13 +199,13 @@ local function command_specs_for(fn, sync, first_arg_factory, init)
command('5RpcCommand! b arg')
end
- local function handler(method, args)
+ local function handler(method, arguments)
eq('test-handler', method)
- eq({'arg'}, args[1])
- eq(5, args[2])
- eq(1, args[3])
- eq('b', args[4])
- eq('regb', args[5])
+ eq({'arg'}, arguments[1])
+ eq(5, arguments[2])
+ eq(1, arguments[3])
+ eq('b', arguments[4])
+ eq('regb', arguments[5])
return ''
end
@@ -243,7 +243,7 @@ local function autocmd_specs_for(fn, sync, first_arg_factory, init)
command('doautocmd BufEnter x.c')
end
- local function handler(method, args)
+ local function handler(method)
eq('test-handler', method)
return ''
end
@@ -259,9 +259,9 @@ local function autocmd_specs_for(fn, sync, first_arg_factory, init)
command('doautocmd BufEnter x.c')
end
- local function handler(method, args)
+ local function handler(method, arguments)
eq('test-handler', method)
- eq('x.c', args[1])
+ eq('x.c', arguments[1])
return ''
end
@@ -303,9 +303,9 @@ local function function_specs_for(fn, sync, first_arg_factory, init)
end
end
- local function handler(method, args)
+ local function handler(method, arguments)
eq('test-handler', method)
- eq({{1, 'a', {'b', 'c'}}}, args)
+ eq({{1, 'a', {'b', 'c'}}}, arguments)
return 'rv'
end
@@ -324,9 +324,9 @@ local function function_specs_for(fn, sync, first_arg_factory, init)
end
end
- local function handler(method, args)
+ local function handler(method, arguments)
eq('test-handler', method)
- eq({{1, 'a', {'b', 'c'}}, 4}, args)
+ eq({{1, 'a', {'b', 'c'}}, 4}, arguments)
return 'rv'
end
diff --git a/test/functional/server/server_spec.lua b/test/functional/server/server_spec.lua
index 1cb3c879b9..d9ce96057e 100644
--- a/test/functional/server/server_spec.lua
+++ b/test/functional/server/server_spec.lua
@@ -1,7 +1,6 @@
local helpers = require('test.functional.helpers')
-local nvim, eq, neq, ok, eval
- = helpers.nvim, helpers.eq, helpers.neq, helpers.ok, helpers.eval
+local nvim, eq, neq, eval = helpers.nvim, helpers.eq, helpers.neq, helpers.eval
local clear = helpers.clear
describe('serverstart(), serverstop()', function()
diff --git a/test/functional/shada/buffers_spec.lua b/test/functional/shada/buffers_spec.lua
index 3666b718f0..fd4809e01a 100644
--- a/test/functional/shada/buffers_spec.lua
+++ b/test/functional/shada/buffers_spec.lua
@@ -1,7 +1,7 @@
-- ShaDa buffer list saving/reading support
local helpers = require('test.functional.helpers')
-local nvim_command, funcs, eq =
- helpers.command, helpers.funcs, helpers.eq
+local nvim_command, funcs, eq, curbufmeths =
+ helpers.command, helpers.funcs, helpers.eq, helpers.curbufmeths
local shada_helpers = require('test.functional.shada.helpers')
local reset, set_additional_cmd, clear =
@@ -9,8 +9,8 @@ local reset, set_additional_cmd, clear =
shada_helpers.clear
describe('ShaDa support code', function()
- testfilename = 'Xtestfile-functional-shada-buffers'
- testfilename_2 = 'Xtestfile-functional-shada-buffers-2'
+ local testfilename = 'Xtestfile-functional-shada-buffers'
+ local testfilename_2 = 'Xtestfile-functional-shada-buffers-2'
before_each(reset)
after_each(clear)
@@ -48,4 +48,43 @@ describe('ShaDa support code', function()
eq(1, funcs.bufnr('$'))
eq('', funcs.bufname(1))
end)
+
+ it('does not dump unlisted buffer', function()
+ set_additional_cmd('set shada+=%')
+ reset()
+ nvim_command('edit ' .. testfilename)
+ nvim_command('edit ' .. testfilename_2)
+ curbufmeths.set_option('buflisted', false)
+ nvim_command('qall')
+ reset()
+ eq(2, funcs.bufnr('$'))
+ eq('', funcs.bufname(1))
+ eq(testfilename, funcs.bufname(2))
+ end)
+
+ it('does not dump quickfix buffer', function()
+ set_additional_cmd('set shada+=%')
+ reset()
+ nvim_command('edit ' .. testfilename)
+ nvim_command('edit ' .. testfilename_2)
+ curbufmeths.set_option('buftype', 'quickfix')
+ nvim_command('qall')
+ reset()
+ eq(2, funcs.bufnr('$'))
+ eq('', funcs.bufname(1))
+ eq(testfilename, funcs.bufname(2))
+ end)
+
+ it('does not dump unnamed buffers', function()
+ set_additional_cmd('set shada+=% hidden')
+ reset()
+ curbufmeths.set_line(0, 'foo')
+ nvim_command('enew')
+ curbufmeths.set_line(0, 'bar')
+ eq(2, funcs.bufnr('$'))
+ nvim_command('qall!')
+ reset()
+ eq(1, funcs.bufnr('$'))
+ eq('', funcs.bufname(1))
+ end)
end)
diff --git a/test/functional/shada/compatibility_spec.lua b/test/functional/shada/compatibility_spec.lua
index 342dee377b..2ca0b16e75 100644
--- a/test/functional/shada/compatibility_spec.lua
+++ b/test/functional/shada/compatibility_spec.lua
@@ -4,9 +4,8 @@ local nvim_command, funcs, eq = helpers.command, helpers.funcs, helpers.eq
local exc_exec = helpers.exc_exec
local shada_helpers = require('test.functional.shada.helpers')
-local reset, set_additional_cmd, clear, get_shada_rw =
- shada_helpers.reset, shada_helpers.set_additional_cmd,
- shada_helpers.clear, shada_helpers.get_shada_rw
+local reset, clear, get_shada_rw = shada_helpers.reset, shada_helpers.clear,
+ shada_helpers.get_shada_rw
local read_shada_file = shada_helpers.read_shada_file
local wshada, sdrcmd, shada_fname = get_shada_rw('Xtest-functional-shada-compatibility.shada')
@@ -181,7 +180,7 @@ describe('ShaDa forward compatibility support code', function()
end
eq(3, found)
nvim_command('wshada! ' .. shada_fname)
- local found = 0
+ found = 0
for i, subv in ipairs(read_shada_file(shada_fname)) do
if i == 1 then
eq(1, subv.type)
@@ -249,7 +248,7 @@ describe('ShaDa forward compatibility support code', function()
end
eq(1, found)
nvim_command('wshada! ' .. shada_fname)
- local found = 0
+ found = 0
for i, v in ipairs(read_shada_file(shada_fname)) do
if i == 1 then
eq(1, v.type)
@@ -289,7 +288,7 @@ describe('ShaDa forward compatibility support code', function()
end
eq(1, found)
nvim_command('wshada! ' .. shada_fname)
- local found = 0
+ found = 0
for i, v in ipairs(read_shada_file(shada_fname)) do
if i == 1 then
eq(1, v.type)
@@ -395,7 +394,7 @@ describe('ShaDa forward compatibility support code', function()
end
eq(1, found)
nvim_command('wshada! ' .. shada_fname)
- local found = 0
+ found = 0
for i, v in ipairs(read_shada_file(shada_fname)) do
if i == 1 then
eq(1, v.type)
@@ -432,7 +431,7 @@ describe('ShaDa forward compatibility support code', function()
end
eq(1, found)
nvim_command('wshada! ' .. shada_fname)
- local found = 0
+ found = 0
for i, v in ipairs(read_shada_file(shada_fname)) do
if i == 1 then
eq(1, v.type)
diff --git a/test/functional/shada/errors_spec.lua b/test/functional/shada/errors_spec.lua
index 16ae77af02..62b9e6c84d 100644
--- a/test/functional/shada/errors_spec.lua
+++ b/test/functional/shada/errors_spec.lua
@@ -124,6 +124,11 @@ describe('ShaDa error handling', function()
eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sc key value which is not a boolean', exc_exec(sdrcmd()))
end)
+ it('fails on search pattern item with NIL search_backward key value', function()
+ wshada('\002\000\009\130\162sX\192\162sb\192')
+ eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sb key value which is not a boolean', exc_exec(sdrcmd()))
+ end)
+
it('fails on search pattern item with NIL has_line_offset key value', function()
wshada('\002\000\009\130\162sX\192\162sl\192')
eq('Vim(rshada):E575: Error while reading ShaDa file: search pattern entry at position 0 has sl key value which is not a boolean', exc_exec(sdrcmd()))
diff --git a/test/functional/shada/helpers.lua b/test/functional/shada/helpers.lua
index c2ff4cadd1..146ae8d51e 100644
--- a/test/functional/shada/helpers.lua
+++ b/test/functional/shada/helpers.lua
@@ -9,15 +9,14 @@ local tmpname = os.tmpname()
local additional_cmd = ''
local function nvim_argv()
- local ret
- local nvim_argv = {nvim_prog, '-u', 'NONE', '-i', tmpname, '-N',
- '--cmd', 'set shortmess+=I background=light noswapfile',
- '--cmd', additional_cmd,
- '--embed'}
+ local argv = {nvim_prog, '-u', 'NONE', '-i', tmpname, '-N',
+ '--cmd', 'set shortmess+=I background=light noswapfile',
+ '--cmd', additional_cmd,
+ '--embed'}
if helpers.prepend_argv then
- return merge_args(helpers.prepend_argv, nvim_argv)
+ return merge_args(helpers.prepend_argv, argv)
else
- return nvim_argv
+ return argv
end
end
@@ -88,7 +87,6 @@ return {
reset=reset,
set_additional_cmd=set_additional_cmd,
clear=clear,
- exc_exec=exc_exec,
get_shada_rw=get_shada_rw,
read_shada_file=read_shada_file,
}
diff --git a/test/functional/shada/history_spec.lua b/test/functional/shada/history_spec.lua
index 1123f829d2..94513945d0 100644
--- a/test/functional/shada/history_spec.lua
+++ b/test/functional/shada/history_spec.lua
@@ -107,14 +107,32 @@ describe('ShaDa support code', function()
end)
it('dumps and loads last search pattern with offset', function()
- funcs.setline('.', {'foo', 'bar'})
+ meths.set_option('wrapscan', false)
+ funcs.setline('.', {'foo', 'bar--'})
nvim_feed('gg0/a/e+1\n')
eq({0, 2, 3, 0}, funcs.getpos('.'))
nvim_command('wshada')
reset()
- funcs.setline('.', {'foo', 'bar'})
+ meths.set_option('wrapscan', false)
+ funcs.setline('.', {'foo', 'bar--'})
nvim_feed('gg0n')
eq({0, 2, 3, 0}, funcs.getpos('.'))
+ eq(1, meths.get_vvar('searchforward'))
+ end)
+
+ it('dumps and loads last search pattern with offset and backward direction',
+ function()
+ meths.set_option('wrapscan', false)
+ funcs.setline('.', {'foo', 'bar--'})
+ nvim_feed('G$?a?e+1\n')
+ eq({0, 2, 3, 0}, funcs.getpos('.'))
+ nvim_command('wshada')
+ reset()
+ meths.set_option('wrapscan', false)
+ funcs.setline('.', {'foo', 'bar--'})
+ nvim_feed('G$n')
+ eq({0, 2, 3, 0}, funcs.getpos('.'))
+ eq(0, meths.get_vvar('searchforward'))
end)
it('saves v:hlsearch=1', function()
diff --git a/test/functional/shada/marks_spec.lua b/test/functional/shada/marks_spec.lua
index 6818844ebd..955a6f382b 100644
--- a/test/functional/shada/marks_spec.lua
+++ b/test/functional/shada/marks_spec.lua
@@ -15,15 +15,15 @@ local nvim_current_line = function()
end
describe('ShaDa support code', function()
- testfilename = 'Xtestfile-functional-shada-marks'
- testfilename_2 = 'Xtestfile-functional-shada-marks-2'
+ local testfilename = 'Xtestfile-functional-shada-marks'
+ local testfilename_2 = 'Xtestfile-functional-shada-marks-2'
before_each(function()
reset()
local fd = io.open(testfilename, 'w')
fd:write('test\n')
fd:write('test2\n')
fd:close()
- local fd = io.open(testfilename_2, 'w')
+ fd = io.open(testfilename_2, 'w')
fd:write('test3\n')
fd:write('test4\n')
fd:close()
@@ -115,7 +115,7 @@ describe('ShaDa support code', function()
eq(tf_full, oldfiles[1])
eq(tf_full_2, oldfiles[2])
nvim_command('rshada!')
- local oldfiles = meths.get_vvar('oldfiles')
+ oldfiles = meths.get_vvar('oldfiles')
table.sort(oldfiles)
eq(2, #oldfiles)
eq(testfilename, oldfiles[1]:sub(-#testfilename))
diff --git a/test/functional/shada/merging_spec.lua b/test/functional/shada/merging_spec.lua
index 7066ca9f54..221f989409 100644
--- a/test/functional/shada/merging_spec.lua
+++ b/test/functional/shada/merging_spec.lua
@@ -1,7 +1,7 @@
-- ShaDa merging data support
local helpers = require('test.functional.helpers')
-local nvim_command, meths, funcs, curbufmeths, eq =
- helpers.command, helpers.meths, helpers.funcs,
+local nvim_command, funcs, curbufmeths, eq =
+ helpers.command, helpers.funcs,
helpers.curbufmeths, helpers.eq
local exc_exec, redir_exec = helpers.exc_exec, helpers.redir_exec
@@ -870,7 +870,7 @@ describe('ShaDa jumps support code', function()
end
wshada(shada)
eq(0, exc_exec(sdrcmd()))
- local shada = ''
+ shada = ''
for i = 1,101 do
local t = i * 2
shada = shada .. (
@@ -964,7 +964,7 @@ describe('ShaDa changes support code', function()
end
wshada(shada)
eq(0, exc_exec(sdrcmd()))
- local shada = ''
+ shada = ''
for i = 1,101 do
local t = i * 2
shada = shada .. (
@@ -1001,7 +1001,7 @@ describe('ShaDa changes support code', function()
end
wshada(shada)
eq(0, exc_exec(sdrcmd()))
- local shada = ''
+ shada = ''
for i = 1,100 do
shada = shada .. ('\011%c\018\131\162mX\195\161f\196\006/a/b/c\161l%c'
):format(i, i)
diff --git a/test/functional/shell/viml_system_spec.lua b/test/functional/shell/viml_system_spec.lua
index 4985c24aec..00b16e9158 100644
--- a/test/functional/shell/viml_system_spec.lua
+++ b/test/functional/shell/viml_system_spec.lua
@@ -133,7 +133,7 @@ describe('system()', function()
-- write more than 1mb of data, which should be enough to overcome
-- the os buffer limit and force multiple event loop iterations to write
-- everything
- for i = 1, 0xffff do
+ for _ = 1, 0xffff do
input[#input + 1] = '01234567890ABCDEFabcdef'
end
input = table.concat(input, '\n')
@@ -299,7 +299,7 @@ describe('systemlist()', function()
describe('passing a lot of input', function()
it('returns the program output', function()
local input = {}
- for i = 1, 0xffff do
+ for _ = 1, 0xffff do
input[#input + 1] = '01234567890ABCDEFabcdef'
end
nvim('set_var', 'input', input)
diff --git a/test/functional/terminal/altscreen_spec.lua b/test/functional/terminal/altscreen_spec.lua
index 9ec0fc7c5a..d9d96b25f9 100644
--- a/test/functional/terminal/altscreen_spec.lua
+++ b/test/functional/terminal/altscreen_spec.lua
@@ -1,6 +1,5 @@
local helpers = require('test.functional.helpers')
local thelpers = require('test.functional.terminal.helpers')
-local Screen = require('test.functional.ui.screen')
local clear, eq, curbuf = helpers.clear, helpers.eq, helpers.curbuf
local feed = helpers.feed
local feed_data = thelpers.feed_data
diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua
index ffdfec4428..55ef254a63 100644
--- a/test/functional/terminal/buffer_spec.lua
+++ b/test/functional/terminal/buffer_spec.lua
@@ -1,5 +1,4 @@
local helpers = require('test.functional.helpers')
-local Screen = require('test.functional.ui.screen')
local thelpers = require('test.functional.terminal.helpers')
local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim
local wait = helpers.wait
diff --git a/test/functional/terminal/cursor_spec.lua b/test/functional/terminal/cursor_spec.lua
index 7f07467fde..e9cb010003 100644
--- a/test/functional/terminal/cursor_spec.lua
+++ b/test/functional/terminal/cursor_spec.lua
@@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')
local Screen = require('test.functional.ui.screen')
local thelpers = require('test.functional.terminal.helpers')
local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim
-local nvim_dir, execute, eq = helpers.nvim_dir, helpers.execute, helpers.eq
+local nvim_dir, execute = helpers.nvim_dir, helpers.execute
local hide_cursor = thelpers.hide_cursor
local show_cursor = thelpers.show_cursor
diff --git a/test/functional/terminal/ex_terminal_spec.lua b/test/functional/terminal/ex_terminal_spec.lua
index 611ba55793..493539b4d3 100644
--- a/test/functional/terminal/ex_terminal_spec.lua
+++ b/test/functional/terminal/ex_terminal_spec.lua
@@ -2,8 +2,7 @@ local helpers = require('test.functional.helpers')
local Screen = require('test.functional.ui.screen')
local clear, wait, nvim = helpers.clear, helpers.wait, helpers.nvim
local nvim_dir = helpers.nvim_dir
-local execute, source = helpers.execute, helpers.source
-local eq, neq = helpers.eq, helpers.neq
+local execute = helpers.execute
describe(':terminal', function()
local screen
diff --git a/test/functional/terminal/helpers.lua b/test/functional/terminal/helpers.lua
index ae13aab277..a32ae650d6 100644
--- a/test/functional/terminal/helpers.lua
+++ b/test/functional/terminal/helpers.lua
@@ -72,7 +72,7 @@ local function screen_setup(extra_height, command)
empty_line,
empty_line,
}
- for i = 1, extra_height do
+ for _ = 1, extra_height do
table.insert(expected, empty_line)
end
diff --git a/test/functional/terminal/highlight_spec.lua b/test/functional/terminal/highlight_spec.lua
index 1a96cb4dba..045f5aa42f 100644
--- a/test/functional/terminal/highlight_spec.lua
+++ b/test/functional/terminal/highlight_spec.lua
@@ -40,7 +40,7 @@ describe('terminal window highlighting', function()
]])
end)
- function descr(title, attr_num, set_attrs_fn)
+ local function descr(title, attr_num, set_attrs_fn)
local function sub(s)
return s:gsub('NUM', attr_num)
end
diff --git a/test/functional/terminal/mouse_spec.lua b/test/functional/terminal/mouse_spec.lua
index ac61abebcb..c4bd3c2663 100644
--- a/test/functional/terminal/mouse_spec.lua
+++ b/test/functional/terminal/mouse_spec.lua
@@ -1,8 +1,7 @@
-local Screen = require('test.functional.ui.screen')
local helpers = require('test.functional.helpers')
local thelpers = require('test.functional.terminal.helpers')
-local clear, eq, curbuf = helpers.clear, helpers.eq, helpers.curbuf
-local feed, execute, nvim = helpers.feed, helpers.execute, helpers.nvim
+local clear = helpers.clear
+local feed, nvim = helpers.feed, helpers.nvim
local feed_data = thelpers.feed_data
describe('terminal mouse', function()
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index ba0c531c7e..14700a2622 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -1,10 +1,10 @@
-- Some sanity checks for the TUI using the builtin terminal emulator
-- as a simple way to send keys and assert screen state.
-local Screen = require('test.functional.ui.screen')
local helpers = require('test.functional.helpers')
local thelpers = require('test.functional.terminal.helpers')
local feed = thelpers.feed_data
local execute = helpers.execute
+local nvim_dir = helpers.nvim_dir
describe('tui', function()
local screen
@@ -173,3 +173,114 @@ describe('tui with non-tty file descriptors', function()
]])
end)
end)
+
+describe('tui focus event handling', function()
+ local screen
+
+ before_each(function()
+ helpers.clear()
+ screen = thelpers.screen_setup(0, '["'..helpers.nvim_prog..'", "-u", "NONE", "-i", "NONE", "--cmd", "set noswapfile"]')
+ execute('autocmd FocusGained * echo "gained"')
+ execute('autocmd FocusLost * echo "lost"')
+ end)
+
+ it('can handle focus events in normal mode', function()
+ feed('\x1b[I')
+ screen:expect([[
+ {1: } |
+ ~ |
+ ~ |
+ ~ |
+ [No Name] |
+ gained |
+ -- TERMINAL -- |
+ ]])
+
+ feed('\x1b[O')
+ screen:expect([[
+ {1: } |
+ ~ |
+ ~ |
+ ~ |
+ [No Name] |
+ lost |
+ -- TERMINAL -- |
+ ]])
+ end)
+
+ it('can handle focus events in insert mode', function()
+ execute('set noshowmode')
+ feed('i')
+ feed('\x1b[I')
+ screen:expect([[
+ {1: } |
+ ~ |
+ ~ |
+ ~ |
+ [No Name] |
+ gained |
+ -- TERMINAL -- |
+ ]])
+ feed('\x1b[O')
+ screen:expect([[
+ {1: } |
+ ~ |
+ ~ |
+ ~ |
+ [No Name] |
+ lost |
+ -- TERMINAL -- |
+ ]])
+ end)
+
+ it('can handle focus events in cmdline mode', function()
+ feed(':')
+ feed('\x1b[I')
+ screen:expect([[
+ |
+ ~ |
+ ~ |
+ ~ |
+ [No Name] |
+ g{1:a}ined |
+ -- TERMINAL -- |
+ ]])
+ feed('\x1b[O')
+ screen:expect([[
+ |
+ ~ |
+ ~ |
+ ~ |
+ [No Name] |
+ l{1:o}st |
+ -- TERMINAL -- |
+ ]])
+ end)
+
+ it('can handle focus events in terminal mode', function()
+ execute('set shell='..nvim_dir..'/shell-test')
+ execute('set laststatus=0')
+ execute('set noshowmode')
+ execute('terminal')
+ feed('\x1b[I')
+ screen:expect([[
+ ready $ |
+ [Process exited 0]{1: } |
+ |
+ |
+ |
+ gained |
+ -- TERMINAL -- |
+ ]])
+ feed('\x1b[O')
+ screen:expect([[
+ ready $ |
+ [Process exited 0]{1: } |
+ |
+ |
+ |
+ lost |
+ -- TERMINAL -- |
+ ]])
+ end)
+end)
diff --git a/test/functional/terminal/window_spec.lua b/test/functional/terminal/window_spec.lua
index c2b9390a11..6c236ed868 100644
--- a/test/functional/terminal/window_spec.lua
+++ b/test/functional/terminal/window_spec.lua
@@ -1,7 +1,7 @@
local helpers = require('test.functional.helpers')
local thelpers = require('test.functional.terminal.helpers')
-local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim
-local wait, eq = helpers.wait, helpers.eq
+local feed, clear = helpers.feed, helpers.clear
+local wait = helpers.wait
describe('terminal window', function()
diff --git a/test/functional/terminal/window_split_tab_spec.lua b/test/functional/terminal/window_split_tab_spec.lua
index c102b1f133..727eba2717 100644
--- a/test/functional/terminal/window_split_tab_spec.lua
+++ b/test/functional/terminal/window_split_tab_spec.lua
@@ -1,8 +1,7 @@
local helpers = require('test.functional.helpers')
local thelpers = require('test.functional.terminal.helpers')
-local clear, eq, curbuf = helpers.clear, helpers.eq, helpers.curbuf
+local clear = helpers.clear
local feed, nvim = helpers.feed, helpers.nvim
-local feed_data = thelpers.feed_data
describe('terminal', function()
local screen
diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua
index 33a53ef201..f9b112e464 100644
--- a/test/functional/ui/highlight_spec.lua
+++ b/test/functional/ui/highlight_spec.lua
@@ -1,6 +1,6 @@
local helpers = require('test.functional.helpers')
local Screen = require('test.functional.ui.screen')
-local clear, feed, nvim = helpers.clear, helpers.feed, helpers.nvim
+local clear, feed = helpers.clear, helpers.feed
local execute, request, eq = helpers.execute, helpers.request, helpers.eq
diff --git a/test/functional/ui/input_spec.lua b/test/functional/ui/input_spec.lua
index a7c8e02def..4818830940 100644
--- a/test/functional/ui/input_spec.lua
+++ b/test/functional/ui/input_spec.lua
@@ -8,7 +8,6 @@ describe('mappings', function()
local cid
local add_mapping = function(mapping, send)
- local str = 'mapped '..mapping
local cmd = "nnoremap "..mapping.." :call rpcnotify("..cid..", 'mapped', '"
..send:gsub('<', '<lt>').."')<cr>"
execute(cmd)
diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua
index c767f9b83a..e1c2d14759 100644
--- a/test/functional/ui/screen.lua
+++ b/test/functional/ui/screen.lua
@@ -106,8 +106,8 @@
-- use `screen:snapshot_util({},true)`
local helpers = require('test.functional.helpers')
-local request, run, stop = helpers.request, helpers.run, helpers.stop
-local eq, dedent = helpers.eq, helpers.dedent
+local request, run = helpers.request, helpers.run
+local dedent = helpers.dedent
local Screen = {}
Screen.__index = Screen
@@ -241,7 +241,7 @@ function Screen:wait(check, timeout)
checked = true
if not err then
success_seen = true
- stop()
+ helpers.stop()
elseif success_seen and #args > 0 then
failure_after_success = true
--print(require('inspect')(args))
@@ -294,9 +294,9 @@ end
function Screen:_handle_resize(width, height)
local rows = {}
- for i = 1, height do
+ for _ = 1, height do
local cols = {}
- for j = 1, width do
+ for _ = 1, width do
table.insert(cols, {text = ' ', attrs = {}})
end
table.insert(rows, cols)
@@ -448,7 +448,7 @@ function Screen:_row_repr(row, attr_ids, attr_ignore)
local rv = {}
local current_attr_id
for i = 1, self._width do
- local attr_id = get_attr_id(attr_ids, attr_ignore, row[i].attrs)
+ local attr_id = self:_get_attr_id(attr_ids, attr_ignore, row[i].attrs)
if current_attr_id and attr_id ~= current_attr_id then
-- close current attribute bracket, add it before any whitespace
-- up to the current cell
@@ -524,8 +524,8 @@ function Screen:print_snapshot(attrs, ignore)
local row = self._rows[i]
for j = 1, self._width do
local attr = row[j].attrs
- if attr_index(attrs, attr) == nil and attr_index(ignore, attr) == nil then
- if not equal_attrs(attr, {}) then
+ if self:_attr_index(attrs, attr) == nil and self:_attr_index(ignore, attr) == nil then
+ if not self:_equal_attrs(attr, {}) then
table.insert(attrs, attr)
end
end
@@ -544,7 +544,7 @@ function Screen:print_snapshot(attrs, ignore)
if self._default_attr_ids == nil or self._default_attr_ids[i] ~= a then
alldefault = false
end
- local dict = "{"..pprint_attrs(a).."}"
+ local dict = "{"..self:_pprint_attrs(a).."}"
table.insert(attrstrs, "["..tostring(i).."] = "..dict)
end
local attrstr = "{"..table.concat(attrstrs, ", ").."}"
@@ -558,7 +558,7 @@ function Screen:print_snapshot(attrs, ignore)
io.stdout:flush()
end
-function pprint_attrs(attrs)
+function Screen:_pprint_attrs(attrs)
local items = {}
for f, v in pairs(attrs) do
local desc = tostring(v)
@@ -572,7 +572,7 @@ function pprint_attrs(attrs)
return table.concat(items, ", ")
end
-function backward_find_meaningful(tbl, from)
+function backward_find_meaningful(tbl, from) -- luacheck: ignore
for i = from or #tbl, 1, -1 do
if tbl[i] ~= ' ' then
return i + 1
@@ -581,24 +581,24 @@ function backward_find_meaningful(tbl, from)
return from
end
-function get_attr_id(attr_ids, ignore, attrs)
+function Screen:_get_attr_id(attr_ids, ignore, attrs)
if not attr_ids then
return
end
for id, a in pairs(attr_ids) do
- if equal_attrs(a, attrs) then
+ if self:_equal_attrs(a, attrs) then
return id
end
end
- if equal_attrs(attrs, {}) or
- ignore == true or attr_index(ignore, attrs) ~= nil then
+ if self:_equal_attrs(attrs, {}) or
+ ignore == true or self:_attr_index(ignore, attrs) ~= nil then
-- ignore this attrs
return nil
end
- return "UNEXPECTED "..pprint_attrs(attrs)
+ return "UNEXPECTED "..self:_pprint_attrs(attrs)
end
-function equal_attrs(a, b)
+function Screen:_equal_attrs(a, b)
return a.bold == b.bold and a.standout == b.standout and
a.underline == b.underline and a.undercurl == b.undercurl and
a.italic == b.italic and a.reverse == b.reverse and
@@ -606,12 +606,12 @@ function equal_attrs(a, b)
a.background == b.background
end
-function attr_index(attrs, attr)
+function Screen:_attr_index(attrs, attr)
if not attrs then
return nil
end
for i,a in pairs(attrs) do
- if equal_attrs(a, attr) then
+ if self:_equal_attrs(a, attr) then
return i
end
end
diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua
index 092cc8c126..a4545eeff0 100644
--- a/test/functional/ui/screen_basic_spec.lua
+++ b/test/functional/ui/screen_basic_spec.lua
@@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers')
local Screen = require('test.functional.ui.screen')
local spawn, set_session, clear = helpers.spawn, helpers.set_session, helpers.clear
local feed, execute = helpers.feed, helpers.execute
-local insert, wait = helpers.insert, helpers.wait
+local insert = helpers.insert
describe('Initial screen', function()
local screen
@@ -11,9 +11,6 @@ describe('Initial screen', function()
'--embed'}
before_each(function()
- if session then
- session:exit(0)
- end
local screen_nvim = spawn(nvim_argv)
set_session(screen_nvim)
screen = Screen.new()
diff --git a/test/functional/ui/searchhl_spec.lua b/test/functional/ui/searchhl_spec.lua
index d04329e1e2..e4217abcfe 100644
--- a/test/functional/ui/searchhl_spec.lua
+++ b/test/functional/ui/searchhl_spec.lua
@@ -1,7 +1,7 @@
local helpers = require('test.functional.helpers')
local Screen = require('test.functional.ui.screen')
-local clear, feed, nvim, insert = helpers.clear, helpers.feed, helpers.nvim, helpers.insert
-local execute, request, eq = helpers.execute, helpers.request, helpers.eq
+local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local execute = helpers.execute
describe('search highlighting', function()
local screen
diff --git a/test/functional/viml/completion_spec.lua b/test/functional/viml/completion_spec.lua
index 5e3d4a6658..12f542de7f 100644
--- a/test/functional/viml/completion_spec.lua
+++ b/test/functional/viml/completion_spec.lua
@@ -1,6 +1,6 @@
local helpers = require('test.functional.helpers')
-local clear, feed, execute = helpers.clear, helpers.feed, helpers.execute
+local clear, feed = helpers.clear, helpers.feed
local eval, eq, neq = helpers.eval, helpers.eq, helpers.neq
local execute, source = helpers.execute, helpers.source
diff --git a/test/includes/CMakeLists.txt b/test/includes/CMakeLists.txt
index a139683b42..3d85197f19 100644
--- a/test/includes/CMakeLists.txt
+++ b/test/includes/CMakeLists.txt
@@ -8,6 +8,7 @@ foreach(hfile ${PRE_HEADERS})
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${post_hfile}
COMMAND ${CMAKE_C_COMPILER} -std=c99 -E -P
${CMAKE_CURRENT_SOURCE_DIR}/${hfile}
+ -I${LIBUV_INCLUDE_DIRS}
-o ${CMAKE_CURRENT_BINARY_DIR}/${post_hfile})
list(APPEND POST_HEADERS ${post_hfile})
endforeach()
diff --git a/test/includes/pre/sys/errno.h b/test/includes/pre/sys/errno.h
deleted file mode 100644
index 0b8934d33e..0000000000
--- a/test/includes/pre/sys/errno.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#include <sys/errno.h>
-
-static const int kENOENT = ENOENT;
-static const int kEEXIST = EEXIST;
diff --git a/test/includes/pre/uv-errno.h b/test/includes/pre/uv-errno.h
new file mode 100644
index 0000000000..6b80f60e5c
--- /dev/null
+++ b/test/includes/pre/uv-errno.h
@@ -0,0 +1,4 @@
+#include <uv-errno.h>
+
+static const int kUV_ENOENT = UV_ENOENT;
+static const int kUV_EEXIST = UV_EEXIST;
diff --git a/test/unit/buffer_spec.lua b/test/unit/buffer_spec.lua
index e0e2b827e9..a2e7bd91af 100644
--- a/test/unit/buffer_spec.lua
+++ b/test/unit/buffer_spec.lua
@@ -1,11 +1,14 @@
+
+local assert = require("luassert")
local helpers = require("test.unit.helpers")
local to_cstr = helpers.to_cstr
local eq = helpers.eq
+local neq = helpers.neq
+local NULL = helpers.NULL
+local globals = helpers.cimport("./src/nvim/globals.h")
local buffer = helpers.cimport("./src/nvim/buffer.h")
-local window = helpers.cimport("./src/nvim/window.h")
-local option = helpers.cimport("./src/nvim/option.h")
describe('buffer functions', function()
@@ -206,4 +209,95 @@ describe('buffer functions', function()
close_buffer(NULL, buf2, buffer.DOBUF_WIPE, 0)
end)
end)
+
+ describe('build_stl_str_hl', function()
+
+ local output_buffer = to_cstr(string.rep(" ", 100))
+
+ local build_stl_str_hl = function(pat)
+ return buffer.build_stl_str_hl(globals.curwin,
+ output_buffer,
+ 100,
+ to_cstr(pat),
+ false,
+ 32,
+ 80,
+ NULL,
+ NULL)
+ end
+
+ it('should copy plain text', function()
+ local width = build_stl_str_hl("this is a test")
+
+ eq(14, width)
+ eq("this is a test", helpers.ffi.string(output_buffer, width))
+
+ end)
+
+ it('should print no file name', function()
+ local width = build_stl_str_hl("%f")
+
+ eq(9, width)
+ eq("[No Name]", helpers.ffi.string(output_buffer, width))
+
+ end)
+
+ it('should print the relative file name', function()
+ buffer.setfname(globals.curbuf, to_cstr("Makefile"), NULL, 1)
+ local width = build_stl_str_hl("%f")
+
+ eq(8, width)
+ eq("Makefile", helpers.ffi.string(output_buffer, width))
+
+ end)
+
+ it('should print the full file name', function()
+ buffer.setfname(globals.curbuf, to_cstr("Makefile"), NULL, 1)
+
+ local width = build_stl_str_hl("%F")
+
+ assert.is_true(8 < width)
+ neq(NULL, string.find(helpers.ffi.string(output_buffer, width), "Makefile"))
+
+ end)
+
+ it('should print the tail file name', function()
+ buffer.setfname(globals.curbuf, to_cstr("src/nvim/buffer.c"), NULL, 1)
+
+ local width = build_stl_str_hl("%t")
+
+ eq(8, width)
+ eq("buffer.c", helpers.ffi.string(output_buffer, width))
+
+ end)
+
+ it('should print the buffer number', function()
+ buffer.setfname(globals.curbuf, to_cstr("src/nvim/buffer.c"), NULL, 1)
+
+ local width = build_stl_str_hl("%n")
+
+ eq(1, width)
+ eq("1", helpers.ffi.string(output_buffer, width))
+ end)
+
+ it('should print the current line number in the buffer', function()
+ buffer.setfname(globals.curbuf, to_cstr("test/unit/buffer_spec.lua"), NULL, 1)
+
+ local width = build_stl_str_hl("%l")
+
+ eq(1, width)
+ eq("0", helpers.ffi.string(output_buffer, width))
+
+ end)
+
+ it('should print the number of lines in the buffer', function()
+ buffer.setfname(globals.curbuf, to_cstr("test/unit/buffer_spec.lua"), NULL, 1)
+
+ local width = build_stl_str_hl("%L")
+
+ eq(1, width)
+ eq("1", helpers.ffi.string(output_buffer, width))
+
+ end)
+ end)
end)
diff --git a/test/unit/fileio_spec.lua b/test/unit/fileio_spec.lua
index 180fc3c184..3e3c36617d 100644
--- a/test/unit/fileio_spec.lua
+++ b/test/unit/fileio_spec.lua
@@ -4,6 +4,7 @@ local helpers = require("test.unit.helpers")
local eq = helpers.eq
local ffi = helpers.ffi
local to_cstr = helpers.to_cstr
+local NULL = helpers.NULL
local fileio = helpers.cimport("./src/nvim/fileio.h")
diff --git a/test/unit/formatc.lua b/test/unit/formatc.lua
index f9397eaec6..3f86c5f1b1 100644
--- a/test/unit/formatc.lua
+++ b/test/unit/formatc.lua
@@ -124,13 +124,13 @@ end
local function set(t)
local s = {}
- for i, v in ipairs(t) do
+ for _, v in ipairs(t) do
s[v] = true
end
return s
end
-local C_keywords = set {
+local C_keywords = set { -- luacheck: ignore
"break", "case", "char", "const", "continue", "default", "do", "double",
"else", "enum", "extern", "float", "for", "goto", "if", "int", "long",
"register", "return", "short", "signed", "sizeof", "static", "struct",
@@ -154,13 +154,13 @@ local C_keywords = set {
-- The first one will have a lot of false positives (the line '{' for
-- example), the second one is more unique.
local function formatc(str)
- local tokens = TokeniseC(str)
+ local toks = TokeniseC(str)
local result = {}
local block_level = 0
local allow_one_nl = false
local end_at_brace = false
- for i, token in ipairs(tokens) do
+ for _, token in ipairs(toks) do
local typ = token[2]
if typ == '{' then
block_level = block_level + 1
@@ -213,8 +213,8 @@ local function formatc(str)
end
-- standalone operation (very handy for debugging)
-local function standalone(...)
- Preprocess = require("preprocess")
+local function standalone(...) -- luacheck: ignore
+ local Preprocess = require("preprocess")
Preprocess.add_to_include_path('./../../src')
Preprocess.add_to_include_path('./../../build/include')
Preprocess.add_to_include_path('./../../.deps/usr/include')
diff --git a/test/unit/garray_spec.lua b/test/unit/garray_spec.lua
index e779cab8a7..9694e3c427 100644
--- a/test/unit/garray_spec.lua
+++ b/test/unit/garray_spec.lua
@@ -5,8 +5,6 @@ local internalize = helpers.internalize
local eq = helpers.eq
local neq = helpers.neq
local ffi = helpers.ffi
-local lib = helpers.lib
-local cstr = helpers.cstr
local to_cstr = helpers.to_cstr
local NULL = helpers.NULL
@@ -48,7 +46,7 @@ local ga_size = function(garr)
return ga_len(garr) * ga_itemsize(garr)
end
-local ga_maxsize = function(garr)
+local ga_maxsize = function(garr) -- luacheck: ignore
return ga_maxlen(garr) * ga_itemsize(garr)
end
@@ -65,8 +63,8 @@ local ga_data_as_ints = function(garr)
end
-- garray manipulation
-local ga_init = function(garr, itemsize, growsize)
- return garray.ga_init(garr, itemsize, growsize)
+local ga_init = function(garr, itemsize_, growsize_)
+ return garray.ga_init(garr, itemsize_, growsize_)
end
local ga_clear = function(garr)
@@ -113,7 +111,7 @@ local ga_set_len = function(garr, len)
end
local ga_inc_len = function(garr, by)
- return ga_set_len(garr, ga_len(garr) + 1)
+ return ga_set_len(garr, ga_len(garr) + by)
end
-- custom append functions
@@ -197,10 +195,9 @@ describe('garray', function()
end)
describe('ga_grow', function()
- local new_and_grow
- function new_and_grow(itemsize, growsize, req)
+ local function new_and_grow(itemsize_, growsize_, req)
local garr = new_garray()
- ga_init(garr, itemsize, growsize)
+ ga_init(garr, itemsize_, growsize_)
eq(0, ga_size(garr)) -- should be 0 at first
eq(NULL, ga_data(garr)) -- should be NULL
ga_grow(garr, req) -- add space for `req` items
@@ -306,7 +303,7 @@ describe('garray', function()
ga_init(garr, ffi.sizeof("char"), 1)
local str = "ohwell●●"
local loop = 5
- for i = 1, loop do
+ for _ = 1, loop do
ga_concat(garr, str)
end
@@ -321,7 +318,7 @@ describe('garray', function()
end)
end)
- function test_concat_fn(input, fn, sep)
+ local function test_concat_fn(input, fn, sep)
local garr = new_string_garray()
ga_append_strings(garr, unpack(input))
if sep == nil then
diff --git a/test/unit/helpers.lua b/test/unit/helpers.lua
index 5bcc661226..7b43b2218c 100644
--- a/test/unit/helpers.lua
+++ b/test/unit/helpers.lua
@@ -18,17 +18,9 @@ local function trim(s)
end
-- a Set that keeps around the lines we've already seen
-if cdefs == nil then
- cdefs = Set:new()
-end
-
-if imported == nil then
- imported = Set:new()
-end
-
-if pragma_pack_id == nil then
- pragma_pack_id = 1
-end
+local cdefs = Set:new()
+local imported = Set:new()
+local pragma_pack_id = 1
-- some things are just too complex for the LuaJIT C parser to digest. We
-- usually don't need them anyway.
@@ -67,7 +59,7 @@ local function cimport(...)
end
local body = nil
- for i=1, 10 do
+ for _ = 1, 10 do
local stream = Preprocess.preprocess_stream(unpack(paths))
body = stream:read("*a")
stream:close()
diff --git a/test/unit/os/env_spec.lua b/test/unit/os/env_spec.lua
index 8e18c599d9..e0e12a24f2 100644
--- a/test/unit/os/env_spec.lua
+++ b/test/unit/os/env_spec.lua
@@ -1,11 +1,9 @@
local helpers = require('test.unit.helpers')
local cimport = helpers.cimport
-local internalize = helpers.internalize
local eq = helpers.eq
local neq = helpers.neq
local ffi = helpers.ffi
-local lib = helpers.lib
local cstr = helpers.cstr
local to_cstr = helpers.to_cstr
local NULL = helpers.NULL
@@ -15,15 +13,15 @@ require('lfs')
local env = cimport('./src/nvim/os/os.h')
describe('env function', function()
- function os_setenv(name, value, override)
+ local function os_setenv(name, value, override)
return env.os_setenv((to_cstr(name)), (to_cstr(value)), override)
end
- function os_unsetenv(name, value, override)
+ local function os_unsetenv(name, _, _)
return env.os_unsetenv((to_cstr(name)))
end
- function os_getenv(name)
+ local function os_getenv(name)
local rval = env.os_getenv((to_cstr(name)))
if rval ~= NULL then
return ffi.string(rval)
diff --git a/test/unit/os/fs_spec.lua b/test/unit/os/fs_spec.lua
index c7a1f55b5d..95c98f18a1 100644
--- a/test/unit/os/fs_spec.lua
+++ b/test/unit/os/fs_spec.lua
@@ -1,3 +1,6 @@
+local lfs = require('lfs')
+local bit = require('bit')
+
local helpers = require('test.unit.helpers')
local cimport = helpers.cimport
@@ -6,16 +9,12 @@ local internalize = helpers.internalize
local eq = helpers.eq
local neq = helpers.neq
local ffi = helpers.ffi
-local lib = helpers.lib
local cstr = helpers.cstr
local to_cstr = helpers.to_cstr
local OK = helpers.OK
local FAIL = helpers.FAIL
local NULL = helpers.NULL
-require('lfs')
-require('bit')
-
cimport('unistd.h')
cimport('./src/nvim/os/shell.h')
cimport('./src/nvim/option_defs.h')
@@ -24,10 +23,9 @@ cimport('./src/nvim/fileio.h')
local fs = cimport('./src/nvim/os/os.h')
cppimport('sys/stat.h')
cppimport('sys/fcntl.h')
-cppimport('sys/errno.h')
+cppimport('uv-errno.h')
-local len = 0
-local buf = ""
+local buffer = ""
local directory = nil
local absolute_executable = nil
local executable_name = nil
@@ -85,24 +83,26 @@ describe('fs function', function()
end)
describe('os_dirname', function()
+ local length
+
local function os_dirname(buf, len)
return fs.os_dirname(buf, len)
end
before_each(function()
- len = (string.len(lfs.currentdir())) + 1
- buf = cstr(len, '')
+ length = (string.len(lfs.currentdir())) + 1
+ buffer = cstr(length, '')
end)
it('returns OK and writes current directory into the buffer if it is large\n enough', function()
- eq(OK, (os_dirname(buf, len)))
- eq(lfs.currentdir(), (ffi.string(buf)))
+ eq(OK, (os_dirname(buffer, length)))
+ eq(lfs.currentdir(), (ffi.string(buffer)))
end)
-- What kind of other failing cases are possible?
it('returns FAIL if the buffer is too small', function()
- local buf = cstr((len - 1), '')
- eq(FAIL, (os_dirname(buf, (len - 1))))
+ local buf = cstr((length - 1), '')
+ eq(FAIL, (os_dirname(buf, (length - 1))))
end)
end)
@@ -213,15 +213,6 @@ describe('fs function', function()
os_setperm('unit-test-directory/test.file', orig_test_file_perm)
end)
- local function os_getperm(filename)
- local perm = fs.os_getperm((to_cstr(filename)))
- return tonumber(perm)
- end
-
- local function os_setperm(filename, perm)
- return fs.os_setperm((to_cstr(filename)), perm)
- end
-
local function os_fchown(filename, user_id, group_id)
local fd = ffi.C.open(filename, 0)
local res = fs.os_fchown(fd, user_id, group_id)
@@ -242,8 +233,8 @@ describe('fs function', function()
end
describe('os_getperm', function()
- it('returns -1 when the given file does not exist', function()
- eq(-1, (os_getperm('non-existing-file')))
+ it('returns UV_ENOENT when the given file does not exist', function()
+ eq(ffi.C.UV_ENOENT, (os_getperm('non-existing-file')))
end)
it('returns a perm > 0 when given an existing file', function()
@@ -454,8 +445,8 @@ describe('fs function', function()
local new_file = 'test_new_file'
local existing_file = 'unit-test-directory/test_existing.file'
- it('returns -ENOENT for O_RDWR on a non-existing file', function()
- eq(-ffi.C.kENOENT, (os_open('non-existing-file', ffi.C.kO_RDWR, 0)))
+ it('returns UV_ENOENT for O_RDWR on a non-existing file', function()
+ eq(ffi.C.UV_ENOENT, (os_open('non-existing-file', ffi.C.kO_RDWR, 0)))
end)
it('returns non-negative for O_CREAT on a non-existing file', function()
@@ -468,9 +459,9 @@ describe('fs function', function()
assert.is_true(0 <= (os_open(existing_file, ffi.C.kO_CREAT, 0)))
end)
- it('returns -EEXIST for O_CREAT|O_EXCL on a existing file', function()
+ it('returns UV_EEXIST for O_CREAT|O_EXCL on a existing file', function()
assert_file_exists(existing_file)
- eq(-ffi.C.kEEXIST, (os_open(existing_file, (bit.bor(ffi.C.kO_CREAT, ffi.C.kO_EXCL)), 0)))
+ eq(ffi.C.kUV_EEXIST, (os_open(existing_file, (bit.bor(ffi.C.kO_CREAT, ffi.C.kO_EXCL)), 0)))
end)
it('sets `rwx` permissions for O_CREAT 700', function()
@@ -611,7 +602,7 @@ describe('fs function', function()
it('removes the given directory and returns 0', function()
lfs.mkdir('unit-test-directory/new-dir')
- eq(0, (os_rmdir('unit-test-directory/new-dir', mode)))
+ eq(0, os_rmdir('unit-test-directory/new-dir'))
eq(false, (os_isdir('unit-test-directory/new-dir')))
end)
end)
diff --git a/test/unit/os/shell_spec.lua b/test/unit/os/shell_spec.lua
index 20cfc17950..01deefab0c 100644
--- a/test/unit/os/shell_spec.lua
+++ b/test/unit/os/shell_spec.lua
@@ -17,7 +17,7 @@ local shell = helpers.cimport(
'./src/nvim/main.h',
'./src/nvim/misc1.h'
)
-local ffi, eq, neq = helpers.ffi, helpers.eq, helpers.neq
+local ffi, eq = helpers.ffi, helpers.eq
local intern = helpers.internalize
local to_cstr = helpers.to_cstr
local NULL = ffi.cast('void *', 0)
@@ -70,7 +70,7 @@ describe('shell functions', function()
end)
it ('returns non-zero exit code', function()
- local status, output = os_system('exit 2')
+ local status = os_system('exit 2')
eq(2, status)
end)
end)
diff --git a/test/unit/os/users_spec.lua b/test/unit/os/users_spec.lua
index df5d2365c6..236481e9e7 100644
--- a/test/unit/os/users_spec.lua
+++ b/test/unit/os/users_spec.lua
@@ -1,26 +1,24 @@
local helpers = require('test.unit.helpers')
local cimport = helpers.cimport
-local internalize = helpers.internalize
local eq = helpers.eq
local ffi = helpers.ffi
local lib = helpers.lib
-local cstr = helpers.cstr
local NULL = helpers.NULL
local OK = helpers.OK
local FAIL = helpers.FAIL
local users = cimport('./src/nvim/os/os.h', 'unistd.h')
-function garray_new()
+local function garray_new()
return ffi.new('garray_T[1]')
end
-function garray_get_len(array)
+local function garray_get_len(array)
return array[0].ga_len
end
-function garray_get_item(array, index)
+local function garray_get_item(array, index)
return (ffi.cast('void **', array[0].ga_data))[index]
end
diff --git a/test/unit/path_spec.lua b/test/unit/path_spec.lua
index 239a255151..9b76834383 100644
--- a/test/unit/path_spec.lua
+++ b/test/unit/path_spec.lua
@@ -1,18 +1,16 @@
+local lfs = require('lfs')
local helpers = require('test.unit.helpers')
local cimport = helpers.cimport
-local internalize = helpers.internalize
local eq = helpers.eq
local neq = helpers.neq
local ffi = helpers.ffi
-local lib = helpers.lib
local cstr = helpers.cstr
local to_cstr = helpers.to_cstr
local NULL = helpers.NULL
local OK = helpers.OK
local FAIL = helpers.FAIL
-require('lfs')
cimport('string.h')
local path = cimport('./src/nvim/path.h')
@@ -23,7 +21,7 @@ local kBothFilesMissing = path.kBothFilesMissing
local kOneFileMissing = path.kOneFileMissing
local kEqualFileNames = path.kEqualFileNames
-local len = 0
+local length = 0
local buffer = nil
describe('path function', function()
@@ -36,19 +34,19 @@ describe('path function', function()
lfs.rmdir('unit-test-directory')
end)
- function path_full_dir_name(directory, buffer, len)
+ local function path_full_dir_name(directory, buf, len)
directory = to_cstr(directory)
- return path.path_full_dir_name(directory, buffer, len)
+ return path.path_full_dir_name(directory, buf, len)
end
before_each(function()
-- Create empty string buffer which will contain the resulting path.
- len = (string.len(lfs.currentdir())) + 22
- buffer = cstr(len, '')
+ length = string.len(lfs.currentdir()) + 22
+ buffer = cstr(length, '')
end)
it('returns the absolute directory name of a given relative one', function()
- local result = path_full_dir_name('..', buffer, len)
+ local result = path_full_dir_name('..', buffer, length)
eq(OK, result)
local old_dir = lfs.currentdir()
lfs.chdir('..')
@@ -58,23 +56,23 @@ describe('path function', function()
end)
it('returns the current directory name if the given string is empty', function()
- eq(OK, (path_full_dir_name('', buffer, len)))
+ eq(OK, (path_full_dir_name('', buffer, length)))
eq(lfs.currentdir(), (ffi.string(buffer)))
end)
it('fails if the given directory does not exist', function()
- eq(FAIL, path_full_dir_name('does_not_exist', buffer, len))
+ eq(FAIL, path_full_dir_name('does_not_exist', buffer, length))
end)
it('works with a normal relative dir', function()
- local result = path_full_dir_name('unit-test-directory', buffer, len)
+ local result = path_full_dir_name('unit-test-directory', buffer, length)
eq(lfs.currentdir() .. '/unit-test-directory', (ffi.string(buffer)))
eq(OK, result)
end)
end)
describe('path_full_compare', function()
- function path_full_compare(s1, s2, cn)
+ local function path_full_compare(s1, s2, cn)
s1 = to_cstr(s1)
s2 = to_cstr(s2)
return path.path_full_compare(s1, s2, cn or 0)
@@ -117,7 +115,7 @@ describe('path function', function()
end)
describe('path_tail', function()
- function path_tail(file)
+ local function path_tail(file)
local res = path.path_tail((to_cstr(file)))
neq(NULL, res)
return ffi.string(res)
@@ -133,7 +131,7 @@ describe('path function', function()
end)
describe('path_tail_with_sep', function()
- function path_tail_with_sep(file)
+ local function path_tail_with_sep(file)
local res = path.path_tail_with_sep((to_cstr(file)))
neq(NULL, res)
return ffi.string(res)
@@ -165,7 +163,7 @@ describe('path function', function()
-- Returns the path tail and length (out param) of the tail.
-- Does not convert the tail from C-pointer to lua string for use with
-- strcmp.
- function invocation_path_tail(invk)
+ local function invocation_path_tail(invk)
local plen = ffi.new('size_t[?]', 1)
local ptail = path.invocation_path_tail((to_cstr(invk)), plen)
neq(NULL, ptail)
@@ -178,7 +176,7 @@ describe('path function', function()
end
-- This test mimics the intended use in C.
- function compare(base, pinvk, len)
+ local function compare(base, pinvk, len)
return eq(0, (ffi.C.strncmp((to_cstr(base)), pinvk, len)))
end
@@ -207,7 +205,7 @@ describe('path function', function()
end)
it('only accepts whitespace as a terminator for the executable name', function()
- local invk, len = invocation_path_tail('exe-a+b_c[]()|#!@$%^&*')
+ local invk, _ = invocation_path_tail('exe-a+b_c[]()|#!@$%^&*')
eq('exe-a+b_c[]()|#!@$%^&*', (ffi.string(invk)))
end)
@@ -215,20 +213,20 @@ describe('path function', function()
local ptail = path.path_tail(to_cstr("a/b/c x y z"))
neq(NULL, ptail)
local tail = ffi.string(ptail)
- local invk, len = invocation_path_tail("a/b/c x y z")
+ local invk, _ = invocation_path_tail("a/b/c x y z")
eq(tail, ffi.string(invk))
end)
it('is not equivalent to path_tail when args contain a path separator', function()
local ptail = path.path_tail(to_cstr("a/b/c x y/z"))
neq(NULL, ptail)
- local invk, len = invocation_path_tail("a/b/c x y/z")
+ local invk, _ = invocation_path_tail("a/b/c x y/z")
neq((ffi.string(ptail)), (ffi.string(invk)))
end)
end)
describe('path_next_component', function()
- function path_next_component(file)
+ local function path_next_component(file)
local res = path.path_next_component((to_cstr(file)))
neq(NULL, res)
return ffi.string(res)
@@ -308,11 +306,11 @@ describe('more path function', function()
-- Since the tests are executed, they are called by an executable. We use
-- that executable for several asserts.
- absolute_executable = arg[0]
+ local absolute_executable = arg[0]
-- Split absolute_executable into a directory and the actual file name for
-- later usage.
- directory, executable_name = string.match(absolute_executable, '^(.*)/(.*)$')
+ local directory, executable_name = string.match(absolute_executable, '^(.*)/(.*)$') -- luacheck: ignore
end)
teardown(function()
@@ -321,27 +319,27 @@ describe('more path function', function()
end)
describe('vim_FullName', function()
- function vim_FullName(filename, buffer, length, force)
+ local function vim_FullName(filename, buf, len, force)
filename = to_cstr(filename)
- return path.vim_FullName(filename, buffer, length, force)
+ return path.vim_FullName(filename, buf, len, force)
end
before_each(function()
-- Create empty string buffer which will contain the resulting path.
- len = (string.len(lfs.currentdir())) + 33
- buffer = cstr(len, '')
+ length = (string.len(lfs.currentdir())) + 33
+ buffer = cstr(length, '')
end)
it('fails if given filename is NULL', function()
local force_expansion = 1
- local result = path.vim_FullName(NULL, buffer, len, force_expansion)
+ local result = path.vim_FullName(NULL, buffer, length, force_expansion)
eq(FAIL, result)
end)
it('uses the filename if the filename is a URL', function()
local force_expansion = 1
local filename = 'http://www.neovim.org'
- local result = vim_FullName(filename, buffer, len, force_expansion)
+ local result = vim_FullName(filename, buffer, length, force_expansion)
eq(filename, (ffi.string(buffer)))
eq(OK, result)
end)
@@ -349,14 +347,14 @@ describe('more path function', function()
it('fails and uses filename if given filename contains non-existing directory', function()
local force_expansion = 1
local filename = 'non_existing_dir/test.file'
- local result = vim_FullName(filename, buffer, len, force_expansion)
+ local result = vim_FullName(filename, buffer, length, force_expansion)
eq(filename, (ffi.string(buffer)))
eq(FAIL, result)
end)
it('concatenates given filename if it does not contain a slash', function()
local force_expansion = 1
- local result = vim_FullName('test.file', buffer, len, force_expansion)
+ local result = vim_FullName('test.file', buffer, length, force_expansion)
local expected = lfs.currentdir() .. '/test.file'
eq(expected, (ffi.string(buffer)))
eq(OK, result)
@@ -364,7 +362,7 @@ describe('more path function', function()
it('concatenates given filename if it is a directory but does not contain a\n slash', function()
local force_expansion = 1
- local result = vim_FullName('..', buffer, len, force_expansion)
+ local result = vim_FullName('..', buffer, length, force_expansion)
local expected = lfs.currentdir() .. '/..'
eq(expected, (ffi.string(buffer)))
eq(OK, result)
@@ -374,7 +372,7 @@ describe('more path function', function()
-- the unit tests? Which other directory would be better?
it('enters given directory (instead of just concatenating the strings) if possible and if path contains a slash', function()
local force_expansion = 1
- local result = vim_FullName('../test.file', buffer, len, force_expansion)
+ local result = vim_FullName('../test.file', buffer, length, force_expansion)
local old_dir = lfs.currentdir()
lfs.chdir('..')
local expected = lfs.currentdir() .. '/test.file'
@@ -386,7 +384,7 @@ describe('more path function', function()
it('just copies the path if it is already absolute and force=0', function()
local force_expansion = 0
local absolute_path = '/absolute/path'
- local result = vim_FullName(absolute_path, buffer, len, force_expansion)
+ local result = vim_FullName(absolute_path, buffer, length, force_expansion)
eq(absolute_path, (ffi.string(buffer)))
eq(OK, result)
end)
@@ -394,14 +392,14 @@ describe('more path function', function()
it('fails and uses filename when the path is relative to HOME', function()
local force_expansion = 1
local absolute_path = '~/home.file'
- local result = vim_FullName(absolute_path, buffer, len, force_expansion)
+ local result = vim_FullName(absolute_path, buffer, length, force_expansion)
eq(absolute_path, (ffi.string(buffer)))
eq(FAIL, result)
end)
it('works with some "normal" relative path with directories', function()
local force_expansion = 1
- local result = vim_FullName('unit-test-directory/test.file', buffer, len, force_expansion)
+ local result = vim_FullName('unit-test-directory/test.file', buffer, length, force_expansion)
eq(OK, result)
eq(lfs.currentdir() .. '/unit-test-directory/test.file', (ffi.string(buffer)))
end)
@@ -411,7 +409,7 @@ describe('more path function', function()
local filename = to_cstr('unit-test-directory/test.file')
-- Don't use the wrapper here but pass a cstring directly to the c
-- function.
- local result = path.vim_FullName(filename, buffer, len, force_expansion)
+ local result = path.vim_FullName(filename, buffer, length, force_expansion)
eq(lfs.currentdir() .. '/unit-test-directory/test.file', (ffi.string(buffer)))
eq('unit-test-directory/test.file', (ffi.string(filename)))
eq(OK, result)
@@ -420,15 +418,15 @@ describe('more path function', function()
it('works with directories that have one path component', function()
local force_expansion = 1
local filename = to_cstr('/tmp')
- local result = path.vim_FullName(filename, buffer, len, force_expansion)
+ local result = path.vim_FullName(filename, buffer, length, force_expansion)
eq('/tmp', ffi.string(buffer))
eq(OK, result)
end)
end)
describe('path_fix_case', function()
- function fix_case(file)
- c_file = to_cstr(file)
+ local function fix_case(file)
+ local c_file = to_cstr(file)
path.path_fix_case(c_file)
return ffi.string(c_file)
end
@@ -493,7 +491,7 @@ describe('more path function', function()
end)
describe('path_is_absolute_path', function()
- function path_is_absolute_path(filename)
+ local function path_is_absolute_path(filename)
filename = to_cstr(filename)
return path.path_is_absolute_path(filename)
end
diff --git a/test/unit/preprocess.lua b/test/unit/preprocess.lua
index d4c2e088a4..e5c838b13b 100644
--- a/test/unit/preprocess.lua
+++ b/test/unit/preprocess.lua
@@ -169,8 +169,8 @@ local type_to_class = {
-- find the best cc. If os.exec causes problems on windows (like popping up
-- a console window) we might consider using something like this:
-- http://scite-ru.googlecode.com/svn/trunk/pack/tools/LuaLib/shell.html#exec
-local function find_best_cc(ccs)
- for _, meta in pairs(ccs) do
+local function find_best_cc(compilers)
+ for _, meta in pairs(compilers) do
local version = io.popen(tostring(meta.path) .. " -v 2>&1")
version:close()
if version then
diff --git a/test/unit/profile_spec.lua b/test/unit/profile_spec.lua
index 2b006a0768..852475fe2c 100644
--- a/test/unit/profile_spec.lua
+++ b/test/unit/profile_spec.lua
@@ -36,20 +36,20 @@ local function cmp_assert(v1, v2, op, opstr)
assert.is_true(res)
end
-local function lt(v1, v2)
- cmp_assert(v1, v2, function(v1, v2) return v1 < v2 end, "<")
+local function lt(a, b) -- luacheck: ignore
+ cmp_assert(a, b, function(x, y) return x < y end, "<")
end
-local function lte(v1, v2)
- cmp_assert(v1, v2, function(v1, v2) return v1 <= v2 end, "<=")
+local function lte(a, b) -- luacheck: ignore
+ cmp_assert(a, b, function(x, y) return x <= y end, "<=")
end
-local function gt(v1, v2)
- cmp_assert(v1, v2, function(v1, v2) return v1 > v2 end, ">")
+local function gt(a, b) -- luacheck: ignore
+ cmp_assert(a, b, function(x, y) return x > y end, ">")
end
-local function gte(v1, v2)
- cmp_assert(v1, v2, function(v1, v2) return v1 >= v2 end, ">=")
+local function gte(a, b)
+ cmp_assert(a, b, function(x, y) return x >= y end, ">=")
end
-- missing functions:
@@ -70,7 +70,7 @@ describe('profiling related functions', function()
local function profile_equal(t1, t2) return prof.profile_equal(t1, t2) end
local function profile_msg(t) return ffi.string(prof.profile_msg(t)) end
- local function toseconds(t)
+ local function toseconds(t) -- luacheck: ignore
local str = trim(profile_msg(t))
local spl = split(str, ".")
local s, us = spl[1], spl[2]
@@ -122,7 +122,7 @@ describe('profiling related functions', function()
local divided = profile_divide(start, divisor)
local res = divided
- for i = 1, divisor - 1 do
+ for _ = 1, divisor - 1 do
res = profile_add(res, divided)
end
@@ -143,7 +143,7 @@ describe('profiling related functions', function()
describe('profile_start', function()
it('increases', function()
local last = profile_start()
- for i=1,100 do
+ for _ = 1, 100 do
local curr = profile_start()
gte(curr, last)
last = curr
@@ -157,7 +157,7 @@ describe('profiling related functions', function()
end)
it('outer elapsed >= inner elapsed', function()
- for i = 1, 100 do
+ for _ = 1, 100 do
local start_outer = profile_start()
local start_inner = profile_start()
local elapsed_inner = profile_end(start_inner)
@@ -238,7 +238,7 @@ describe('profiling related functions', function()
-- t2 >= t1 => profile_cmp(t1, t2) >= 0
assert.is_true(cmp >= 0)
- local cmp = profile_cmp(profile_sub(start3, start1), profile_sub(start2, start1))
+ cmp = profile_cmp(profile_sub(start3, start1), profile_sub(start2, start1))
-- t2 <= t1 => profile_cmp(t1, t2) <= 0
assert.is_true(cmp <= 0)
end)
diff --git a/test/unit/set.lua b/test/unit/set.lua
index bfb6b8c41c..4e66546f32 100644
--- a/test/unit/set.lua
+++ b/test/unit/set.lua
@@ -35,7 +35,7 @@ end
-- adds the argument table to this Set
function Set:union_table(t)
- for k, v in pairs(t) do
+ for _, v in pairs(t) do
self:add(v)
end
end
diff --git a/third-party/cmake/BuildLuarocks.cmake b/third-party/cmake/BuildLuarocks.cmake
index cb38b3b6cc..f3e5a96220 100644
--- a/third-party/cmake/BuildLuarocks.cmake
+++ b/third-party/cmake/BuildLuarocks.cmake
@@ -114,8 +114,6 @@ add_custom_target(lpeg
list(APPEND THIRD_PARTY_DEPS lpeg)
if(USE_BUNDLED_BUSTED)
- # We can remove the cliargs dependency once the busted version dependency
- # is fixed.
add_custom_command(OUTPUT ${HOSTDEPS_BIN_DIR}/busted
COMMAND ${LUAROCKS_BINARY}
ARGS build https://raw.githubusercontent.com/Olivine-Labs/busted/v2.0.rc11-0/busted-2.0.rc11-0.rockspec ${LUAROCKS_BUILDARGS}
@@ -123,12 +121,19 @@ if(USE_BUNDLED_BUSTED)
add_custom_target(busted
DEPENDS ${HOSTDEPS_BIN_DIR}/busted)
+ add_custom_command(OUTPUT ${HOSTDEPS_BIN_DIR}/luacheck
+ COMMAND ${LUAROCKS_BINARY}
+ ARGS build https://raw.githubusercontent.com/mpeterv/luacheck/0.12.0/luacheck-scm-1.rockspec ${LUAROCKS_BUILDARGS}
+ DEPENDS busted)
+ add_custom_target(luacheck
+ DEPENDS ${HOSTDEPS_BIN_DIR}/luacheck)
+
add_custom_command(OUTPUT ${HOSTDEPS_LIB_DIR}/luarocks/rocks/nvim-client
COMMAND ${LUAROCKS_BINARY}
ARGS build https://raw.githubusercontent.com/neovim/lua-client/0.0.1-14/nvim-client-0.0.1-14.rockspec ${LUAROCKS_BUILDARGS} LIBUV_DIR=${HOSTDEPS_INSTALL_DIR}
- DEPENDS busted libuv)
+ DEPENDS luacheck libuv)
add_custom_target(nvim-client
DEPENDS ${HOSTDEPS_LIB_DIR}/luarocks/rocks/nvim-client)
- list(APPEND THIRD_PARTY_DEPS busted nvim-client)
+ list(APPEND THIRD_PARTY_DEPS busted luacheck nvim-client)
endif()