diff options
106 files changed, 3629 insertions, 2488 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 74e161d989..a4e49ccfc5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -374,13 +374,6 @@ include_directories(SYSTEM ${MSGPACK_INCLUDE_DIRS}) find_package(LibLUV 1.30.0 REQUIRED) include_directories(SYSTEM ${LIBLUV_INCLUDE_DIRS}) -find_package(UTF8PROC REQUIRED) -include_directories(SYSTEM ${UTF8PROC_INCLUDE_DIRS}) -if(WIN32) - add_definitions(-DUTF8PROC_STATIC) -endif() - - # Note: The test lib requires LuaJIT; it will be skipped if LuaJIT is missing. option(PREFER_LUA "Prefer Lua over LuaJIT in the nvim executable." OFF) diff --git a/cmake/FindUTF8PROC.cmake b/cmake/FindUTF8PROC.cmake deleted file mode 100644 index fdb462b779..0000000000 --- a/cmake/FindUTF8PROC.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# - Try to find utf8proc -# Once done this will define -# UTF8PROC_FOUND - System has utf8proc -# UTF8PROC_INCLUDE_DIRS - The utf8proc include directories -# UTF8PROC_LIBRARIES - The libraries needed to use utf8proc - -include(LibFindMacros) - -set(UTF8PROC_NAMES utf8proc) -if(MSVC) - # "utf8proc_static" is used for MSVC (when built statically from third-party). - # https://github.com/JuliaStrings/utf8proc/commit/0975bf9b6. - list(APPEND UTF8PROC_NAMES utf8proc_static) -endif() -libfind_pkg_detect(UTF8PROC utf8proc FIND_PATH utf8proc.h FIND_LIBRARY ${UTF8PROC_NAMES}) -libfind_process(UTF8PROC REQUIRED) diff --git a/runtime/autoload/netrw.vim b/runtime/autoload/netrw.vim index fa86223d53..b69ad7187a 100644 --- a/runtime/autoload/netrw.vim +++ b/runtime/autoload/netrw.vim @@ -5460,6 +5460,11 @@ fun! netrw#CheckIfRemote(...) else let curfile= expand("%") endif + + " Ignore terminal buffers + if &buftype ==# 'terminal' + return 0 + endif " call Decho("curfile<".curfile.">") if curfile =~ '^\a\{3,}://' " call Dret("netrw#CheckIfRemote 1") diff --git a/runtime/autoload/provider/clipboard.vim b/runtime/autoload/provider/clipboard.vim index c86f7d0c2f..a96a0a61b7 100644 --- a/runtime/autoload/provider/clipboard.vim +++ b/runtime/autoload/provider/clipboard.vim @@ -113,8 +113,13 @@ function! provider#clipboard#Executable() abort let s:paste['*'] = s:paste['+'] return 'doitclient' elseif executable('win32yank.exe') - let s:copy['+'] = 'win32yank.exe -i --crlf' - let s:paste['+'] = 'win32yank.exe -o --lf' + if has('wsl') && getftype(exepath('win32yank.exe')) == 'link' + let win32yank = resolve(exepath('win32yank.exe')) + else + let win32yank = 'win32yank.exe' + endif + let s:copy['+'] = win32yank.' -i --crlf' + let s:paste['+'] = win32yank.' -o --lf' let s:copy['*'] = s:copy['+'] let s:paste['*'] = s:paste['+'] return 'win32yank' diff --git a/runtime/doc/filetype.txt b/runtime/doc/filetype.txt index c649688d99..1fce37c594 100644 --- a/runtime/doc/filetype.txt +++ b/runtime/doc/filetype.txt @@ -275,7 +275,7 @@ Note that the last one is the value of $VIMRUNTIME which has been expanded. Note that when using a plugin manager or |packages| many directories will be added to 'runtimepath'. These plugins each require their own directory, don't -put them directly in ~/.vim/plugin. +put them directly in ~/.config/nvim/plugin. What if it looks like your plugin is not being loaded? You can find out what happens when Vim starts up by using the |-V| argument: > diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt index 2f5427f6fc..4c59e53343 100644 --- a/runtime/doc/lsp.txt +++ b/runtime/doc/lsp.txt @@ -64,7 +64,7 @@ FAQ *lsp-faq* - Q: How to force-reload LSP? A: Stop all clients, then reload the buffer. > - :lua vim.lsp.stop_all_clients() + :lua vim.lsp.stop_client(vim.lsp.get_active_clients()) :edit - Q: Why isn't completion working? diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index 800f24b5c9..7f376cbbf0 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -908,7 +908,10 @@ deep_equal({a}, {b}) *vim.deep_equal()* deepcopy({orig}) *vim.deepcopy()* Returns a deep copy of the given object. Non-table objects are copied as in a typical Lua assignment, whereas table objects - are copied recursively. + are copied recursively. Functions are naively copied, so + functions in the copied table point to the same functions as + those in the input table. Userdata and threads are not copied + and will throw an error. Parameters: ~ {orig} Table to copy diff --git a/runtime/doc/spell.txt b/runtime/doc/spell.txt index 1f1599f560..b88e26cdff 100644 --- a/runtime/doc/spell.txt +++ b/runtime/doc/spell.txt @@ -504,7 +504,7 @@ then Vim will try to guess. Multiple {inname} arguments can be given to combine regions into one Vim spell file. Example: > - :mkspell ~/.vim/spell/en /tmp/en_US /tmp/en_CA /tmp/en_AU + :mkspell ~/.config/nvim/spell/en /tmp/en_US /tmp/en_CA /tmp/en_AU < This combines the English word lists for US, CA and AU into one en.spl file. Up to eight regions can be combined. *E754* *E755* diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index 30ccb699cd..57337aeac2 100644 --- a/runtime/doc/syntax.txt +++ b/runtime/doc/syntax.txt @@ -4647,8 +4647,8 @@ in their own color. ":colorscheme" in a color scheme script. To customize a colorscheme use another name, e.g. - "~/.vim/colors/mine.vim", and use `:runtime` to load - the original colorscheme: > + "~/.config/nvim/colors/mine.vim", and use `:runtime` to + load the original colorscheme: > runtime colors/evening.vim hi Statement ctermfg=Blue guifg=Blue diff --git a/runtime/doc/ui.txt b/runtime/doc/ui.txt index de54ce59b6..b243d9ba50 100644 --- a/runtime/doc/ui.txt +++ b/runtime/doc/ui.txt @@ -592,6 +592,12 @@ tabs. When |ext_messages| is active, no message grid is used, and this event will not be sent. +["win_viewport", grid, win, topline, botline, curline, curcol] + Indicates the range of buffer text displayed in the window, as well + as the cursor position in the buffer. All positions are zero-based. + `botline` is set to one more than the line count of the buffer, if + there are filler lines past the end. + ============================================================================== Popupmenu Events *ui-popupmenu* diff --git a/runtime/filetype.vim b/runtime/filetype.vim index 49e1e9909b..5068f9be76 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -1,7 +1,7 @@ " Vim support file to detect file types " " Maintainer: Bram Moolenaar <Bram@vim.org> -" Last Change: 2019 Nov 26 +" Last Change: 2020 Apr 12 " Listen very carefully, I will say this only once if exists("did_load_filetypes") @@ -229,11 +229,14 @@ au BufNewFile,BufRead *.bl setf blank " Blkid cache file au BufNewFile,BufRead */etc/blkid.tab,*/etc/blkid.tab.old setf xml +" BSDL +au BufNewFile,BufRead *bsd,*.bsdl setf bsdl + " Bazel (http://bazel.io) autocmd BufRead,BufNewFile *.bzl,WORKSPACE,BUILD.bazel setf bzl if has("fname_case") " There is another check for BUILD further below. - autocmd BufRead,BufNewFile BUILD setf bzl + autocmd BufRead,BufNewFile BUILD setf bzl endif " C or lpc @@ -1639,9 +1642,11 @@ au BufNewFile,BufRead */etc/sysctl.conf,*/etc/sysctl.d/*.conf setf sysctl " Systemd unit files au BufNewFile,BufRead */systemd/*.{automount,mount,path,service,socket,swap,target,timer} setf systemd " Systemd overrides -au BufNewFile,BufRead /etc/systemd/system/*.d/*.conf setf systemd +au BufNewFile,BufRead */etc/systemd/system/*.d/*.conf setf systemd +au BufNewFile,BufRead */.config/systemd/user/*.d/*.conf setf systemd " Systemd temp files -au BufNewFile,BufRead /etc/systemd/system/*.d/.#* setf systemd +au BufNewFile,BufRead */etc/systemd/system/*.d/.#* setf systemd +au BufNewFile,BufRead */.config/systemd/user/*.d/.#* setf systemd " Synopsys Design Constraints au BufNewFile,BufRead *.sdc setf sdc @@ -1772,7 +1777,7 @@ au BufNewFile,BufRead *.va,*.vams setf verilogams au BufNewFile,BufRead *.sv,*.svh setf systemverilog " VHDL -au BufNewFile,BufRead *.hdl,*.vhd,*.vhdl,*.vbe,*.vst setf vhdl +au BufNewFile,BufRead *.hdl,*.vhd,*.vhdl,*.vbe,*.vst,*.vho setf vhdl " Vim script au BufNewFile,BufRead *.vim,*.vba,.exrc,_exrc setf vim diff --git a/runtime/lua/vim/lsp/callbacks.lua b/runtime/lua/vim/lsp/callbacks.lua index 644c12f98c..bcadd0e2c3 100644 --- a/runtime/lua/vim/lsp/callbacks.lua +++ b/runtime/lua/vim/lsp/callbacks.lua @@ -29,6 +29,17 @@ M['textDocument/publishDiagnostics'] = function(_, _, result) return end util.buf_clear_diagnostics(bufnr) + + -- https://microsoft.github.io/language-server-protocol/specifications/specification-current/#diagnostic + -- The diagnostic's severity. Can be omitted. If omitted it is up to the + -- client to interpret diagnostics as error, warning, info or hint. + -- TODO: Replace this with server-specific heuristics to infer severity. + for _, diagnostic in ipairs(result.diagnostics) do + if diagnostic.severity == nil then + diagnostic.severity = protocol.DiagnosticSeverity.Error + end + end + util.buf_diagnostics_save_positions(bufnr, result.diagnostics) util.buf_diagnostics_underline(bufnr, result.diagnostics) util.buf_diagnostics_virtual_text(bufnr, result.diagnostics) @@ -101,11 +112,20 @@ local function location_callback(_, method, result) local _ = log.info() and log.info(method, 'No location found') return nil end - util.jump_to_location(result[1]) - if #result > 1 then - util.set_qflist(util.locations_to_items(result)) - api.nvim_command("copen") - api.nvim_command("wincmd p") + + -- textDocument/definition can return Location or Location[] + -- https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_definition + + if vim.tbl_islist(result) then + util.jump_to_location(result[1]) + + if #result > 1 then + util.set_qflist(util.locations_to_items(result)) + api.nvim_command("copen") + api.nvim_command("wincmd p") + end + else + util.jump_to_location(result) end end @@ -114,72 +134,13 @@ M['textDocument/definition'] = location_callback M['textDocument/typeDefinition'] = location_callback M['textDocument/implementation'] = location_callback ---- Convert SignatureHelp response to preview contents. --- https://microsoft.github.io/language-server-protocol/specifications/specification-3-14/#textDocument_signatureHelp -local function signature_help_to_preview_contents(input) - if not input.signatures then - return - end - --The active signature. If omitted or the value lies outside the range of - --`signatures` the value defaults to zero or is ignored if `signatures.length - --=== 0`. Whenever possible implementors should make an active decision about - --the active signature and shouldn't rely on a default value. - local contents = {} - local active_signature = input.activeSignature or 0 - -- If the activeSignature is not inside the valid range, then clip it. - if active_signature >= #input.signatures then - active_signature = 0 - end - local signature = input.signatures[active_signature + 1] - if not signature then - return - end - vim.list_extend(contents, vim.split(signature.label, '\n', true)) - if signature.documentation then - util.convert_input_to_markdown_lines(signature.documentation, contents) - end - if input.parameters then - local active_parameter = input.activeParameter or 0 - -- If the activeParameter is not inside the valid range, then clip it. - if active_parameter >= #input.parameters then - active_parameter = 0 - end - local parameter = signature.parameters and signature.parameters[active_parameter] - if parameter then - --[=[ - --Represents a parameter of a callable-signature. A parameter can - --have a label and a doc-comment. - interface ParameterInformation { - --The label of this parameter information. - -- - --Either a string or an inclusive start and exclusive end offsets within its containing - --signature label. (see SignatureInformation.label). The offsets are based on a UTF-16 - --string representation as `Position` and `Range` does. - -- - --*Note*: a label of type string should be a substring of its containing signature label. - --Its intended use case is to highlight the parameter label part in the `SignatureInformation.label`. - label: string | [number, number]; - --The human-readable doc-comment of this parameter. Will be shown - --in the UI but can be omitted. - documentation?: string | MarkupContent; - } - --]=] - -- TODO highlight parameter - if parameter.documentation then - util.convert_input_to_markdown_lines(parameter.documentation, contents) - end - end - end - return contents -end - M['textDocument/signatureHelp'] = function(_, method, result) util.focusable_preview(method, function() if not (result and result.signatures and result.signatures[1]) then return { 'No signature available' } end -- TODO show popup when signatures is empty? - local lines = signature_help_to_preview_contents(result) + local lines = util.convert_signature_help_to_markdown_lines(result) lines = util.trim_empty_lines(lines) if vim.tbl_isempty(lines) then return { 'No signature available' } diff --git a/runtime/lua/vim/lsp/rpc.lua b/runtime/lua/vim/lsp/rpc.lua index 74d73da31f..dad1dc11f1 100644 --- a/runtime/lua/vim/lsp/rpc.lua +++ b/runtime/lua/vim/lsp/rpc.lua @@ -140,14 +140,23 @@ local function format_rpc_error(err) validate { err = { err, 't' }; } - local code_name = assert(protocol.ErrorCodes[err.code], "err.code is invalid") - local message_parts = {"RPC", code_name} + + -- There is ErrorCodes in the LSP specification, + -- but in ResponseError.code it is not used and the actual type is number. + local code + if protocol.ErrorCodes[err.code] then + code = string.format("code_name = %s,", protocol.ErrorCodes[err.code]) + else + code = string.format("code_name = unknown, code = %s,", err.code) + end + + local message_parts = {"RPC[Error]", code} if err.message then - table.insert(message_parts, "message = ") + table.insert(message_parts, "message =") table.insert(message_parts, string.format("%q", err.message)) end if err.data then - table.insert(message_parts, "data = ") + table.insert(message_parts, "data =") table.insert(message_parts, vim.inspect(err.data)) end return table.concat(message_parts, ' ') diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 5dd010f2a4..ce5baf5b4b 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -157,11 +157,23 @@ local function sort_completion_items(items) end end +-- Returns text that should be inserted when selecting completion item. The precedence is as follows: +-- textEdit.newText > insertText > label +-- https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion +local function get_completion_word(item) + if item.textEdit ~= nil and item.textEdit.newText ~= nil then + return item.textEdit.newText + elseif item.insertText ~= nil then + return item.insertText + end + return item.label +end + -- Some lanuguage servers return complementary candidates whose prefixes do not match are also returned. -- So we exclude completion candidates whose prefix does not match. local function remove_unmatch_completion_items(items, prefix) return vim.tbl_filter(function(item) - local word = item.insertText or item.label + local word = get_completion_word(item) return vim.startswith(word, prefix) end, items) end @@ -193,7 +205,7 @@ function M.text_document_completion_list_to_complete_items(result, prefix) end end - local word = completion_item.insertText or completion_item.label + local word = get_completion_word(completion_item) table.insert(matches, { word = word, abbr = completion_item.label, @@ -275,6 +287,65 @@ function M.convert_input_to_markdown_lines(input, contents) return contents end +--- Convert SignatureHelp response to markdown lines. +-- https://microsoft.github.io/language-server-protocol/specifications/specification-3-14/#textDocument_signatureHelp +function M.convert_signature_help_to_markdown_lines(signature_help) + if not signature_help.signatures then + return + end + --The active signature. If omitted or the value lies outside the range of + --`signatures` the value defaults to zero or is ignored if `signatures.length + --=== 0`. Whenever possible implementors should make an active decision about + --the active signature and shouldn't rely on a default value. + local contents = {} + local active_signature = signature_help.activeSignature or 0 + -- If the activeSignature is not inside the valid range, then clip it. + if active_signature >= #signature_help.signatures then + active_signature = 0 + end + local signature = signature_help.signatures[active_signature + 1] + if not signature then + return + end + vim.list_extend(contents, vim.split(signature.label, '\n', true)) + if signature.documentation then + M.convert_input_to_markdown_lines(signature.documentation, contents) + end + if signature_help.parameters then + local active_parameter = signature_help.activeParameter or 0 + -- If the activeParameter is not inside the valid range, then clip it. + if active_parameter >= #signature_help.parameters then + active_parameter = 0 + end + local parameter = signature.parameters and signature.parameters[active_parameter] + if parameter then + --[=[ + --Represents a parameter of a callable-signature. A parameter can + --have a label and a doc-comment. + interface ParameterInformation { + --The label of this parameter information. + -- + --Either a string or an inclusive start and exclusive end offsets within its containing + --signature label. (see SignatureInformation.label). The offsets are based on a UTF-16 + --string representation as `Position` and `Range` does. + -- + --*Note*: a label of type string should be a substring of its containing signature label. + --Its intended use case is to highlight the parameter label part in the `SignatureInformation.label`. + label: string | [number, number]; + --The human-readable doc-comment of this parameter. Will be shown + --in the UI but can be omitted. + documentation?: string | MarkupContent; + } + --]=] + -- TODO highlight parameter + if parameter.documentation then + M.convert_input_help_to_markdown_lines(parameter.documentation, contents) + end + end + end + return contents +end + function M.make_floating_popup_options(width, height, opts) validate { opts = { opts, 't', true }; @@ -522,8 +593,7 @@ function M.open_floating_preview(contents, filetype, opts) end api.nvim_buf_set_lines(floating_bufnr, 0, -1, true, contents) api.nvim_buf_set_option(floating_bufnr, 'modifiable', false) - -- TODO make InsertCharPre disappearing optional? - api.nvim_command("autocmd CursorMoved,BufHidden,InsertCharPre <buffer> ++once lua pcall(vim.api.nvim_win_close, "..floating_winnr..", true)") + M.close_preview_autocmd({"CursorMoved", "CursorMovedI", "BufHidden"}, floating_winnr) return floating_bufnr, floating_winnr end @@ -725,7 +795,8 @@ do [protocol.DocumentHighlightKind.Read] = "LspReferenceRead"; [protocol.DocumentHighlightKind.Write] = "LspReferenceWrite"; } - highlight_range(bufnr, reference_ns, document_highlight_kind[reference["kind"]], start_pos, end_pos) + local kind = reference["kind"] or protocol.DocumentHighlightKind.Text + highlight_range(bufnr, reference_ns, document_highlight_kind[kind], start_pos, end_pos) end end diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua index 1bf1c63fd7..d18fcfaf95 100644 --- a/runtime/lua/vim/shared.lua +++ b/runtime/lua/vim/shared.lua @@ -8,6 +8,9 @@ local vim = vim or {} --- Returns a deep copy of the given object. Non-table objects are copied as --- in a typical Lua assignment, whereas table objects are copied recursively. +--- Functions are naively copied, so functions in the copied table point to the +--- same functions as those in the input table. Userdata and threads are not +--- copied and will throw an error. --- --@param orig Table to copy --@returns New table of copied keys and (nested) values. @@ -34,10 +37,16 @@ vim.deepcopy = (function() string = _id, ['nil'] = _id, boolean = _id, + ['function'] = _id, } return function(orig) - return deepcopy_funcs[type(orig)](orig) + local f = deepcopy_funcs[type(orig)] + if f then + return f(orig) + else + error("Cannot deepcopy object of type "..type(orig)) + end end end)() diff --git a/runtime/lua/vim/treesitter.lua b/runtime/lua/vim/treesitter.lua index 8dacfa11cf..1836227540 100644 --- a/runtime/lua/vim/treesitter.lua +++ b/runtime/lua/vim/treesitter.lua @@ -124,7 +124,7 @@ end function M.parse_query(lang, query) M.require_language(lang) local self = setmetatable({}, Query) - self.query = vim._ts_parse_query(lang, query) + self.query = vim._ts_parse_query(lang, vim.fn.escape(query,'\\')) self.info = self.query:inspect() self.captures = self.info.captures self.regexes = {} diff --git a/scripts/vim-patch.sh b/scripts/vim-patch.sh index e844d2951c..dc62c9e744 100755 --- a/scripts/vim-patch.sh +++ b/scripts/vim-patch.sh @@ -676,9 +676,11 @@ review_pr() { echo echo "Downloading data for pull request #${pr}." - local pr_commit_urls=( - "$(curl -Ssf "https://api.github.com/repos/neovim/neovim/pulls/${pr}/commits" \ - | jq -r '.[].html_url')") + local -a pr_commit_urls + while IFS= read -r pr_commit_url; do + pr_commit_urls+=("$pr_commit_url") + done < <(curl -Ssf "https://api.github.com/repos/neovim/neovim/pulls/${pr}/commits" \ + | jq -r '.[].html_url') echo "Found ${#pr_commit_urls[@]} commit(s)." diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 2bfa193a63..0521b7be53 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -220,7 +220,7 @@ set(gen_cflags ${gen_cflags} ${C_FLAGS_${build_type}_ARRAY} ${C_FLAGS_ARRAY}) function(get_preproc_output varname iname) if(MSVC) - set(${varname} /P /Fi${iname} PARENT_SCOPE) + set(${varname} /P /Fi${iname} /nologo PARENT_SCOPE) else() set(${varname} -E -o ${iname} PARENT_SCOPE) endif() @@ -573,7 +573,6 @@ set_target_properties( libnvim PROPERTIES POSITION_INDEPENDENT_CODE ON - OUTPUT_NAME nvim ) set_property( TARGET libnvim diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 7578f0fbc5..b345dcaccd 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -1402,7 +1402,7 @@ Integer nvim_buf_add_highlight(Buffer buffer, uint64_t ns_id = src2ns(&src_id); - if (!(0 <= line && line < buf->b_ml.ml_line_count)) { + if (!(line < buf->b_ml.ml_line_count)) { // safety check, we can't add marks outside the range return src_id; } diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h index 6677e248cf..ab31db39e9 100644 --- a/src/nvim/api/ui_events.in.h +++ b/src/nvim/api/ui_events.in.h @@ -115,6 +115,10 @@ void win_close(Integer grid) void msg_set_pos(Integer grid, Integer row, Boolean scrolled, String sep_char) FUNC_API_SINCE(6) FUNC_API_BRIDGE_IMPL FUNC_API_COMPOSITOR_IMPL; +void win_viewport(Integer grid, Window win, Integer topline, + Integer botline, Integer curline, Integer curcol) + FUNC_API_SINCE(7) FUNC_API_REMOTE_ONLY; + void popupmenu_show(Array items, Integer selected, Integer row, Integer col, Integer grid) FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index cf18f6b19a..7383a304f1 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -253,7 +253,7 @@ void nvim_feedkeys(String keys, String mode, Boolean escape_csi) if (execute) { int save_msg_scroll = msg_scroll; - /* Avoid a 1 second delay when the keys start Insert mode. */ + // Avoid a 1 second delay when the keys start Insert mode. msg_scroll = false; if (!dangerous) { ex_normal_busy++; diff --git a/src/nvim/ascii.h b/src/nvim/ascii.h index ff6840d690..2397af27cc 100644 --- a/src/nvim/ascii.h +++ b/src/nvim/ascii.h @@ -23,26 +23,26 @@ #define NL '\012' #define NL_STR "\012" #define FF '\014' -#define CAR '\015' /* CR is used by Mac OS X */ +#define CAR '\015' // CR is used by Mac OS X #define ESC '\033' #define ESC_STR "\033" #define DEL 0x7f #define DEL_STR "\177" #define CSI 0x9b // Control Sequence Introducer #define CSI_STR "\233" -#define DCS 0x90 /* Device Control String */ -#define STERM 0x9c /* String Terminator */ +#define DCS 0x90 // Device Control String +#define STERM 0x9c // String Terminator #define POUND 0xA3 -#define Ctrl_chr(x) (TOUPPER_ASC(x) ^ 0x40) /* '?' -> DEL, '@' -> ^@, etc. */ +#define Ctrl_chr(x) (TOUPPER_ASC(x) ^ 0x40) // '?' -> DEL, '@' -> ^@, etc. #define Meta(x) ((x) | 0x80) #define CTRL_F_STR "\006" #define CTRL_H_STR "\010" #define CTRL_V_STR "\026" -#define Ctrl_AT 0 /* @ */ +#define Ctrl_AT 0 // @ #define Ctrl_A 1 #define Ctrl_B 2 #define Ctrl_C 3 @@ -69,16 +69,14 @@ #define Ctrl_X 24 #define Ctrl_Y 25 #define Ctrl_Z 26 -/* CTRL- [ Left Square Bracket == ESC*/ -#define Ctrl_BSL 28 /* \ BackSLash */ -#define Ctrl_RSB 29 /* ] Right Square Bracket */ -#define Ctrl_HAT 30 /* ^ */ +// CTRL- [ Left Square Bracket == ESC +#define Ctrl_BSL 28 // \ BackSLash +#define Ctrl_RSB 29 // ] Right Square Bracket +#define Ctrl_HAT 30 // ^ #define Ctrl__ 31 -/* - * Character that separates dir names in a path. - */ +// Character that separates dir names in a path. #ifdef BACKSLASH_IN_FILENAME # define PATHSEP psepc # define PATHSEPSTR pseps @@ -168,4 +166,4 @@ static inline bool ascii_isspace(int c) return (c >= 9 && c <= 13) || c == ' '; } -#endif /* NVIM_ASCII_H */ +#endif // NVIM_ASCII_H diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index c2573cf942..24ba43676a 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -1750,6 +1750,7 @@ buf_T * buflist_new(char_u *ffname, char_u *sfname, linenr_T lnum, int flags) apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, false, curbuf); } if (aborting()) { // autocmds may abort script processing + xfree(ffname); return NULL; } if (buf == curbuf) { diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 3993f61a3d..2460159fc0 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -67,14 +67,14 @@ typedef struct { * off off w_botline not valid * on off not possible */ -#define VALID_WROW 0x01 /* w_wrow (window row) is valid */ -#define VALID_WCOL 0x02 /* w_wcol (window col) is valid */ -#define VALID_VIRTCOL 0x04 /* w_virtcol (file col) is valid */ -#define VALID_CHEIGHT 0x08 /* w_cline_height and w_cline_folded valid */ -#define VALID_CROW 0x10 /* w_cline_row is valid */ -#define VALID_BOTLINE 0x20 /* w_botine and w_empty_rows are valid */ -#define VALID_BOTLINE_AP 0x40 /* w_botine is approximated */ -#define VALID_TOPLINE 0x80 /* w_topline is valid (for cursor position) */ +#define VALID_WROW 0x01 // w_wrow (window row) is valid +#define VALID_WCOL 0x02 // w_wcol (window col) is valid +#define VALID_VIRTCOL 0x04 // w_virtcol (file col) is valid +#define VALID_CHEIGHT 0x08 // w_cline_height and w_cline_folded valid +#define VALID_CROW 0x10 // w_cline_row is valid +#define VALID_BOTLINE 0x20 // w_botine and w_empty_rows are valid +#define VALID_BOTLINE_AP 0x40 // w_botine is approximated +#define VALID_TOPLINE 0x80 // w_topline is valid (for cursor position) // flags for b_flags #define BF_RECOVERED 0x01 // buffer has been recovered @@ -92,7 +92,7 @@ typedef struct { #define BF_DUMMY 0x80 // dummy buffer, only used internally #define BF_PRESERVED 0x100 // ":preserve" was used -/* Mask to check for flags that prevent normal writing */ +// Mask to check for flags that prevent normal writing #define BF_WRITE_MASK (BF_NOTEDITED + BF_NEW + BF_READERR) typedef struct window_S win_T; @@ -160,11 +160,11 @@ typedef struct */ typedef struct { int wo_arab; -# define w_p_arab w_onebuf_opt.wo_arab /* 'arabic' */ +# define w_p_arab w_onebuf_opt.wo_arab // 'arabic' int wo_bri; # define w_p_bri w_onebuf_opt.wo_bri // 'breakindent' char_u *wo_briopt; -# define w_p_briopt w_onebuf_opt.wo_briopt /* 'breakindentopt' */ +# define w_p_briopt w_onebuf_opt.wo_briopt // 'breakindentopt' int wo_diff; # define w_p_diff w_onebuf_opt.wo_diff // 'diff' char_u *wo_fdc; @@ -172,78 +172,80 @@ typedef struct { char_u *wo_fdc_save; # define w_p_fdc_save w_onebuf_opt.wo_fdc_save // 'fdc' saved for diff mode int wo_fen; -# define w_p_fen w_onebuf_opt.wo_fen /* 'foldenable' */ +# define w_p_fen w_onebuf_opt.wo_fen // 'foldenable' int wo_fen_save; -# define w_p_fen_save w_onebuf_opt.wo_fen_save /* 'foldenable' saved for diff mode */ + // 'foldenable' saved for diff mode +# define w_p_fen_save w_onebuf_opt.wo_fen_save char_u *wo_fdi; -# define w_p_fdi w_onebuf_opt.wo_fdi /* 'foldignore' */ +# define w_p_fdi w_onebuf_opt.wo_fdi // 'foldignore' long wo_fdl; -# define w_p_fdl w_onebuf_opt.wo_fdl /* 'foldlevel' */ +# define w_p_fdl w_onebuf_opt.wo_fdl // 'foldlevel' int wo_fdl_save; -# define w_p_fdl_save w_onebuf_opt.wo_fdl_save /* 'foldlevel' state saved for diff mode */ + // 'foldlevel' state saved for diff mode +# define w_p_fdl_save w_onebuf_opt.wo_fdl_save char_u *wo_fdm; -# define w_p_fdm w_onebuf_opt.wo_fdm /* 'foldmethod' */ +# define w_p_fdm w_onebuf_opt.wo_fdm // 'foldmethod' char_u *wo_fdm_save; -# define w_p_fdm_save w_onebuf_opt.wo_fdm_save /* 'fdm' saved for diff mode */ +# define w_p_fdm_save w_onebuf_opt.wo_fdm_save // 'fdm' saved for diff mode long wo_fml; -# define w_p_fml w_onebuf_opt.wo_fml /* 'foldminlines' */ +# define w_p_fml w_onebuf_opt.wo_fml // 'foldminlines' long wo_fdn; -# define w_p_fdn w_onebuf_opt.wo_fdn /* 'foldnestmax' */ +# define w_p_fdn w_onebuf_opt.wo_fdn // 'foldnestmax' char_u *wo_fde; -# define w_p_fde w_onebuf_opt.wo_fde /* 'foldexpr' */ +# define w_p_fde w_onebuf_opt.wo_fde // 'foldexpr' char_u *wo_fdt; -# define w_p_fdt w_onebuf_opt.wo_fdt /* 'foldtext' */ +# define w_p_fdt w_onebuf_opt.wo_fdt // 'foldtext' char_u *wo_fmr; -# define w_p_fmr w_onebuf_opt.wo_fmr /* 'foldmarker' */ +# define w_p_fmr w_onebuf_opt.wo_fmr // 'foldmarker' int wo_lbr; -# define w_p_lbr w_onebuf_opt.wo_lbr /* 'linebreak' */ +# define w_p_lbr w_onebuf_opt.wo_lbr // 'linebreak' int wo_list; -#define w_p_list w_onebuf_opt.wo_list /* 'list' */ +#define w_p_list w_onebuf_opt.wo_list // 'list' int wo_nu; -#define w_p_nu w_onebuf_opt.wo_nu /* 'number' */ +#define w_p_nu w_onebuf_opt.wo_nu // 'number' int wo_rnu; -#define w_p_rnu w_onebuf_opt.wo_rnu /* 'relativenumber' */ +#define w_p_rnu w_onebuf_opt.wo_rnu // 'relativenumber' long wo_nuw; -# define w_p_nuw w_onebuf_opt.wo_nuw /* 'numberwidth' */ +# define w_p_nuw w_onebuf_opt.wo_nuw // 'numberwidth' int wo_wfh; -# define w_p_wfh w_onebuf_opt.wo_wfh /* 'winfixheight' */ +# define w_p_wfh w_onebuf_opt.wo_wfh // 'winfixheight' int wo_wfw; -# define w_p_wfw w_onebuf_opt.wo_wfw /* 'winfixwidth' */ +# define w_p_wfw w_onebuf_opt.wo_wfw // 'winfixwidth' int wo_pvw; -# define w_p_pvw w_onebuf_opt.wo_pvw /* 'previewwindow' */ +# define w_p_pvw w_onebuf_opt.wo_pvw // 'previewwindow' int wo_rl; -# define w_p_rl w_onebuf_opt.wo_rl /* 'rightleft' */ +# define w_p_rl w_onebuf_opt.wo_rl // 'rightleft' char_u *wo_rlc; -# define w_p_rlc w_onebuf_opt.wo_rlc /* 'rightleftcmd' */ +# define w_p_rlc w_onebuf_opt.wo_rlc // 'rightleftcmd' long wo_scr; -#define w_p_scr w_onebuf_opt.wo_scr /* 'scroll' */ +#define w_p_scr w_onebuf_opt.wo_scr // 'scroll' int wo_spell; -# define w_p_spell w_onebuf_opt.wo_spell /* 'spell' */ +# define w_p_spell w_onebuf_opt.wo_spell // 'spell' int wo_cuc; -# define w_p_cuc w_onebuf_opt.wo_cuc /* 'cursorcolumn' */ +# define w_p_cuc w_onebuf_opt.wo_cuc // 'cursorcolumn' int wo_cul; -# define w_p_cul w_onebuf_opt.wo_cul /* 'cursorline' */ +# define w_p_cul w_onebuf_opt.wo_cul // 'cursorline' char_u *wo_cc; -# define w_p_cc w_onebuf_opt.wo_cc /* 'colorcolumn' */ +# define w_p_cc w_onebuf_opt.wo_cc // 'colorcolumn' char_u *wo_stl; -#define w_p_stl w_onebuf_opt.wo_stl /* 'statusline' */ +#define w_p_stl w_onebuf_opt.wo_stl // 'statusline' int wo_scb; -# define w_p_scb w_onebuf_opt.wo_scb /* 'scrollbind' */ - int wo_diff_saved; /* options were saved for starting diff mode */ +# define w_p_scb w_onebuf_opt.wo_scb // 'scrollbind' + int wo_diff_saved; // options were saved for starting diff mode # define w_p_diff_saved w_onebuf_opt.wo_diff_saved - int wo_scb_save; /* 'scrollbind' saved for diff mode*/ + int wo_scb_save; // 'scrollbind' saved for diff mode # define w_p_scb_save w_onebuf_opt.wo_scb_save int wo_wrap; -#define w_p_wrap w_onebuf_opt.wo_wrap /* 'wrap' */ - int wo_wrap_save; /* 'wrap' state saved for diff mode*/ +#define w_p_wrap w_onebuf_opt.wo_wrap // 'wrap' + int wo_wrap_save; // 'wrap' state saved for diff mode # define w_p_wrap_save w_onebuf_opt.wo_wrap_save - char_u *wo_cocu; /* 'concealcursor' */ + char_u *wo_cocu; // 'concealcursor' # define w_p_cocu w_onebuf_opt.wo_cocu - long wo_cole; /* 'conceallevel' */ + long wo_cole; // 'conceallevel' # define w_p_cole w_onebuf_opt.wo_cole int wo_crb; -# define w_p_crb w_onebuf_opt.wo_crb /* 'cursorbind' */ - int wo_crb_save; /* 'cursorbind' state saved for diff mode*/ +# define w_p_crb w_onebuf_opt.wo_crb // 'cursorbind' + int wo_crb_save; // 'cursorbind' state saved for diff mode # define w_p_crb_save w_onebuf_opt.wo_crb_save char_u *wo_scl; # define w_p_scl w_onebuf_opt.wo_scl // 'signcolumn' @@ -271,14 +273,14 @@ typedef struct { * most-recently-used order. */ struct wininfo_S { - wininfo_T *wi_next; /* next entry or NULL for last entry */ - wininfo_T *wi_prev; /* previous entry or NULL for first entry */ - win_T *wi_win; /* pointer to window that did set wi_fpos */ - pos_T wi_fpos; /* last cursor position in the file */ - bool wi_optset; /* true when wi_opt has useful values */ - winopt_T wi_opt; /* local window options */ - bool wi_fold_manual; /* copy of w_fold_manual */ - garray_T wi_folds; /* clone of w_folds */ + wininfo_T *wi_next; // next entry or NULL for last entry + wininfo_T *wi_prev; // previous entry or NULL for first entry + win_T *wi_win; // pointer to window that did set wi_fpos + pos_T wi_fpos; // last cursor position in the file + bool wi_optset; // true when wi_opt has useful values + winopt_T wi_opt; // local window options + bool wi_fold_manual; // copy of w_fold_manual + garray_T wi_folds; // clone of w_folds }; /* @@ -288,8 +290,8 @@ struct wininfo_S { * TODO: move struct arglist to another header */ typedef struct arglist { - garray_T al_ga; /* growarray with the array of file names */ - int al_refcount; /* number of windows using this arglist */ + garray_T al_ga; // growarray with the array of file names + int al_refcount; // number of windows using this arglist int id; ///< id of this arglist } alist_T; @@ -301,8 +303,8 @@ typedef struct arglist { * TODO: move aentry_T to another header */ typedef struct argentry { - char_u *ae_fname; /* file name as specified */ - int ae_fnum; /* buffer number with expanded file name */ + char_u *ae_fname; // file name as specified + int ae_fnum; // buffer number with expanded file name } aentry_T; # define ALIST(win) (win)->w_alist @@ -318,21 +320,21 @@ typedef struct argentry { * Used for the typeahead buffer: typebuf. */ typedef struct { - char_u *tb_buf; /* buffer for typed characters */ - char_u *tb_noremap; /* mapping flags for characters in tb_buf[] */ - int tb_buflen; /* size of tb_buf[] */ - int tb_off; /* current position in tb_buf[] */ - int tb_len; /* number of valid bytes in tb_buf[] */ - int tb_maplen; /* nr of mapped bytes in tb_buf[] */ - int tb_silent; /* nr of silently mapped bytes in tb_buf[] */ - int tb_no_abbr_cnt; /* nr of bytes without abbrev. in tb_buf[] */ - int tb_change_cnt; /* nr of time tb_buf was changed; never zero */ + char_u *tb_buf; // buffer for typed characters + char_u *tb_noremap; // mapping flags for characters in tb_buf[] + int tb_buflen; // size of tb_buf[] + int tb_off; // current position in tb_buf[] + int tb_len; // number of valid bytes in tb_buf[] + int tb_maplen; // nr of mapped bytes in tb_buf[] + int tb_silent; // nr of silently mapped bytes in tb_buf[] + int tb_no_abbr_cnt; // nr of bytes without abbrev. in tb_buf[] + int tb_change_cnt; // nr of time tb_buf was changed; never zero } typebuf_T; -/* Struct to hold the saved typeahead for save_typeahead(). */ +// Struct to hold the saved typeahead for save_typeahead(). typedef struct { typebuf_T save_typebuf; - int typebuf_valid; /* TRUE when save_typebuf valid */ + int typebuf_valid; // TRUE when save_typebuf valid int old_char; int old_mod_mask; buffheader_T save_readbuf1; @@ -363,15 +365,15 @@ struct mapblock { */ struct stl_hlrec { char_u *start; - int userhl; /* 0: no HL, 1-9: User HL, < 0 for syn ID */ + int userhl; // 0: no HL, 1-9: User HL, < 0 for syn ID }; -/* values for b_syn_spell: what to do with toplevel text */ -#define SYNSPL_DEFAULT 0 /* spell check if @Spell not defined */ -#define SYNSPL_TOP 1 /* spell check toplevel text */ -#define SYNSPL_NOTOP 2 /* don't spell check toplevel text */ +// values for b_syn_spell: what to do with toplevel text +#define SYNSPL_DEFAULT 0 // spell check if @Spell not defined +#define SYNSPL_TOP 1 // spell check toplevel text +#define SYNSPL_NOTOP 2 // don't spell check toplevel text -/* avoid #ifdefs for when b_spell is not available */ +// avoid #ifdefs for when b_spell is not available # define B_SPELL(buf) ((buf)->b_spell) typedef struct qf_info_S qf_info_T; @@ -380,10 +382,10 @@ typedef struct qf_info_S qf_info_T; * Used for :syntime: timing of executing a syntax pattern. */ typedef struct { - proftime_T total; /* total time used */ - proftime_T slowest; /* time of slowest call */ - long count; /* nr of times used */ - long match; /* nr of times matched */ + proftime_T total; // total time used + proftime_T slowest; // time of slowest call + long count; // nr of times used + long match; // nr of times matched } syn_time_T; /* @@ -411,25 +413,23 @@ typedef struct { char_u *b_syn_linecont_pat; // line continuation pattern regprog_T *b_syn_linecont_prog; // line continuation program syn_time_T b_syn_linecont_time; - int b_syn_linecont_ic; /* ignore-case flag for above */ - int b_syn_topgrp; /* for ":syntax include" */ - int b_syn_conceal; /* auto-conceal for :syn cmds */ - int b_syn_folditems; /* number of patterns with the HL_FOLD - flag set */ - /* - * b_sst_array[] contains the state stack for a number of lines, for the - * start of that line (col == 0). This avoids having to recompute the - * syntax state too often. - * b_sst_array[] is allocated to hold the state for all displayed lines, - * and states for 1 out of about 20 other lines. - * b_sst_array pointer to an array of synstate_T - * b_sst_len number of entries in b_sst_array[] - * b_sst_first pointer to first used entry in b_sst_array[] or NULL - * b_sst_firstfree pointer to first free entry in b_sst_array[] or NULL - * b_sst_freecount number of free entries in b_sst_array[] - * b_sst_check_lnum entries after this lnum need to be checked for - * validity (MAXLNUM means no check needed) - */ + int b_syn_linecont_ic; // ignore-case flag for above + int b_syn_topgrp; // for ":syntax include" + int b_syn_conceal; // auto-conceal for :syn cmds + int b_syn_folditems; // number of patterns with the HL_FOLD + // flag set + // b_sst_array[] contains the state stack for a number of lines, for the + // start of that line (col == 0). This avoids having to recompute the + // syntax state too often. + // b_sst_array[] is allocated to hold the state for all displayed lines, + // and states for 1 out of about 20 other lines. + // b_sst_array pointer to an array of synstate_T + // b_sst_len number of entries in b_sst_array[] + // b_sst_first pointer to first used entry in b_sst_array[] or NULL + // b_sst_firstfree pointer to first free entry in b_sst_array[] or NULL + // b_sst_freecount number of free entries in b_sst_array[] + // b_sst_check_lnum entries after this lnum need to be checked for + // validity (MAXLNUM means no check needed) synstate_T *b_sst_array; int b_sst_len; synstate_T *b_sst_first; @@ -488,10 +488,10 @@ struct file_buffer { memline_T b_ml; // associated memline (also contains line count - buf_T *b_next; /* links in list of buffers */ + buf_T *b_next; // links in list of buffers buf_T *b_prev; - int b_nwindows; /* nr of windows open on this buffer */ + int b_nwindows; // nr of windows open on this buffer int b_flags; // various BF_ flags int b_locked; // Buffer is being closed or referenced, don't @@ -532,24 +532,23 @@ struct file_buffer { */ bool b_mod_set; /* true when there are changes since the last time the display was updated */ - linenr_T b_mod_top; /* topmost lnum that was changed */ - linenr_T b_mod_bot; /* lnum below last changed line, AFTER the - change */ - long b_mod_xlines; /* number of extra buffer lines inserted; - negative when lines were deleted */ - - wininfo_T *b_wininfo; /* list of last used info for each window */ + linenr_T b_mod_top; // topmost lnum that was changed + linenr_T b_mod_bot; // lnum below last changed line, AFTER the + // change + long b_mod_xlines; // number of extra buffer lines inserted; + // negative when lines were deleted + wininfo_T *b_wininfo; // list of last used info for each window - long b_mtime; /* last change time of original file */ - long b_mtime_read; /* last change time when reading */ - uint64_t b_orig_size; /* size of original file in bytes */ - int b_orig_mode; /* mode of original file */ + long b_mtime; // last change time of original file + long b_mtime_read; // last change time when reading + uint64_t b_orig_size; // size of original file in bytes + int b_orig_mode; // mode of original file - fmark_T b_namedm[NMARKS]; /* current named marks (mark.c) */ + fmark_T b_namedm[NMARKS]; // current named marks (mark.c) - /* These variables are set when VIsual_active becomes FALSE */ + // These variables are set when VIsual_active becomes FALSE visualinfo_T b_visual; - int b_visual_mode_eval; /* b_visual.vi_mode for visualmode() */ + int b_visual_mode_eval; // b_visual.vi_mode for visualmode() fmark_T b_last_cursor; // cursor position when last unloading this // buffer @@ -560,8 +559,8 @@ struct file_buffer { * the changelist contains old change positions */ fmark_T b_changelist[JUMPLISTSIZE]; - int b_changelistlen; /* number of active entries */ - bool b_new_change; /* set by u_savecommon() */ + int b_changelistlen; // number of active entries + bool b_new_change; // set by u_savecommon() /* * Character table, only used in charset.c for 'iskeyword' @@ -572,9 +571,9 @@ struct file_buffer { // Table used for mappings local to a buffer. mapblock_T *(b_maphash[MAX_MAPHASH]); - /* First abbreviation local to a buffer. */ + // First abbreviation local to a buffer. mapblock_T *b_first_abbr; - /* User commands local to the buffer. */ + // User commands local to the buffer. garray_T b_ucmds; /* * start and end of an operator, also used for '[ and '] @@ -583,31 +582,31 @@ struct file_buffer { pos_T b_op_start_orig; // used for Insstart_orig pos_T b_op_end; - bool b_marks_read; /* Have we read ShaDa marks yet? */ + bool b_marks_read; // Have we read ShaDa marks yet? /* * The following only used in undo.c. */ - u_header_T *b_u_oldhead; /* pointer to oldest header */ - u_header_T *b_u_newhead; /* pointer to newest header; may not be valid - if b_u_curhead is not NULL */ - u_header_T *b_u_curhead; /* pointer to current header */ - int b_u_numhead; /* current number of headers */ - bool b_u_synced; /* entry lists are synced */ - long b_u_seq_last; /* last used undo sequence number */ - long b_u_save_nr_last; /* counter for last file write */ - long b_u_seq_cur; /* hu_seq of header below which we are now */ - time_t b_u_time_cur; /* uh_time of header below which we are now */ - long b_u_save_nr_cur; /* file write nr after which we are now */ + u_header_T *b_u_oldhead; // pointer to oldest header + u_header_T *b_u_newhead; // pointer to newest header; may not be valid + // if b_u_curhead is not NULL + u_header_T *b_u_curhead; // pointer to current header + int b_u_numhead; // current number of headers + bool b_u_synced; // entry lists are synced + long b_u_seq_last; // last used undo sequence number + long b_u_save_nr_last; // counter for last file write + long b_u_seq_cur; // hu_seq of header below which we are now + time_t b_u_time_cur; // uh_time of header below which we are now + long b_u_save_nr_cur; // file write nr after which we are now /* * variables for "U" command in undo.c */ - char_u *b_u_line_ptr; /* saved line for "U" command */ - linenr_T b_u_line_lnum; /* line number of line in u_line */ - colnr_T b_u_line_colnr; /* optional column number */ + char_u *b_u_line_ptr; // saved line for "U" command + linenr_T b_u_line_lnum; // line number of line in u_line + colnr_T b_u_line_colnr; // optional column number - bool b_scanned; /* ^N/^P have scanned this buffer */ + bool b_scanned; // ^N/^P have scanned this buffer // flags for use of ":lmap" and IM control long b_p_iminsert; // input mode for insert @@ -617,10 +616,10 @@ struct file_buffer { #define B_IMODE_LMAP 1 // Input via langmap # define B_IMODE_LAST 1 - short b_kmap_state; /* using "lmap" mappings */ -# define KEYMAP_INIT 1 /* 'keymap' was set, call keymap_init() */ -# define KEYMAP_LOADED 2 /* 'keymap' mappings have been loaded */ - garray_T b_kmap_ga; /* the keymap table */ + int16_t b_kmap_state; // using "lmap" mappings +# define KEYMAP_INIT 1 // 'keymap' was set, call keymap_init() +# define KEYMAP_LOADED 2 // 'keymap' mappings have been loaded + garray_T b_kmap_ga; // the keymap table /* * Options local to a buffer. @@ -720,9 +719,9 @@ struct file_buffer { int b_p_udf; ///< 'undofile' char_u *b_p_lw; ///< 'lispwords' local value - /* end of buffer options */ + // end of buffer options - /* values set from b_p_cino */ + // values set from b_p_cino int b_ind_level; int b_ind_open_imag; int b_ind_no_brace; @@ -763,11 +762,11 @@ struct file_buffer { linenr_T b_no_eol_lnum; /* non-zero lnum when last line of next binary * write should not have an end-of-line */ - int b_start_eol; /* last line had eol when it was read */ - int b_start_ffc; /* first char of 'ff' when edit started */ - char_u *b_start_fenc; /* 'fileencoding' when edit started or NULL */ - int b_bad_char; /* "++bad=" argument when edit started or 0 */ - int b_start_bomb; /* 'bomb' when it was read */ + int b_start_eol; // last line had eol when it was read + int b_start_ffc; // first char of 'ff' when edit started + char_u *b_start_fenc; // 'fileencoding' when edit started or NULL + int b_bad_char; // "++bad=" argument when edit started or 0 + int b_start_bomb; // 'bomb' when it was read ScopeDictDictItem b_bufvar; ///< Variable for "b:" Dictionary. dict_T *b_vars; ///< b: scope dictionary. @@ -866,8 +865,8 @@ struct file_buffer { typedef struct diffblock_S diff_T; struct diffblock_S { diff_T *df_next; - linenr_T df_lnum[DB_COUNT]; /* line number in buffer */ - linenr_T df_count[DB_COUNT]; /* nr of inserted/changed lines */ + linenr_T df_lnum[DB_COUNT]; // line number in buffer + linenr_T df_count[DB_COUNT]; // nr of inserted/changed lines }; #define SNAP_HELP_IDX 0 @@ -915,11 +914,11 @@ struct tabpage_S { * wl_lnum and wl_lastlnum are invalid too. */ typedef struct w_line { - linenr_T wl_lnum; /* buffer line number for logical line */ - uint16_t wl_size; /* height in screen lines */ - char wl_valid; /* TRUE values are valid for text in buffer */ - char wl_folded; /* TRUE when this is a range of folded lines */ - linenr_T wl_lastlnum; /* last buffer line number for logical line */ + linenr_T wl_lnum; // buffer line number for logical line + uint16_t wl_size; // height in screen lines + char wl_valid; // TRUE values are valid for text in buffer + char wl_folded; // TRUE when this is a range of folded lines + linenr_T wl_lastlnum; // last buffer line number for logical line } wline_T; /* @@ -942,9 +941,9 @@ struct frame_S { win_T *fr_win; // window that fills this frame }; -#define FR_LEAF 0 /* frame is a leaf */ -#define FR_ROW 1 /* frame with a row of windows */ -#define FR_COL 2 /* frame with a column of windows */ +#define FR_LEAF 0 // frame is a leaf +#define FR_ROW 1 // frame with a row of windows +#define FR_COL 2 // frame with a column of windows /* * Struct used for highlighting 'hlsearch' matches, matches defined by @@ -1145,16 +1144,16 @@ struct window_S { top of the window */ char w_topline_was_set; /* flag set to TRUE when topline is set, e.g. by winrestview() */ - int w_topfill; /* number of filler lines above w_topline */ - int w_old_topfill; /* w_topfill at last redraw */ - bool w_botfill; /* true when filler lines are actually - below w_topline (at end of file) */ - bool w_old_botfill; /* w_botfill at last redraw */ - colnr_T w_leftcol; /* window column number of the left most - character in the window; used when - 'wrap' is off */ - colnr_T w_skipcol; /* starting column when a single line - doesn't fit in the window */ + int w_topfill; // number of filler lines above w_topline + int w_old_topfill; // w_topfill at last redraw + bool w_botfill; // true when filler lines are actually + // below w_topline (at end of file) + bool w_old_botfill; // w_botfill at last redraw + colnr_T w_leftcol; // window column number of the left most + // character in the window; used when + // 'wrap' is off + colnr_T w_skipcol; // starting column when a single line + // doesn't fit in the window // // Layout of the window in the screen. @@ -1188,16 +1187,18 @@ struct window_S { int w_valid; pos_T w_valid_cursor; /* last known position of w_cursor, used to adjust w_valid */ - colnr_T w_valid_leftcol; /* last known w_leftcol */ + colnr_T w_valid_leftcol; // last known w_leftcol + + bool w_viewport_invalid; /* * w_cline_height is the number of physical lines taken by the buffer line * that the cursor is on. We use this to avoid extra calls to plines(). */ - int w_cline_height; /* current size of cursor line */ - bool w_cline_folded; /* cursor line is folded */ + int w_cline_height; // current size of cursor line + bool w_cline_folded; // cursor line is folded - int w_cline_row; /* starting row of the cursor line */ + int w_cline_row; // starting row of the cursor line colnr_T w_virtcol; // column number of the cursor in the // buffer line, as opposed to the column @@ -1211,7 +1212,7 @@ struct window_S { * This is related to positions in the window, not in the display or * buffer, thus w_wrow is relative to w_winrow. */ - int w_wrow, w_wcol; /* cursor position in window */ + int w_wrow, w_wcol; // cursor position in window linenr_T w_botline; // number of the line below the bottom of // the window @@ -1229,42 +1230,42 @@ struct window_S { * what is currently displayed. wl_valid is reset to indicated this. * This is used for efficient redrawing. */ - int w_lines_valid; /* number of valid entries */ + int w_lines_valid; // number of valid entries wline_T *w_lines; - garray_T w_folds; /* array of nested folds */ - bool w_fold_manual; /* when true: some folds are opened/closed - manually */ - bool w_foldinvalid; /* when true: folding needs to be - recomputed */ - int w_nrwidth; /* width of 'number' and 'relativenumber' - column being used */ + garray_T w_folds; // array of nested folds + bool w_fold_manual; // when true: some folds are opened/closed + // manually + bool w_foldinvalid; // when true: folding needs to be + // recomputed + int w_nrwidth; // width of 'number' and 'relativenumber' + // column being used /* * === end of cached values === */ - int w_redr_type; /* type of redraw to be performed on win */ - int w_upd_rows; /* number of window lines to update when - w_redr_type is REDRAW_TOP */ - linenr_T w_redraw_top; /* when != 0: first line needing redraw */ - linenr_T w_redraw_bot; /* when != 0: last line needing redraw */ - int w_redr_status; /* if TRUE status line must be redrawn */ + int w_redr_type; // type of redraw to be performed on win + int w_upd_rows; // number of window lines to update when + // w_redr_type is REDRAW_TOP + linenr_T w_redraw_top; // when != 0: first line needing redraw + linenr_T w_redraw_bot; // when != 0: last line needing redraw + int w_redr_status; // if TRUE status line must be redrawn - /* remember what is shown in the ruler for this window (if 'ruler' set) */ - pos_T w_ru_cursor; /* cursor position shown in ruler */ - colnr_T w_ru_virtcol; /* virtcol shown in ruler */ - linenr_T w_ru_topline; /* topline shown in ruler */ - linenr_T w_ru_line_count; /* line count used for ruler */ - int w_ru_topfill; /* topfill shown in ruler */ - char w_ru_empty; /* TRUE if ruler shows 0-1 (empty line) */ + // remember what is shown in the ruler for this window (if 'ruler' set) + pos_T w_ru_cursor; // cursor position shown in ruler + colnr_T w_ru_virtcol; // virtcol shown in ruler + linenr_T w_ru_topline; // topline shown in ruler + linenr_T w_ru_line_count; // line count used for ruler + int w_ru_topfill; // topfill shown in ruler + char w_ru_empty; // TRUE if ruler shows 0-1 (empty line) - int w_alt_fnum; /* alternate file (for # and CTRL-^) */ + int w_alt_fnum; // alternate file (for # and CTRL-^) - alist_T *w_alist; /* pointer to arglist for this window */ - int w_arg_idx; /* current index in argument list (can be - out of range!) */ - int w_arg_idx_invalid; /* editing another file than w_arg_idx */ + alist_T *w_alist; // pointer to arglist for this window + int w_arg_idx; // current index in argument list (can be + // out of range!) + int w_arg_idx_invalid; // editing another file than w_arg_idx char_u *w_localdir; /* absolute path of local directory or NULL */ @@ -1302,20 +1303,20 @@ struct window_S { * a new line after setting the w_pcmark. If not, then we revert to * using the previous w_pcmark. */ - pos_T w_pcmark; /* previous context mark */ - pos_T w_prev_pcmark; /* previous w_pcmark */ + pos_T w_pcmark; // previous context mark + pos_T w_prev_pcmark; // previous w_pcmark /* * the jumplist contains old cursor positions */ xfmark_T w_jumplist[JUMPLISTSIZE]; - int w_jumplistlen; /* number of active entries */ - int w_jumplistidx; /* current position */ + int w_jumplistlen; // number of active entries + int w_jumplistidx; // current position - int w_changelistidx; /* current position in b_changelist */ + int w_changelistidx; // current position in b_changelist - matchitem_T *w_match_head; /* head of match list */ - int w_next_match_id; /* next match ID */ + matchitem_T *w_match_head; // head of match list + int w_next_match_id; // next match ID /* * the tagstack grows from 0 upwards: @@ -1323,9 +1324,9 @@ struct window_S { * entry 1: newer * entry 2: newest */ - taggy_T w_tagstack[TAGSTACKSIZE]; /* the tag stack */ - int w_tagstackidx; /* idx just below active entry */ - int w_tagstacklen; /* number of tags on stack */ + taggy_T w_tagstack[TAGSTACKSIZE]; // the tag stack + int w_tagstackidx; // idx just below active entry + int w_tagstacklen; // number of tags on stack ScreenGrid w_grid; // the grid specific to the window bool w_pos_changed; // true if window position changed @@ -1343,13 +1344,11 @@ struct window_S { linenr_T w_nrwidth_line_count; /* line count when ml_nrwidth_width * was computed. */ - int w_nrwidth_width; /* nr of chars to print line count. */ + int w_nrwidth_width; // nr of chars to print line count. - qf_info_T *w_llist; /* Location list for this window */ - /* - * Location list reference used in the location list window. - * In a non-location list window, w_llist_ref is NULL. - */ + qf_info_T *w_llist; // Location list for this window + // Location list reference used in the location list window. + // In a non-location list window, w_llist_ref is NULL. qf_info_T *w_llist_ref; }; diff --git a/src/nvim/cursor_shape.h b/src/nvim/cursor_shape.h index 2c466603f0..a23fa6836d 100644 --- a/src/nvim/cursor_shape.h +++ b/src/nvim/cursor_shape.h @@ -33,11 +33,11 @@ SHAPE_HOR = 1, ///< horizontal bar cursor SHAPE_VER = 2 ///< vertical bar cursor } CursorShape; -#define MSHAPE_NUMBERED 1000 /* offset for shapes identified by number */ -#define MSHAPE_HIDE 1 /* hide mouse pointer */ +#define MSHAPE_NUMBERED 1000 // offset for shapes identified by number +#define MSHAPE_HIDE 1 // hide mouse pointer -#define SHAPE_MOUSE 1 /* used for mouse pointer shape */ -#define SHAPE_CURSOR 2 /* used for text cursor shape */ +#define SHAPE_MOUSE 1 // used for mouse pointer shape +#define SHAPE_CURSOR 2 // used for text cursor shape typedef struct cursor_entry { char *full_name; ///< mode description diff --git a/src/nvim/diff.c b/src/nvim/diff.c index f8b7592d0b..3de5fc49bd 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -648,8 +648,8 @@ void diff_redraw(bool dofold) foldUpdateAll(wp); } - /* A change may have made filler lines invalid, need to take care - * of that for other windows. */ + // A change may have made filler lines invalid, need to take care + // of that for other windows. int n = diff_check(wp, wp->w_topline); if (((wp != curwin) && (wp->w_topfill > 0)) || (n > 0)) { diff --git a/src/nvim/edit.c b/src/nvim/edit.c index c7867f22c5..a291ed0401 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -184,7 +184,7 @@ static bool compl_used_match; // Selected one of the matches. static int compl_was_interrupted = FALSE; /* didn't finish finding completions. */ -static int compl_restarting = FALSE; /* don't insert match */ +static bool compl_restarting = false; // don't insert match // When the first completion is done "compl_started" is set. When it's // false the word to be completed must be located. @@ -197,7 +197,7 @@ static int compl_matches = 0; static char_u *compl_pattern = NULL; static int compl_direction = FORWARD; static int compl_shows_dir = FORWARD; -static int compl_pending = 0; /* > 1 for postponed CTRL-N */ +static int compl_pending = 0; // > 1 for postponed CTRL-N static pos_T compl_startpos; static colnr_T compl_col = 0; /* column where the text starts * that is being completed */ @@ -249,30 +249,30 @@ typedef struct insert_state { #define BACKSPACE_WORD_NOT_SPACE 3 #define BACKSPACE_LINE 4 -static size_t spell_bad_len = 0; /* length of located bad word */ +static size_t spell_bad_len = 0; // length of located bad word -static colnr_T Insstart_textlen; /* length of line when insert started */ -static colnr_T Insstart_blank_vcol; /* vcol for first inserted blank */ -static bool update_Insstart_orig = true; /* set Insstart_orig to Insstart */ +static colnr_T Insstart_textlen; // length of line when insert started +static colnr_T Insstart_blank_vcol; // vcol for first inserted blank +static bool update_Insstart_orig = true; // set Insstart_orig to Insstart -static char_u *last_insert = NULL; /* the text of the previous insert, - K_SPECIAL and CSI are escaped */ -static int last_insert_skip; /* nr of chars in front of previous insert */ -static int new_insert_skip; /* nr of chars in front of current insert */ -static int did_restart_edit; /* "restart_edit" when calling edit() */ +static char_u *last_insert = NULL; // the text of the previous insert, + // K_SPECIAL and CSI are escaped +static int last_insert_skip; // nr of chars in front of previous insert +static int new_insert_skip; // nr of chars in front of current insert +static int did_restart_edit; // "restart_edit" when calling edit() static bool can_cindent; // may do cindenting on this line -static int old_indent = 0; /* for ^^D command in insert mode */ +static int old_indent = 0; // for ^^D command in insert mode -static int revins_on; /* reverse insert mode on */ -static int revins_chars; /* how much to skip after edit */ -static int revins_legal; /* was the last char 'legal'? */ -static int revins_scol; /* start column of revins session */ +static int revins_on; // reverse insert mode on +static int revins_chars; // how much to skip after edit +static int revins_legal; // was the last char 'legal'? +static int revins_scol; // start column of revins session -static int ins_need_undo; /* call u_save() before inserting a - char. Set when edit() is called. - after that arrow_used is used. */ +static bool ins_need_undo; // call u_save() before inserting a + // char. Set when edit() is called. + // after that arrow_used is used. static bool did_add_space = false; // auto_format() added an extra space // under the cursor @@ -464,8 +464,8 @@ static void insert_enter(InsertState *s) change_warning(s->i == 0 ? 0 : s->i + 1); } - ui_cursor_shape(); /* may show different cursor shape */ - do_digraph(-1); /* clear digraphs */ + ui_cursor_shape(); // may show different cursor shape + do_digraph(-1); // clear digraphs // Get the current length of the redo buffer, those characters have to be // skipped if we want to get to the inserted characters. @@ -1420,9 +1420,8 @@ bool edit(int cmdchar, bool startln, long count) * Only redraw when there are no characters available. This speeds up * inserting sequences of characters (e.g., for CTRL-R). */ -static void -ins_redraw ( - int ready /* not busy with something */ +static void ins_redraw( + bool ready // not busy with something ) { bool conceal_cursor_moved = false; @@ -1503,7 +1502,7 @@ ins_redraw ( } showruler(false); setcursor(); - emsg_on_display = FALSE; /* may remove error message now */ + emsg_on_display = false; // may remove error message now } /* @@ -1512,24 +1511,25 @@ ins_redraw ( static void ins_ctrl_v(void) { int c; - int did_putchar = FALSE; + bool did_putchar = false; - /* may need to redraw when no more chars available now */ - ins_redraw(FALSE); + // may need to redraw when no more chars available now + ins_redraw(false); if (redrawing() && !char_avail()) { - edit_putchar('^', TRUE); - did_putchar = TRUE; + edit_putchar('^', true); + did_putchar = true; } AppendToRedobuff(CTRL_V_STR); add_to_showcmd_c(Ctrl_V); c = get_literal(); - if (did_putchar) - /* when the line fits in 'columns' the '^' is at the start of the next - * line and will not removed by the redraw */ + if (did_putchar) { + // when the line fits in 'columns' the '^' is at the start of the next + // line and will not removed by the redraw edit_unputchar(); + } clear_showcmd(); insert_special(c, true, true); revins_chars++; @@ -1541,16 +1541,16 @@ static void ins_ctrl_v(void) * Used while handling CTRL-K, CTRL-V, etc. in Insert mode. */ static int pc_status; -#define PC_STATUS_UNSET 0 /* pc_bytes was not set */ -#define PC_STATUS_RIGHT 1 /* right halve of double-wide char */ -#define PC_STATUS_LEFT 2 /* left halve of double-wide char */ -#define PC_STATUS_SET 3 /* pc_bytes was filled */ -static char_u pc_bytes[MB_MAXBYTES + 1]; /* saved bytes */ +#define PC_STATUS_UNSET 0 // pc_bytes was not set +#define PC_STATUS_RIGHT 1 // right halve of double-wide char +#define PC_STATUS_LEFT 2 // left halve of double-wide char +#define PC_STATUS_SET 3 // pc_bytes was filled +static char_u pc_bytes[MB_MAXBYTES + 1]; // saved bytes static int pc_attr; static int pc_row; static int pc_col; -void edit_putchar(int c, int highlight) +void edit_putchar(int c, bool highlight) { int attr; @@ -1583,7 +1583,7 @@ void edit_putchar(int c, int highlight) } } - /* save the character to be able to put it back */ + // save the character to be able to put it back if (pc_status == PC_STATUS_UNSET) { grid_getbytes(&curwin->w_grid, pc_row, pc_col, pc_bytes, &pc_attr); pc_status = PC_STATUS_SET; @@ -1706,29 +1706,29 @@ change_indent ( int type, int amount, int round, - int replaced, /* replaced character, put on replace stack */ - int call_changed_bytes /* call changed_bytes() */ + int replaced, // replaced character, put on replace stack + int call_changed_bytes // call changed_bytes() ) { int vcol; int last_vcol; - int insstart_less; /* reduction for Insstart.col */ + int insstart_less; // reduction for Insstart.col int new_cursor_col; int i; char_u *ptr; int save_p_list; int start_col; colnr_T vc; - colnr_T orig_col = 0; /* init for GCC */ - char_u *new_line, *orig_line = NULL; /* init for GCC */ + colnr_T orig_col = 0; // init for GCC + char_u *new_line, *orig_line = NULL; // init for GCC - /* VREPLACE mode needs to know what the line was like before changing */ + // VREPLACE mode needs to know what the line was like before changing if (State & VREPLACE_FLAG) { - orig_line = vim_strsave(get_cursor_line_ptr()); /* Deal with NULL below */ + orig_line = vim_strsave(get_cursor_line_ptr()); // Deal with NULL below orig_col = curwin->w_cursor.col; } - /* for the following tricks we don't want list mode */ + // for the following tricks we don't want list mode save_p_list = curwin->w_p_list; curwin->w_p_list = FALSE; vc = getvcol_nolist(&curwin->w_cursor); @@ -1741,7 +1741,7 @@ change_indent ( */ start_col = curwin->w_cursor.col; - /* determine offset from first non-blank */ + // determine offset from first non-blank new_cursor_col = curwin->w_cursor.col; beginline(BL_WHITE); new_cursor_col -= curwin->w_cursor.col; @@ -1755,8 +1755,9 @@ change_indent ( if (new_cursor_col < 0) vcol = get_indent() - vcol; - if (new_cursor_col > 0) /* can't fix replace stack */ + if (new_cursor_col > 0) { // can't fix replace stack start_col = -1; + } /* * Set the new indent. The cursor will be put on the first non-blank. @@ -1766,9 +1767,10 @@ change_indent ( else { int save_State = State; - /* Avoid being called recursively. */ - if (State & VREPLACE_FLAG) + // Avoid being called recursively. + if (State & VREPLACE_FLAG) { State = INSERT; + } shift_line(type == INDENT_DEC, round, 1, call_changed_bytes); State = save_State; } @@ -1871,8 +1873,8 @@ change_indent ( */ if (REPLACE_NORMAL(State) && start_col >= 0) { while (start_col > (int)curwin->w_cursor.col) { - replace_join(0); /* remove a NUL from the replace stack */ - --start_col; + replace_join(0); // remove a NUL from the replace stack + start_col--; } while (start_col < (int)curwin->w_cursor.col || replaced) { replace_push(NUL); @@ -1890,10 +1892,10 @@ change_indent ( * put it back again the way we wanted it. */ if (State & VREPLACE_FLAG) { - /* Save new line */ + // Save new line new_line = vim_strsave(get_cursor_line_ptr()); - /* We only put back the new line up to the cursor */ + // We only put back the new line up to the cursor new_line[curwin->w_cursor.col] = NUL; int new_col = curwin->w_cursor.col; @@ -1903,10 +1905,10 @@ change_indent ( curbuf_splice_pending++; - /* Backspace from cursor to start of line */ + // Backspace from cursor to start of line backspace_until_column(0); - /* Insert new stuff into line again */ + // Insert new stuff into line again ins_bytes(new_line); xfree(new_line); @@ -1932,10 +1934,11 @@ void truncate_spaces(char_u *line) { int i; - /* find start of trailing white space */ + // find start of trailing white space for (i = (int)STRLEN(line) - 1; i >= 0 && ascii_iswhite(line[i]); i--) { - if (State & REPLACE_FLAG) - replace_join(0); /* remove a NUL from the replace stack */ + if (State & REPLACE_FLAG) { + replace_join(0); // remove a NUL from the replace stack + } } line[i + 1] = NUL; } @@ -2004,7 +2007,7 @@ static void ins_ctrl_x(void) compl_cont_status |= CONT_INTRPT; else compl_cont_status = 0; - /* We're not sure which CTRL-X mode it will be yet */ + // We're not sure which CTRL-X mode it will be yet ctrl_x_mode = CTRL_X_NOT_DEFINED_YET; edit_submode = (char_u *)_(CTRL_X_MSG(ctrl_x_mode)); edit_submode_pre = NULL; @@ -2153,8 +2156,8 @@ int ins_compl_add_infercase(char_u *str_arg, int len, bool icase, char_u *fname, { char_u *str = str_arg; int i, c; - int actual_len; /* Take multi-byte characters */ - int actual_compl_length; /* into account. */ + int actual_len; // Take multi-byte characters + int actual_compl_length; // into account. int min_len; bool has_lower = false; bool was_letter = false; @@ -2174,16 +2177,15 @@ int ins_compl_add_infercase(char_u *str_arg, int len, bool icase, char_u *fname, } else actual_len = len; - /* Find actual length of original text. */ - if (has_mbyte) { + // Find actual length of original text. + { const char_u *p = compl_orig_text; actual_compl_length = 0; while (*p != NUL) { MB_PTR_ADV(p); actual_compl_length++; } - } else - actual_compl_length = compl_length; + } /* "actual_len" may be smaller than "actual_compl_length" when using * thesaurus, only use the minimum when comparing. */ @@ -2353,7 +2355,7 @@ static int ins_compl_add(char_u *const str, int len, } while (match != NULL && match != compl_first_match); } - /* Remove any popup menu before changing the list of matches. */ + // Remove any popup menu before changing the list of matches. ins_compl_del_pum(); /* @@ -2409,16 +2411,18 @@ static int ins_compl_add(char_u *const str, int len, else if (dir == FORWARD) { match->cp_next = compl_curr_match->cp_next; match->cp_prev = compl_curr_match; - } else { /* BACKWARD */ + } else { // BACKWARD match->cp_next = compl_curr_match; match->cp_prev = compl_curr_match->cp_prev; } - if (match->cp_next) + if (match->cp_next) { match->cp_next->cp_prev = match; - if (match->cp_prev) + } + if (match->cp_prev) { match->cp_prev->cp_next = match; - else /* if there's nothing before, it is the first match */ + } else { // if there's nothing before, it is the first match compl_first_match = match; + } compl_curr_match = match; /* @@ -2459,7 +2463,7 @@ static void ins_compl_longest_match(compl_T *match) int had_match; if (compl_leader == NULL) { - /* First match, use it as a whole. */ + // First match, use it as a whole. compl_leader = vim_strsave(match->cp_str); had_match = (curwin->w_cursor.col > compl_col); ins_compl_delete(); @@ -2472,7 +2476,7 @@ static void ins_compl_longest_match(compl_T *match) ins_compl_delete(); compl_used_match = false; } else { - /* Reduce the text if this match differs from compl_leader. */ + // Reduce the text if this match differs from compl_leader. p = compl_leader; s = match->cp_str; while (*p != NUL) { @@ -2489,7 +2493,7 @@ static void ins_compl_longest_match(compl_T *match) } if (*p != NUL) { - /* Leader was shortened, need to change the inserted text. */ + // Leader was shortened, need to change the inserted text. *p = NUL; had_match = (curwin->w_cursor.col > compl_col); ins_compl_delete(); @@ -2539,7 +2543,7 @@ static int ins_compl_make_cyclic(void) * Find the end of the list. */ match = compl_first_match; - /* there's always an entry for the compl_orig_text, it doesn't count. */ + // there's always an entry for the compl_orig_text, it doesn't count. while (match->cp_next != NULL && match->cp_next != compl_first_match) { match = match->cp_next; ++count; @@ -2586,7 +2590,7 @@ void set_completion(colnr_T startcol, list_T *list) startcol = curwin->w_cursor.col; compl_col = startcol; compl_length = (int)curwin->w_cursor.col - (int)startcol; - /* compl_pattern doesn't need to be set */ + // compl_pattern doesn't need to be set compl_orig_text = vim_strnsave(get_cursor_line_ptr() + compl_col, compl_length); if (p_ic) { @@ -2719,10 +2723,10 @@ void ins_compl_show_pum(void) if (!pum_wanted() || !pum_enough_matches()) return; - /* Dirty hard-coded hack: remove any matchparen highlighting. */ + // Dirty hard-coded hack: remove any matchparen highlighting. do_cmdline_cmd("if exists('g:loaded_matchparen')|3match none|endif"); - /* Update the screen before drawing the popup menu over it. */ + // Update the screen before drawing the popup menu over it. update_screen(0); if (compl_match_array == NULL) { @@ -2813,17 +2817,19 @@ void ins_compl_show_pum(void) compl = compl->cp_next; } while (compl != NULL && compl != compl_first_match); - if (!shown_match_ok) /* no displayed match at all */ + if (!shown_match_ok) { // no displayed match at all cur = -1; + } } else { - /* popup menu already exists, only need to find the current item.*/ - for (i = 0; i < compl_match_arraysize; ++i) + // popup menu already exists, only need to find the current item. + for (i = 0; i < compl_match_arraysize; i++) { if (compl_match_array[i].pum_text == compl_shown_match->cp_str || compl_match_array[i].pum_text == compl_shown_match->cp_text[CPT_ABBR]) { cur = i; break; } + } } // In Replace mode when a $ is displayed at the end of the line only @@ -2843,8 +2849,8 @@ void ins_compl_show_pum(void) } } -#define DICT_FIRST (1) /* use just first element in "dict" */ -#define DICT_EXACT (2) /* "dict" is the exact name of a file */ +#define DICT_FIRST (1) // use just first element in "dict" +#define DICT_EXACT (2) // "dict" is the exact name of a file /* * Add any identifiers that match the given pattern in the list of dictionary @@ -2854,8 +2860,8 @@ static void ins_compl_dictionaries ( char_u *dict_start, char_u *pat, - int flags, /* DICT_FIRST and/or DICT_EXACT */ - int thesaurus /* Thesaurus completion */ + int flags, // DICT_FIRST and/or DICT_EXACT + int thesaurus // Thesaurus completion ) { char_u *dict = dict_start; @@ -2877,9 +2883,9 @@ ins_compl_dictionaries ( } buf = xmalloc(LSIZE); - regmatch.regprog = NULL; /* so that we can goto theend */ + regmatch.regprog = NULL; // so that we can goto theend - /* If 'infercase' is set, don't use 'smartcase' here */ + // If 'infercase' is set, don't use 'smartcase' here save_p_scs = p_scs; if (curbuf->b_p_inf) p_scs = FALSE; @@ -2902,10 +2908,10 @@ ins_compl_dictionaries ( goto theend; } - /* ignore case depends on 'ignorecase', 'smartcase' and "pat" */ + // ignore case depends on 'ignorecase', 'smartcase' and "pat" regmatch.rm_ic = ignorecase(pat); while (*dict != NUL && !got_int && !compl_interrupted) { - /* copy one dictionary file name into buf */ + // copy one dictionary file name into buf if (flags == DICT_EXACT) { count = 1; files = &dict; @@ -2930,7 +2936,7 @@ ins_compl_dictionaries ( else ptr = pat; spell_dump_compl(ptr, regmatch.rm_ic, &dir, 0); - } else if (count > 0) { /* avoid warning for using "files" uninit */ + } else if (count > 0) { // avoid warning for using "files" uninit ins_compl_files(count, files, thesaurus, flags, ®match, buf, &dir); if (flags != DICT_EXACT) @@ -2996,20 +3002,18 @@ static void ins_compl_files(int count, char_u **files, int thesaurus, int flags, break; wstart = ptr; - /* Find end of the word. */ - if (has_mbyte) - /* Japanese words may have characters in - * different classes, only separate words - * with single-byte non-word characters. */ - while (*ptr != NUL) { - int l = (*mb_ptr2len)(ptr); - - if (l < 2 && !vim_iswordc(*ptr)) - break; - ptr += l; + // Find end of the word. + // Japanese words may have characters in + // different classes, only separate words + // with single-byte non-word characters. + while (*ptr != NUL) { + const int l = utfc_ptr2len(ptr); + + if (l < 2 && !vim_iswordc(*ptr)) { + break; } - else - ptr = find_word_end(ptr); + ptr += l; + } // Add the word. Skip the regexp match. if (wstart != regmatch->startp[0]) { @@ -3018,15 +3022,17 @@ static void ins_compl_files(int count, char_u **files, int thesaurus, int flags, } } } - if (add_r == OK) - /* if dir was BACKWARD then honor it just once */ + if (add_r == OK) { + // if dir was BACKWARD then honor it just once *dir = FORWARD; - else if (add_r == FAIL) + } else if (add_r == FAIL) { break; - /* avoid expensive call to vim_regexec() when at end - * of line */ - if (*ptr == '\n' || got_int) + } + // avoid expensive call to vim_regexec() when at end + // of line + if (*ptr == '\n' || got_int) { break; + } } line_breakcheck(); ins_compl_check_keys(50, false); @@ -3273,9 +3279,10 @@ static int ins_compl_bs(void) xfree(compl_leader); compl_leader = vim_strnsave(line + compl_col, (int)(p - line) - compl_col); ins_compl_new_leader(); - if (compl_shown_match != NULL) - /* Make sure current match is not a hidden item. */ + if (compl_shown_match != NULL) { + // Make sure current match is not a hidden item. compl_curr_match = compl_shown_match; + } return NUL; } @@ -3319,7 +3326,7 @@ static void ins_compl_new_leader(void) compl_enter_selects = !compl_used_match; - /* Show the popup menu with a different set of matches. */ + // Show the popup menu with a different set of matches. ins_compl_show_pum(); /* Don't let Enter select the original text when there is no popup menu. @@ -3362,9 +3369,10 @@ static void ins_compl_addleader(int c) ins_char(c); } - /* If we didn't complete finding matches we must search again. */ - if (ins_compl_need_restart()) + // If we didn't complete finding matches we must search again. + if (ins_compl_need_restart()) { ins_compl_restart(); + } xfree(compl_leader); compl_leader = vim_strnsave(get_cursor_line_ptr() + compl_col, @@ -3420,9 +3428,9 @@ static void ins_compl_addfrommatch(void) compl_T *cp; assert(compl_shown_match != NULL); p = compl_shown_match->cp_str; - if ((int)STRLEN(p) <= len) { /* the match is too short */ - /* When still at the original match use the first entry that matches - * the leader. */ + if ((int)STRLEN(p) <= len) { // the match is too short + // When still at the original match use the first entry that matches + // the leader. if (compl_shown_match->cp_flags & CP_ORIGINAL_TEXT) { p = NULL; for (cp = compl_shown_match->cp_next; cp != NULL @@ -3462,14 +3470,14 @@ static bool ins_compl_prep(int c) if (c != Ctrl_R && vim_is_ctrl_x_key(c)) edit_submode_extra = NULL; - /* Ignore end of Select mode mapping and mouse scroll buttons. */ + // Ignore end of Select mode mapping and mouse scroll buttons. if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP || c == K_MOUSELEFT || c == K_MOUSERIGHT || c == K_EVENT || c == K_COMMAND) { return retval; } - /* Set "compl_get_longest" when finding the first matches. */ + // Set "compl_get_longest" when finding the first matches. if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET || (ctrl_x_mode == CTRL_X_NORMAL && !compl_started)) { compl_get_longest = (strstr((char *)p_cot, "longest") != NULL); @@ -3502,7 +3510,7 @@ static bool ins_compl_prep(int c) ctrl_x_mode = CTRL_X_DICTIONARY; break; case Ctrl_R: - /* Simply allow ^R to happen without affecting ^X mode */ + // Simply allow ^R to happen without affecting ^X mode break; case Ctrl_T: ctrl_x_mode = CTRL_X_THESAURUS; @@ -3516,9 +3524,9 @@ static bool ins_compl_prep(int c) case 's': case Ctrl_S: ctrl_x_mode = CTRL_X_SPELL; - ++emsg_off; /* Avoid getting the E756 error twice. */ + emsg_off++; // Avoid getting the E756 error twice. spell_back_to_badword(); - --emsg_off; + emsg_off--; break; case Ctrl_RSB: ctrl_x_mode = CTRL_X_TAGS; @@ -3617,10 +3625,10 @@ static bool ins_compl_prep(int c) // When completing whole lines: fix indent for 'cindent'. // Otherwise, break line if it's too long. if (compl_cont_mode == CTRL_X_WHOLE_LINE) { - /* re-indent the current line */ + // re-indent the current line if (want_cindent) { do_c_expr_indent(); - want_cindent = FALSE; /* don't do it again */ + want_cindent = false; // don't do it again } } else { int prev_col = curwin->w_cursor.col; @@ -3724,10 +3732,11 @@ static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg) char_u *ptr = ptr_arg; if (ptr == NULL) { - if (compl_leader != NULL) + if (compl_leader != NULL) { ptr = compl_leader; - else - return; /* nothing to do */ + } else { + return; // nothing to do + } } if (compl_orig_text != NULL) { p = compl_orig_text; @@ -3756,9 +3765,10 @@ static buf_T *ins_compl_next_buf(buf_T *buf, int flag) { static win_T *wp; - if (flag == 'w') { /* just windows */ - if (buf == curbuf) /* first call for this flag/expansion */ + if (flag == 'w') { // just windows + if (buf == curbuf) { // first call for this flag/expansion wp = curwin; + } assert(wp); while ((wp = (wp->w_next != NULL ? wp->w_next : firstwin)) != curwin && wp->w_buffer->b_scanned) @@ -3836,7 +3846,7 @@ expand_by_function( EMSG(_(e_complwin)); goto theend; } - curwin->w_cursor = pos; /* restore the cursor position */ + curwin->w_cursor = pos; // restore the cursor position validate_cursor(); if (!equalpos(curwin->w_cursor, pos)) { EMSG(_(e_compldel)); @@ -4474,8 +4484,7 @@ ins_compl_next ( int num_matches = -1; int todo = count; compl_T *found_compl = NULL; - int found_end = FALSE; - int advance; + bool found_end = false; const bool started = compl_started; /* When user complete function return -1 for findstart which is next @@ -4511,17 +4520,17 @@ ins_compl_next ( if (allow_get_expansion && insert_match && (!(compl_get_longest || compl_restarting) || compl_used_match)) - /* Delete old text to be replaced */ + // Delete old text to be replaced ins_compl_delete(); - /* When finding the longest common text we stick at the original text, - * don't let CTRL-N or CTRL-P move to the first match. */ - advance = count != 1 || !allow_get_expansion || !compl_get_longest; + // When finding the longest common text we stick at the original text, + // don't let CTRL-N or CTRL-P move to the first match. + bool advance = count != 1 || !allow_get_expansion || !compl_get_longest; - /* When restarting the search don't insert the first match either. */ + // When restarting the search don't insert the first match either. if (compl_restarting) { - advance = FALSE; - compl_restarting = FALSE; + advance = false; + compl_restarting = false; } /* Repeat this for when <PageUp> or <PageDown> is typed. But don't wrap @@ -4555,10 +4564,10 @@ ins_compl_next ( ++compl_pending; } - /* Find matches. */ + // Find matches. num_matches = ins_compl_get_exp(&compl_startpos); - /* handle any pending completions */ + // handle any pending completions while (compl_pending != 0 && compl_direction == compl_shows_dir && advance) { if (compl_pending > 0 && compl_shown_match->cp_next != NULL) { @@ -4571,7 +4580,7 @@ ins_compl_next ( } else break; } - found_end = FALSE; + found_end = false; } if ((compl_shown_match->cp_flags & CP_ORIGINAL_TEXT) == 0 && compl_leader != NULL @@ -4583,17 +4592,17 @@ ins_compl_next ( found_compl = compl_shown_match; } - /* Stop at the end of the list when we found a usable match. */ + // Stop at the end of the list when we found a usable match. if (found_end) { if (found_compl != NULL) { compl_shown_match = found_compl; break; } - todo = 1; /* use first usable match after wrapping around */ + todo = 1; // use first usable match after wrapping around } } - /* Insert the text of the new completion, or the compl_leader. */ + // Insert the text of the new completion, or the compl_leader. if (compl_no_insert && !started) { ins_bytes(compl_orig_text + ins_compl_len()); compl_used_match = false; @@ -4687,9 +4696,10 @@ void ins_compl_check_keys(int frequency, int in_compl_func) return; } - /* Only do this at regular intervals */ - if (++count < frequency) + // Only do this at regular intervals + if (++count < frequency) { return; + } count = 0; /* Check for a typed key. Do use mappings, otherwise vim_is_ctrl_x_key() @@ -4697,7 +4707,7 @@ void ins_compl_check_keys(int frequency, int in_compl_func) int c = vpeekc_any(); if (c != NUL) { if (vim_is_ctrl_x_key(c) && c != Ctrl_X && c != Ctrl_R) { - c = safe_vgetc(); /* Eat the character */ + c = safe_vgetc(); // Eat the character compl_shows_dir = ins_compl_key2dir(c); (void)ins_compl_next(false, ins_compl_key2count(c), c != K_UP && c != K_DOWN, in_compl_func); @@ -4766,8 +4776,9 @@ static int ins_compl_key2count(int c) if (ins_compl_pum_key(c) && c != K_UP && c != K_DOWN) { h = pum_get_height(); - if (h > 3) - h -= 2; /* keep some context */ + if (h > 3) { + h -= 2; // keep some context + } return h; } return 1; @@ -4805,8 +4816,8 @@ static bool ins_compl_use_match(int c) static int ins_complete(int c, bool enable_pum) { char_u *line; - int startcol = 0; /* column where searched text starts */ - colnr_T curs_col; /* cursor column */ + int startcol = 0; // column where searched text starts + colnr_T curs_col; // cursor column int n; int save_w_wrow; int save_w_leftcol; @@ -4818,7 +4829,7 @@ static int ins_complete(int c, bool enable_pum) insert_match = ins_compl_use_match(c); if (!compl_started) { - /* First time we hit ^N or ^P (in a row, I mean) */ + // First time we hit ^N or ^P (in a row, I mean) did_ai = false; did_si = false; @@ -4856,7 +4867,7 @@ static int ins_complete(int c, bool enable_pum) compl_col = (colnr_T)getwhitecols(line); compl_startpos.col = compl_col; compl_startpos.lnum = curwin->w_cursor.lnum; - compl_cont_status &= ~CONT_SOL; /* clear SOL if present */ + compl_cont_status &= ~CONT_SOL; // clear SOL if present } else { /* S_IPOS was set when we inserted a word that was at the * beginning of the line, which means that we'll go to SOL @@ -4888,7 +4899,7 @@ static int ins_complete(int c, bool enable_pum) } else compl_cont_status &= CONT_LOCAL; - if (!(compl_cont_status & CONT_ADDING)) { /* normal expansion */ + if (!(compl_cont_status & CONT_ADDING)) { // normal expansion compl_cont_mode = ctrl_x_mode; if (ctrl_x_mode != CTRL_X_NORMAL) { // Remove LOCAL if ctrl_x_mode != CTRL_X_NORMAL @@ -4917,7 +4928,7 @@ static int ins_complete(int c, bool enable_pum) } else if (compl_cont_status & CONT_ADDING) { char_u *prefix = (char_u *)"\\<"; - /* we need up to 2 extra chars for the prefix */ + // we need up to 2 extra chars for the prefix compl_pattern = xmalloc(quote_meta(NULL, line + compl_col, compl_length) + 2); if (!vim_iswordp(line + compl_col) @@ -4969,14 +4980,16 @@ static int ins_complete(int c, bool enable_pum) } else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) { compl_col = (colnr_T)getwhitecols(line); compl_length = (int)curs_col - (int)compl_col; - if (compl_length < 0) /* cursor in indent: empty pattern */ + if (compl_length < 0) { // cursor in indent: empty pattern compl_length = 0; - if (p_ic) + } + if (p_ic) { compl_pattern = str_foldcase(line + compl_col, compl_length, NULL, 0); - else + } else { compl_pattern = vim_strnsave(line + compl_col, compl_length); + } } else if (ctrl_x_mode == CTRL_X_FILES) { - /* Go back to just before the first filename character. */ + // Go back to just before the first filename character. if (startcol > 0) { char_u *p = line + startcol; @@ -5048,7 +5061,7 @@ static int ins_complete(int c, bool enable_pum) EMSG(_(e_complwin)); return FAIL; } - curwin->w_cursor = pos; /* restore the cursor position */ + curwin->w_cursor = pos; // restore the cursor position validate_cursor(); if (!equalpos(curwin->w_cursor, pos)) { EMSG(_(e_compldel)); @@ -5100,7 +5113,7 @@ static int ins_complete(int c, bool enable_pum) spell_expand_check_cap(compl_col); compl_length = (int)curs_col - compl_col; } - /* Need to obtain "line" again, it may have become invalid. */ + // Need to obtain "line" again, it may have become invalid. line = ml_get(curwin->w_cursor.lnum); compl_pattern = vim_strnsave(line + compl_col, compl_length); } else { @@ -5111,7 +5124,7 @@ static int ins_complete(int c, bool enable_pum) if (compl_cont_status & CONT_ADDING) { edit_submode_pre = (char_u *)_(" Adding"); if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) { - /* Insert a new line, keep indentation but ignore 'comments' */ + // Insert a new line, keep indentation but ignore 'comments' char_u *old = curbuf->b_p_com; curbuf->b_p_com = (char_u *)""; @@ -5136,7 +5149,7 @@ static int ins_complete(int c, bool enable_pum) * the redo buffer. */ ins_compl_fixRedoBufForLeader(NULL); - /* Always add completion for the original text. */ + // Always add completion for the original text. xfree(compl_orig_text); compl_orig_text = vim_strnsave(line + compl_col, compl_length); if (p_ic) { @@ -5173,8 +5186,9 @@ static int ins_complete(int c, bool enable_pum) n = ins_compl_next(true, ins_compl_key2count(c), insert_match, false); - if (n > 1) /* all matches have been found */ + if (n > 1) { // all matches have been found compl_matches = n; + } compl_curr_match = compl_shown_match; compl_direction = compl_shows_dir; @@ -5185,7 +5199,7 @@ static int ins_complete(int c, bool enable_pum) got_int = FALSE; } - /* we found no match if the list has only the "compl_orig_text"-entry */ + // we found no match if the list has only the "compl_orig_text"-entry if (compl_first_match == compl_first_match->cp_next) { edit_submode_extra = (compl_cont_status & CONT_ADDING) && compl_length > 1 @@ -5221,7 +5235,7 @@ static int ins_complete(int c, bool enable_pum) edit_submode_extra = (char_u *)_("The only match"); edit_submode_highl = HLF_COUNT; } else { - /* Update completion sequence number when needed. */ + // Update completion sequence number when needed. if (compl_curr_match->cp_number == -1) { int number = 0; compl_T *match; @@ -5244,24 +5258,27 @@ static int ins_complete(int c, bool enable_pum) match != NULL && match->cp_number == -1; match = match->cp_next) match->cp_number = ++number; - } else { /* BACKWARD */ - /* search forwards (upwards) for the first valid (!= -1) - * number. This should normally succeed already at the - * first loop cycle, so it's fast! */ - for (match = compl_curr_match->cp_next; match != NULL - && match != compl_first_match; - match = match->cp_next) + } else { // BACKWARD + // search forwards (upwards) for the first valid (!= -1) + // number. This should normally succeed already at the + // first loop cycle, so it's fast! + for (match = compl_curr_match->cp_next; + match != NULL && match != compl_first_match; + match = match->cp_next) { if (match->cp_number != -1) { number = match->cp_number; break; } - if (match != NULL) - /* go down and assign all numbers which are not - * assigned yet */ - for (match = match->cp_prev; match - && match->cp_number == -1; - match = match->cp_prev) + } + if (match != NULL) { + // go down and assign all numbers which are not + // assigned yet + for (match = match->cp_prev; + match && match->cp_number == -1; + match = match->cp_prev) { match->cp_number = ++number; + } + } } } @@ -5320,7 +5337,7 @@ static int ins_complete(int c, bool enable_pum) */ static unsigned quote_meta(char_u *dest, char_u *src, int len) { - unsigned m = (unsigned)len + 1; /* one extra for the NUL */ + unsigned m = (unsigned)len + 1; // one extra for the NUL for (; --len >= 0; src++) { switch (*src) { @@ -5332,8 +5349,9 @@ static unsigned quote_meta(char_u *dest, char_u *src, int len) break; FALLTHROUGH; case '~': - if (!p_magic) /* quote these only if magic is set */ + if (!p_magic) { // quote these only if magic is set break; + } FALLTHROUGH; case '\\': if (ctrl_x_mode == CTRL_X_DICTIONARY @@ -5343,24 +5361,24 @@ static unsigned quote_meta(char_u *dest, char_u *src, int len) case '^': // currently it's not needed. case '$': m++; - if (dest != NULL) + if (dest != NULL) { *dest++ = '\\'; + } break; } - if (dest != NULL) + if (dest != NULL) { *dest++ = *src; - /* Copy remaining bytes of a multibyte character. */ - if (has_mbyte) { - int i, mb_len; - - mb_len = (*mb_ptr2len)(src) - 1; - if (mb_len > 0 && len >= mb_len) - for (i = 0; i < mb_len; ++i) { - --len; - ++src; - if (dest != NULL) - *dest++ = *src; + } + // Copy remaining bytes of a multibyte character. + const int mb_len = utfc_ptr2len(src) - 1; + if (mb_len > 0 && len >= mb_len) { + for (int i = 0; i < mb_len; i++) { + len--; + src++; + if (dest != NULL) { + *dest++ = *src; } + } } } if (dest != NULL) @@ -5387,7 +5405,7 @@ int get_literal(void) if (got_int) return Ctrl_C; - ++no_mapping; /* don't map the next key hits */ + no_mapping++; // don't map the next key hits cc = 0; i = 0; for (;; ) { @@ -5425,20 +5443,23 @@ int get_literal(void) if (cc > 255 && unicode == 0 ) - cc = 255; /* limit range to 0-255 */ + cc = 255; // limit range to 0-255 nc = 0; - if (hex) { /* hex: up to two chars */ - if (i >= 2) + if (hex) { // hex: up to two chars + if (i >= 2) { break; - } else if (unicode) { /* Unicode: up to four or eight chars */ - if ((unicode == 'u' && i >= 4) || (unicode == 'U' && i >= 8)) + } + } else if (unicode) { // Unicode: up to four or eight chars + if ((unicode == 'u' && i >= 4) || (unicode == 'U' && i >= 8)) { break; - } else if (i >= 3) /* decimal or octal: up to three chars */ + } + } else if (i >= 3) { // decimal or octal: up to three chars break; + } } - if (i == 0) { /* no number entered */ - if (nc == K_ZERO) { /* NUL is stored as NL */ + if (i == 0) { // no number entered + if (nc == K_ZERO) { // NUL is stored as NL cc = '\n'; nc = 0; } else { @@ -5454,7 +5475,7 @@ int get_literal(void) --no_mapping; if (nc) vungetc(nc); - got_int = FALSE; /* CTRL-C typed after CTRL-V is not an interrupt */ + got_int = false; // CTRL-C typed after CTRL-V is not an interrupt return cc; } @@ -5517,11 +5538,10 @@ static void insert_special(int c, int allow_modmask, int ctrlv) * INSCHAR_DO_COM - format comments * INSCHAR_COM_LIST - format comments with num list or 2nd line indent */ -void -insertchar ( - int c, /* character to insert or NUL */ - int flags, /* INSCHAR_FORMAT, etc. */ - int second_indent /* indent for second line if >= 0 */ +void insertchar( + int c, // character to insert or NUL + int flags, // INSCHAR_FORMAT, etc. + int second_indent // indent for second line if >= 0 ) { int textwidth; @@ -5557,27 +5577,27 @@ insertchar ( || ((!has_format_option(FO_INS_LONG) || Insstart_textlen <= (colnr_T)textwidth) && (!fo_ins_blank - || Insstart_blank_vcol <= (colnr_T)textwidth - )))))) { - /* Format with 'formatexpr' when it's set. Use internal formatting - * when 'formatexpr' isn't set or it returns non-zero. */ - int do_internal = TRUE; + || Insstart_blank_vcol <= (colnr_T)textwidth)))))) { + // Format with 'formatexpr' when it's set. Use internal formatting + // when 'formatexpr' isn't set or it returns non-zero. + bool do_internal = true; colnr_T virtcol = get_nolist_virtcol() + char2cells(c != NUL ? c : gchar_cursor()); if (*curbuf->b_p_fex != NUL && (flags & INSCHAR_NO_FEX) == 0 && (force_format || virtcol > (colnr_T)textwidth)) { do_internal = (fex_format(curwin->w_cursor.lnum, 1L, c) != 0); - /* It may be required to save for undo again, e.g. when setline() - * was called. */ - ins_need_undo = TRUE; + // It may be required to save for undo again, e.g. when setline() + // was called. + ins_need_undo = true; } if (do_internal) internal_format(textwidth, second_indent, flags, c == NUL, c); } - if (c == NUL) /* only formatting was wanted */ + if (c == NUL) { // only formatting was wanted return; + } // Check whether this character should end a comment. if (did_ai && c == end_comment_pending) { @@ -5681,8 +5701,8 @@ insertchar ( buf[i++] = c; } - do_digraph(-1); /* clear digraphs */ - do_digraph(buf[i-1]); /* may be the start of a digraph */ + do_digraph(-1); // clear digraphs + do_digraph(buf[i-1]); // may be the start of a digraph buf[i] = NUL; ins_str(buf); if (flags & INSCHAR_CTRLV) { @@ -5725,7 +5745,7 @@ internal_format ( int second_indent, int flags, int format_only, - int c /* character to be inserted (can be NUL) */ + int c // character to be inserted (can be NUL) ) { int cc; @@ -5736,7 +5756,7 @@ internal_format ( int fo_white_par = has_format_option(FO_WHITE_PAR); int first_line = TRUE; colnr_T leader_len; - int no_leader = FALSE; + bool no_leader = false; int do_comments = (flags & INSCHAR_DO_COM); int has_lbr = curwin->w_p_lbr; @@ -5761,10 +5781,10 @@ internal_format ( * Repeat breaking lines, until the current line is not too long. */ while (!got_int) { - int startcol; /* Cursor column at entry */ - int wantcol; /* column at textwidth border */ - int foundcol; /* column for start of spaces */ - int end_foundcol = 0; /* column for start of word */ + int startcol; // Cursor column at entry + int wantcol; // column at textwidth border + int foundcol; // column for start of spaces + int end_foundcol = 0; // column for start of word colnr_T len; colnr_T virtcol; int orig_col = 0; @@ -5777,33 +5797,37 @@ internal_format ( if (virtcol <= (colnr_T)textwidth) break; - if (no_leader) - do_comments = FALSE; - else if (!(flags & INSCHAR_FORMAT) - && has_format_option(FO_WRAP_COMS)) - do_comments = TRUE; + if (no_leader) { + do_comments = false; + } else if (!(flags & INSCHAR_FORMAT) + && has_format_option(FO_WRAP_COMS)) { + do_comments = true; + } - /* Don't break until after the comment leader */ - if (do_comments) - leader_len = get_leader_len(get_cursor_line_ptr(), NULL, FALSE, TRUE); - else + // Don't break until after the comment leader + if (do_comments) { + leader_len = get_leader_len(get_cursor_line_ptr(), NULL, false, true); + } else { leader_len = 0; + } - /* If the line doesn't start with a comment leader, then don't - * start one in a following broken line. Avoids that a %word - * moved to the start of the next line causes all following lines - * to start with %. */ - if (leader_len == 0) - no_leader = TRUE; + // If the line doesn't start with a comment leader, then don't + // start one in a following broken line. Avoids that a %word + // moved to the start of the next line causes all following lines + // to start with %. + if (leader_len == 0) { + no_leader = true; + } if (!(flags & INSCHAR_FORMAT) && leader_len == 0 - && !has_format_option(FO_WRAP)) - + && !has_format_option(FO_WRAP)) { break; - if ((startcol = curwin->w_cursor.col) == 0) + } + if ((startcol = curwin->w_cursor.col) == 0) { break; + } - /* find column of textwidth border */ + // find column of textwidth border coladvance((colnr_T)textwidth); wantcol = curwin->w_cursor.col; @@ -5823,7 +5847,7 @@ internal_format ( else cc = gchar_cursor(); if (WHITECHAR(cc)) { - /* remember position of blank just before text */ + // remember position of blank just before text end_col = curwin->w_cursor.col; // find start of sequence of blanks @@ -5854,18 +5878,21 @@ internal_format ( } if (has_format_option(FO_ONE_LETTER)) { - /* do not break after one-letter words */ - if (curwin->w_cursor.col == 0) - break; /* one-letter word at begin */ - /* do not break "#a b" when 'tw' is 2 */ - if (curwin->w_cursor.col <= leader_len) + // do not break after one-letter words + if (curwin->w_cursor.col == 0) { + break; // one-letter word at begin + } + // do not break "#a b" when 'tw' is 2 + if (curwin->w_cursor.col <= leader_len) { break; + } col = curwin->w_cursor.col; dec_cursor(); cc = gchar_cursor(); - if (WHITECHAR(cc)) - continue; /* one-letter, continue */ + if (WHITECHAR(cc)) { + continue; // one-letter, continue + } curwin->w_cursor.col = col; } @@ -5876,14 +5903,15 @@ internal_format ( if (curwin->w_cursor.col <= (colnr_T)wantcol) break; } else if (cc >= 0x100 && fo_multibyte) { - /* Break after or before a multi-byte character. */ + // Break after or before a multi-byte character. if (curwin->w_cursor.col != startcol) { - /* Don't break until after the comment leader */ - if (curwin->w_cursor.col < leader_len) + // Don't break until after the comment leader + if (curwin->w_cursor.col < leader_len) { break; + } col = curwin->w_cursor.col; inc_cursor(); - /* Don't change end_foundcol if already set. */ + // Don't change end_foundcol if already set. if (foundcol != curwin->w_cursor.col) { foundcol = curwin->w_cursor.col; end_foundcol = foundcol; @@ -5901,11 +5929,13 @@ internal_format ( dec_cursor(); cc = gchar_cursor(); - if (WHITECHAR(cc)) - continue; /* break with space */ - /* Don't break until after the comment leader */ - if (curwin->w_cursor.col < leader_len) + if (WHITECHAR(cc)) { + continue; // break with space + } + // Don't break until after the comment leader + if (curwin->w_cursor.col < leader_len) { break; + } curwin->w_cursor.col = col; @@ -5919,12 +5949,12 @@ internal_format ( dec_cursor(); } - if (foundcol == 0) { /* no spaces, cannot break line */ + if (foundcol == 0) { // no spaces, cannot break line curwin->w_cursor.col = startcol; break; } - /* Going to break the line, remove any "$" now. */ + // Going to break the line, remove any "$" now. undisplay_dollar(); /* @@ -5932,10 +5962,11 @@ internal_format ( * stack functions. VREPLACE does not use this, and backspaces * over the text instead. */ - if (State & VREPLACE_FLAG) - orig_col = startcol; /* Will start backspacing from here */ - else + if (State & VREPLACE_FLAG) { + orig_col = startcol; // Will start backspacing from here + } else { replace_offset = startcol - end_foundcol; + } /* * adjust startcol for spaces that will be deleted and @@ -5958,13 +5989,15 @@ internal_format ( curwin->w_cursor.col = orig_col; saved_text[startcol] = NUL; - /* Backspace over characters that will move to the next line */ - if (!fo_white_par) + // Backspace over characters that will move to the next line + if (!fo_white_par) { backspace_until_column(foundcol); + } } else { - /* put cursor after pos. to break line */ - if (!fo_white_par) + // put cursor after pos. to break line + if (!fo_white_par) { curwin->w_cursor.col = foundcol; + } } /* @@ -5982,32 +6015,29 @@ internal_format ( replace_offset = 0; if (first_line) { if (!(flags & INSCHAR_COM_LIST)) { - /* - * This section is for auto-wrap of numeric lists. When not - * in insert mode (i.e. format_lines()), the INSCHAR_COM_LIST - * flag will be set and open_line() will handle it (as seen - * above). The code here (and in get_number_indent()) will - * recognize comments if needed... - */ - if (second_indent < 0 && has_format_option(FO_Q_NUMBER)) - second_indent = - get_number_indent(curwin->w_cursor.lnum - 1); + // This section is for auto-wrap of numeric lists. When not + // in insert mode (i.e. format_lines()), the INSCHAR_COM_LIST + // flag will be set and open_line() will handle it (as seen + // above). The code here (and in get_number_indent()) will + // recognize comments if needed... + if (second_indent < 0 && has_format_option(FO_Q_NUMBER)) { + second_indent = get_number_indent(curwin->w_cursor.lnum - 1); + } if (second_indent >= 0) { - if (State & VREPLACE_FLAG) - change_indent(INDENT_SET, second_indent, - FALSE, NUL, TRUE); - else if (leader_len > 0 && second_indent - leader_len > 0) { - int i; + if (State & VREPLACE_FLAG) { + change_indent(INDENT_SET, second_indent, false, NUL, true); + } else if (leader_len > 0 && second_indent - leader_len > 0) { int padding = second_indent - leader_len; - /* We started at the first_line of a numbered list - * that has a comment. the open_line() function has - * inserted the proper comment leader and positioned - * the cursor at the end of the split line. Now we - * add the additional whitespace needed after the - * comment leader for the numbered list. */ - for (i = 0; i < padding; i++) + // We started at the first_line of a numbered list + // that has a comment. the open_line() function has + // inserted the proper comment leader and positioned + // the cursor at the end of the split line. Now we + // add the additional whitespace needed after the + // comment leader for the numbered list. + for (int i = 0; i < padding; i++) { ins_str((char_u *)" "); + } changed_bytes(curwin->w_cursor.lnum, leader_len); } else { (void)set_indent(second_indent, SIN_CHANGED); @@ -6045,8 +6075,9 @@ internal_format ( line_breakcheck(); } - if (save_char != NUL) /* put back space after cursor */ + if (save_char != NUL) { // put back space after cursor pchar_cursor(save_char); + } curwin->w_p_lbr = has_lbr; @@ -6063,10 +6094,9 @@ internal_format ( * The caller must have saved the cursor line for undo, following ones will be * saved here. */ -void -auto_format ( - int trailblank, /* when TRUE also format with trailing blank */ - int prev_line /* may start in previous line */ +void auto_format( + bool trailblank, // when true also format with trailing blank + bool prev_line // may start in previous line ) { pos_T pos; @@ -6085,11 +6115,11 @@ auto_format ( // may remove added space check_auto_format(false); - /* Don't format in Insert mode when the cursor is on a trailing blank, the - * user might insert normal text next. Also skip formatting when "1" is - * in 'formatoptions' and there is a single character before the cursor. - * Otherwise the line would be broken and when typing another non-white - * next they are not joined back together. */ + // Don't format in Insert mode when the cursor is on a trailing blank, the + // user might insert normal text next. Also skip formatting when "1" is + // in 'formatoptions' and there is a single character before the cursor. + // Otherwise the line would be broken and when typing another non-white + // next they are not joined back together. wasatend = (pos.col == (colnr_T)STRLEN(old)); if (*old != NUL && !trailblank && wasatend) { dec_cursor(); @@ -6132,16 +6162,16 @@ auto_format ( saved_cursor.lnum = 0; if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) { - /* "cannot happen" */ + // "cannot happen" curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count; coladvance((colnr_T)MAXCOL); } else check_cursor_col(); - /* Insert mode: If the cursor is now after the end of the line while it - * previously wasn't, the line was broken. Because of the rule above we - * need to add a space when 'w' is in 'formatoptions' to keep a paragraph - * formatted. */ + // Insert mode: If the cursor is now after the end of the line while it + // previously wasn't, the line was broken. Because of the rule above we + // need to add a space when 'w' is in 'formatoptions' to keep a paragraph + // formatted. if (!wasatend && has_format_option(FO_WHITE_PAR)) { new = get_cursor_line_ptr(); len = (colnr_T)STRLEN(new); @@ -6200,17 +6230,16 @@ static void check_auto_format( * if invalid value, use 0. * Set default to window width (maximum 79) for "gq" operator. */ -int -comp_textwidth ( - int ff /* force formatting (for "gq" command) */ +int comp_textwidth( + int ff // force formatting (for "gq" command) ) { int textwidth; textwidth = curbuf->b_p_tw; if (textwidth == 0 && curbuf->b_p_wm) { - /* The width is the window width minus 'wrapmargin' minus all the - * things that add to the margin. */ + // The width is the window width minus 'wrapmargin' minus all the + // things that add to the margin. textwidth = curwin->w_width_inner - curbuf->b_p_wm; if (cmdwin_type != 0) { textwidth -= 1; @@ -6251,7 +6280,9 @@ static void redo_literal(int c) // start_arrow() is called when an arrow key is used in insert mode. // For undo/redo it resembles hitting the <ESC> key. -static void start_arrow(pos_T *end_insert_pos /* can be NULL */) +static void start_arrow( + pos_T *end_insert_pos // can be NULL +) { start_arrow_common(end_insert_pos, true); } @@ -6324,8 +6355,8 @@ int stop_arrow(void) Insstart_textlen = (colnr_T)linetabsize(get_cursor_line_ptr()); if (u_save_cursor() == OK) { - arrow_used = FALSE; - ins_need_undo = FALSE; + arrow_used = false; + ins_need_undo = false; } ai_col = 0; if (State & VREPLACE_FLAG) { @@ -6336,11 +6367,12 @@ int stop_arrow(void) AppendToRedobuff("1i"); // Pretend we start an insertion. new_insert_skip = 2; } else if (ins_need_undo) { - if (u_save_cursor() == OK) - ins_need_undo = FALSE; + if (u_save_cursor() == OK) { + ins_need_undo = false; + } } - /* Always open fold at the cursor line when inserting something. */ + // Always open fold at the cursor line when inserting something. foldOpenCursor(); return arrow_used || ins_need_undo ? FAIL : OK; @@ -6354,15 +6386,15 @@ int stop_arrow(void) static void stop_insert ( pos_T *end_insert_pos, - int esc, /* called by ins_esc() */ - int nomove /* <c-\><c-o>, don't move cursor */ + int esc, // called by ins_esc() + int nomove // <c-\><c-o>, don't move cursor ) { int cc; char_u *ptr; stop_redo_ins(); - replace_flush(); /* abandon replace stack */ + replace_flush(); // abandon replace stack /* * Save the inserted text for later redo with ^@ and CTRL-A. @@ -6379,16 +6411,16 @@ stop_insert ( xfree(ptr); if (!arrow_used && end_insert_pos != NULL) { - /* Auto-format now. It may seem strange to do this when stopping an - * insertion (or moving the cursor), but it's required when appending - * a line and having it end in a space. But only do it when something - * was actually inserted, otherwise undo won't work. */ + // Auto-format now. It may seem strange to do this when stopping an + // insertion (or moving the cursor), but it's required when appending + // a line and having it end in a space. But only do it when something + // was actually inserted, otherwise undo won't work. if (!ins_need_undo && has_format_option(FO_AUTO)) { pos_T tpos = curwin->w_cursor; - /* When the cursor is at the end of the line after a space the - * formatting will move it to the following word. Avoid that by - * moving the cursor onto the space. */ + // When the cursor is at the end of the line after a space the + // formatting will move it to the following word. Avoid that by + // moving the cursor onto the space. cc = 'x'; if (curwin->w_cursor.col > 0 && gchar_cursor() == NUL) { dec_cursor(); @@ -6414,11 +6446,11 @@ stop_insert ( // If a space was inserted for auto-formatting, remove it now. check_auto_format(true); - /* If we just did an auto-indent, remove the white space from the end - * of the line, and put the cursor back. - * Do this when ESC was used or moving the cursor up/down. - * Check for the old position still being valid, just in case the text - * got changed unexpectedly. */ + // If we just did an auto-indent, remove the white space from the end + // of the line, and put the cursor back. + // Do this when ESC was used or moving the cursor up/down. + // Check for the old position still being valid, just in case the text + // got changed unexpectedly. if (!nomove && did_ai && (esc || (vim_strchr(p_cpo, CPO_INDENT) == NULL && curwin->w_cursor.lnum != end_insert_pos->lnum)) @@ -6426,7 +6458,7 @@ stop_insert ( pos_T tpos = curwin->w_cursor; curwin->w_cursor = *end_insert_pos; - check_cursor_col(); /* make sure it is not past the line */ + check_cursor_col(); // make sure it is not past the line for (;; ) { if (gchar_cursor() == NUL && curwin->w_cursor.col > 0) --curwin->w_cursor.col; @@ -6438,10 +6470,10 @@ stop_insert ( break; // should not happen } } - if (curwin->w_cursor.lnum != tpos.lnum) + if (curwin->w_cursor.lnum != tpos.lnum) { curwin->w_cursor = tpos; - else { - /* reset tpos, could have been invalidated in the loop above */ + } else { + // reset tpos, could have been invalidated in the loop above tpos = curwin->w_cursor; tpos.col++; if (cc != NUL && gchar_pos(&tpos) == NUL) { @@ -6449,8 +6481,8 @@ stop_insert ( } } - /* <C-S-Right> may have started Visual mode, adjust the position for - * deleted characters. */ + // <C-S-Right> may have started Visual mode, adjust the position for + // deleted characters. if (VIsual_active && VIsual.lnum == curwin->w_cursor.lnum) { int len = (int)STRLEN(get_cursor_line_ptr()); @@ -6466,8 +6498,8 @@ stop_insert ( can_si = false; can_si_back = false; - /* Set '[ and '] to the inserted text. When end_insert_pos is NULL we are - * now in a different buffer. */ + // Set '[ and '] to the inserted text. When end_insert_pos is NULL we are + // now in a different buffer. if (end_insert_pos != NULL) { curbuf->b_op_start = Insstart; curbuf->b_op_start_orig = Insstart_orig; @@ -6486,9 +6518,10 @@ void set_last_insert(int c) xfree(last_insert); last_insert = xmalloc(MB_MAXBYTES * 3 + 5); s = last_insert; - /* Use the CTRL-V only when entering a special char */ - if (c < ' ' || c == DEL) + // Use the CTRL-V only when entering a special char + if (c < ' ' || c == DEL) { *s++ = Ctrl_V; + } s = add_char2buf(c, s); *s++ = ESC; *s++ = NUL; @@ -6574,7 +6607,7 @@ int oneright(void) if (virtual_active()) { pos_T prevpos = curwin->w_cursor; - /* Adjust for multi-wide char (excluding TAB) */ + // Adjust for multi-wide char (excluding TAB) ptr = get_cursor_pos_ptr(); coladvance(getviscol() + ((*ptr != TAB && vim_isprintc(utf_ptr2char(ptr))) ? ptr2cells(ptr) : 1)); @@ -6585,20 +6618,18 @@ int oneright(void) } ptr = get_cursor_pos_ptr(); - if (*ptr == NUL) - return FAIL; /* already at the very end */ + if (*ptr == NUL) { + return FAIL; // already at the very end + } - if (has_mbyte) - l = (*mb_ptr2len)(ptr); - else - l = 1; + l = utfc_ptr2len(ptr); - /* move "l" bytes right, but don't end up on the NUL, unless 'virtualedit' - * contains "onemore". */ + // move "l" bytes right, but don't end up on the NUL, unless 'virtualedit' + // contains "onemore". if (ptr[l] == NUL - && (ve_flags & VE_ONEMORE) == 0 - ) + && (ve_flags & VE_ONEMORE) == 0) { return FAIL; + } curwin->w_cursor.col += l; curwin->w_set_curswant = TRUE; @@ -6614,25 +6645,23 @@ int oneleft(void) if (v == 0) return FAIL; - /* We might get stuck on 'showbreak', skip over it. */ + // We might get stuck on 'showbreak', skip over it. width = 1; for (;; ) { coladvance(v - width); - /* getviscol() is slow, skip it when 'showbreak' is empty, - 'breakindent' is not set and there are no multi-byte - characters */ - if ((*p_sbr == NUL - && !curwin->w_p_bri - && !has_mbyte - ) || getviscol() < v) + // getviscol() is slow, skip it when 'showbreak' is empty, + // 'breakindent' is not set and there are no multi-byte + // characters + if (getviscol() < v) { break; - ++width; + } + width++; } if (curwin->w_cursor.coladd == 1) { char_u *ptr; - /* Adjust for multi-wide char (not a TAB) */ + // Adjust for multi-wide char (not a TAB) ptr = get_cursor_pos_ptr(); if (*ptr != TAB && vim_isprintc(utf_ptr2char(ptr)) && ptr2cells(ptr) > 1) { @@ -6650,17 +6679,16 @@ int oneleft(void) curwin->w_set_curswant = TRUE; --curwin->w_cursor.col; - /* if the character on the left of the current cursor is a multi-byte - * character, move to its first byte */ - if (has_mbyte) - mb_adjust_cursor(); + // if the character on the left of the current cursor is a multi-byte + // character, move to its first byte + mb_adjust_cursor(); return OK; } int cursor_up ( long n, - int upd_topline /* When TRUE: update topline */ + int upd_topline // When TRUE: update topline ) { linenr_T lnum; @@ -6678,19 +6706,21 @@ cursor_up ( /* * Count each sequence of folded lines as one logical line. */ - /* go to the start of the current fold */ + // go to the start of the current fold (void)hasFolding(lnum, &lnum, NULL); while (n--) { - /* move up one line */ - --lnum; - if (lnum <= 1) + // move up one line + lnum--; + if (lnum <= 1) { break; - /* If we entered a fold, move to the beginning, unless in - * Insert mode or when 'foldopen' contains "all": it will open - * in a moment. */ - if (n > 0 || !((State & INSERT) || (fdo_flags & FDO_ALL))) + } + // If we entered a fold, move to the beginning, unless in + // Insert mode or when 'foldopen' contains "all": it will open + // in a moment. + if (n > 0 || !((State & INSERT) || (fdo_flags & FDO_ALL))) { (void)hasFolding(lnum, &lnum, NULL); + } } if (lnum < 1) lnum = 1; @@ -6699,11 +6729,12 @@ cursor_up ( curwin->w_cursor.lnum = lnum; } - /* try to advance to the column we want to be at */ + // try to advance to the column we want to be at coladvance(curwin->w_curswant); - if (upd_topline) - update_topline(); /* make sure curwin->w_topline is valid */ + if (upd_topline) { + update_topline(); // make sure curwin->w_topline is valid + } return OK; } @@ -6714,14 +6745,14 @@ cursor_up ( int cursor_down ( long n, - int upd_topline /* When TRUE: update topline */ + int upd_topline // When TRUE: update topline ) { linenr_T lnum; if (n > 0) { lnum = curwin->w_cursor.lnum; - /* Move to last line of fold, will fail if it's the end-of-file. */ + // Move to last line of fold, will fail if it's the end-of-file. (void)hasFolding(lnum, NULL, &lnum); // This fails if the cursor is already in the last line. @@ -6733,7 +6764,7 @@ cursor_down ( else if (hasAnyFolding(curwin)) { linenr_T last; - /* count each sequence of folded lines as one logical line */ + // count each sequence of folded lines as one logical line while (n--) { if (hasFolding(lnum, NULL, &last)) lnum = last + 1; @@ -6749,11 +6780,12 @@ cursor_down ( curwin->w_cursor.lnum = lnum; } - /* try to advance to the column we want to be at */ + // try to advance to the column we want to be at coladvance(curwin->w_curswant); - if (upd_topline) - update_topline(); /* make sure curwin->w_topline is valid */ + if (upd_topline) { + update_topline(); // make sure curwin->w_topline is valid + } return OK; } @@ -6763,11 +6795,10 @@ cursor_down ( * Last_insert actually is a copy of the redo buffer, so we * first have to remove the command. */ -int -stuff_inserted ( - int c, /* Command character to be inserted */ - long count, /* Repeat this many times */ - int no_esc /* Don't add an ESC at the end */ +int stuff_inserted( + int c, // Command character to be inserted + long count, // Repeat this many times + int no_esc // Don't add an ESC at the end ) { char_u *esc_ptr; @@ -6781,18 +6812,18 @@ stuff_inserted ( return FAIL; } - /* may want to stuff the command character, to start Insert mode */ - if (c != NUL) + // may want to stuff the command character, to start Insert mode + if (c != NUL) { stuffcharReadbuff(c); + } if ((esc_ptr = STRRCHR(ptr, ESC)) != NULL) { // remove the ESC. *esc_ptr = NUL; } - /* when the last char is either "0" or "^" it will be quoted if no ESC - * comes after it OR if it will inserted more than once and "ptr" - * starts with ^D. -- Acevedo - */ + // when the last char is either "0" or "^" it will be quoted if no ESC + // comes after it OR if it will inserted more than once and "ptr" + // starts with ^D. -- Acevedo last_ptr = (esc_ptr ? esc_ptr : ptr + STRLEN(ptr)) - 1; if (last_ptr >= ptr && (*last_ptr == '0' || *last_ptr == '^') && (no_esc || (*ptr == Ctrl_D && count > 1))) { @@ -6813,12 +6844,14 @@ stuff_inserted ( if (last) *last_ptr = last; - if (esc_ptr != NULL) - *esc_ptr = ESC; /* put the ESC back */ + if (esc_ptr != NULL) { + *esc_ptr = ESC; // put the ESC back + } - /* may want to stuff a trailing ESC, to get out of Insert mode */ - if (!no_esc) + // may want to stuff a trailing ESC, to get out of Insert mode + if (!no_esc) { stuffcharReadbuff(ESC); + } return OK; } @@ -6843,8 +6876,9 @@ char_u *get_last_insert_save(void) return NULL; s = vim_strsave(last_insert + last_insert_skip); len = (int)STRLEN(s); - if (len > 0 && s[len - 1] == ESC) /* remove trailing ESC */ + if (len > 0 && s[len - 1] == ESC) { // remove trailing ESC s[len - 1] = NUL; + } return s; } @@ -6886,8 +6920,8 @@ static bool echeck_abbr(int c) */ static char_u *replace_stack = NULL; -static ssize_t replace_stack_nr = 0; /* next entry in replace stack */ -static ssize_t replace_stack_len = 0; /* max. number of entries */ +static ssize_t replace_stack_nr = 0; // next entry in replace stack +static ssize_t replace_stack_len = 0; // max. number of entries /// Push character that is replaced onto the the replace stack. /// @@ -6941,9 +6975,8 @@ static int replace_pop(void) * Join the top two items on the replace stack. This removes to "off"'th NUL * encountered. */ -static void -replace_join ( - int off /* offset for which NUL to remove */ +static void replace_join( + int off // offset for which NUL to remove ) { int i; @@ -6966,7 +6999,7 @@ static void replace_pop_ins(void) int cc; int oldState = State; - State = NORMAL; /* don't want REPLACE here */ + State = NORMAL; // don't want REPLACE here while ((cc = replace_pop()) > 0) { mb_replace_pop_ins(cc); dec_cursor(); @@ -6985,7 +7018,7 @@ static void mb_replace_pop_ins(int cc) int i; int c; - if (has_mbyte && (n = MB_BYTE2LEN(cc)) > 1) { + if ((n = MB_BYTE2LEN(cc)) > 1) { buf[0] = cc; for (i = 1; i < n; ++i) buf[i] = replace_pop(); @@ -6994,31 +7027,33 @@ static void mb_replace_pop_ins(int cc) ins_char(cc); } - if (enc_utf8) - /* Handle composing chars. */ - for (;; ) { - c = replace_pop(); - if (c == -1) /* stack empty */ - break; - if ((n = MB_BYTE2LEN(c)) == 1) { - /* Not a multi-byte char, put it back. */ - replace_push(c); - break; + // Handle composing chars. + for (;; ) { + c = replace_pop(); + if (c == -1) { // stack empty + break; + } + if ((n = MB_BYTE2LEN(c)) == 1) { + // Not a multi-byte char, put it back. + replace_push(c); + break; + } else { + buf[0] = c; + assert(n > 1); + for (i = 1; i < n; i++) { + buf[i] = replace_pop(); + } + if (utf_iscomposing(utf_ptr2char(buf))) { + ins_bytes_len(buf, n); } else { - buf[0] = c; - assert(n > 1); - for (i = 1; i < n; ++i) - buf[i] = replace_pop(); - if (utf_iscomposing(utf_ptr2char(buf))) - ins_bytes_len(buf, n); - else { - /* Not a composing char, put it back. */ - for (i = n - 1; i >= 0; --i) - replace_push(buf[i]); - break; + // Not a composing char, put it back. + for (i = n - 1; i >= 0; i--) { + replace_push(buf[i]); } + break; } } + } } /* @@ -7056,8 +7091,8 @@ static void replace_do_bs(int limit_col) cc = replace_pop(); if (cc > 0) { if (l_State & VREPLACE_FLAG) { - /* Get the number of screen cells used by the character we are - * going to delete. */ + // Get the number of screen cells used by the character we are + // going to delete. getvcol(curwin, &curwin->w_cursor, NULL, &start_vcol, NULL); orig_vcols = chartabsize(get_cursor_pos_ptr(), start_vcol); } @@ -7074,7 +7109,7 @@ static void replace_do_bs(int limit_col) replace_pop_ins(); if (l_State & VREPLACE_FLAG) { - /* Get the number of screen cells used by the inserted characters */ + // Get the number of screen cells used by the inserted characters p = get_cursor_pos_ptr(); ins_len = (int)STRLEN(p) - orig_len; vcol = start_vcol; @@ -7084,8 +7119,8 @@ static void replace_do_bs(int limit_col) } vcol -= start_vcol; - /* Delete spaces that were inserted after the cursor to keep the - * text aligned. */ + // Delete spaces that were inserted after the cursor to keep the + // text aligned. curwin->w_cursor.col += ins_len; while (vcol > orig_vcols && gchar_cursor() == ' ') { del_char(false); @@ -7094,7 +7129,7 @@ static void replace_do_bs(int limit_col) curwin->w_cursor.col -= ins_len; } - /* mark the buffer as changed and prepare for displaying */ + // mark the buffer as changed and prepare for displaying changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col); } else if (cc == 0) (void)del_char_after_col(limit_col); @@ -7162,10 +7197,11 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) return false; } - if (*curbuf->b_p_inde != NUL) - look = curbuf->b_p_indk; /* 'indentexpr' set: use 'indentkeys' */ - else - look = curbuf->b_p_cink; /* 'indentexpr' empty: use 'cinkeys' */ + if (*curbuf->b_p_inde != NUL) { + look = curbuf->b_p_indk; // 'indentexpr' set: use 'indentkeys' + } else { + look = curbuf->b_p_cink; // 'indentexpr' empty: use 'cinkeys' + } while (*look) { /* * Find out if we want to try a match with this key, depending on @@ -7364,10 +7400,12 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty) */ int hkmap(int c) { - if (p_hkmapp) { /* phonetic mapping, by Ilya Dogolazky */ - enum {hALEF=0, BET, GIMEL, DALET, HEI, VAV, ZAIN, HET, TET, IUD, - KAFsofit, hKAF, LAMED, MEMsofit, MEM, NUNsofit, NUN, SAMEH, AIN, - PEIsofit, PEI, ZADIsofit, ZADI, KOF, RESH, hSHIN, TAV}; + if (p_hkmapp) { // phonetic mapping, by Ilya Dogolazky + enum { + hALEF = 0, BET, GIMEL, DALET, HEI, VAV, ZAIN, HET, TET, IUD, + KAFsofit, hKAF, LAMED, MEMsofit, MEM, NUNsofit, NUN, SAMEH, AIN, + PEIsofit, PEI, ZADIsofit, ZADI, KOF, RESH, hSHIN, TAV + }; static char_u map[26] = {(char_u)hALEF /*a*/, (char_u)BET /*b*/, (char_u)hKAF /*c*/, (char_u)DALET /*d*/, (char_u)-1 /*e*/, (char_u)PEIsofit /*f*/, @@ -7379,28 +7417,27 @@ int hkmap(int c) (char_u)VAV /*v*/, (char_u)hSHIN /*w*/, (char_u)-1 /*x*/, (char_u)AIN /*y*/, (char_u)ZADI /*z*/}; - if (c == 'N' || c == 'M' || c == 'P' || c == 'C' || c == 'Z') + if (c == 'N' || c == 'M' || c == 'P' || c == 'C' || c == 'Z') { return (int)(map[CharOrd(c)] - 1 + p_aleph); - /* '-1'='sofit' */ - else if (c == 'x') + } else if (c == 'x') { // '-1'='sofit' return 'X'; - else if (c == 'q') - return '\''; /* {geresh}={'} */ - else if (c == 246) - return ' '; /* \"o --> ' ' for a german keyboard */ - else if (c == 228) - return ' '; /* \"a --> ' ' -- / -- */ - else if (c == 252) - return ' '; /* \"u --> ' ' -- / -- */ - /* NOTE: islower() does not do the right thing for us on Linux so we - * do this the same was as 5.7 and previous, so it works correctly on - * all systems. Specifically, the e.g. Delete and Arrow keys are - * munged and won't work if e.g. searching for Hebrew text. - */ - else if (c >= 'a' && c <= 'z') + } else if (c == 'q') { + return '\''; // {geresh}={'} + } else if (c == 246) { + return ' '; // \"o --> ' ' for a german keyboard + } else if (c == 228) { + return ' '; // \"a --> ' ' -- / -- + } else if (c == 252) { + return ' '; // \"u --> ' ' -- / -- + } else if (c >= 'a' && c <= 'z') { + // NOTE: islower() does not do the right thing for us on Linux so we + // do this the same was as 5.7 and previous, so it works correctly on + // all systems. Specifically, the e.g. Delete and Arrow keys are + // munged and won't work if e.g. searching for Hebrew text. return (int)(map[CharOrdLow(c)] + p_aleph); - else + } else { return c; + } } else { switch (c) { case '`': return ';'; @@ -7409,7 +7446,7 @@ int hkmap(int c) case 'q': return '/'; case 'w': return '\''; - /* Hebrew letters - set offset from 'a' */ + // Hebrew letters - set offset from 'a' case ',': c = '{'; break; case '.': c = 'v'; break; case ';': c = 't'; break; @@ -7439,10 +7476,10 @@ static void ins_reg(void) */ pc_status = PC_STATUS_UNSET; if (redrawing() && !char_avail()) { - /* may need to redraw when no more chars available now */ - ins_redraw(FALSE); + // may need to redraw when no more chars available now + ins_redraw(false); - edit_putchar('"', TRUE); + edit_putchar('"', true); add_to_showcmd_c(Ctrl_R); } @@ -7455,7 +7492,7 @@ static void ins_reg(void) regname = plain_vgetc(); LANGMAP_ADJUST(regname, TRUE); if (regname == Ctrl_R || regname == Ctrl_O || regname == Ctrl_P) { - /* Get a third key for literal register insertion */ + // Get a third key for literal register insertion literally = regname; add_to_showcmd_c(literally); regname = plain_vgetc(); @@ -7463,9 +7500,9 @@ static void ins_reg(void) } --no_mapping; - /* Don't call u_sync() while typing the expression or giving an error - * message for it. Only call it explicitly. */ - ++no_u_sync; + // Don't call u_sync() while typing the expression or giving an error + // message for it. Only call it explicitly. + no_u_sync++; if (regname == '=') { pos_T curpos = curwin->w_cursor; @@ -7484,7 +7521,7 @@ static void ins_reg(void) need_redraw = true; // remove the '"' } else { if (literally == Ctrl_O || literally == Ctrl_P) { - /* Append the command to the redo buffer. */ + // Append the command to the redo buffer. AppendCharToRedobuff(Ctrl_R); AppendCharToRedobuff(literally); AppendCharToRedobuff(regname); @@ -7501,19 +7538,22 @@ static void ins_reg(void) need_redraw = true; } } - --no_u_sync; - if (u_sync_once == 1) - ins_need_undo = TRUE; + no_u_sync--; + if (u_sync_once == 1) { + ins_need_undo = true; + } u_sync_once = 0; clear_showcmd(); - /* If the inserted register is empty, we need to remove the '"' */ - if (need_redraw || stuff_empty()) + // If the inserted register is empty, we need to remove the '"' + if (need_redraw || stuff_empty()) { edit_unputchar(); + } - /* Disallow starting Visual mode here, would get a weird mode. */ - if (!vis_active && VIsual_active) + // Disallow starting Visual mode here, would get a weird mode. + if (!vis_active && VIsual_active) { end_visual_mode(); + } } /* @@ -7523,7 +7563,7 @@ static void ins_ctrl_g(void) { int c; - /* Right after CTRL-X the cursor will be after the ruler. */ + // Right after CTRL-X the cursor will be after the ruler. setcursor(); /* @@ -7534,24 +7574,25 @@ static void ins_ctrl_g(void) c = plain_vgetc(); --no_mapping; switch (c) { - /* CTRL-G k and CTRL-G <Up>: cursor up to Insstart.col */ + // CTRL-G k and CTRL-G <Up>: cursor up to Insstart.col case K_UP: case Ctrl_K: case 'k': ins_up(TRUE); break; - /* CTRL-G j and CTRL-G <Down>: cursor down to Insstart.col */ + // CTRL-G j and CTRL-G <Down>: cursor down to Insstart.col case K_DOWN: case Ctrl_J: case 'j': ins_down(TRUE); break; - /* CTRL-G u: start new undoable edit */ - case 'u': u_sync(TRUE); - ins_need_undo = TRUE; + // CTRL-G u: start new undoable edit + case 'u': + u_sync(true); + ins_need_undo = true; - /* Need to reset Insstart, esp. because a BS that joins - * a line to the previous one must save for undo. */ + // Need to reset Insstart, esp. because a BS that joins + // a line to the previous one must save for undo. update_Insstart_orig = false; Insstart = curwin->w_cursor; break; @@ -7563,7 +7604,7 @@ static void ins_ctrl_g(void) dont_sync_undo = kNone; break; - /* Unknown CTRL-G command, reserved for future expansion. */ + // Unknown CTRL-G command, reserved for future expansion. default: vim_beep(BO_CTRLG); } } @@ -7585,7 +7626,7 @@ static void ins_ctrl_hat(void) } set_iminsert_global(); showmode(); - /* Show/unshow value of 'keymap' in status lines. */ + // Show/unshow value of 'keymap' in status lines. status_redraw_curbuf(); } @@ -7626,10 +7667,11 @@ static bool ins_esc(long *count, int cmdchar, bool nomove) *count = 0; } - if (--*count > 0) { /* repeat what was typed */ - /* Vi repeats the insert without replacing characters. */ - if (vim_strchr(p_cpo, CPO_REPLCNT) != NULL) + if (--*count > 0) { // repeat what was typed + // Vi repeats the insert without replacing characters. + if (vim_strchr(p_cpo, CPO_REPLCNT) != NULL) { State &= ~REPLACE_FLAG; + } (void)start_redo_ins(); if (cmdchar == 'r' || cmdchar == 'v') { @@ -7644,12 +7686,13 @@ static bool ins_esc(long *count, int cmdchar, bool nomove) undisplay_dollar(); } - /* When an autoindent was removed, curswant stays after the - * indent */ - if (restart_edit == NUL && (colnr_T)temp == curwin->w_cursor.col) - curwin->w_set_curswant = TRUE; + // When an autoindent was removed, curswant stays after the + // indent + if (restart_edit == NUL && (colnr_T)temp == curwin->w_cursor.col) { + curwin->w_set_curswant = true; + } - /* Remember the last Insert position in the '^ mark. */ + // Remember the last Insert position in the '^ mark. if (!cmdmod.keepjumps) { RESET_FMARK(&curbuf->b_last_insert, curwin->w_cursor, curbuf->b_fnum); } @@ -7670,23 +7713,23 @@ static bool ins_esc(long *count, int cmdchar, bool nomove) ) { if (curwin->w_cursor.coladd > 0 || ve_flags == VE_ALL) { oneleft(); - if (restart_edit != NUL) - ++curwin->w_cursor.coladd; + if (restart_edit != NUL) { + curwin->w_cursor.coladd++; + } } else { - --curwin->w_cursor.col; - /* Correct cursor for multi-byte character. */ - if (has_mbyte) - mb_adjust_cursor(); + curwin->w_cursor.col--; + // Correct cursor for multi-byte character. + mb_adjust_cursor(); } } State = NORMAL; - /* need to position cursor again (e.g. when on a TAB ) */ + // need to position cursor again (e.g. when on a TAB ) changed_cline_bef_curs(); setmouse(); - ui_cursor_shape(); /* may show different cursor shape */ + ui_cursor_shape(); // may show different cursor shape // When recording or for CTRL-O, need to display the new mode. // Otherwise remove the mode message. @@ -7782,7 +7825,7 @@ static void ins_insert(int replaceState) } AppendCharToRedobuff(K_INS); showmode(); - ui_cursor_shape(); /* may show different cursor shape */ + ui_cursor_shape(); // may show different cursor shape } /* @@ -7796,10 +7839,11 @@ static void ins_ctrl_o(void) restart_edit = 'R'; else restart_edit = 'I'; - if (virtual_active()) - ins_at_eol = FALSE; /* cursor always keeps its column */ - else + if (virtual_active()) { + ins_at_eol = false; // cursor always keeps its column + } else { ins_at_eol = (gchar_cursor() == NUL); + } } /* @@ -7881,11 +7925,12 @@ static void ins_bs_one(colnr_T *vcolp) dec_cursor(); getvcol(curwin, &curwin->w_cursor, vcolp, NULL, NULL); if (State & REPLACE_FLAG) { - /* Don't delete characters before the insert point when in - * Replace mode */ + // Don't delete characters before the insert point when in + // Replace mode if (curwin->w_cursor.lnum != Insstart.lnum - || curwin->w_cursor.col >= Insstart.col) + || curwin->w_cursor.col >= Insstart.col) { replace_do_bs(-1); + } } else { (void)del_char(false); } @@ -7904,13 +7949,13 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) { linenr_T lnum; int cc; - int temp = 0; /* init for GCC */ + int temp = 0; // init for GCC colnr_T save_col; colnr_T mincol; bool did_backspace = false; int in_indent; int oldState; - int cpc[MAX_MCO]; /* composing characters */ + int cpc[MAX_MCO]; // composing characters // can't delete anything in an empty file // can't backup past first character in buffer @@ -7974,23 +8019,22 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) * cc >= 0: NL was replaced, put original characters back */ cc = -1; - if (State & REPLACE_FLAG) - cc = replace_pop(); /* returns -1 if NL was inserted */ - /* - * In replace mode, in the line we started replacing, we only move the - * cursor. - */ + if (State & REPLACE_FLAG) { + cc = replace_pop(); // returns -1 if NL was inserted + } + // In replace mode, in the line we started replacing, we only move the + // cursor. if ((State & REPLACE_FLAG) && curwin->w_cursor.lnum <= lnum) { dec_cursor(); } else { if (!(State & VREPLACE_FLAG) || curwin->w_cursor.lnum > orig_line_count) { - temp = gchar_cursor(); /* remember current char */ - --curwin->w_cursor.lnum; + temp = gchar_cursor(); // remember current char + curwin->w_cursor.lnum--; - /* When "aw" is in 'formatoptions' we must delete the space at - * the end of the line, otherwise the line will be broken - * again when auto-formatting. */ + // When "aw" is in 'formatoptions' we must delete the space at + // the end of the line, otherwise the line will be broken + // again when auto-formatting. if (has_format_option(FO_AUTO) && has_format_option(FO_WHITE_PAR)) { char_u *ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, @@ -8031,20 +8075,19 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) curwin->w_cursor.col = save_col; cc = replace_pop(); } - /* restore the characters that NL replaced */ + // restore the characters that NL replaced replace_pop_ins(); State = oldState; } } did_ai = false; } else { - /* - * Delete character(s) before the cursor. - */ - if (revins_on) /* put cursor on last inserted char */ + // Delete character(s) before the cursor. + if (revins_on) { // put cursor on last inserted char dec_cursor(); + } mincol = 0; - /* keep indent */ + // keep indent if (mode == BACKSPACE_LINE && (curbuf->b_p_ai || cindent_on() @@ -8079,9 +8122,9 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) ts = get_sw_value(curbuf); else ts = get_sts_value(); - /* Compute the virtual column where we want to be. Since - * 'showbreak' may get in the way, need to get the last column of - * the previous character. */ + // Compute the virtual column where we want to be. Since + // 'showbreak' may get in the way, need to get the last column of + // the previous character. getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL); start_vcol = vcol; dec_cursor(); @@ -8089,14 +8132,15 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) inc_cursor(); want_vcol = (want_vcol / ts) * ts; - /* delete characters until we are at or before want_vcol */ + // delete characters until we are at or before want_vcol while (vcol > want_vcol - && (cc = *(get_cursor_pos_ptr() - 1), ascii_iswhite(cc))) + && (cc = *(get_cursor_pos_ptr() - 1), ascii_iswhite(cc))) { ins_bs_one(&vcol); + } - /* insert extra spaces until we are at want_vcol */ + // insert extra spaces until we are at want_vcol while (vcol < want_vcol) { - /* Remember the first char we inserted */ + // Remember the first char we inserted if (curwin->w_cursor.lnum == Insstart_orig.lnum && curwin->w_cursor.col < Insstart_orig.col) { Insstart_orig.col = curwin->w_cursor.col; @@ -8112,18 +8156,16 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL); } - /* If we are now back where we started delete one character. Can - * happen when using 'sts' and 'linebreak'. */ - if (vcol >= start_vcol) + // If we are now back where we started delete one character. Can + // happen when using 'sts' and 'linebreak'. + if (vcol >= start_vcol) { ins_bs_one(&vcol); - - // Delete upto starting point, start of line or previous word. + } } else { - int cclass = 0, prev_cclass = 0; + // Delete upto starting point, start of line or previous word. + int prev_cclass = 0; - if (has_mbyte) { - cclass = mb_get_class(get_cursor_pos_ptr()); - } + int cclass = mb_get_class(get_cursor_pos_ptr()); do { if (!revins_on) { // put cursor on char to be deleted dec_cursor(); @@ -8191,21 +8233,22 @@ static bool ins_bs(int c, int mode, int *inserted_space_p) // with. AppendCharToRedobuff(c); - /* If deleted before the insertion point, adjust it */ + // If deleted before the insertion point, adjust it if (curwin->w_cursor.lnum == Insstart_orig.lnum && curwin->w_cursor.col < Insstart_orig.col) { Insstart_orig.col = curwin->w_cursor.col; } - /* vi behaviour: the cursor moves backward but the character that - * was there remains visible - * Vim behaviour: the cursor moves backward and the character that - * was there is erased from the screen. - * We can emulate the vi behaviour by pretending there is a dollar - * displayed even when there isn't. - * --pkv Sun Jan 19 01:56:40 EST 2003 */ - if (vim_strchr(p_cpo, CPO_BACKSPACE) != NULL && dollar_vcol == -1) + // vi behaviour: the cursor moves backward but the character that + // was there remains visible + // Vim behaviour: the cursor moves backward and the character that + // was there is erased from the screen. + // We can emulate the vi behaviour by pretending there is a dollar + // displayed even when there isn't. + // --pkv Sun Jan 19 01:56:40 EST 2003 + if (vim_strchr(p_cpo, CPO_BACKSPACE) != NULL && dollar_vcol == -1) { dollar_vcol = curwin->w_virtcol; + } // When deleting a char the cursor line must never be in a closed fold. // E.g., when 'foldmethod' is indent and deleting the first non-white @@ -8247,7 +8290,7 @@ static void ins_mouse(int c) can_cindent = true; } - /* redraw status lines (in case another window became active) */ + // redraw status lines (in case another window became active) redraw_statuslines(); } @@ -8270,7 +8313,7 @@ static void ins_mousescroll(int dir) if (curwin == old_curwin) undisplay_dollar(); - /* Don't scroll the window in which completion is being done. */ + // Don't scroll the window in which completion is being done. if (!pum_visible() || curwin != old_curwin ) { @@ -8312,9 +8355,10 @@ static void ins_left(void) if (!end_change) { AppendCharToRedobuff(K_LEFT); } - /* If exit reversed string, position is fixed */ - if (revins_scol != -1 && (int)curwin->w_cursor.col >= revins_scol) + // If exit reversed string, position is fixed + if (revins_scol != -1 && (int)curwin->w_cursor.col >= revins_scol) { revins_legal++; + } revins_chars++; } else if (vim_strchr(p_ww, '[') != NULL && curwin->w_cursor.lnum > 1) { // if 'whichwrap' set for cursor in insert mode may go to previous line. @@ -8407,14 +8451,13 @@ static void ins_right(void) revins_legal++; if (revins_chars) revins_chars--; - } - /* if 'whichwrap' set for cursor in insert mode, may move the - * cursor to the next line */ - else if (vim_strchr(p_ww, ']') != NULL - && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) { + } else if (vim_strchr(p_ww, ']') != NULL + && curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) { + // if 'whichwrap' set for cursor in insert mode, may move the + // cursor to the next line start_arrow(&curwin->w_cursor); - curwin->w_set_curswant = TRUE; - ++curwin->w_cursor.lnum; + curwin->w_set_curswant = true; + curwin->w_cursor.lnum++; curwin->w_cursor.col = 0; } else { vim_beep(BO_CRSR); @@ -8443,9 +8486,8 @@ static void ins_s_right(void) dont_sync_undo = kFalse; } -static void -ins_up ( - int startcol /* when TRUE move to Insstart.col */ +static void ins_up( + bool startcol // when true move to Insstart.col ) { pos_T tpos; @@ -8475,7 +8517,7 @@ static void ins_pageup(void) undisplay_dollar(); if (mod_mask & MOD_MASK_CTRL) { - /* <C-PageUp>: tab page back */ + // <C-PageUp>: tab page back if (first_tabpage->tp_next != NULL) { start_arrow(&curwin->w_cursor); goto_tabpage(-1); @@ -8492,9 +8534,8 @@ static void ins_pageup(void) } } -static void -ins_down ( - int startcol /* when TRUE move to Insstart.col */ +static void ins_down( + bool startcol // when true move to Insstart.col ) { pos_T tpos; @@ -8524,7 +8565,7 @@ static void ins_pagedown(void) undisplay_dollar(); if (mod_mask & MOD_MASK_CTRL) { - /* <C-PageDown>: tab page forward */ + // <C-PageDown>: tab page forward if (first_tabpage->tp_next != NULL) { start_arrow(&curwin->w_cursor); goto_tabpage(0); @@ -8611,7 +8652,7 @@ static bool ins_tab(void) */ if (!curbuf->b_p_et && (get_sts_value() || (p_sta && ind))) { char_u *ptr; - char_u *saved_line = NULL; /* init for GCC */ + char_u *saved_line = NULL; // init for GCC pos_T pos; pos_T fpos; pos_T *cursor; @@ -8633,18 +8674,19 @@ static bool ins_tab(void) cursor = &curwin->w_cursor; } - /* When 'L' is not in 'cpoptions' a tab always takes up 'ts' spaces. */ - if (vim_strchr(p_cpo, CPO_LISTWM) == NULL) - curwin->w_p_list = FALSE; + // When 'L' is not in 'cpoptions' a tab always takes up 'ts' spaces. + if (vim_strchr(p_cpo, CPO_LISTWM) == NULL) { + curwin->w_p_list = false; + } - /* Find first white before the cursor */ + // Find first white before the cursor fpos = curwin->w_cursor; while (fpos.col > 0 && ascii_iswhite(ptr[-1])) { --fpos.col; --ptr; } - /* In Replace mode, don't change characters before the insert point. */ + // In Replace mode, don't change characters before the insert point. if ((State & REPLACE_FLAG) && fpos.lnum == Insstart.lnum && fpos.col < Insstart.col) { @@ -8652,12 +8694,12 @@ static bool ins_tab(void) fpos.col = Insstart.col; } - /* compute virtual column numbers of first white and cursor */ + // compute virtual column numbers of first white and cursor getvcol(curwin, &fpos, &vcol, NULL, NULL); getvcol(curwin, cursor, &want_vcol, NULL, NULL); - /* Use as many TABs as possible. Beware of 'breakindent', 'showbreak' - and 'linebreak' adding extra virtual columns. */ + // Use as many TABs as possible. Beware of 'breakindent', 'showbreak' + // and 'linebreak' adding extra virtual columns. while (ascii_iswhite(*ptr)) { i = lbr_chartabsize(NULL, (char_u *)"\t", vcol); if (vcol + i > want_vcol) @@ -8665,10 +8707,11 @@ static bool ins_tab(void) if (*ptr != TAB) { *ptr = TAB; if (change_col < 0) { - change_col = fpos.col; /* Column of first change */ - /* May have to adjust Insstart */ - if (fpos.lnum == Insstart.lnum && fpos.col < Insstart.col) + change_col = fpos.col; // Column of first change + // May have to adjust Insstart + if (fpos.lnum == Insstart.lnum && fpos.col < Insstart.col) { Insstart.col = fpos.col; + } } } ++fpos.col; @@ -8680,29 +8723,30 @@ static bool ins_tab(void) int repl_off = 0; char_u *line = ptr; - /* Skip over the spaces we need. */ + // Skip over the spaces we need. while (vcol < want_vcol && *ptr == ' ') { vcol += lbr_chartabsize(line, ptr, vcol); ++ptr; ++repl_off; } if (vcol > want_vcol) { - /* Must have a char with 'showbreak' just before it. */ - --ptr; - --repl_off; + // Must have a char with 'showbreak' just before it. + ptr--; + repl_off--; } fpos.col += repl_off; - /* Delete following spaces. */ + // Delete following spaces. i = cursor->col - fpos.col; if (i > 0) { STRMOVE(ptr, ptr + i); - /* correct replace stack. */ + // correct replace stack. if ((State & REPLACE_FLAG) - && !(State & VREPLACE_FLAG) - ) - for (temp = i; --temp >= 0; ) + && !(State & VREPLACE_FLAG)) { + for (temp = i; --temp >= 0; ) { replace_join(repl_off); + } + } } cursor->col -= i; @@ -8712,11 +8756,11 @@ static bool ins_tab(void) * spacing. */ if (State & VREPLACE_FLAG) { - /* Backspace from real cursor to change_col */ + // Backspace from real cursor to change_col backspace_until_column(change_col); - /* Insert each char in saved_line from changed_col to - * ptr-cursor */ + // Insert each char in saved_line from changed_col to + // ptr-cursor ins_bytes_len(saved_line + change_col, cursor->col - change_col); } @@ -8760,10 +8804,11 @@ static bool ins_eol(int c) * in open_line(). */ - /* Put cursor on NUL if on the last char and coladd is 1 (happens after - * CTRL-O). */ - if (virtual_active() && curwin->w_cursor.coladd > 0) + // Put cursor on NUL if on the last char and coladd is 1 (happens after + // CTRL-O). + if (virtual_active() && curwin->w_cursor.coladd > 0) { coladvance(getviscol()); + } // NL in reverse insert will always start in the end of current line. if (revins_on) { @@ -8791,15 +8836,15 @@ static int ins_digraph(void) { int c; int cc; - int did_putchar = FALSE; + bool did_putchar = false; pc_status = PC_STATUS_UNSET; if (redrawing() && !char_avail()) { - /* may need to redraw when no more chars available now */ - ins_redraw(FALSE); + // may need to redraw when no more chars available now + ins_redraw(false); - edit_putchar('?', TRUE); - did_putchar = TRUE; + edit_putchar('?', true); + did_putchar = true; add_to_showcmd_c(Ctrl_K); } @@ -8815,21 +8860,21 @@ static int ins_digraph(void) edit_unputchar(); } - if (IS_SPECIAL(c) || mod_mask) { /* special key */ + if (IS_SPECIAL(c) || mod_mask) { // special key clear_showcmd(); insert_special(c, TRUE, FALSE); return NUL; } if (c != ESC) { - did_putchar = FALSE; + did_putchar = false; if (redrawing() && !char_avail()) { - /* may need to redraw when no more chars available now */ - ins_redraw(FALSE); + // may need to redraw when no more chars available now + ins_redraw(false); if (char2cells(c) == 1) { - ins_redraw(FALSE); - edit_putchar(c, TRUE); - did_putchar = TRUE; + ins_redraw(false); + edit_putchar(c, true); + did_putchar = true; } add_to_showcmd_c(c); } @@ -8868,7 +8913,7 @@ int ins_copychar(linenr_T lnum) return NUL; } - /* try to advance to the cursor column */ + // try to advance to the cursor column temp = 0; line = ptr = ml_get(lnum); prev_ptr = ptr; @@ -8918,8 +8963,8 @@ static int ins_ctrl_ey(int tc) curbuf->b_p_tw = tw_save; revins_chars++; revins_legal++; - c = Ctrl_V; /* pretend CTRL-V is last character */ - auto_format(FALSE, TRUE); + c = Ctrl_V; // pretend CTRL-V is last character + auto_format(false, true); } } return c; @@ -8954,9 +8999,10 @@ static void ins_try_si(int c) */ ptr = ml_get(pos->lnum); i = pos->col; - if (i > 0) /* skip blanks before '{' */ - while (--i > 0 && ascii_iswhite(ptr[i])) - ; + if (i > 0) { // skip blanks before '{' + while (--i > 0 && ascii_iswhite(ptr[i])) { + } + } curwin->w_cursor.lnum = pos->lnum; curwin->w_cursor.col = i; if (ptr[i] == ')' && (pos = findmatch(NULL, '(')) != NULL) @@ -8979,9 +9025,10 @@ static void ins_try_si(int c) while (curwin->w_cursor.lnum > 1) { ptr = skipwhite(ml_get(--(curwin->w_cursor.lnum))); - /* ignore empty lines and lines starting with '#'. */ - if (*ptr != '#' && *ptr != NUL) + // ignore empty lines and lines starting with '#'. + if (*ptr != '#' && *ptr != NUL) { break; + } } if (get_indent() >= i) temp = FALSE; @@ -8996,14 +9043,15 @@ static void ins_try_si(int c) * set indent of '#' always to 0 */ if (curwin->w_cursor.col > 0 && can_si && c == '#') { - /* remember current indent for next line */ + // remember current indent for next line old_indent = get_indent(); (void)set_indent(0, SIN_CHANGED); } - /* Adjust ai_col, the char at this position can be deleted. */ - if (ai_col > curwin->w_cursor.col) + // Adjust ai_col, the char at this position can be deleted. + if (ai_col > curwin->w_cursor.col) { ai_col = curwin->w_cursor.col; + } } /* diff --git a/src/nvim/eval.c b/src/nvim/eval.c index ca0e078e4a..12b13a1f08 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -54,7 +54,7 @@ // TODO(ZyX-I): Remove DICT_MAXNEST, make users be non-recursive instead -#define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */ +#define DICT_MAXNEST 100 // maximum nesting of lists and dicts // Character used as separator in autoload function/variable names. #define AUTOLOAD_CHAR '#' @@ -106,7 +106,7 @@ static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T *), 4, NULL}; #define SCRIPT_SV(id) (((scriptvar_T **)ga_scripts.ga_data)[(id) - 1]) #define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab) -static int echo_attr = 0; /* attributes used for ":echo" */ +static int echo_attr = 0; // attributes used for ":echo" // flags used in uf_flags #define FC_ABORT 0x01 // abort function on error @@ -155,16 +155,16 @@ struct funccall_S { * Info used by a ":for" loop. */ typedef struct { - int fi_semicolon; /* TRUE if ending in '; var]' */ - int fi_varcount; /* nr of variables in the list */ - listwatch_T fi_lw; /* keep an eye on the item used. */ - list_T *fi_list; /* list being used */ + int fi_semicolon; // TRUE if ending in '; var]' + int fi_varcount; // nr of variables in the list + listwatch_T fi_lw; // keep an eye on the item used. + list_T *fi_list; // list being used } forinfo_T; -/* values for vv_flags: */ -#define VV_COMPAT 1 /* compatible, also used without "v:" */ -#define VV_RO 2 /* read-only */ -#define VV_RO_SBX 4 /* read-only in the sandbox */ +// values for vv_flags: +#define VV_COMPAT 1 // compatible, also used without "v:" +#define VV_RO 2 // read-only +#define VV_RO_SBX 4 // read-only in the sandbox #define VV(idx, name, type, flags) \ [idx] = { \ @@ -281,7 +281,7 @@ static struct vimvar { }; #undef VV -/* shorthand */ +// shorthand #define vv_type vv_di.di_tv.v_type #define vv_nr vv_di.di_tv.vval.v_number #define vv_special vv_di.di_tv.vval.v_special @@ -386,12 +386,14 @@ void eval_init(void) else p->vv_di.di_flags = DI_FLAGS_FIX; - /* add to v: scope dict, unless the value is not always available */ - if (p->vv_type != VAR_UNKNOWN) + // add to v: scope dict, unless the value is not always available + if (p->vv_type != VAR_UNKNOWN) { hash_add(&vimvarht, p->vv_di.di_key); - if (p->vv_flags & VV_COMPAT) - /* add to compat scope dict */ + } + if (p->vv_flags & VV_COMPAT) { + // add to compat scope dict hash_add(&compat_hashtab, p->vv_di.di_key); + } } vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; @@ -465,16 +467,16 @@ void eval_clear(void) } } hash_clear(&vimvarht); - hash_init(&vimvarht); /* garbage_collect() will access it */ + hash_init(&vimvarht); // garbage_collect() will access it hash_clear(&compat_hashtab); free_scriptnames(); free_locales(); - /* global variables */ + // global variables vars_clear(&globvarht); - /* autoloaded script names */ + // autoloaded script names ga_clear_strings(&ga_loaded); /* Script-local variables. First clear all the variables and in a second @@ -527,7 +529,7 @@ int func_level(void *cookie) return ((funccall_T *)cookie)->level; } -/* pointer to funccal for currently active function */ +// pointer to funccal for currently active function funccall_T *current_funccal = NULL; // Pointer to list of previously used funccal, still around because some @@ -568,25 +570,25 @@ static char_u *redir_varname = NULL; int var_redir_start( char_u *name, - int append /* append to an existing variable */ + int append // append to an existing variable ) { int save_emsg; int err; typval_T tv; - /* Catch a bad name early. */ + // Catch a bad name early. if (!eval_isnamec1(*name)) { EMSG(_(e_invarg)); return FAIL; } - /* Make a copy of the name, it is used in redir_lval until redir ends. */ + // Make a copy of the name, it is used in redir_lval until redir ends. redir_varname = vim_strsave(name); redir_lval = xcalloc(1, sizeof(lval_T)); - /* The output is stored in growarray "redir_ga" until redirection ends. */ + // The output is stored in growarray "redir_ga" until redirection ends. ga_init(&redir_ga, (int)sizeof(char), 500); // Parse the variable name (can be a dict or list entry). @@ -595,12 +597,13 @@ var_redir_start( if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL) { clear_lval(redir_lval); - if (redir_endp != NULL && *redir_endp != NUL) - /* Trailing characters are present after the variable name */ + if (redir_endp != NULL && *redir_endp != NUL) { + // Trailing characters are present after the variable name EMSG(_(e_trailing)); - else + } else { EMSG(_(e_invarg)); - redir_endp = NULL; /* don't store a value, only cleanup */ + } + redir_endp = NULL; // don't store a value, only cleanup var_redir_stop(); return FAIL; } @@ -620,7 +623,7 @@ var_redir_start( err = did_emsg; did_emsg |= save_emsg; if (err) { - redir_endp = NULL; /* don't store a value, only cleanup */ + redir_endp = NULL; // don't store a value, only cleanup var_redir_stop(); return FAIL; } @@ -644,10 +647,11 @@ void var_redir_str(char_u *value, int value_len) if (redir_lval == NULL) return; - if (value_len == -1) - len = (int)STRLEN(value); /* Append the entire string */ - else - len = value_len; /* Append only "value_len" characters */ + if (value_len == -1) { + len = (int)STRLEN(value); // Append the entire string + } else { + len = value_len; // Append only "value_len" characters + } ga_grow(&redir_ga, len); memmove((char *)redir_ga.ga_data + redir_ga.ga_len, value, len); @@ -663,9 +667,9 @@ void var_redir_stop(void) typval_T tv; if (redir_lval != NULL) { - /* If there was no error: assign the text to the variable. */ + // If there was no error: assign the text to the variable. if (redir_endp != NULL) { - ga_append(&redir_ga, NUL); /* Append the trailing NUL. */ + ga_append(&redir_ga, NUL); // Append the trailing NUL. tv.v_type = VAR_STRING; tv.vval.v_string = redir_ga.ga_data; // Call get_lval() again, if it's inside a Dict or List it may @@ -766,7 +770,7 @@ eval_to_bool( char_u *arg, bool *error, char_u **nextcmd, - int skip /* only parse, don't execute */ + int skip // only parse, don't execute ) { typval_T tv; @@ -1240,8 +1244,9 @@ void restore_funccal(void *vfc) * counted for the script/function itself. * Should always be called in pair with prof_child_exit(). */ -void prof_child_enter(proftime_T *tm /* place to store waittime */ - ) +void prof_child_enter( + proftime_T *tm // place to store waittime +) { funccall_T *fc = current_funccal; @@ -1256,8 +1261,9 @@ void prof_child_enter(proftime_T *tm /* place to store waittime */ * Take care of time spent in a child. * Should always be called after prof_child_enter(). */ -void prof_child_exit(proftime_T *tm /* where waittime was stored */ - ) +void prof_child_exit( + proftime_T *tm // where waittime was stored +) { funccall_T *fc = current_funccal; @@ -1282,7 +1288,6 @@ int eval_foldexpr(char_u *arg, int *cp) { typval_T tv; varnumber_T retval; - char_u *s; int use_sandbox = was_set_insecurely((char_u *)"foldexpr", OPT_LOCAL); @@ -1291,20 +1296,21 @@ int eval_foldexpr(char_u *arg, int *cp) ++sandbox; ++textlock; *cp = NUL; - if (eval0(arg, &tv, NULL, TRUE) == FAIL) + if (eval0(arg, &tv, NULL, true) == FAIL) { retval = 0; - else { - /* If the result is a number, just return the number. */ - if (tv.v_type == VAR_NUMBER) + } else { + // If the result is a number, just return the number. + if (tv.v_type == VAR_NUMBER) { retval = tv.vval.v_number; - else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) + } else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) { retval = 0; - else { - /* If the result is a string, check if there is a non-digit before - * the number. */ - s = tv.vval.v_string; - if (!ascii_isdigit(*s) && *s != '-') + } else { + // If the result is a string, check if there is a non-digit before + // the number. + char_u *s = tv.vval.v_string; + if (!ascii_isdigit(*s) && *s != '-') { *cp = *s++; + } retval = atol((char *)s); } tv_clear(&tv); @@ -1644,10 +1650,10 @@ static const char_u *skip_var_list(const char_u *arg, int *var_count, const char_u *s; if (*arg == '[') { - /* "[var, var]": find the matching ']'. */ + // "[var, var]": find the matching ']'. p = arg; for (;; ) { - p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ + p = skipwhite(p + 1); // skip whites after '[', ';' or ',' s = skip_var_one(p); if (s == p) { EMSG2(_(e_invarg2), p); @@ -2085,7 +2091,7 @@ char_u *get_lval(char_u *const name, typval_T *const rettv, hashtab_T *ht; int quiet = flags & GLV_QUIET; - /* Clear everything in "lp". */ + // Clear everything in "lp". memset(lp, 0, sizeof(lval_T)); if (skip) { @@ -2103,7 +2109,7 @@ char_u *get_lval(char_u *const name, typval_T *const rettv, (const char_u **)&expr_end, fne_flags); if (expr_start != NULL) { - /* Don't expand the name when we already know there is an error. */ + // Don't expand the name when we already know there is an error. if (unlet && !ascii_iswhite(*p) && !ends_excmd(*p) && *p != '[' && *p != '.') { EMSG(_(e_trailing)); @@ -2183,7 +2189,7 @@ char_u *get_lval(char_u *const name, typval_T *const rettv, } p = key + len; } else { - /* Get the index [expr] or the first index [expr: ]. */ + // Get the index [expr] or the first index [expr: ]. p = skipwhite(p + 1); if (*p == ':') { empty1 = true; @@ -2199,7 +2205,7 @@ char_u *get_lval(char_u *const name, typval_T *const rettv, } } - /* Optionally get the second index [ :expr]. */ + // Optionally get the second index [ :expr]. if (*p == ':') { if (lp->ll_tv->v_type == VAR_DICT) { if (!quiet) { @@ -2245,8 +2251,8 @@ char_u *get_lval(char_u *const name, typval_T *const rettv, return NULL; } - /* Skip to past ']'. */ - ++p; + // Skip to past ']'. + p++; } if (lp->ll_tv->v_type == VAR_DICT) { @@ -2672,7 +2678,7 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx) if (cmdidx == CMD_let || cmdidx == CMD_const) { xp->xp_context = EXPAND_USER_VARS; if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) { - /* ":let var1 var2 ...": find last space. */ + // ":let var1 var2 ...": find last space. for (p = arg + STRLEN(arg); p >= arg; ) { xp->xp_pattern = p; MB_PTR_BACK(arg, p); @@ -2701,7 +2707,7 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx) } } else if (c == '$') { - /* environment variable */ + // environment variable xp->xp_context = EXPAND_ENV_VARS; } else if (c == '=') { got_eq = TRUE; @@ -2713,18 +2719,20 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx) } else if ((c == '<' || c == '#') && xp->xp_context == EXPAND_FUNCTIONS && vim_strchr(xp->xp_pattern, '(') == NULL) { - /* Function name can start with "<SNR>" and contain '#'. */ + // Function name can start with "<SNR>" and contain '#'. break; } else if (cmdidx != CMD_let || got_eq) { - if (c == '"') { /* string */ - while ((c = *++xp->xp_pattern) != NUL && c != '"') - if (c == '\\' && xp->xp_pattern[1] != NUL) - ++xp->xp_pattern; + if (c == '"') { // string + while ((c = *++xp->xp_pattern) != NUL && c != '"') { + if (c == '\\' && xp->xp_pattern[1] != NUL) { + xp->xp_pattern++; + } + } xp->xp_context = EXPAND_NOTHING; - } else if (c == '\'') { /* literal string */ - /* Trick: '' is like stopping and starting a literal string. */ - while ((c = *++xp->xp_pattern) != NUL && c != '\'') - /* skip */; + } else if (c == '\'') { // literal string + // Trick: '' is like stopping and starting a literal string. + while ((c = *++xp->xp_pattern) != NUL && c != '\'') { + } xp->xp_context = EXPAND_NOTHING; } else if (c == '|') { if (xp->xp_pattern[1] == '|') { @@ -2739,9 +2747,10 @@ void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx) * anyway. */ xp->xp_context = EXPAND_EXPRESSION; arg = xp->xp_pattern; - if (*arg != NUL) - while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) - /* skip */; + if (*arg != NUL) { + while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) { + } + } } xp->xp_pattern = arg; } @@ -3152,7 +3161,7 @@ static int do_lock_var(lval_T *lp, char_u *const name_end, const int deep, } else if (lp->ll_range) { listitem_T *li = lp->ll_li; - /* (un)lock a range of List items. */ + // (un)lock a range of List items. while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) { tv_item_lock(TV_LIST_ITEM_TV(li), deep, lock); li = TV_LIST_ITEM_NEXT(lp->ll_list, li); @@ -3202,7 +3211,7 @@ static char_u *cat_prefix_varname(int prefix, char_u *name) if (len > varnamebuflen) { xfree(varnamebuf); - len += 10; /* some additional space */ + len += 10; // some additional space varnamebuf = xmalloc(len); varnamebuflen = len; } @@ -3231,7 +3240,7 @@ char_u *get_user_var_name(expand_T *xp, int idx) tdone = 0; } - /* Global variables */ + // Global variables if (gdone < globvarht.ht_used) { if (gdone++ == 0) hi = globvarht.ht_array; @@ -3244,7 +3253,7 @@ char_u *get_user_var_name(expand_T *xp, int idx) return hi->hi_key; } - /* b: variables */ + // b: variables ht = &curbuf->b_vars->dv_hashtab; if (bdone < ht->ht_used) { if (bdone++ == 0) @@ -3256,7 +3265,7 @@ char_u *get_user_var_name(expand_T *xp, int idx) return cat_prefix_varname('b', hi->hi_key); } - /* w: variables */ + // w: variables ht = &curwin->w_vars->dv_hashtab; if (wdone < ht->ht_used) { if (wdone++ == 0) @@ -3268,7 +3277,7 @@ char_u *get_user_var_name(expand_T *xp, int idx) return cat_prefix_varname('w', hi->hi_key); } - /* t: variables */ + // t: variables ht = &curtab->tp_vars->dv_hashtab; if (tdone < ht->ht_used) { if (tdone++ == 0) @@ -3294,7 +3303,7 @@ char_u *get_user_var_name(expand_T *xp, int idx) /// Return TRUE if "pat" matches "text". /// Does not use 'cpo' and always uses 'magic'. -static int pattern_match(char_u *pat, char_u *text, int ic) +static int pattern_match(char_u *pat, char_u *text, bool ic) { int matches = 0; regmatch_T regmatch; @@ -3409,8 +3418,9 @@ int eval1(char_u **arg, typval_T *rettv, int evaluate) * Get the second variable. */ *arg = skipwhite(*arg + 1); - if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ + if (eval1(arg, rettv, evaluate && result) == FAIL) { // recursive! return FAIL; + } /* * Check for the ":". @@ -3604,10 +3614,10 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) char_u *p; int i; exptype_T type = TYPE_UNKNOWN; - int type_is = FALSE; /* TRUE for "is" and "isnot" */ + bool type_is = false; // true for "is" and "isnot" int len = 2; varnumber_T n1, n2; - int ic; + bool ic; /* * Get the first variable. @@ -3645,7 +3655,7 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) } if (!isalnum(p[len]) && p[len] != '_') { type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; - type_is = TRUE; + type_is = true; } } break; @@ -3655,23 +3665,18 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) * If there is a comparative operator, use it. */ if (type != TYPE_UNKNOWN) { - /* extra question mark appended: ignore case */ + // extra question mark appended: ignore case if (p[len] == '?') { - ic = TRUE; - ++len; - } - /* extra '#' appended: match case */ - else if (p[len] == '#') { - ic = FALSE; - ++len; - } - /* nothing appended: use 'ignorecase' */ - else + ic = true; + len++; + } else if (p[len] == '#') { // extra '#' appended: match case + ic = false; + len++; + } else { // nothing appended: use 'ignorecase' ic = p_ic; + } - /* - * Get the second variable. - */ + // Get the second variable. *arg = skipwhite(p + len); if (eval5(arg, &var2, evaluate) == FAIL) { tv_clear(rettv); @@ -3816,7 +3821,7 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) const char *const s1 = tv_get_string_buf(rettv, buf1); const char *const s2 = tv_get_string_buf(&var2, buf2); if (type != TYPE_MATCH && type != TYPE_NOMATCH) { - i = mb_strcmp_ic((bool)ic, s1, s2); + i = mb_strcmp_ic(ic, s1, s2); } else { i = 0; } @@ -3977,7 +3982,7 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate) } tv_clear(rettv); - /* If there is a float on either side the result is a float. */ + // If there is a float on either side the result is a float. if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) { if (op == '+') f1 = f1 + f2; @@ -4416,7 +4421,7 @@ eval_index( char_u **arg, typval_T *rettv, int evaluate, - int verbose /* give error messages */ + int verbose // give error messages ) { bool empty1 = false; @@ -4512,7 +4517,7 @@ eval_index( } } - /* Check for the ']'. */ + // Check for the ']'. if (**arg != ']') { if (verbose) { EMSG(_(e_missbrac)); @@ -4523,7 +4528,7 @@ eval_index( } return FAIL; } - *arg = skipwhite(*arg + 1); /* skip the ']' */ + *arg = skipwhite(*arg + 1); // skip the ']' } if (evaluate) { @@ -4715,28 +4720,29 @@ int get_option_tv(const char **const arg, typval_T *const rettv, opt_type = get_option_value((char_u *)(*arg), &numval, rettv == NULL ? NULL : &stringval, opt_flags); - if (opt_type == -3) { /* invalid name */ - if (rettv != NULL) + if (opt_type == -3) { // invalid name + if (rettv != NULL) { EMSG2(_("E113: Unknown option: %s"), *arg); + } ret = FAIL; } else if (rettv != NULL) { - if (opt_type == -2) { /* hidden string option */ + if (opt_type == -2) { // hidden string option rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; - } else if (opt_type == -1) { /* hidden number option */ + } else if (opt_type == -1) { // hidden number option rettv->v_type = VAR_NUMBER; rettv->vval.v_number = 0; - } else if (opt_type == 1) { /* number option */ + } else if (opt_type == 1) { // number option rettv->v_type = VAR_NUMBER; rettv->vval.v_number = numval; - } else { /* string option */ + } else { // string option rettv->v_type = VAR_STRING; rettv->vval.v_string = stringval; } } else if (working && (opt_type == -2 || opt_type == -1)) ret = FAIL; - *option_end = c; /* put back for error messages */ + *option_end = c; // put back for error messages *arg = option_end; return ret; @@ -4770,7 +4776,7 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate) return FAIL; } - /* If only parsing, set *arg and return here */ + // If only parsing, set *arg and return here if (!evaluate) { *arg = p + 1; return OK; @@ -4794,9 +4800,9 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate) case 'r': *name++ = CAR; ++p; break; case 't': *name++ = TAB; ++p; break; - case 'X': /* hex: "\x1", "\x12" */ + case 'X': // hex: "\x1", "\x12" case 'x': - case 'u': /* Unicode: "\u0023" */ + case 'u': // Unicode: "\u0023" case 'U': if (ascii_isxdigit(p[1])) { int n, nr; @@ -4825,7 +4831,7 @@ static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate) } break; - /* octal: "\1", "\12", "\123" */ + // octal: "\1", "\12", "\123" case '0': case '1': case '2': @@ -4894,7 +4900,7 @@ static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate) return FAIL; } - /* If only parsing return after setting "*arg" */ + // If only parsing return after setting "*arg" if (!evaluate) { *arg = p + 1; return OK; @@ -5656,10 +5662,12 @@ static int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate) * But {} is an empty Dictionary. */ if (*start != '}') { - if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ + if (eval1(&start, &tv, false) == FAIL) { // recursive! return FAIL; - if (*start == '}') + } + if (*start == '}') { return NOTDONE; + } } if (evaluate) { @@ -5670,8 +5678,9 @@ static int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate) *arg = skipwhite(*arg + 1); while (**arg != '}' && **arg != NUL) { - if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ + if (eval1(arg, &tvkey, evaluate) == FAIL) { // recursive! goto failret; + } if (**arg != ':') { EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); tv_clear(&tvkey); @@ -6099,8 +6108,8 @@ get_func_tv( { char_u *argp; int ret = OK; - typval_T argvars[MAX_FUNC_ARGS + 1]; /* vars for arguments */ - int argcount = 0; /* number of arguments found */ + typval_T argvars[MAX_FUNC_ARGS + 1]; // vars for arguments + int argcount = 0; // number of arguments found /* * Get the arguments. @@ -6319,6 +6328,10 @@ call_func( } if (error == ERROR_NONE && partial->pt_argc > 0) { for (argv_clear = 0; argv_clear < partial->pt_argc; argv_clear++) { + if (argv_clear + argcount_in >= MAX_FUNC_ARGS) { + error = ERROR_TOOMANY; + goto theend; + } tv_copy(&partial->pt_argv[argv_clear], &argv[argv_clear]); } for (int i = 0; i < argcount_in; i++) { @@ -6332,12 +6345,12 @@ call_func( if (error == ERROR_NONE && evaluate) { char_u *rfname = fname; - /* Ignore "g:" before a function name. */ + // Ignore "g:" before a function name. if (fname[0] == 'g' && fname[1] == ':') { rfname = fname + 2; } - rettv->v_type = VAR_NUMBER; /* default rettv is number zero */ + rettv->v_type = VAR_NUMBER; // default rettv is number zero rettv->vval.v_number = 0; error = ERROR_UNKNOWN; @@ -6359,7 +6372,7 @@ call_func( if (fp == NULL && apply_autocmds(EVENT_FUNCUNDEFINED, rfname, rfname, TRUE, NULL) && !aborting()) { - /* executed an autocommand, search for the function again */ + // executed an autocommand, search for the function again fp = find_func(rfname); } // Try loading a package. @@ -6373,7 +6386,9 @@ call_func( error = ERROR_DELETED; } else if (fp != NULL) { if (argv_func != NULL) { - argcount = argv_func(argcount, argvars, fp->uf_args.ga_len); + // postponed filling in the arguments, do it now + argcount = argv_func(argcount, argvars, argv_clear, + fp->uf_args.ga_len); } if (fp->uf_flags & FC_RANGE) { *doesrange = true; @@ -6421,10 +6436,9 @@ call_func( if (error == ERROR_NONE) ret = OK; - /* - * Report an error unless the argument evaluation or function call has been - * cancelled due to an aborting error, an interrupt, or an exception. - */ +theend: + // Report an error unless the argument evaluation or function call has been + // cancelled due to an aborting error, an interrupt, or an exception. if (!aborting()) { switch (error) { case ERROR_UNKNOWN: @@ -7121,6 +7135,10 @@ void common_function(typval_T *argvars, typval_T *rettv, list = argvars[arg_idx].vval.v_list; if (tv_list_len(list) == 0) { arg_idx = 0; + } else if (tv_list_len(list) > MAX_FUNC_ARGS) { + emsg_funcname((char *)e_toomanyarg, name); + xfree(name); + goto theend; } } } @@ -7324,7 +7342,7 @@ dict_T *get_win_info(win_T *wp, int16_t tpnr, int16_t winnr) win_T * find_win_by_nr( typval_T *vp, - tabpage_T *tp /* NULL for current tab page */ + tabpage_T *tp // NULL for current tab page ) { int nr = (int)tv_get_number_chk(vp, NULL); @@ -7387,7 +7405,7 @@ void getwinvar( typval_T *argvars, typval_T *rettv, - int off /* 1 for gettabwinvar() */ + int off // 1 for gettabwinvar() ) { win_T *win, *oldcurwin; @@ -8614,19 +8632,19 @@ pos_T *var2fpos(const typval_T *const tv, const int dollar_lnum, if (name[0] == 'w' && dollar_lnum) { pos.col = 0; - if (name[1] == '0') { /* "w0": first visible line */ + if (name[1] == '0') { // "w0": first visible line update_topline(); // In silent Ex mode topline is zero, but that's not a valid line // number; use one instead. pos.lnum = curwin->w_topline > 0 ? curwin->w_topline : 1; return &pos; - } else if (name[1] == '$') { /* "w$": last visible line */ + } else if (name[1] == '$') { // "w$": last visible line validate_botline(); // In silent Ex mode botline is zero, return zero then. pos.lnum = curwin->w_botline > 0 ? curwin->w_botline - 1 : 0; return &pos; } - } else if (name[0] == '$') { /* last column or line */ + } else if (name[0] == '$') { // last column or line if (dollar_lnum) { pos.lnum = curbuf->b_ml.ml_line_count; pos.col = 0; @@ -8766,7 +8784,7 @@ int get_name_len(const char **const arg, { int len; - *alias = NULL; /* default to no alias */ + *alias = NULL; // default to no alias if ((*arg)[0] == (char)K_SPECIAL && (*arg)[1] == (char)KS_EXTRA && (*arg)[2] == (char)KE_SNR) { @@ -8776,7 +8794,7 @@ int get_name_len(const char **const arg, } len = eval_fname_script(*arg); if (len > 0) { - /* literal "<SID>", "s:" or "<SNR>" */ + // literal "<SID>", "s:" or "<SNR>" *arg += len; } @@ -8939,7 +8957,7 @@ static char_u *make_expanded_name(const char_u *in_start, char_u *expr_start, } xfree(temp_result); - *in_end = c1; /* put char back for error messages */ + *in_end = c1; // put char back for error messages *expr_start = '{'; *expr_end = '}'; @@ -8948,7 +8966,7 @@ static char_u *make_expanded_name(const char_u *in_start, char_u *expr_start, (const char_u **)&expr_start, (const char_u **)&expr_end, 0); if (expr_start != NULL) { - /* Further expansion! */ + // Further expansion! temp_result = make_expanded_name(retval, expr_start, expr_end, temp_result); xfree(retval); @@ -9304,8 +9322,8 @@ int handle_subscript( const char **const arg, typval_T *rettv, - int evaluate, /* do more than finding the end */ - int verbose /* give error messages */ + int evaluate, // do more than finding the end + int verbose // give error messages ) { int ret = OK; @@ -9518,7 +9536,8 @@ dictitem_T *find_var(const char *const name, const size_t name_len, return find_var_in_scoped_ht(name, name_len, no_autoload || htp != NULL); } -/// Find variable in hashtab +/// Find variable in hashtab. +/// When "varname" is empty returns curwin/curtab/etc vars dictionary. /// /// @param[in] ht Hashtab to find variable in. /// @param[in] htname Hashtab name (first character). @@ -10244,10 +10263,10 @@ int var_item_copy(const vimconv_T *const conv, case VAR_DICT: to->v_type = VAR_DICT; to->v_lock = 0; - if (from->vval.v_dict == NULL) + if (from->vval.v_dict == NULL) { to->vval.v_dict = NULL; - else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) { - /* use the copy made earlier */ + } else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) { + // use the copy made earlier to->vval.v_dict = from->vval.v_dict->dv_copydict; ++to->vval.v_dict->dv_refcount; } else { @@ -10410,7 +10429,7 @@ void ex_execute(exarg_T *eap) MSG_ATTR(ga.ga_data, echo_attr); ui_flush(); } else if (eap->cmdidx == CMD_echoerr) { - /* We don't want to abort following commands, restore did_emsg. */ + // We don't want to abort following commands, restore did_emsg. save_did_emsg = did_emsg; msg_ext_set_kind("echoerr"); EMSG((char_u *)ga.ga_data); @@ -10489,7 +10508,7 @@ void ex_function(exarg_T *eap) int nesting; dictitem_T *v; funcdict_T fudi; - static int func_nr = 0; /* number for nameless function */ + static int func_nr = 0; // number for nameless function int paren; hashtab_T *ht; int todo; @@ -10652,9 +10671,10 @@ void ex_function(exarg_T *eap) EMSG2(_("E124: Missing '(': %s"), eap->arg); goto ret_free; } - /* attempt to continue by skipping some text */ - if (vim_strchr(p, '(') != NULL) + // attempt to continue by skipping some text + if (vim_strchr(p, '(') != NULL) { p = vim_strchr(p, '('); + } } p = skipwhite(p + 1); @@ -10676,9 +10696,10 @@ void ex_function(exarg_T *eap) if (arg[j] != NUL) emsg_funcname((char *)e_invarg2, arg); } - /* Disallow using the g: dict. */ - if (fudi.fd_dict != NULL && fudi.fd_dict->dv_scope == VAR_DEF_SCOPE) + // Disallow using the g: dict. + if (fudi.fd_dict != NULL && fudi.fd_dict->dv_scope == VAR_DEF_SCOPE) { EMSG(_("E862: Cannot use g: here")); + } } if (get_function_args(&p, ')', &newargs, &varargs, eap->skip) == FAIL) { @@ -10760,7 +10781,7 @@ void ex_function(exarg_T *eap) need_wait_return = false; if (line_arg != NULL) { - /* Use eap->arg, split up in parts by line breaks. */ + // Use eap->arg, split up in parts by line breaks. theline = line_arg; p = vim_strchr(theline, '\n'); if (p == NULL) @@ -10823,11 +10844,11 @@ void ex_function(exarg_T *eap) } } } else { - /* skip ':' and blanks*/ - for (p = theline; ascii_iswhite(*p) || *p == ':'; ++p) - ; + // skip ':' and blanks + for (p = theline; ascii_iswhite(*p) || *p == ':'; p++) { + } - /* Check for "endfunction". */ + // Check for "endfunction". if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) { if (*p == '!') { p++; @@ -10865,7 +10886,7 @@ void ex_function(exarg_T *eap) || STRNCMP(p, "try", 3) == 0) indent += 2; - /* Check for defining a function inside this function. */ + // Check for defining a function inside this function. if (checkforcmd(&p, "function", 2)) { if (*p == '!') { p = skipwhite(p + 1); @@ -10910,9 +10931,8 @@ void ex_function(exarg_T *eap) || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) || (p[0] == 'm' && p[1] == 'z' - && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) - )) { - /* ":python <<" continues until a dot, like ":append" */ + && (!ASCII_ISALPHA(p[2]) || p[2] == 's')))) { + // ":python <<" continues until a dot, like ":append" p = skipwhite(arg + 2); if (*p == NUL) skip_until = vim_strsave((char_u *)"."); @@ -10949,7 +10969,7 @@ void ex_function(exarg_T *eap) } } - /* Add the line to the function. */ + // Add the line to the function. ga_grow(&newlines, 1 + sourcing_lnum_off); /* Copy the line to newly allocated memory. get_one_sourceline() @@ -10963,9 +10983,10 @@ void ex_function(exarg_T *eap) while (sourcing_lnum_off-- > 0) ((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL; - /* Check for end of eap->arg. */ - if (line_arg != NULL && *line_arg == NUL) + // Check for end of eap->arg. + if (line_arg != NULL && *line_arg == NUL) { line_arg = NULL; + } } /* Don't define the function when skipping commands or when an error was @@ -11046,7 +11067,7 @@ void ex_function(exarg_T *eap) int slen, plen; char_u *scriptname; - /* Check that the autoload name matches the script name. */ + // Check that the autoload name matches the script name. int j = FAIL; if (sourcing_name != NULL) { scriptname = (char_u *)autoload_name((const char *)name, STRLEN(name)); @@ -11084,11 +11105,11 @@ void ex_function(exarg_T *eap) fudi.fd_di->di_tv.v_type = VAR_FUNC; fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); - /* behave like "dict" was used */ + // behave like "dict" was used flags |= FC_DICT; } - /* insert the new function in the function list */ + // insert the new function in the function list STRCPY(fp->uf_name, name); if (overwrite) { hi = hash_find(&func_hashtab, name); @@ -11254,7 +11275,7 @@ trans_function_name( goto theend; } - /* Check if the name is a Funcref. If so, use the value. */ + // Check if the name is a Funcref. If so, use the value. if (lv.ll_exp_name != NULL) { len = (int)strlen(lv.ll_exp_name); name = deref_func_name(lv.ll_exp_name, &len, partial, @@ -11625,8 +11646,9 @@ void func_dump_profile(FILE *fd) int st_len = 0; todo = (int)func_hashtab.ht_used; - if (todo == 0) - return; /* nothing to dump */ + if (todo == 0) { + return; // nothing to dump + } sorttab = xmalloc(sizeof(ufunc_T *) * todo); @@ -11695,7 +11717,7 @@ prof_sort_list( ufunc_T **sorttab, int st_len, char *title, - int prefer_self /* when equal print only self time */ + int prefer_self // when equal print only self time ) { int i; @@ -11723,8 +11745,8 @@ static void prof_func_line( int count, proftime_T *total, proftime_T *self, - int prefer_self /* when equal print only self time */ - ) + int prefer_self // when equal print only self time +) { if (count > 0) { fprintf(fd, "%5d ", count); @@ -12150,7 +12172,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, int save_did_emsg; static int depth = 0; dictitem_T *v; - int fixvar_idx = 0; /* index in fixvar[] */ + int fixvar_idx = 0; // index in fixvar[] int ai; bool islambda = false; char_u numbuf[NUMBUFLEN]; @@ -12161,7 +12183,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, bool did_save_redo = false; save_redo_T save_redo; - /* If depth of calling is getting too high, don't execute the function */ + // If depth of calling is getting too high, don't execute the function if (depth >= p_mfd) { EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); rettv->v_type = VAR_NUMBER; @@ -12188,8 +12210,8 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, fc->linenr = 0; fc->returned = FALSE; fc->level = ex_nesting_level; - /* Check if this function has a breakpoint. */ - fc->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); + // Check if this function has a breakpoint. + fc->breakpoint = dbg_find_breakpoint(false, fp->uf_name, (linenr_T)0); fc->dbg_tick = debug_tick; // Set up fields for closure. @@ -12300,8 +12322,8 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, } } - /* Don't redraw while executing the function. */ - ++RedrawingDisabled; + // Don't redraw while executing the function. + RedrawingDisabled++; save_sourcing_name = sourcing_name; save_sourcing_lnum = sourcing_lnum; sourcing_lnum = 1; @@ -12403,7 +12425,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, save_did_emsg = did_emsg; did_emsg = FALSE; - /* call do_cmdline() to execute the lines */ + // call do_cmdline() to execute the lines do_cmdline(NULL, get_func_line, (void *)fc, DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); @@ -12435,7 +12457,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, } } - /* when being verbose, mention the return value */ + // when being verbose, mention the return value if (p_verbose >= 12) { ++no_wait_return; verbose_enter_scroll(); @@ -12554,7 +12576,7 @@ static int can_free_funccal(funccall_T *fc, int copyID) static void free_funccal( funccall_T *fc, - int free_val /* a: vars were allocated */ + int free_val // a: vars were allocated ) { for (int i = 0; i < fc->fc_funcs.ga_len; i++) { @@ -12671,10 +12693,11 @@ void ex_return(exarg_T *eap) /* When skipping or the return gets pending, advance to the next command * in this line (!returning). Otherwise, ignore the rest of the line. * Following lines will be ignored by get_func_line(). */ - if (returning) + if (returning) { eap->nextcmd = NULL; - else if (eap->nextcmd == NULL) /* no argument */ + } else if (eap->nextcmd == NULL) { // no argument eap->nextcmd = check_nextcmd(arg); + } if (eap->skip) --emsg_skip; @@ -12693,9 +12716,10 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv) int idx; cstack_T *const cstack = eap->cstack; - if (reanimate) - /* Undo the return. */ - current_funccal->returned = FALSE; + if (reanimate) { + // Undo the return. + current_funccal->returned = false; + } /* * Cleanup (and inactivate) conditionals, but stop when a try conditional @@ -12721,7 +12745,7 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv) } if (rettv != NULL) { - /* Store the value of the pending return. */ + // Store the value of the pending return. cstack->cs_rettv[idx] = xcalloc(1, sizeof(typval_T)); *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; } else @@ -12787,9 +12811,9 @@ char_u *get_func_line(int c, void *cookie, int indent, bool do_concat) funccall_T *fcp = (funccall_T *)cookie; ufunc_T *fp = fcp->func; char_u *retval; - garray_T *gap; /* growarray with function lines */ + garray_T *gap; // growarray with function lines - /* If breakpoints have been added/deleted need to check for it. */ + // If breakpoints have been added/deleted need to check for it. if (fcp->dbg_tick != debug_tick) { fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, sourcing_lnum); @@ -12800,16 +12824,17 @@ char_u *get_func_line(int c, void *cookie, int indent, bool do_concat) gap = &fp->uf_lines; if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) - || fcp->returned) + || fcp->returned) { retval = NULL; - else { - /* Skip NULL lines (continuation lines). */ + } else { + // Skip NULL lines (continuation lines). while (fcp->linenr < gap->ga_len - && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL) - ++fcp->linenr; - if (fcp->linenr >= gap->ga_len) + && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL) { + fcp->linenr++; + } + if (fcp->linenr >= gap->ga_len) { retval = NULL; - else { + } else { retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); sourcing_lnum = fcp->linenr; if (do_profiling == PROF_YES) @@ -12817,12 +12842,12 @@ char_u *get_func_line(int c, void *cookie, int indent, bool do_concat) } } - /* Did we encounter a breakpoint? */ + // Did we encounter a breakpoint? if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) { dbg_breakpoint(fp->uf_name, sourcing_lnum); - /* Find next breakpoint. */ - fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, - sourcing_lnum); + // Find next breakpoint. + fcp->breakpoint = dbg_find_breakpoint(false, fp->uf_name, + sourcing_lnum); fcp->dbg_tick = debug_tick; } @@ -12843,10 +12868,11 @@ void func_line_start(void *cookie) if (fp->uf_profiling && sourcing_lnum >= 1 && sourcing_lnum <= fp->uf_lines.ga_len) { fp->uf_tml_idx = sourcing_lnum - 1; - /* Skip continuation lines. */ - while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL) - --fp->uf_tml_idx; - fp->uf_tml_execed = FALSE; + // Skip continuation lines. + while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL) { + fp->uf_tml_idx--; + } + fp->uf_tml_execed = false; fp->uf_tml_start = profile_start(); fp->uf_tml_children = profile_zero(); fp->uf_tml_wait = profile_get_wait(); @@ -13157,14 +13183,14 @@ modify_fname( int has_fullname = 0; repeat: - /* ":p" - full path/file_name */ + // ":p" - full path/file_name if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') { has_fullname = 1; valid |= VALID_PATH; *usedlen += 2; - /* Expand "~/path" for all systems and "~user/path" for Unix */ + // Expand "~/path" for all systems and "~user/path" for Unix if ((*fnamep)[0] == '~' #if !defined(UNIX) && ((*fnamep)[1] == '/' @@ -13176,7 +13202,7 @@ repeat: && !(tilde_file && (*fnamep)[1] == NUL) ) { *fnamep = expand_env_save(*fnamep); - xfree(*bufp); /* free any allocated file name */ + xfree(*bufp); // free any allocated file name *bufp = *fnamep; if (*fnamep == NULL) return -1; @@ -13194,20 +13220,20 @@ repeat: } } - /* FullName_save() is slow, don't use it when not needed. */ + // FullName_save() is slow, don't use it when not needed. if (*p != NUL || !vim_isAbsName(*fnamep)) { - *fnamep = (char_u *)FullName_save((char *)*fnamep, *p != NUL); - xfree(*bufp); /* free any allocated file name */ + *fnamep = (char_u *)FullName_save((char *)(*fnamep), *p != NUL); + xfree(*bufp); // free any allocated file name *bufp = *fnamep; if (*fnamep == NULL) return -1; } - /* Append a path separator to a directory. */ + // Append a path separator to a directory. if (os_isdir(*fnamep)) { - /* Make room for one or two extra characters. */ + // Make room for one or two extra characters. *fnamep = vim_strnsave(*fnamep, STRLEN(*fnamep) + 2); - xfree(*bufp); /* free any allocated file name */ + xfree(*bufp); // free any allocated file name *bufp = *fnamep; if (*fnamep == NULL) return -1; @@ -13215,9 +13241,9 @@ repeat: } } - /* ":." - path relative to the current directory */ - /* ":~" - path relative to the home directory */ - /* ":8" - shortname path - postponed till after */ + // ":." - path relative to the current directory + // ":~" - path relative to the home directory + // ":8" - shortname path - postponed till after while (src[*usedlen] == ':' && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) { *usedlen += 2; @@ -13225,7 +13251,7 @@ repeat: continue; } pbuf = NULL; - /* Need full path first (use expand_env() to remove a "~/") */ + // Need full path first (use expand_env() to remove a "~/") if (!has_fullname) { if (c == '.' && **fnamep == '~') p = pbuf = expand_env_save(*fnamep); @@ -13243,14 +13269,14 @@ repeat: if (s != NULL) { *fnamep = s; if (pbuf != NULL) { - xfree(*bufp); /* free any allocated file name */ + xfree(*bufp); // free any allocated file name *bufp = pbuf; pbuf = NULL; } } } else { - home_replace(NULL, p, dirname, MAXPATHL, TRUE); - /* Only replace it when it starts with '~' */ + home_replace(NULL, p, dirname, MAXPATHL, true); + // Only replace it when it starts with '~' if (*dirname == '~') { s = vim_strsave(dirname); *fnamep = s; @@ -13265,8 +13291,8 @@ repeat: tail = path_tail(*fnamep); *fnamelen = STRLEN(*fnamep); - /* ":h" - head, remove "/file_name", can be repeated */ - /* Don't remove the first "/" or "c:\" */ + // ":h" - head, remove "/file_name", can be repeated + // Don't remove the first "/" or "c:\" while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') { valid |= VALID_HEAD; *usedlen += 2; @@ -13276,7 +13302,7 @@ repeat: } *fnamelen = (size_t)(tail - *fnamep); if (*fnamelen == 0) { - /* Result is empty. Turn it into "." to make ":cd %:h" work. */ + // Result is empty. Turn it into "." to make ":cd %:h" work. xfree(*bufp); *bufp = *fnamep = tail = vim_strsave((char_u *)"."); *fnamelen = 1; @@ -13287,21 +13313,21 @@ repeat: } } - /* ":8" - shortname */ + // ":8" - shortname if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') { *usedlen += 2; } - /* ":t" - tail, just the basename */ + // ":t" - tail, just the basename if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') { *usedlen += 2; *fnamelen -= (size_t)(tail - *fnamep); *fnamep = tail; } - /* ":e" - extension, can be repeated */ - /* ":r" - root, without extension, can be repeated */ + // ":e" - extension, can be repeated + // ":r" - root, without extension, can be repeated while (src[*usedlen] == ':' && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) { /* find a '.' in the tail: @@ -13353,8 +13379,8 @@ repeat: *usedlen += 2; } - /* ":s?pat?foo?" - substitute */ - /* ":gs?pat?foo?" - global substitute */ + // ":s?pat?foo?" - substitute + // ":gs?pat?foo?" - global substitute if (src[*usedlen] == ':' && (src[*usedlen + 1] == 's' || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) { @@ -13374,12 +13400,12 @@ repeat: sep = *s++; if (sep) { - /* find end of pattern */ + // find end of pattern p = vim_strchr(s, sep); if (p != NULL) { pat = vim_strnsave(s, (int)(p - s)); s = p + 1; - /* find end of substitution */ + // find end of substitution p = vim_strchr(s, sep); if (p != NULL) { sub = vim_strnsave(s, (int)(p - s)); @@ -13396,9 +13422,10 @@ repeat: } xfree(pat); } - /* after using ":s", repeat all the modifiers */ - if (didit) + // after using ":s", repeat all the modifiers + if (didit) { goto repeat; + } } } @@ -13437,7 +13464,7 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, char_u *save_cpo; char_u *zero_width = NULL; - /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ + // Make 'cpoptions' empty, so that the 'l' flag doesn't work here save_cpo = p_cpo; p_cpo = empty_option; @@ -13451,7 +13478,7 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, tail = str; end = str + STRLEN(str); while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) { - /* Skip empty match except for first match. */ + // Skip empty match except for first match. if (regmatch.startp[0] == regmatch.endp[0]) { if (zero_width == regmatch.startp[0]) { // avoid getting stuck on a match with an empty string @@ -13473,7 +13500,7 @@ char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, ga_grow(&ga, (int)((end - tail) + sublen - (regmatch.endp[0] - regmatch.startp[0]))); - /* copy the text up to where the match is */ + // copy the text up to where the match is int i = (int)(regmatch.startp[0] - tail); memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); // add the substituted text diff --git a/src/nvim/eval.h b/src/nvim/eval.h index 918823c311..7606d16f5d 100644 --- a/src/nvim/eval.h +++ b/src/nvim/eval.h @@ -187,7 +187,7 @@ extern const list_T *eval_msgpack_type_lists[LAST_MSGPACK_TYPE + 1]; #undef LAST_MSGPACK_TYPE -typedef int (*ArgvFunc)(int current_argcount, typval_T *argv, +typedef int (*ArgvFunc)(int current_argcount, typval_T *argv, int argskip, int called_func_argcount); /// trans_function_name() flags diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 6d67279e64..2dfc46023a 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -971,15 +971,16 @@ static void f_col(typval_T *argvars, typval_T *rettv, FunPtr fptr) fp = var2fpos(&argvars[0], FALSE, &fnum); if (fp != NULL && fnum == curbuf->b_fnum) { if (fp->col == MAXCOL) { - /* '> can be MAXCOL, get the length of the line then */ - if (fp->lnum <= curbuf->b_ml.ml_line_count) + // '> can be MAXCOL, get the length of the line then + if (fp->lnum <= curbuf->b_ml.ml_line_count) { col = (colnr_T)STRLEN(ml_get(fp->lnum)) + 1; - else + } else { col = MAXCOL; + } } else { col = fp->col + 1; - /* col(".") when the cursor is on the NUL at the end of the line - * because of "coladd" can be seen as an extra column. */ + // col(".") when the cursor is on the NUL at the end of the line + // because of "coladd" can be seen as an extra column. if (virtual_active() && fp == &curwin->w_cursor) { char_u *p = get_cursor_pos_ptr(); @@ -1664,25 +1665,29 @@ static void f_diff_hlID(typval_T *argvars, typval_T *rettv, FunPtr fptr) int filler_lines; int col; - if (lnum < 0) /* ignore type error in {lnum} arg */ + if (lnum < 0) { // ignore type error in {lnum} arg lnum = 0; + } if (lnum != prev_lnum || changedtick != buf_get_changedtick(curbuf) || fnum != curbuf->b_fnum) { - /* New line, buffer, change: need to get the values. */ + // New line, buffer, change: need to get the values. filler_lines = diff_check(curwin, lnum); if (filler_lines < 0) { if (filler_lines == -1) { change_start = MAXCOL; change_end = -1; - if (diff_find_change(curwin, lnum, &change_start, &change_end)) - hlID = HLF_ADD; /* added line */ - else - hlID = HLF_CHD; /* changed line */ - } else - hlID = HLF_ADD; /* added line */ - } else + if (diff_find_change(curwin, lnum, &change_start, &change_end)) { + hlID = HLF_ADD; // added line + } else { + hlID = HLF_CHD; // changed line + } + } else { + hlID = HLF_ADD; // added line + } + } else { hlID = (hlf_T)0; + } prev_lnum = lnum; changedtick = buf_get_changedtick(curbuf); fnum = curbuf->b_fnum; @@ -2060,8 +2065,8 @@ static void f_expand(typval_T *argvars, typval_T *rettv, FunPtr fptr) } else rettv->vval.v_string = result; } else { - /* When the optional second argument is non-zero, don't remove matches - * for 'wildignore' and don't put matches for 'suffixes' at the end. */ + // When the optional second argument is non-zero, don't remove matches + // for 'wildignore' and don't put matches for 'suffixes' at the end. if (argvars[1].v_type != VAR_UNKNOWN && tv_get_number_chk(&argvars[1], &error)) { options |= WILD_KEEP_ALL; @@ -2480,9 +2485,9 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } - /* Find interesting text in this line. */ + // Find interesting text in this line. s = skipwhite(ml_get(lnum)); - /* skip C comment-start */ + // skip C comment-start if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) { s = skipwhite(s + 2); if (*skipwhite(s) == NUL && lnum + 1 < foldend) { @@ -2500,7 +2505,7 @@ static void f_foldtext(typval_T *argvars, typval_T *rettv, FunPtr fptr) sprintf((char *)r, txt, dashes, count); len = (int)STRLEN(r); STRCAT(r, s); - /* remove 'foldmarker' and 'commentstring' */ + // remove 'foldmarker' and 'commentstring' foldtext_cleanup(r + len); rettv->vval.v_string = r; } @@ -2802,11 +2807,12 @@ static void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) buf_T *const buf = tv_get_buf(&argvars[0], false); if (buf != NULL && varname != NULL) { - // set curbuf to be our buf, temporarily - buf_T *const save_curbuf = curbuf; - curbuf = buf; - if (*varname == '&') { // buffer-local-option + buf_T *const save_curbuf = curbuf; + + // set curbuf to be our buf, temporarily + curbuf = buf; + if (varname[1] == NUL) { // get all buffer-local options in a dict dict_T *opts = get_winbuf_options(true); @@ -2819,19 +2825,21 @@ static void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) // buffer-local-option done = true; } + + // restore previous notion of curbuf + curbuf = save_curbuf; } else { // Look up the variable. // Let getbufvar({nr}, "") return the "b:" dictionary. - dictitem_T *const v = find_var_in_ht(&curbuf->b_vars->dv_hashtab, 'b', - varname, strlen(varname), false); + dictitem_T *const v = *varname == NUL + ? (dictitem_T *)&buf->b_bufvar + : find_var_in_ht(&buf->b_vars->dv_hashtab, 'b', + varname, strlen(varname), false); if (v != NULL) { tv_copy(&v->di_tv, rettv); done = true; } } - - // restore previous notion of curbuf - curbuf = save_curbuf; } emsg_off--; @@ -2925,10 +2933,10 @@ static void f_getchar(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_number = n; if (IS_SPECIAL(n) || mod_mask != 0) { - char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ + char_u temp[10]; // modifier: 3, mbyte-char: 6, NUL: 1 int i = 0; - /* Turn a special key into three bytes, plus modifier. */ + // Turn a special key into three bytes, plus modifier. if (mod_mask != 0) { temp[i++] = K_SPECIAL; temp[i++] = KS_MODIFIER; @@ -3277,7 +3285,7 @@ static void f_getfsize(typval_T *argvars, typval_T *rettv, FunPtr fptr) } else { rettv->vval.v_number = (varnumber_T)filesize; - /* non-perfect check for overflow */ + // non-perfect check for overflow if ((uint64_t)rettv->vval.v_number != filesize) { rettv->vval.v_number = -2; } @@ -4026,7 +4034,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr) "dialog_con", "diff", "digraphs", - "eval", /* always present, of course! */ + "eval", // always present, of course! "ex_extra", "extra_search", "file_in_path", @@ -4094,7 +4102,7 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr) "textobjects", "timers", "title", - "user-commands", /* was accidentally included in 5.4 */ + "user-commands", // was accidentally included in 5.4 "user_commands", "vertsplit", "virtualedit", @@ -4550,9 +4558,9 @@ static void f_inputlist(typval_T *argvars, typval_T *rettv, FunPtr fptr) } msg_start(); - msg_row = Rows - 1; /* for when 'cmdheight' > 1 */ - lines_left = Rows; /* avoid more prompt */ - msg_scroll = TRUE; + msg_row = Rows - 1; // for when 'cmdheight' > 1 + lines_left = Rows; // avoid more prompt + msg_scroll = true; msg_clr_eos(); TV_LIST_ITER_CONST(argvars[0].vval.v_list, li, { @@ -5426,7 +5434,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv, long idx = 0; char_u *tofree = NULL; - /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ + // Make 'cpoptions' empty, the 'l' flag should not be used here. save_cpo = p_cpo; p_cpo = (char_u *)""; @@ -5492,12 +5500,12 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv, start = 0; if (start > len) goto theend; - /* When "count" argument is there ignore matches before "start", - * otherwise skip part of the string. Differs when pattern is "^" - * or "\<". */ - if (argvars[3].v_type != VAR_UNKNOWN) + // When "count" argument is there ignore matches before "start", + // otherwise skip part of the string. Differs when pattern is "^" + // or "\<". + if (argvars[3].v_type != VAR_UNKNOWN) { startcol = start; - else { + } else { str += start; len -= start; } @@ -5536,7 +5544,7 @@ static void find_some_match(typval_T *const argvars, typval_T *const rettv, if (l == NULL && !match) break; - /* Advance to just after the match. */ + // Advance to just after the match. if (l != NULL) { li = TV_LIST_ITEM_NEXT(l, li); idx++; @@ -5643,8 +5651,11 @@ static void f_matchadd(typval_T *argvars, typval_T *rettv, FunPtr fptr) { char grpbuf[NUMBUFLEN]; char patbuf[NUMBUFLEN]; + // group const char *const grp = tv_get_string_buf_chk(&argvars[0], grpbuf); + // pattern const char *const pat = tv_get_string_buf_chk(&argvars[1], patbuf); + // default priority int prio = 10; int id = -1; bool error = false; @@ -6309,12 +6320,12 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) { bool binary = false; FILE *fd; - char_u buf[(IOSIZE/256)*256]; /* rounded to avoid odd + 1 */ + char_u buf[(IOSIZE/256) * 256]; // rounded to avoid odd + 1 int io_size = sizeof(buf); - int readlen; /* size of last fread() */ - char_u *prev = NULL; /* previously read bytes, if any */ - long prevlen = 0; /* length of data in prev */ - long prevsize = 0; /* size of prev buffer */ + int readlen; // size of last fread() + char_u *prev = NULL; // previously read bytes, if any + long prevlen = 0; // length of data in prev + long prevsize = 0; // size of prev buffer long maxline = MAXLNUM; if (argvars[1].v_type != VAR_UNKNOWN) { @@ -6353,14 +6364,17 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) char_u *s = NULL; size_t len = p - start; - /* Finished a line. Remove CRs before NL. */ + // Finished a line. Remove CRs before NL. if (readlen > 0 && !binary) { - while (len > 0 && start[len - 1] == '\r') - --len; - /* removal may cross back to the "prev" string */ - if (len == 0) - while (prevlen > 0 && prev[prevlen - 1] == '\r') - --prevlen; + while (len > 0 && start[len - 1] == '\r') { + len--; + } + // removal may cross back to the "prev" string + if (len == 0) { + while (prevlen > 0 && prev[prevlen - 1] == '\r') { + prevlen--; + } + } } if (prevlen == 0) { assert(len < INT_MAX); @@ -6372,7 +6386,7 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) s = xrealloc(prev, prevlen + len + 1); memcpy(s + prevlen, start, len); s[prevlen + len] = NUL; - prev = NULL; /* the list will own the string */ + prev = NULL; // the list will own the string prevlen = prevsize = 0; } @@ -6411,13 +6425,12 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (back2 == 0xef && back1 == 0xbb) { char_u *dest = p - 2; - /* Usually a BOM is at the beginning of a file, and so at - * the beginning of a line; then we can just step over it. - */ - if (start == dest) + // Usually a BOM is at the beginning of a file, and so at + // the beginning of a line; then we can just step over it. + if (start == dest) { start = p + 1; - else { - /* have to shuffle buf to close gap */ + } else { + // have to shuffle buf to close gap int adjust_prevlen = 0; if (dest < buf) { // -V782 @@ -6433,13 +6446,13 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) } } } - } /* for */ + } // for if ((maxline >= 0 && tv_list_len(l) >= maxline) || readlen <= 0) { break; } if (start < p) { - /* There's part of a line in buf, store it in "prev". */ + // There's part of a line in buf, store it in "prev". if (p - start + prevlen >= prevsize) { /* A common use case is ordinary text files and "prev" gets a * fragment of a line, so the first allocation is made @@ -6454,11 +6467,11 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, FunPtr fptr) } prev = xrealloc(prev, prevsize); } - /* Add the line part to end of "prev". */ + // Add the line part to end of "prev". memmove(prev + prevlen, start, p - start); prevlen += (long)(p - start); } - } /* while */ + } // while xfree(prev); fclose(fd); @@ -6709,7 +6722,12 @@ static void f_resolve(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->v_type = VAR_STRING; const char *fname = tv_get_string(&argvars[0]); #ifdef WIN32 - char *const v = os_resolve_shortcut(fname); + char *v = os_resolve_shortcut(fname); + if (v == NULL) { + if (os_is_reparse_point_include(fname)) { + v = os_realpath(fname, v); + } + } rettv->vval.v_string = (char_u *)(v == NULL ? xstrdup(fname) : v); #else # ifdef HAVE_READLINK @@ -6950,7 +6968,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp) pos_T save_cursor; bool save_p_ws = p_ws; int dir; - int retval = 0; /* default: FAIL */ + int retval = 0; // default: FAIL long lnum_stop = 0; proftime_T tm; long time_limit = 0; @@ -6974,7 +6992,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp) options |= SEARCH_COL; } - /* Optional arguments: line number to stop searching and timeout. */ + // Optional arguments: line number to stop searching and timeout. if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) { lnum_stop = tv_get_number_chk(&argvars[2], NULL); if (lnum_stop < 0) { @@ -6988,7 +7006,7 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp) } } - /* Set the time limit, if there is one. */ + // Set the time limit, if there is one. tm = profile_setlimit(time_limit); /* @@ -7018,20 +7036,21 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp) setpcmark(); curwin->w_cursor = pos; if (match_pos != NULL) { - /* Store the match cursor position */ + // Store the match cursor position match_pos->lnum = pos.lnum; match_pos->col = pos.col + 1; } - /* "/$" will put the cursor after the end of the line, may need to - * correct that here */ + // "/$" will put the cursor after the end of the line, may need to + // correct that here check_cursor(); } - /* If 'n' flag is used: restore cursor position. */ - if (flags & SP_NOMOVE) + // If 'n' flag is used: restore cursor position. + if (flags & SP_NOMOVE) { curwin->w_cursor = save_cursor; - else - curwin->w_set_curswant = TRUE; + } else { + curwin->w_set_curswant = true; + } theend: p_ws = save_p_ws; @@ -7370,7 +7389,7 @@ static void f_searchdecl(typval_T *argvars, typval_T *rettv, FunPtr fptr) int thisblock = 0; bool error = false; - rettv->vval.v_number = 1; /* default: FAIL */ + rettv->vval.v_number = 1; // default: FAIL const char *const name = tv_get_string_chk(&argvars[0]); if (argvars[1].v_type != VAR_UNKNOWN) { @@ -7528,11 +7547,11 @@ do_searchpair( size_t pat2_len; size_t pat3_len; - /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ + // Make 'cpoptions' empty, the 'l' flag should not be used here. save_cpo = p_cpo; p_cpo = empty_option; - /* Set the time limit, if there is one. */ + // Set the time limit, if there is one. tm = profile_setlimit(time_limit); // Make two search patterns: start/end (pat2, for in nested pairs) and @@ -7580,17 +7599,18 @@ do_searchpair( if (firstpos.lnum == 0) firstpos = pos; if (equalpos(pos, foundpos)) { - /* Found the same position again. Can happen with a pattern that - * has "\zs" at the end and searching backwards. Advance one - * character and try again. */ - if (dir == BACKWARD) + // Found the same position again. Can happen with a pattern that + // has "\zs" at the end and searching backwards. Advance one + // character and try again. + if (dir == BACKWARD) { decl(&pos); - else + } else { incl(&pos); + } } foundpos = pos; - /* clear the start flag to avoid getting stuck here */ + // clear the start flag to avoid getting stuck here options &= ~SEARCH_START; // If the skip pattern matches, ignore this match. @@ -7601,7 +7621,7 @@ do_searchpair( const bool r = eval_expr_to_bool(skip, &err); curwin->w_cursor = save_pos; if (err) { - /* Evaluating {skip} caused an error, break here. */ + // Evaluating {skip} caused an error, break here. curwin->w_cursor = save_cursor; retval = -1; break; @@ -7611,49 +7631,54 @@ do_searchpair( } if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) { - /* Found end when searching backwards or start when searching - * forward: nested pair. */ - ++nest; - pat = pat2; /* nested, don't search for middle */ + // Found end when searching backwards or start when searching + // forward: nested pair. + nest++; + pat = pat2; // nested, don't search for middle } else { - /* Found end when searching forward or start when searching - * backward: end of (nested) pair; or found middle in outer pair. */ - if (--nest == 1) - pat = pat3; /* outer level, search for middle */ + // Found end when searching forward or start when searching + // backward: end of (nested) pair; or found middle in outer pair. + if (--nest == 1) { + pat = pat3; // outer level, search for middle + } } if (nest == 0) { - /* Found the match: return matchcount or line number. */ - if (flags & SP_RETCOUNT) - ++retval; - else + // Found the match: return matchcount or line number. + if (flags & SP_RETCOUNT) { + retval++; + } else { retval = pos.lnum; - if (flags & SP_SETPCMARK) + } + if (flags & SP_SETPCMARK) { setpcmark(); + } curwin->w_cursor = pos; if (!(flags & SP_REPEAT)) break; - nest = 1; /* search for next unmatched */ + nest = 1; // search for next unmatched } } if (match_pos != NULL) { - /* Store the match cursor position */ + // Store the match cursor position match_pos->lnum = curwin->w_cursor.lnum; match_pos->col = curwin->w_cursor.col + 1; } - /* If 'n' flag is used or search failed: restore cursor position. */ - if ((flags & SP_NOMOVE) || retval == 0) + // If 'n' flag is used or search failed: restore cursor position. + if ((flags & SP_NOMOVE) || retval == 0) { curwin->w_cursor = save_cursor; + } xfree(pat2); xfree(pat3); - if (p_cpo == empty_option) + if (p_cpo == empty_option) { p_cpo = save_cpo; - else - /* Darn, evaluating the {skip} expression changed the value. */ + } else { + // Darn, evaluating the {skip} expression changed the value. free_string_option(save_cpo); + } return retval; } @@ -7807,10 +7832,9 @@ static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) // reset notion of buffer aucmd_restbuf(&aco); } else { - buf_T *save_curbuf = curbuf; - const size_t varname_len = STRLEN(varname); char *const bufvarname = xmalloc(varname_len + 3); + buf_T *const save_curbuf = curbuf; curbuf = buf; memcpy(bufvarname, "b:", 2); memcpy(bufvarname + 2, varname, varname_len + 1); @@ -9031,7 +9055,7 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort) info.item_compare_selfdict = NULL; if (argvars[1].v_type != VAR_UNKNOWN) { - /* optional second argument: {func} */ + // optional second argument: {func} if (argvars[1].v_type == VAR_FUNC) { info.item_compare_func = (const char *)argvars[1].vval.v_string; } else if (argvars[1].v_type == VAR_PARTIAL) { @@ -9292,7 +9316,7 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr) bool keepempty = false; bool typeerr = false; - /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ + // Make 'cpoptions' empty, the 'l' flag should not be used here. save_cpo = p_cpo; p_cpo = (char_u *)""; @@ -9480,10 +9504,10 @@ static void f_strftime(typval_T *argvars, typval_T *rettv, FunPtr fptr) struct tm curtime; struct tm *curtime_ptr = os_localtime_r(&seconds, &curtime); - /* MSVC returns NULL for an invalid value of seconds. */ - if (curtime_ptr == NULL) + // MSVC returns NULL for an invalid value of seconds. + if (curtime_ptr == NULL) { rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); - else { + } else { vimconv_T conv; char_u *enc; @@ -10180,7 +10204,7 @@ static int get_winnr(tabpage_T *tp, typval_T *argvar) for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin; wp != twin; wp = wp->w_next) { if (wp == NULL) { - /* didn't find it in this tabpage */ + // didn't find it in this tabpage nr = 0; break; } @@ -10769,9 +10793,10 @@ static void f_visualmode(typval_T *argvars, typval_T *rettv, FunPtr fptr) str[1] = NUL; rettv->vval.v_string = vim_strsave(str); - /* A non-zero number or non-empty string argument: reset mode. */ - if (non_zero_arg(&argvars[0])) + // A non-zero number or non-empty string argument: reset mode. + if (non_zero_arg(&argvars[0])) { curbuf->b_visual_mode_eval = NUL; + } } /* diff --git a/src/nvim/event/stream.c b/src/nvim/event/stream.c index d1a53fa4b6..0e87f7c6c1 100644 --- a/src/nvim/event/stream.c +++ b/src/nvim/event/stream.c @@ -16,6 +16,11 @@ # include "event/stream.c.generated.h" #endif +// For compatbility with libuv < 1.19.0 (tested on 1.18.0) +#if UV_VERSION_MINOR < 19 +#define uv_stream_get_write_queue_size(stream) stream->write_queue_size +#endif + /// Sets the stream associated with `fd` to "blocking" mode. /// /// @return `0` on success, or libuv error code on failure. diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 4f8bf63ffe..27d5e4998f 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -197,7 +197,7 @@ static void save_dbg_stuff(struct dbg_stuff *dsp) static void restore_dbg_stuff(struct dbg_stuff *dsp) { - suppress_errthrow = FALSE; + suppress_errthrow = false; trylevel = dsp->trylevel; force_abort = dsp->force_abort; caught_stack = dsp->caught_stack; @@ -394,8 +394,8 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, * Initialize "force_abort" and "suppress_errthrow" at the top level. */ if (!recursive) { - force_abort = FALSE; - suppress_errthrow = FALSE; + force_abort = false; + suppress_errthrow = false; } // If requested, store and reset the global values controlling the @@ -879,16 +879,14 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, xfree(sourcing_name); sourcing_name = saved_sourcing_name; sourcing_lnum = saved_sourcing_lnum; + } else if (got_int || (did_emsg && force_abort)) { + // On an interrupt or an aborting error not converted to an exception, + // disable the conversion of errors to exceptions. (Interrupts are not + // converted any more, here.) This enables also the interrupt message + // when force_abort is set and did_emsg unset in case of an interrupt + // from a finally clause after an error. + suppress_errthrow = true; } - /* - * On an interrupt or an aborting error not converted to an exception, - * disable the conversion of errors to exceptions. (Interrupts are not - * converted any more, here.) This enables also the interrupt message - * when force_abort is set and did_emsg unset in case of an interrupt - * from a finally clause after an error. - */ - else if (got_int || (did_emsg && force_abort)) - suppress_errthrow = TRUE; } // The current cstack will be freed when do_cmdline() returns. An uncaught @@ -9293,8 +9291,9 @@ static void ex_match(exarg_T *eap) static void ex_fold(exarg_T *eap) { - if (foldManualAllowed(TRUE)) - foldCreate(eap->line1, eap->line2); + if (foldManualAllowed(true)) { + foldCreate(curwin, eap->line1, eap->line2); + } } static void ex_foldopen(exarg_T *eap) diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index f70a568e4a..6ef196dbd1 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.c @@ -508,7 +508,7 @@ static int throw_exception(void *value, except_type_T type, char_u *cmdname) nomem: xfree(excp); - suppress_errthrow = TRUE; + suppress_errthrow = true; EMSG(_(e_outofmem)); fail: current_exception = NULL; diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 0c28f2ae70..ecaab76612 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -2447,9 +2447,10 @@ redraw: /* make following messages go to the next line */ msg_didout = FALSE; msg_col = 0; - if (msg_row < Rows - 1) - ++msg_row; - emsg_on_display = FALSE; /* don't want os_delay() */ + if (msg_row < Rows - 1) { + msg_row++; + } + emsg_on_display = false; // don't want os_delay() if (got_int) ga_clear(&line_ga); diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c index b8f2927480..1b797c6168 100644 --- a/src/nvim/ex_session.c +++ b/src/nvim/ex_session.c @@ -799,7 +799,7 @@ static int makeopens(FILE *fd, char_u *dirnow) // if (fprintf(fd, "%s", "let s:sx = expand(\"<sfile>:p:r\").\"x.vim\"\n" - "if file_readable(s:sx)\n" + "if filereadable(s:sx)\n" " exe \"source \" . fnameescape(s:sx)\n" "endif\n") < 0) { return FAIL; diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index e77b556024..38d111f2aa 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -789,7 +789,7 @@ bool decorations_redraw_start(buf_T *buf, int top_row, ExtmarkItem *item = map_ref(uint64_t, ExtmarkItem)(buf->b_extmark_index, start_id, false); if ((!(mark.id&MARKTREE_END_FLAG) && altpos.row < top_row - && !kv_size(item->virt_text)) + && item && !kv_size(item->virt_text)) || ((mark.id&MARKTREE_END_FLAG) && altpos.row >= top_row)) { goto next_mark; } @@ -854,7 +854,7 @@ int decorations_redraw_col(buf_T *buf, int col, DecorationRedrawState *state) if (endpos.row < mark.row || (endpos.row == mark.row && endpos.col <= mark.col)) { - if (!kv_size(item->virt_text)) { + if (item && !kv_size(item->virt_text)) { goto next_mark; } } diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index e5845e0749..8da1c94219 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -62,6 +62,11 @@ #define BUFSIZE 8192 /* size of normal write buffer */ #define SMBUFSIZE 256 /* size of emergency write buffer */ +// For compatibility with libuv < 1.20.0 (tested on 1.18.0) +#ifndef UV_FS_COPYFILE_FICLONE +#define UV_FS_COPYFILE_FICLONE 0 +#endif + // // The autocommands are stored in a list for each event. // Autocommands for the same pattern, that are consecutive, are joined @@ -407,11 +412,27 @@ readfile( if (newfile) { if (apply_autocmds_exarg(EVENT_BUFREADCMD, NULL, sfname, - FALSE, curbuf, eap)) - return aborting() ? FAIL : OK; + false, curbuf, eap)) { + int status = OK; + + if (aborting()) { + status = FAIL; + } + + // The BufReadCmd code usually uses ":read" to get the text and + // perhaps ":file" to change the buffer name. But we should + // consider this to work like ":edit", thus reset the + // BF_NOTEDITED flag. Then ":write" will work to overwrite the + // same file. + if (status == OK) { + curbuf->b_flags &= ~BF_NOTEDITED; + } + return status; + } } else if (apply_autocmds_exarg(EVENT_FILEREADCMD, sfname, sfname, - FALSE, NULL, eap)) + false, NULL, eap)) { return aborting() ? FAIL : OK; + } curbuf->b_op_start = pos; } diff --git a/src/nvim/fold.c b/src/nvim/fold.c index c14a64fa38..405f15d751 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -539,12 +539,10 @@ int foldManualAllowed(int create) return FALSE; } -/* foldCreate() {{{2 */ -/* - * Create a fold from line "start" to line "end" (inclusive) in the current - * window. - */ -void foldCreate(linenr_T start, linenr_T end) +// foldCreate() {{{2 +/// Create a fold from line "start" to line "end" (inclusive) in the current +/// window. +void foldCreate(win_T *wp, linenr_T start, linenr_T end) { fold_T *fp; garray_T *gap; @@ -565,16 +563,16 @@ void foldCreate(linenr_T start, linenr_T end) end_rel = end; } - /* When 'foldmethod' is "marker" add markers, which creates the folds. */ - if (foldmethodIsMarker(curwin)) { - foldCreateMarkers(start, end); + // When 'foldmethod' is "marker" add markers, which creates the folds. + if (foldmethodIsMarker(wp)) { + foldCreateMarkers(wp, start, end); return; } - checkupdate(curwin); + checkupdate(wp); - /* Find the place to insert the new fold. */ - gap = &curwin->w_folds; + // Find the place to insert the new fold + gap = &wp->w_folds; for (;; ) { if (!foldFind(gap, start_rel, &fp)) break; @@ -584,12 +582,14 @@ void foldCreate(linenr_T start, linenr_T end) start_rel -= fp->fd_top; end_rel -= fp->fd_top; if (use_level || fp->fd_flags == FD_LEVEL) { - use_level = TRUE; - if (level >= curwin->w_p_fdl) - closed = TRUE; - } else if (fp->fd_flags == FD_CLOSED) - closed = TRUE; - ++level; + use_level = true; + if (level >= wp->w_p_fdl) { + closed = true; + } + } else if (fp->fd_flags == FD_CLOSED) { + closed = true; + } + level++; } else { /* This fold and new fold overlap: Insert here and move some folds * inside the new fold. */ @@ -655,13 +655,13 @@ void foldCreate(linenr_T start, linenr_T end) } -/* deleteFold() {{{2 */ -/* - * Delete a fold at line "start" in the current window. - * When "end" is not 0, delete all folds from "start" to "end". - * When "recursive" is TRUE delete recursively. - */ +// deleteFold() {{{2 +/// @param start delete all folds from start to end when not 0 +/// @param end delete all folds from start to end when not 0 +/// @param recursive delete recursively if true +/// @param had_visual true when Visual selection used void deleteFold( + win_T *const wp, const linenr_T start, const linenr_T end, const int recursive, @@ -678,11 +678,11 @@ void deleteFold( linenr_T first_lnum = MAXLNUM; linenr_T last_lnum = 0; - checkupdate(curwin); + checkupdate(wp); while (lnum <= end) { // Find the deepest fold for "start". - garray_T *gap = &curwin->w_folds; + garray_T *gap = &wp->w_folds; garray_T *found_ga = NULL; linenr_T lnum_off = 0; bool use_level = false; @@ -694,10 +694,11 @@ void deleteFold( found_fp = fp; found_off = lnum_off; - /* if "lnum" is folded, don't check nesting */ - if (check_closed(curwin, fp, &use_level, level, - &maybe_small, lnum_off)) + // if "lnum" is folded, don't check nesting + if (check_closed(wp, fp, &use_level, level, + &maybe_small, lnum_off)) { break; + } /* check nested folds */ gap = &fp->fd_nested; @@ -709,16 +710,20 @@ void deleteFold( } else { lnum = found_fp->fd_top + found_fp->fd_len + found_off; - if (foldmethodIsManual(curwin)) + if (foldmethodIsManual(wp)) { deleteFoldEntry(found_ga, - (int)(found_fp - (fold_T *)found_ga->ga_data), recursive); - else { - if (first_lnum > found_fp->fd_top + found_off) + (int)(found_fp - (fold_T *)found_ga->ga_data), + recursive); + } else { + if (first_lnum > found_fp->fd_top + found_off) { first_lnum = found_fp->fd_top + found_off; - if (last_lnum < lnum) + } + if (last_lnum < lnum) { last_lnum = lnum; - if (!did_one) - parseMarker(curwin); + } + if (!did_one) { + parseMarker(wp); + } deleteFoldMarkers(found_fp, recursive, found_off); } did_one = true; @@ -737,6 +742,7 @@ void deleteFold( check_cursor_col(); if (last_lnum > 0) { + // TODO(teto): pass the buffer changed_lines(first_lnum, (colnr_T)0, last_lnum, 0L, false); // send one nvim_buf_lines_event at the end @@ -1048,7 +1054,7 @@ void cloneFoldGrowArray(garray_T *from, garray_T *to) * the first fold below it (careful: it can be beyond the end of the array!). * Returns FALSE when there is no fold that contains "lnum". */ -static int foldFind(garray_T *gap, linenr_T lnum, fold_T **fpp) +static int foldFind(const garray_T *gap, linenr_T lnum, fold_T **fpp) { linenr_T low, high; fold_T *fp; @@ -1487,12 +1493,15 @@ static int getDeepestNestingRecurse(garray_T *gap) return maxlevel; } -/* check_closed() {{{2 */ -/* - * Check if a fold is closed and update the info needed to check nested folds. - */ +// check_closed() {{{2 +/// Check if a fold is closed and update the info needed to check nested folds. +/// +/// @param[in,out] use_levelp true: outer fold had FD_LEVEL +/// @param level folding depth +/// @param[out] maybe_smallp TRUE: outer this had fd_small == kNone +/// @param lnum_off line number offset for fp->fd_top static bool check_closed( - win_T *const win, + win_T *const wp, fold_T *const fp, bool *const use_levelp, // true: outer fold had FD_LEVEL const int level, // folding depth @@ -1506,7 +1515,7 @@ static bool check_closed( * fold and all folds it contains depend on 'foldlevel'. */ if (*use_levelp || fp->fd_flags == FD_LEVEL) { *use_levelp = true; - if (level >= win->w_p_fdl) { + if (level >= wp->w_p_fdl) { closed = true; } } else if (fp->fd_flags == FD_CLOSED) { @@ -1521,7 +1530,7 @@ static bool check_closed( if (*maybe_smallp) { fp->fd_small = kNone; } - checkSmall(win, fp, lnum_off); + checkSmall(wp, fp, lnum_off); if (fp->fd_small == kTrue) { closed = false; } @@ -1529,10 +1538,9 @@ static bool check_closed( return closed; } -/* checkSmall() {{{2 */ -/* - * Update fd_small field of fold "fp". - */ +// checkSmall() {{{2 +/// Update fd_small field of fold "fp". +/// @param lnum_off offset for fp->fd_top static void checkSmall( win_T *const wp, @@ -1575,19 +1583,21 @@ static void setSmallMaybe(garray_T *gap) * Create a fold from line "start" to line "end" (inclusive) in the current * window by adding markers. */ -static void foldCreateMarkers(linenr_T start, linenr_T end) +static void foldCreateMarkers(win_T *wp, linenr_T start, linenr_T end) { - if (!MODIFIABLE(curbuf)) { + buf_T *buf = wp->w_buffer; + if (!MODIFIABLE(buf)) { EMSG(_(e_modifiable)); return; } - parseMarker(curwin); + parseMarker(wp); - foldAddMarker(start, curwin->w_p_fmr, foldstartmarkerlen); - foldAddMarker(end, foldendmarker, foldendmarkerlen); + foldAddMarker(buf, start, wp->w_p_fmr, foldstartmarkerlen); + foldAddMarker(buf, end, foldendmarker, foldendmarkerlen); /* Update both changes here, to avoid all folds after the start are * changed when the start marker is inserted and the end isn't. */ + // TODO(teto): pass the buffer changed_lines(start, (colnr_T)0, end, 0L, false); // Note: foldAddMarker() may not actually change start and/or end if @@ -1601,12 +1611,13 @@ static void foldCreateMarkers(linenr_T start, linenr_T end) /* * Add "marker[markerlen]" in 'commentstring' to line "lnum". */ -static void foldAddMarker(linenr_T lnum, const char_u *marker, size_t markerlen) +static void foldAddMarker( + buf_T *buf, linenr_T lnum, const char_u *marker, size_t markerlen) { - char_u *cms = curbuf->b_p_cms; + char_u *cms = buf->b_p_cms; char_u *line; char_u *newline; - char_u *p = (char_u *)strstr((char *)curbuf->b_p_cms, "%s"); + char_u *p = (char_u *)strstr((char *)buf->b_p_cms, "%s"); bool line_is_comment = false; // Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end @@ -1631,7 +1642,7 @@ static void foldAddMarker(linenr_T lnum, const char_u *marker, size_t markerlen) } ml_replace(lnum, newline, false); if (added) { - extmark_splice(curbuf, (int)lnum-1, (int)line_len, + extmark_splice(buf, (int)lnum-1, (int)line_len, 0, 0, 0, (int)added, kExtmarkUndo); } @@ -1893,6 +1904,7 @@ void foldtext_cleanup(char_u *str) /* * Update the folding for window "wp", at least from lines "top" to "bot". * Return TRUE if any folds did change. + * IEMS = "Indent Expr Marker Syntax" */ static void foldUpdateIEMS(win_T *const wp, linenr_T top, linenr_T bot) { diff --git a/src/nvim/globals.h b/src/nvim/globals.h index ccf704fe76..f102c3ddd8 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -220,7 +220,7 @@ EXTERN int did_emsg_syntax; // did_emsg set because of a // syntax error EXTERN int called_emsg; // always set by emsg() EXTERN int ex_exitval INIT(= 0); // exit value for ex mode -EXTERN int emsg_on_display INIT(= false); // there is an error message +EXTERN bool emsg_on_display INIT(= false); // there is an error message EXTERN int rc_did_emsg INIT(= false); // vim_regcomp() called emsg() EXTERN int no_wait_return INIT(= 0); // don't wait for return for now @@ -296,7 +296,7 @@ EXTERN struct msglist **msg_list INIT(= NULL); /// interrupt message or reporting an exception that is still uncaught at the /// top level (which has already been discarded then). Also used for the error /// message when no exception can be thrown. -EXTERN int suppress_errthrow INIT(= false); +EXTERN bool suppress_errthrow INIT(= false); /// The stack of all caught and not finished exceptions. The exception on the /// top of the stack is the one got by evaluation of v:exception. The complete @@ -638,7 +638,7 @@ EXTERN int arrow_used; // Normally false, set to true after // hitting cursor key in insert mode. // Used by vgetorpeek() to decide when // to call u_sync() -EXTERN int ins_at_eol INIT(= false); // put cursor after eol when +EXTERN bool ins_at_eol INIT(= false); // put cursor after eol when // restarting edit after CTRL-O EXTERN char_u *edit_submode INIT(= NULL); // msg for CTRL-X submode EXTERN char_u *edit_submode_pre INIT(= NULL); // prepended to edit_submode diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c index cb5c5338a1..f1f84e63be 100644 --- a/src/nvim/hardcopy.c +++ b/src/nvim/hardcopy.c @@ -162,21 +162,21 @@ static option_table_T mbfont_opts[OPT_MBFONT_NUM_OPTIONS] = * These values determine the print position on a page. */ typedef struct { - int lead_spaces; /* remaining spaces for a TAB */ - int print_pos; /* virtual column for computing TABs */ - colnr_T column; /* byte column */ - linenr_T file_line; /* line nr in the buffer */ - size_t bytes_printed; /* bytes printed so far */ - int ff; /* seen form feed character */ + int lead_spaces; // remaining spaces for a TAB + int print_pos; // virtual column for computing TABs + colnr_T column; // byte column + linenr_T file_line; // line nr in the buffer + size_t bytes_printed; // bytes printed so far + int ff; // seen form feed character } prt_pos_T; struct prt_mediasize_S { char *name; - double width; /* width and height in points for portrait */ + double width; // width and height in points for portrait double height; }; -/* PS font names, must be in Roman, Bold, Italic, Bold-Italic order */ +// PS font names, must be in Roman, Bold, Italic, Bold-Italic order struct prt_ps_font_S { int wx; int uline_offset; @@ -200,7 +200,7 @@ struct prt_ps_charset_S { int has_charset; }; -/* Collections of encodings and charsets for multi-byte printing */ +// Collections of encodings and charsets for multi-byte printing struct prt_ps_mbfont_S { int num_encodings; struct prt_ps_encoding_S *encodings; @@ -361,9 +361,10 @@ static uint32_t darken_rgb(uint32_t rgb) static uint32_t prt_get_term_color(int colorindex) { - /* TODO: Should check for xterm with 88 or 256 colors. */ - if (t_colors > 8) + // TODO(vim): Should check for xterm with 88 or 256 colors. + if (t_colors > 8) { return cterm_color_16[colorindex % 16]; + } return cterm_color_8[colorindex % 8]; } @@ -535,7 +536,7 @@ static void prt_header(prt_settings_T *const psettings, const int pagenum, p_header, use_sandbox, ' ', width, NULL, NULL); - /* Reset line numbers */ + // Reset line numbers curwin->w_cursor.lnum = tmp_lnum; curwin->w_topline = tmp_topline; curwin->w_botline = tmp_botline; @@ -602,7 +603,7 @@ void ex_hardcopy(exarg_T *eap) if (*eap->arg == '>') { char_u *errormsg = NULL; - /* Expand things like "%.ps". */ + // Expand things like "%.ps". if (expand_filename(eap, eap->cmdlinep, &errormsg) == FAIL) { if (errormsg != NULL) EMSG(errormsg); @@ -666,7 +667,7 @@ void ex_hardcopy(exarg_T *eap) goto print_fail_no_begin; } - /* Set colors and font to normal. */ + // Set colors and font to normal. curr_bg = 0xffffffff; curr_fg = 0xffffffff; curr_italic = kNone; @@ -691,8 +692,8 @@ void ex_hardcopy(exarg_T *eap) for (collated_copies = 0; collated_copies < settings.n_collated_copies; collated_copies++) { - prt_pos_T prtpos; /* current print position */ - prt_pos_T page_prtpos; /* print position at page start */ + prt_pos_T prtpos; // current print position + prt_pos_T page_prtpos; // print position at page start int side; memset(&page_prtpos, 0, sizeof(prt_pos_T)); @@ -700,7 +701,7 @@ void ex_hardcopy(exarg_T *eap) prtpos = page_prtpos; if (jobsplit && collated_copies > 0) { - /* Splitting jobs: Stop a previous job and start a new one. */ + // Splitting jobs: Stop a previous job and start a new one. mch_print_end(&settings); if (!mch_print_begin(&settings)) goto print_fail_no_begin; @@ -717,7 +718,7 @@ void ex_hardcopy(exarg_T *eap) for (uncollated_copies = 0; uncollated_copies < settings.n_uncollated_copies; uncollated_copies++) { - /* Set the print position to the start of this page. */ + // Set the print position to the start of this page. prtpos = page_prtpos; /* @@ -728,7 +729,7 @@ void ex_hardcopy(exarg_T *eap) * Print one page. */ - /* Check for interrupt character every page. */ + // Check for interrupt character every page. os_breakcheck(); if (got_int || settings.user_abort) goto print_fail; @@ -759,11 +760,12 @@ void ex_hardcopy(exarg_T *eap) prtpos.column = hardcopy_line(&settings, page_line, &prtpos); if (prtpos.column == 0) { - /* finished a file line */ + // finished a file line prtpos.bytes_printed += STRLEN(skipwhite(ml_get(prtpos.file_line))); - if (++prtpos.file_line > eap->line2) - break; /* reached the end */ + if (++prtpos.file_line > eap->line2) { + break; // reached the end + } } else if (prtpos.ff) { /* Line had a formfeed in it - start new page but * stay on the current line */ @@ -771,10 +773,12 @@ void ex_hardcopy(exarg_T *eap) } } - if (!mch_print_end_page()) + if (!mch_print_end_page()) { goto print_fail; - if (prtpos.file_line > eap->line2) - break; /* reached the end */ + } + if (prtpos.file_line > eap->line2) { + break; // reached the end + } } /* @@ -791,7 +795,7 @@ void ex_hardcopy(exarg_T *eap) if (settings.duplex && prtpos.file_line <= eap->line2) ++page_count; - /* Remember the position where the next page starts. */ + // Remember the position where the next page starts. page_prtpos = prtpos; } @@ -855,7 +859,7 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T id = syn_get_final_id(id); else id = 0; - /* Get the line again, a multi-line regexp may invalidate it. */ + // Get the line again, a multi-line regexp may invalidate it. line = ml_get(ppos->file_line); if (id != current_syn_id) { @@ -881,9 +885,10 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T if (need_break) break; } - /* Keep the TAB if we didn't finish it. */ - if (need_break && tab_spaces > 0) + // Keep the TAB if we didn't finish it. + if (need_break && tab_spaces > 0) { break; + } } else if (line[col] == FF && printer_opts[OPT_PRINT_FORMFEED].present && TOLOWER_ASC(printer_opts[OPT_PRINT_FORMFEED].string[0]) @@ -942,7 +947,7 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T * http://www.adobe.com */ -#define PRT_PS_DEFAULT_DPI (72) /* Default user space resolution */ +#define PRT_PS_DEFAULT_DPI (72) // Default user space resolution #define PRT_PS_DEFAULT_FONTSIZE (10) #define PRT_PS_DEFAULT_BUFFER_SIZE (80) @@ -951,20 +956,20 @@ static colnr_T hardcopy_line(prt_settings_T *psettings, int page_line, prt_pos_T static struct prt_mediasize_S prt_mediasize[] = { - {"A4", 595.0, 842.0}, - {"letter", 612.0, 792.0}, - {"10x14", 720.0, 1008.0}, - {"A3", 842.0, 1191.0}, - {"A5", 420.0, 595.0}, - {"B4", 729.0, 1032.0}, - {"B5", 516.0, 729.0}, - {"executive", 522.0, 756.0}, - {"folio", 595.0, 935.0}, - {"ledger", 1224.0, 792.0}, /* Yes, it is wider than taller! */ - {"legal", 612.0, 1008.0}, - {"quarto", 610.0, 780.0}, - {"statement", 396.0, 612.0}, - {"tabloid", 792.0, 1224.0} + { "A4", 595.0, 842.0 }, + { "letter", 612.0, 792.0 }, + { "10x14", 720.0, 1008.0 }, + { "A3", 842.0, 1191.0 }, + { "A5", 420.0, 595.0 }, + { "B4", 729.0, 1032.0 }, + { "B5", 516.0, 729.0 }, + { "executive", 522.0, 756.0 }, + { "folio", 595.0, 935.0 }, + { "ledger", 1224.0, 792.0 }, // Yes, it is wider than taller! + { "legal", 612.0, 1008.0 }, + { "quarto", 610.0, 780.0 }, + { "statement", 396.0, 612.0 }, + { "tabloid", 792.0, 1224.0 } }; #define PRT_PS_FONT_ROMAN (0) @@ -972,7 +977,7 @@ static struct prt_mediasize_S prt_mediasize[] = #define PRT_PS_FONT_OBLIQUE (2) #define PRT_PS_FONT_BOLDOBLIQUE (3) -/* Standard font metrics for Courier family */ +// Standard font metrics for Courier family static struct prt_ps_font_S prt_ps_courier_font = { 600, @@ -981,7 +986,7 @@ static struct prt_ps_font_S prt_ps_courier_font = {"Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique"} }; -/* Generic font metrics for multi-byte fonts */ +// Generic font metrics for multi-byte fonts static struct prt_ps_font_S prt_ps_mb_font = { 1000, @@ -990,9 +995,8 @@ static struct prt_ps_font_S prt_ps_mb_font = {NULL, NULL, NULL, NULL} }; -/* Pointer to current font set being used */ -static struct prt_ps_font_S* prt_ps_font; - +// Pointer to current font set being used +static struct prt_ps_font_S *prt_ps_font; #define CS_JIS_C_1978 (0x01) #define CS_JIS_X_1983 (0x02) @@ -1003,7 +1007,7 @@ static struct prt_ps_font_S* prt_ps_font; #define CS_KANJITALK6 (0x40) #define CS_KANJITALK7 (0x80) -/* Japanese encodings and charsets */ +// Japanese encodings and charsets static struct prt_ps_encoding_S j_encodings[] = { {"iso-2022-jp", NULL, (CS_JIS_C_1978|CS_JIS_X_1983|CS_JIS_X_1990| @@ -1035,7 +1039,7 @@ static struct prt_ps_charset_S j_charsets[] = #define CS_GBK (0x20) #define CS_SC_ISO10646 (0x40) -/* Simplified Chinese encodings and charsets */ +// Simplified Chinese encodings and charsets static struct prt_ps_encoding_S sc_encodings[] = { {"iso-2022", NULL, (CS_GB_2312_80|CS_GBT_12345_90)}, @@ -1071,7 +1075,7 @@ static struct prt_ps_charset_S sc_charsets[] = #define CS_DLHKS (0x800) #define CS_TC_ISO10646 (0x1000) -/* Traditional Chinese encodings and charsets */ +// Traditional Chinese encodings and charsets static struct prt_ps_encoding_S tc_encodings[] = { {"iso-2022", NULL, (CS_CNS_PLANE_1|CS_CNS_PLANE_2)}, @@ -1108,7 +1112,7 @@ static struct prt_ps_charset_S tc_charsets[] = #define CS_KR_X_1992_MS (0x04) #define CS_KR_ISO10646 (0x08) -/* Korean encodings and charsets */ +// Korean encodings and charsets static struct prt_ps_encoding_S k_encodings[] = { {"iso-2022-kr", NULL, CS_KR_X_1992}, @@ -1167,7 +1171,7 @@ static struct prt_ps_mbfont_S prt_ps_mbfonts[] = } }; -/* Types of PS resource file currently used */ +// Types of PS resource file currently used #define PRT_RESOURCE_TYPE_PROCSET (0) #define PRT_RESOURCE_TYPE_ENCODING (1) #define PRT_RESOURCE_TYPE_CMAP (2) @@ -1195,7 +1199,7 @@ static char *prt_resource_types[] = "cmap" }; -/* Strings to look for in a PS resource file */ +// Strings to look for in a PS resource file #define PRT_RESOURCE_HEADER "%!PS-Adobe-" #define PRT_RESOURCE_RESOURCE "Resource-" #define PRT_RESOURCE_PROCSET "ProcSet" @@ -1255,20 +1259,20 @@ static double prt_pos_y_moveto = 0.0; * Various control variables used to decide when and how to change the * PostScript graphics state. */ -static int prt_need_moveto; -static int prt_do_moveto; -static int prt_need_font; +static bool prt_need_moveto; +static bool prt_do_moveto; +static bool prt_need_font; static int prt_font; -static int prt_need_underline; +static bool prt_need_underline; static TriState prt_underline; static TriState prt_do_underline; -static int prt_need_fgcol; +static bool prt_need_fgcol; static uint32_t prt_fgcol; -static int prt_need_bgcol; -static int prt_do_bgcol; +static bool prt_need_bgcol; +static bool prt_do_bgcol; static uint32_t prt_bgcol; static uint32_t prt_new_bgcol; -static int prt_attribute_change; +static bool prt_attribute_change; static double prt_text_run; static int prt_page_num; static int prt_bufsiz; @@ -1296,8 +1300,8 @@ static int prt_out_mbyte; static int prt_custom_cmap; static char prt_cmap[80]; static int prt_use_courier; -static int prt_in_ascii; -static int prt_half_width; +static bool prt_in_ascii; +static bool prt_half_width; static char *prt_ascii_encoding; static char_u prt_hexchar[] = "0123456789abcdef"; @@ -1416,18 +1420,19 @@ static void prt_write_real(double val, int prec) int fraction; prt_real_bits(val, prec, &integer, &fraction); - /* Emit integer part */ - sprintf((char *)prt_line_buffer, "%d", integer); + // Emit integer part + snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), "%d", integer); prt_write_file(prt_line_buffer); - /* Only emit fraction if necessary */ + // Only emit fraction if necessary if (fraction != 0) { - /* Remove any trailing zeros */ + // Remove any trailing zeros while ((fraction % 10) == 0) { prec--; fraction /= 10; } - /* Emit fraction left padded with zeros */ - sprintf((char *)prt_line_buffer, ".%0*d", prec, fraction); + // Emit fraction left padded with zeros + snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), ".%0*d", + prec, fraction); prt_write_file(prt_line_buffer); } sprintf((char *)prt_line_buffer, " "); @@ -1447,13 +1452,13 @@ static void prt_def_var(char *name, double value, int prec) prt_write_file(prt_line_buffer); } -/* Convert size from font space to user space at current font scale */ +// Convert size from font space to user space at current font scale #define PRT_PS_FONT_TO_USER(scale, size) ((size) * ((scale)/1000.0)) static void prt_flush_buffer(void) { if (!GA_EMPTY(&prt_ps_buffer)) { - /* Any background color must be drawn first */ + // Any background color must be drawn first if (prt_do_bgcol && (prt_new_bgcol != PRCOLOR_WHITE)) { unsigned int r, g, b; @@ -1461,14 +1466,14 @@ static void prt_flush_buffer(void) prt_write_real(prt_pos_x_moveto, 2); prt_write_real(prt_pos_y_moveto, 2); prt_write_string("m\n"); - prt_do_moveto = FALSE; + prt_do_moveto = false; } - /* Size of rect of background color on which text is printed */ + // Size of rect of background color on which text is printed prt_write_real(prt_text_run, 2); prt_write_real(prt_line_height, 2); - /* Lastly add the color of the background */ + // Lastly add the color of the background r = (prt_new_bgcol & 0xff0000) >> 16; g = (prt_new_bgcol & 0xff00) >> 8; b = prt_new_bgcol & 0xff; @@ -1485,10 +1490,10 @@ static void prt_flush_buffer(void) prt_write_real(prt_pos_x_moveto, 2); prt_write_real(prt_pos_y_moveto, 2); prt_write_string("m\n"); - prt_do_moveto = FALSE; + prt_do_moveto = false; } - /* Underline length of text run */ + // Underline length of text run prt_write_real(prt_text_run, 2); prt_write_string("ul\n"); } @@ -1503,16 +1508,16 @@ static void prt_flush_buffer(void) prt_write_string(">"); else prt_write_string(")"); - /* Add a moveto if need be and use the appropriate show procedure */ + // Add a moveto if need be and use the appropriate show procedure if (prt_do_moveto) { prt_write_real(prt_pos_x_moveto, 2); prt_write_real(prt_pos_y_moveto, 2); - /* moveto and a show */ + // moveto and a show prt_write_string("ms\n"); - prt_do_moveto = FALSE; - } else /* Simple show */ + prt_do_moveto = false; + } else { // Simple show prt_write_string("s\n"); - + } ga_clear(&prt_ps_buffer); ga_init(&prt_ps_buffer, (int)sizeof(char), prt_bufsiz); } @@ -1536,7 +1541,7 @@ static int prt_find_resource(char *name, struct prt_ps_resource_S *resource) buffer = xmallocz(MAXPATHL); STRLCPY(resource->name, name, 64); - /* Look for named resource file in runtimepath */ + // Look for named resource file in runtimepath STRCPY(buffer, "print"); add_pathsep((char *)buffer); xstrlcat((char *)buffer, name, MAXPATHL); @@ -1548,7 +1553,7 @@ static int prt_find_resource(char *name, struct prt_ps_resource_S *resource) return retval; } -/* PS CR and LF characters have platform independent values */ +// PS CR and LF characters have platform independent values #define PSLF (0x0a) #define PSCR (0x0d) @@ -1558,7 +1563,7 @@ static int prt_resfile_next_line(void) { int idx; - /* Move to start of next line and then find end of line */ + // Move to start of next line and then find end of line idx = prt_resfile.line_end + 1; while (idx < prt_resfile.len) { if (prt_resfile.buffer[idx] != PSLF && prt_resfile.buffer[idx] != PSCR) @@ -1577,12 +1582,13 @@ static int prt_resfile_next_line(void) return idx < prt_resfile.len; } -static int prt_resfile_strncmp(int offset, char *string, int len) +static int prt_resfile_strncmp(int offset, const char *string, int len) + FUNC_ATTR_NONNULL_ALL { - /* Force not equal if string is longer than remainder of line */ - if (len > (prt_resfile.line_end - (prt_resfile.line_start + offset))) + // Force not equal if string is longer than remainder of line + if (len > (prt_resfile.line_end - (prt_resfile.line_start + offset))) { return 1; - + } return STRNCMP(&prt_resfile.buffer[prt_resfile.line_start + offset], string, len); } @@ -1615,178 +1621,182 @@ static int prt_resfile_skip_ws(int offset) /* prt_next_dsc() - returns detail on next DSC comment line found. Returns true * if a DSC comment is found, else false */ -static int prt_next_dsc(struct prt_dsc_line_S *p_dsc_line) +static bool prt_next_dsc(struct prt_dsc_line_S *p_dsc_line) + FUNC_ATTR_NONNULL_ALL { int comment; int offset; - /* Move to start of next line */ - if (!prt_resfile_next_line()) - return FALSE; - - /* DSC comments always start %% */ - if (prt_resfile_strncmp(0, "%%", 2) != 0) - return FALSE; - - /* Find type of DSC comment */ - for (comment = 0; comment < (int)ARRAY_SIZE(prt_dsc_table); comment++) + // Move to start of next line + if (!prt_resfile_next_line()) { + return false; + } + // DSC comments always start %% + if (prt_resfile_strncmp(0, "%%", 2) != 0) { + return false; + } + // Find type of DSC comment + for (comment = 0; comment < (int)ARRAY_SIZE(prt_dsc_table); comment++) { if (prt_resfile_strncmp(0, prt_dsc_table[comment].string, - prt_dsc_table[comment].len) == 0) + prt_dsc_table[comment].len) == 0) { break; - + } + } if (comment != ARRAY_SIZE(prt_dsc_table)) { - /* Return type of comment */ + // Return type of comment p_dsc_line->type = prt_dsc_table[comment].type; offset = prt_dsc_table[comment].len; } else { - /* Unrecognised DSC comment, skip to ws after comment leader */ + // Unrecognised DSC comment, skip to ws after comment leader p_dsc_line->type = PRT_DSC_MISC_TYPE; offset = prt_resfile_skip_nonws(0); - if (offset == -1) - return FALSE; + if (offset == -1) { + return false; + } } - /* Skip ws to comment value */ + // Skip ws to comment value offset = prt_resfile_skip_ws(offset); - if (offset == -1) - return FALSE; - + if (offset == -1) { + return false; + } p_dsc_line->string = &prt_resfile.buffer[prt_resfile.line_start + offset]; p_dsc_line->len = prt_resfile.line_end - (prt_resfile.line_start + offset); - return TRUE; + return true; } /* Improved hand crafted parser to get the type, title, and version number of a * PS resource file so the file details can be added to the DSC header comments. */ -static int prt_open_resource(struct prt_ps_resource_S *resource) +static bool prt_open_resource(struct prt_ps_resource_S *resource) + FUNC_ATTR_NONNULL_ALL { - int offset; - int seen_all; - int seen_title; - int seen_version; - FILE *fd_resource; struct prt_dsc_line_S dsc_line; - fd_resource = os_fopen((char *)resource->filename, READBIN); + FILE *fd_resource = os_fopen((char *)resource->filename, READBIN); if (fd_resource == NULL) { EMSG2(_("E624: Can't open file \"%s\""), resource->filename); - return FALSE; + return false; } memset(prt_resfile.buffer, NUL, PRT_FILE_BUFFER_LEN); - /* Parse first line to ensure valid resource file */ + // Parse first line to ensure valid resource file prt_resfile.len = (int)fread((char *)prt_resfile.buffer, sizeof(char_u), PRT_FILE_BUFFER_LEN, fd_resource); if (ferror(fd_resource)) { EMSG2(_("E457: Can't read PostScript resource file \"%s\""), resource->filename); fclose(fd_resource); - return FALSE; + return false; } fclose(fd_resource); prt_resfile.line_end = -1; prt_resfile.line_start = 0; - if (!prt_resfile_next_line()) - return FALSE; - - offset = 0; + if (!prt_resfile_next_line()) { + return false; + } + int offset = 0; if (prt_resfile_strncmp(offset, PRT_RESOURCE_HEADER, (int)STRLEN(PRT_RESOURCE_HEADER)) != 0) { EMSG2(_("E618: file \"%s\" is not a PostScript resource file"), - resource->filename); - return FALSE; + resource->filename); + return false; } - /* Skip over any version numbers and following ws */ + // Skip over any version numbers and following ws offset += (int)STRLEN(PRT_RESOURCE_HEADER); offset = prt_resfile_skip_nonws(offset); - if (offset == -1) - return FALSE; + if (offset == -1) { + return false; + } offset = prt_resfile_skip_ws(offset); - if (offset == -1) - return FALSE; - + if (offset == -1) { + return false; + } if (prt_resfile_strncmp(offset, PRT_RESOURCE_RESOURCE, (int)STRLEN(PRT_RESOURCE_RESOURCE)) != 0) { EMSG2(_("E619: file \"%s\" is not a supported PostScript resource file"), - resource->filename); - return FALSE; + resource->filename); + return false; } offset += (int)STRLEN(PRT_RESOURCE_RESOURCE); - /* Decide type of resource in the file */ + // Decide type of resource in the file if (prt_resfile_strncmp(offset, PRT_RESOURCE_PROCSET, - (int)STRLEN(PRT_RESOURCE_PROCSET)) == 0) + (int)STRLEN(PRT_RESOURCE_PROCSET)) == 0) { resource->type = PRT_RESOURCE_TYPE_PROCSET; - else if (prt_resfile_strncmp(offset, PRT_RESOURCE_ENCODING, - (int)STRLEN(PRT_RESOURCE_ENCODING)) == 0) + } else if (prt_resfile_strncmp(offset, PRT_RESOURCE_ENCODING, + (int)STRLEN(PRT_RESOURCE_ENCODING)) == 0) { resource->type = PRT_RESOURCE_TYPE_ENCODING; - else if (prt_resfile_strncmp(offset, PRT_RESOURCE_CMAP, - (int)STRLEN(PRT_RESOURCE_CMAP)) == 0) + } else if (prt_resfile_strncmp(offset, PRT_RESOURCE_CMAP, + (int)STRLEN(PRT_RESOURCE_CMAP)) == 0) { resource->type = PRT_RESOURCE_TYPE_CMAP; - else { + } else { EMSG2(_("E619: file \"%s\" is not a supported PostScript resource file"), - resource->filename); - return FALSE; + resource->filename); + return false; } - /* Look for title and version of resource */ + // Look for title and version of resource resource->title[0] = '\0'; resource->version[0] = '\0'; - seen_title = FALSE; - seen_version = FALSE; - seen_all = FALSE; + bool seen_title = false; + bool seen_version = false; + bool seen_all = false; while (!seen_all && prt_next_dsc(&dsc_line)) { switch (dsc_line.type) { case PRT_DSC_TITLE_TYPE: STRLCPY(resource->title, dsc_line.string, dsc_line.len + 1); - seen_title = TRUE; - if (seen_version) - seen_all = TRUE; + seen_title = true; + if (seen_version) { + seen_all = true; + } break; case PRT_DSC_VERSION_TYPE: STRLCPY(resource->version, dsc_line.string, dsc_line.len + 1); - seen_version = TRUE; - if (seen_title) - seen_all = TRUE; + seen_version = true; + if (seen_title) { + seen_all = true; + } break; case PRT_DSC_ENDCOMMENTS_TYPE: - /* Wont find title or resource after this comment, stop searching */ - seen_all = TRUE; + // Wont find title or resource after this comment, stop searching + seen_all = true; break; case PRT_DSC_MISC_TYPE: - /* Not interested in whatever comment this line had */ + // Not interested in whatever comment this line had break; } } if (!seen_title || !seen_version) { EMSG2(_("E619: file \"%s\" is not a supported PostScript resource file"), - resource->filename); - return FALSE; + resource->filename); + return false; } - return TRUE; + return true; } -static int prt_check_resource(struct prt_ps_resource_S *resource, char_u *version) +static bool prt_check_resource(const struct prt_ps_resource_S *resource, + const char_u *version) + FUNC_ATTR_NONNULL_ALL { - /* Version number m.n should match, the revision number does not matter */ + // Version number m.n should match, the revision number does not matter if (STRNCMP(resource->version, version, STRLEN(version))) { EMSG2(_("E621: \"%s\" resource file has wrong version"), - resource->name); - return FALSE; + resource->name); + return false; } - /* Other checks to be added as needed */ - return TRUE; + // Other checks to be added as needed + return true; } static void prt_dsc_start(void) @@ -1810,7 +1820,7 @@ static void prt_dsc_textline(char *comment, char *text) static void prt_dsc_text(char *comment, char *text) { - /* TODO - should scan 'text' for any chars needing escaping! */ + // TODO(vim): - should scan 'text' for any chars needing escaping! vim_snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), "%%%%%s: (%s)\n", comment, text); prt_write_file(prt_line_buffer); @@ -1834,9 +1844,8 @@ static void prt_dsc_ints(char *comment, int count, int *ints) prt_write_string("\n"); } -static void -prt_dsc_resources ( - char *comment, /* if NULL add to previous */ +static void prt_dsc_resources( + char *comment, // if NULL add to previous char *type, char *string ) @@ -1887,8 +1896,9 @@ static void prt_dsc_requirements(int duplex, int tumble, int collate, int color, prt_write_string(" color"); if (num_copies > 1) { prt_write_string(" numcopies("); - /* Note: no space wanted so don't use prt_write_int() */ - sprintf((char *)prt_line_buffer, "%d", num_copies); + // Note: no space wanted so don't use prt_write_int() + snprintf((char *)prt_line_buffer, sizeof(prt_line_buffer), "%d", + num_copies); prt_write_file(prt_line_buffer); prt_write_string(")"); } @@ -2038,13 +2048,13 @@ static int prt_get_lpp(void) prt_ps_font->bbox_min_y)) / 2); } - /* Get height for topmost line based on background rect offset. */ + // Get height for topmost line based on background rect offset. prt_first_line_height = prt_line_height + prt_bgcol_offset; - /* Calculate lpp */ + // Calculate lpp lpp = (int)((prt_top_margin - prt_bottom_margin) / prt_line_height); - /* Adjust top margin if there is a header */ + // Adjust top margin if there is a header prt_top_margin -= prt_line_height * prt_header_height(); return lpp - prt_header_height(); @@ -2057,7 +2067,7 @@ static int prt_match_encoding(char *p_encoding, struct prt_ps_mbfont_S *p_cmap, struct prt_ps_encoding_S *p_mbenc; *pp_mbenc = NULL; - /* Look for recognised encoding */ + // Look for recognised encoding enc_len = (int)STRLEN(p_encoding); p_mbenc = p_cmap->encodings; for (mbenc = 0; mbenc < p_cmap->num_encodings; mbenc++) { @@ -2076,9 +2086,10 @@ static int prt_match_charset(char *p_charset, struct prt_ps_mbfont_S *p_cmap, st int char_len; struct prt_ps_charset_S *p_mbchar; - /* Look for recognised character set, using default if one is not given */ - if (*p_charset == NUL) + // Look for recognised character set, using default if one is not given + if (*p_charset == NUL) { p_charset = p_cmap->defcs; + } char_len = (int)STRLEN(p_charset); p_mbchar = p_cmap->charsets; for (mbchar = 0; mbchar < p_cmap->num_charsets; mbchar++) { @@ -2133,7 +2144,7 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) break; } - /* Use first encoding matched if no charset matched */ + // Use first encoding matched if no charset matched if (p_mbenc_first != NULL && p_mbchar == NULL) { p_mbenc = p_mbenc_first; cmap = effective_cmap; @@ -2144,24 +2155,24 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) prt_out_mbyte = (p_mbenc != NULL); if (prt_out_mbyte) { - /* Build CMap name - will be same for all multi-byte fonts used */ + // Build CMap name - will be same for all multi-byte fonts used prt_cmap[0] = NUL; prt_custom_cmap = (p_mbchar == NULL); if (!prt_custom_cmap) { - /* Check encoding and character set are compatible */ + // Check encoding and character set are compatible if ((p_mbenc->needs_charset & p_mbchar->has_charset) == 0) { EMSG(_("E673: Incompatible multi-byte encoding and character set.")); return FALSE; } - /* Add charset name if not empty */ + // Add charset name if not empty if (p_mbchar->cmap_charset != NULL) { STRLCPY(prt_cmap, p_mbchar->cmap_charset, sizeof(prt_cmap) - 2); STRCAT(prt_cmap, "-"); } } else { - /* Add custom CMap character set name */ + // Add custom CMap character set name if (*p_pmcs == NUL) { EMSG(_("E674: printmbcharset cannot be empty with multi-byte encoding.")); return FALSE; @@ -2170,7 +2181,7 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) STRCAT(prt_cmap, "-"); } - /* CMap name ends with (optional) encoding name and -H for horizontal */ + // CMap name ends with (optional) encoding name and -H for horizontal if (p_mbenc->cmap_encoding != NULL && STRLEN(prt_cmap) + STRLEN(p_mbenc->cmap_encoding) + 3 < sizeof(prt_cmap)) { STRCAT(prt_cmap, p_mbenc->cmap_encoding); @@ -2183,7 +2194,7 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) return FALSE; } - /* Derive CID font names with fallbacks if not defined */ + // Derive CID font names with fallbacks if not defined prt_build_cid_fontname(PRT_PS_FONT_ROMAN, mbfont_opts[OPT_MBFONT_REGULAR].string, mbfont_opts[OPT_MBFONT_REGULAR].strlen); @@ -2288,9 +2299,10 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) psettings->chars_per_line = prt_get_cpl(); psettings->lines_per_page = prt_get_lpp(); - /* Catch margin settings that leave no space for output! */ - if (psettings->chars_per_line <= 0 || psettings->lines_per_page <= 0) + // Catch margin settings that leave no space for output! + if (psettings->chars_per_line <= 0 || psettings->lines_per_page <= 0) { return FAIL; + } /* * Sort out the number of copies to be printed. PS by default will do @@ -2329,10 +2341,10 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) prt_tumble = TRUE; } - /* For now user abort not supported */ + // For now user abort not supported psettings->user_abort = 0; - /* If the user didn't specify a file name, use a temp file. */ + // If the user didn't specify a file name, use a temp file. if (psettings->outfile == NULL) { prt_ps_file_name = vim_tempname(); if (prt_ps_file_name == NULL) { @@ -2360,12 +2372,12 @@ int mch_print_init(prt_settings_T *psettings, char_u *jobname, int forceit) prt_page_num = 0; - prt_attribute_change = FALSE; - prt_need_moveto = FALSE; - prt_need_font = FALSE; - prt_need_fgcol = FALSE; - prt_need_bgcol = FALSE; - prt_need_underline = FALSE; + prt_attribute_change = false; + prt_need_moveto = false; + prt_need_font = false; + prt_need_fgcol = false; + prt_need_bgcol = false; + prt_need_underline = false; prt_file_error = FALSE; @@ -2416,9 +2428,7 @@ static int prt_add_resource(struct prt_ps_resource_S *resource) int mch_print_begin(prt_settings_T *psettings) { - time_t now; int bbox[4]; - char *p_time; double left; double right; double top; @@ -2442,10 +2452,10 @@ int mch_print_begin(prt_settings_T *psettings) } prt_dsc_textline("For", buffer); prt_dsc_textline("Creator", longVersion); - /* Note: to ensure Clean8bit I don't think we can use LC_TIME */ - now = time(NULL); - p_time = ctime(&now); - /* Note: ctime() adds a \n so we have to remove it :-( */ + // Note: to ensure Clean8bit I don't think we can use LC_TIME + char ctime_buf[50]; + char *p_time = os_ctime(ctime_buf, sizeof(ctime_buf)); + // Note: os_ctime() adds a \n so we have to remove it :-( p = vim_strchr((char_u *)p_time, '\n'); if (p != NULL) *p = NUL; @@ -2483,14 +2493,15 @@ int mch_print_begin(prt_settings_T *psettings) + 0.5); } prt_dsc_ints("BoundingBox", 4, bbox); - /* The media width and height does not change with landscape printing! */ + // The media width and height does not change with landscape printing! prt_dsc_docmedia(prt_mediasize[prt_media].name, - prt_mediasize[prt_media].width, - prt_mediasize[prt_media].height, - (double)0, NULL, NULL); - /* Define fonts needed */ - if (!prt_out_mbyte || prt_use_courier) + prt_mediasize[prt_media].width, + prt_mediasize[prt_media].height, + (double)0, NULL, NULL); + // Define fonts needed + if (!prt_out_mbyte || prt_use_courier) { prt_dsc_font_resource("DocumentNeededResources", &prt_ps_courier_font); + } if (prt_out_mbyte) { prt_dsc_font_resource((prt_use_courier ? NULL : "DocumentNeededResources"), &prt_ps_mb_font); @@ -2498,7 +2509,7 @@ int mch_print_begin(prt_settings_T *psettings) prt_dsc_resources(NULL, "cmap", prt_cmap); } - /* Search for external resources VIM supplies */ + // Search for external resources VIM supplies if (!prt_find_resource("prolog", &res_prolog)) { EMSG(_("E456: Can't find PostScript resource file \"prolog.ps\"")); return FALSE; @@ -2508,7 +2519,7 @@ int mch_print_begin(prt_settings_T *psettings) if (!prt_check_resource(&res_prolog, PRT_PROLOG_VERSION)) return FALSE; if (prt_out_mbyte) { - /* Look for required version of multi-byte printing procset */ + // Look for required version of multi-byte printing procset if (!prt_find_resource("cidfont", &res_cidfont)) { EMSG(_("E456: Can't find PostScript resource file \"cidfont.ps\"")); return FALSE; @@ -2528,15 +2539,15 @@ int mch_print_begin(prt_settings_T *psettings) p_encoding = enc_skip(p_penc); if (*p_encoding == NUL || !prt_find_resource((char *)p_encoding, &res_encoding)) { - /* 'printencoding' not set or not supported - find alternate */ + // 'printencoding' not set or not supported - find alternate int props; p_encoding = enc_skip(p_enc); props = enc_canon_props(p_encoding); if (!(props & ENC_8BIT) || !prt_find_resource((char *)p_encoding, &res_encoding)) { - /* 8-bit 'encoding' is not supported */ - /* Use latin1 as default printing encoding */ + // 8-bit 'encoding' is not supported + // Use latin1 as default printing encoding p_encoding = (char_u *)"latin1"; if (!prt_find_resource((char *)p_encoding, &res_encoding)) { EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""), @@ -2554,7 +2565,7 @@ int mch_print_begin(prt_settings_T *psettings) if (*p_encoding == NUL) p_encoding = enc_skip(p_enc); if (prt_use_courier) { - /* Include ASCII range encoding vector */ + // Include ASCII range encoding vector if (!prt_find_resource(prt_ascii_encoding, &res_encoding)) { EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""), prt_ascii_encoding); @@ -2579,7 +2590,7 @@ int mch_print_begin(prt_settings_T *psettings) prt_do_conv = prt_conv.vc_type != CONV_NONE; if (prt_out_mbyte && prt_custom_cmap) { - /* Find user supplied CMap */ + // Find user supplied CMap if (!prt_find_resource(prt_cmap, &res_cmap)) { EMSG2(_("E456: Can't find PostScript resource file \"%s.ps\""), prt_cmap); @@ -2589,7 +2600,7 @@ int mch_print_begin(prt_settings_T *psettings) return FALSE; } - /* List resources supplied */ + // List resources supplied STRCPY(buffer, res_prolog.title); STRCAT(buffer, " "); STRCAT(buffer, res_prolog.version); @@ -2623,9 +2634,10 @@ int mch_print_begin(prt_settings_T *psettings) */ prt_dsc_noarg("BeginDefaults"); - /* List font resources most likely common to all pages */ - if (!prt_out_mbyte || prt_use_courier) + // List font resources most likely common to all pages + if (!prt_out_mbyte || prt_use_courier) { prt_dsc_font_resource("PageResources", &prt_ps_courier_font); + } if (prt_out_mbyte) { prt_dsc_font_resource((prt_use_courier ? NULL : "PageResources"), &prt_ps_mb_font); @@ -2633,7 +2645,7 @@ int mch_print_begin(prt_settings_T *psettings) prt_dsc_resources(NULL, "cmap", prt_cmap); } - /* Paper will be used for all pages */ + // Paper will be used for all pages prt_dsc_textline("PageMedia", prt_mediasize[prt_media].name); prt_dsc_noarg("EndDefaults"); @@ -2643,15 +2655,18 @@ int mch_print_begin(prt_settings_T *psettings) */ prt_dsc_noarg("BeginProlog"); - /* Add required procsets - NOTE: order is important! */ - if (!prt_add_resource(&res_prolog)) - return FALSE; + // Add required procsets - NOTE: order is important! + if (!prt_add_resource(&res_prolog)) { + return false; + } if (prt_out_mbyte) { - /* Add CID font procset, and any user supplied CMap */ - if (!prt_add_resource(&res_cidfont)) - return FALSE; - if (prt_custom_cmap && !prt_add_resource(&res_cmap)) - return FALSE; + // Add CID font procset, and any user supplied CMap + if (!prt_add_resource(&res_cidfont)) { + return false; + } + if (prt_custom_cmap && !prt_add_resource(&res_cmap)) { + return false; + } } if (!prt_out_mbyte || prt_use_courier) @@ -2667,7 +2682,7 @@ int mch_print_begin(prt_settings_T *psettings) */ prt_dsc_noarg("BeginSetup"); - /* Device setup - page size and number of uncollated copies */ + // Device setup - page size and number of uncollated copies prt_write_int((int)prt_mediasize[prt_media].width); prt_write_int((int)prt_mediasize[prt_media].height); prt_write_int(0); @@ -2680,7 +2695,7 @@ int mch_print_begin(prt_settings_T *psettings) prt_write_boolean(prt_collate); prt_write_string("c\n"); - /* Font resource inclusion and definition */ + // Font resource inclusion and definition if (!prt_out_mbyte || prt_use_courier) { /* When using Courier for ASCII range when printing multi-byte, need to * pick up ASCII encoding to use with it. */ @@ -2723,35 +2738,36 @@ int mch_print_begin(prt_settings_T *psettings) if (!prt_custom_cmap) prt_dsc_resources("IncludeResource", "cmap", prt_cmap); prt_def_cidfont("CF1", (int)prt_line_height, - prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD]); - } else - /* Use ROMAN for BOLD */ + prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLD]); + } else { + // Use ROMAN for BOLD prt_dup_cidfont("CF0", "CF1"); - + } if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE] != NULL) { prt_dsc_resources("IncludeResource", "font", prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]); if (!prt_custom_cmap) prt_dsc_resources("IncludeResource", "cmap", prt_cmap); prt_def_cidfont("CF2", (int)prt_line_height, - prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]); - } else - /* Use ROMAN for OBLIQUE */ + prt_ps_mb_font.ps_fontname[PRT_PS_FONT_OBLIQUE]); + } else { + // Use ROMAN for OBLIQUE prt_dup_cidfont("CF0", "CF2"); - + } if (prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE] != NULL) { prt_dsc_resources("IncludeResource", "font", prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]); if (!prt_custom_cmap) prt_dsc_resources("IncludeResource", "cmap", prt_cmap); prt_def_cidfont("CF3", (int)prt_line_height, - prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]); - } else - /* Use BOLD for BOLDOBLIQUE */ + prt_ps_mb_font.ps_fontname[PRT_PS_FONT_BOLDOBLIQUE]); + } else { + // Use BOLD for BOLDOBLIQUE prt_dup_cidfont("CF1", "CF3"); + } } - /* Misc constant vars used for underlining and background rects */ + // Misc constant vars used for underlining and background rects prt_def_var("UO", PRT_PS_FONT_TO_USER(prt_line_height, prt_ps_font->uline_offset), 2); prt_def_var("UW", PRT_PS_FONT_TO_USER(prt_line_height, @@ -2760,7 +2776,7 @@ int mch_print_begin(prt_settings_T *psettings) prt_dsc_noarg("EndSetup"); - /* Fail if any problems writing out to the PS file */ + // Fail if any problems writing out to the PS file retval = !prt_file_error; return retval; @@ -2783,7 +2799,7 @@ void mch_print_end(prt_settings_T *psettings) if (!prt_file_error && psettings->outfile == NULL && !got_int && !psettings->user_abort) { - /* Close the file first. */ + // Close the file first. if (prt_ps_fd != NULL) { fclose(prt_ps_fd); prt_ps_fd = NULL; @@ -2834,7 +2850,7 @@ int mch_print_begin_page(char_u *str) prt_bgcol = PRCOLOR_WHITE; prt_font = PRT_PS_FONT_ROMAN; - /* Set up page transformation for landscape printing. */ + // Set up page transformation for landscape printing. if (!prt_portrait) { prt_write_int(-((int)prt_mediasize[prt_media].width)); prt_write_string("sl\n"); @@ -2842,7 +2858,7 @@ int mch_print_begin_page(char_u *str) prt_dsc_noarg("EndPageSetup"); - /* We have reset the font attributes, force setting them again. */ + // We have reset the font attributes, force setting them again. curr_bg = 0xffffffff; curr_fg = 0xffffffff; curr_bold = kNone; @@ -2868,9 +2884,9 @@ void mch_print_start_line(const bool margin, const int page_line) prt_pos_y = prt_top_margin - prt_first_line_height - page_line * prt_line_height; - prt_attribute_change = TRUE; - prt_need_moveto = TRUE; - prt_half_width = FALSE; + prt_attribute_change = true; + prt_need_moveto = true; + prt_half_width = false; } int mch_print_text_out(char_u *const textp, size_t len) @@ -2892,16 +2908,16 @@ int mch_print_text_out(char_u *const textp, size_t len) const bool in_ascii = (len == 1 && *p < 0x80); if (prt_in_ascii) { if (!in_ascii) { - /* No longer in ASCII range - need to switch font */ - prt_in_ascii = FALSE; - prt_need_font = TRUE; - prt_attribute_change = TRUE; + // No longer in ASCII range - need to switch font + prt_in_ascii = false; + prt_need_font = true; + prt_attribute_change = true; } } else if (in_ascii) { - /* Now in ASCII range - need to switch font */ - prt_in_ascii = TRUE; - prt_need_font = TRUE; - prt_attribute_change = TRUE; + // Now in ASCII range - need to switch font + prt_in_ascii = true; + prt_need_font = true; + prt_attribute_change = true; } } if (prt_out_mbyte) { @@ -2911,16 +2927,16 @@ int mch_print_text_out(char_u *const textp, size_t len) } if (prt_half_width) { if (!half_width) { - prt_half_width = FALSE; + prt_half_width = false; prt_pos_x += prt_char_width/4; - prt_need_moveto = TRUE; - prt_attribute_change = TRUE; + prt_need_moveto = true; + prt_attribute_change = true; } } else if (half_width) { - prt_half_width = TRUE; + prt_half_width = true; prt_pos_x += prt_char_width/4; - prt_need_moveto = TRUE; - prt_attribute_change = TRUE; + prt_need_moveto = true; + prt_attribute_change = true; } } @@ -2929,24 +2945,25 @@ int mch_print_text_out(char_u *const textp, size_t len) */ if (prt_attribute_change) { prt_flush_buffer(); - /* Reset count of number of chars that will be printed */ + // Reset count of number of chars that will be printed prt_text_run = 0; if (prt_need_moveto) { prt_pos_x_moveto = prt_pos_x; prt_pos_y_moveto = prt_pos_y; - prt_do_moveto = TRUE; + prt_do_moveto = true; - prt_need_moveto = FALSE; + prt_need_moveto = false; } if (prt_need_font) { - if (!prt_in_ascii) + if (!prt_in_ascii) { prt_write_string("CF"); - else + } else { prt_write_string("F"); + } prt_write_int(prt_font); prt_write_string("sf\n"); - prt_need_font = FALSE; + prt_need_font = false; } if (prt_need_fgcol) { unsigned int r, g, b; @@ -2962,22 +2979,24 @@ int mch_print_text_out(char_u *const textp, size_t len) prt_write_real(b / 255.0, 3); prt_write_string("r\n"); } - prt_need_fgcol = FALSE; + prt_need_fgcol = false; } if (prt_bgcol != PRCOLOR_WHITE) { prt_new_bgcol = prt_bgcol; - if (prt_need_bgcol) - prt_do_bgcol = TRUE; - } else - prt_do_bgcol = FALSE; - prt_need_bgcol = FALSE; + if (prt_need_bgcol) { + prt_do_bgcol = true; + } + } else { + prt_do_bgcol = false; + } + prt_need_bgcol = false; if (prt_need_underline) prt_do_underline = prt_underline; - prt_need_underline = FALSE; + prt_need_underline = false; - prt_attribute_change = FALSE; + prt_attribute_change = false; } if (prt_do_conv) { @@ -3062,29 +3081,29 @@ void mch_print_set_font(const TriState iBold, const TriState iItalic, if (font != prt_font) { prt_font = font; - prt_attribute_change = TRUE; - prt_need_font = TRUE; + prt_attribute_change = true; + prt_need_font = true; } if (prt_underline != iUnderline) { prt_underline = iUnderline; - prt_attribute_change = TRUE; - prt_need_underline = TRUE; + prt_attribute_change = true; + prt_need_underline = true; } } void mch_print_set_bg(uint32_t bgcol) { prt_bgcol = bgcol; - prt_attribute_change = TRUE; - prt_need_bgcol = TRUE; + prt_attribute_change = true; + prt_need_bgcol = true; } void mch_print_set_fg(uint32_t fgcol) { if (fgcol != prt_fgcol) { prt_fgcol = fgcol; - prt_attribute_change = TRUE; - prt_need_fgcol = TRUE; + prt_attribute_change = true; + prt_need_fgcol = true; } } diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c index 0f9984ec38..2af09f10cb 100644 --- a/src/nvim/if_cscope.c +++ b/src/nvim/if_cscope.c @@ -71,10 +71,10 @@ static void cs_usage_msg(csid_e x) static enum { - EXP_CSCOPE_SUBCMD, /* expand ":cscope" sub-commands */ - EXP_SCSCOPE_SUBCMD, /* expand ":scscope" sub-commands */ - EXP_CSCOPE_FIND, /* expand ":cscope find" arguments */ - EXP_CSCOPE_KILL /* expand ":cscope kill" arguments */ + EXP_CSCOPE_SUBCMD, // expand ":cscope" sub-commands + EXP_SCSCOPE_SUBCMD, // expand ":scscope" sub-commands + EXP_CSCOPE_FIND, // expand ":cscope find" arguments + EXP_CSCOPE_KILL // expand ":cscope kill" arguments } expand_what; /* @@ -87,13 +87,13 @@ char_u *get_cscope_name(expand_T *xp, int idx) switch (expand_what) { case EXP_CSCOPE_SUBCMD: - /* Complete with sub-commands of ":cscope": - * add, find, help, kill, reset, show */ + // Complete with sub-commands of ":cscope": + // add, find, help, kill, reset, show return (char_u *)cs_cmds[idx].name; case EXP_SCSCOPE_SUBCMD: { - /* Complete with sub-commands of ":scscope": same sub-commands as - * ":cscope" but skip commands which don't support split windows */ + // Complete with sub-commands of ":scscope": same sub-commands as + // ":cscope" but skip commands which don't support split windows int i; for (i = 0, current_idx = 0; cs_cmds[i].name != NULL; i++) if (cs_cmds[i].cansplit) @@ -118,10 +118,10 @@ char_u *get_cscope_name(expand_T *xp, int idx) { static char connection[5]; - /* ":cscope kill" accepts connection numbers or partial names of - * the pathname of the cscope database as argument. Only complete - * with connection numbers. -1 can also be used to kill all - * connections. */ + // ":cscope kill" accepts connection numbers or partial names of + // the pathname of the cscope database as argument. Only complete + // with connection numbers. -1 can also be used to kill all + // connections. size_t i; for (i = 0, current_idx = 0; i < csinfo_size; i++) { if (csinfo[i].fname == NULL) @@ -149,7 +149,7 @@ void set_context_in_cscope_cmd(expand_T *xp, const char *arg, cmdidx_T cmdidx) expand_what = ((cmdidx == CMD_scscope) ? EXP_SCSCOPE_SUBCMD : EXP_CSCOPE_SUBCMD); - /* (part of) subcommand already typed */ + // (part of) subcommand already typed if (*arg != NUL) { const char *p = (const char *)skiptowhite((const char_u *)arg); if (*p != NUL) { // Past first word. @@ -175,7 +175,7 @@ void set_context_in_cscope_cmd(expand_T *xp, const char *arg, cmdidx_T cmdidx) static void do_cscope_general( exarg_T *eap, - int make_split /* whether to split window */ + int make_split // whether to split window ) { cscmd_T *cmdp; @@ -276,17 +276,19 @@ void ex_cstag(exarg_T *eap) /// This simulates a vim_fgets(), but for cscope, returns the next line /// from the cscope output. should only be called from find_tags() /// -/// @return TRUE if eof, FALSE otherwise -int cs_fgets(char_u *buf, int size) +/// @return true if eof, FALSE otherwise +bool cs_fgets(char_u *buf, int size) + FUNC_ATTR_NONNULL_ALL { char *p; - if ((p = cs_manage_matches(NULL, NULL, 0, Get)) == NULL) + if ((p = cs_manage_matches(NULL, NULL, 0, Get)) == NULL) { return true; + } STRLCPY(buf, p, size); - return FALSE; -} /* cs_fgets */ + return false; +} /// Called only from do_tag(), when popping the tag stack. @@ -328,48 +330,53 @@ void cs_print_tags(void) * * Note: All string comparisons are case sensitive! */ -int cs_connection(int num, char_u *dbpath, char_u *ppath) +bool cs_connection(int num, char_u *dbpath, char_u *ppath) { - if (num < 0 || num > 4 || (num > 0 && !dbpath)) + if (num < 0 || num > 4 || (num > 0 && !dbpath)) { return false; + } for (size_t i = 0; i < csinfo_size; i++) { - if (!csinfo[i].fname) + if (!csinfo[i].fname) { continue; - - if (num == 0) - return TRUE; - + } + if (num == 0) { + return true; + } switch (num) { case 1: - if (strstr(csinfo[i].fname, (char *)dbpath)) - return TRUE; + if (strstr(csinfo[i].fname, (char *)dbpath)) { + return true; + } break; case 2: - if (strcmp(csinfo[i].fname, (char *)dbpath) == 0) - return TRUE; + if (strcmp(csinfo[i].fname, (char *)dbpath) == 0) { + return true; + } break; case 3: if (strstr(csinfo[i].fname, (char *)dbpath) && ((!ppath && !csinfo[i].ppath) || (ppath && csinfo[i].ppath - && strstr(csinfo[i].ppath, (char *)ppath)))) - return TRUE; + && strstr(csinfo[i].ppath, (char *)ppath)))) { + return true; + } break; case 4: if ((strcmp(csinfo[i].fname, (char *)dbpath) == 0) && ((!ppath && !csinfo[i].ppath) || (ppath && csinfo[i].ppath - && (strcmp(csinfo[i].ppath, (char *)ppath) == 0)))) - return TRUE; + && (strcmp(csinfo[i].ppath, (char *)ppath) == 0)))) { + return true; + } break; } } - return FALSE; -} /* cs_connection */ + return false; +} // cs_connection /* @@ -419,7 +426,7 @@ cs_add_common( size_t usedlen = 0; char_u *fbuf = NULL; - /* get the filename (arg1), expand it, and try to stat it */ + // get the filename (arg1), expand it, and try to stat it fname = xmalloc(MAXPATHL + 1); expand_env((char_u *)arg1, (char_u *)fname, MAXPATHL); @@ -451,7 +458,7 @@ staterr: } int i; - /* if filename is a directory, append the cscope database name to it */ + // if filename is a directory, append the cscope database name to it if ((file_info.stat.st_mode & S_IFMT) == S_IFDIR) { fname2 = (char *)xmalloc(strlen(CSCOPE_DBFILE) + strlen(fname) + 2); @@ -512,18 +519,18 @@ add_err: xfree(fname); xfree(ppath); return CSCOPE_FAILURE; -} /* cs_add_common */ +} static int cs_check_for_connections(void) { return cs_cnt_connections() > 0; -} /* cs_check_for_connections */ +} static int cs_check_for_tags(void) { return p_tags[0] != NUL && curbuf->b_p_tags != NULL; -} /* cs_check_for_tags */ +} /// Count the number of cscope connections. static size_t cs_cnt_connections(void) @@ -535,10 +542,10 @@ static size_t cs_cnt_connections(void) cnt++; } return cnt; -} /* cs_cnt_connections */ +} static void cs_reading_emsg( - size_t idx /* connection index */ + size_t idx // connection index ) { EMSGU(_("E262: error reading cscope connection %" PRIu64), idx); @@ -602,7 +609,7 @@ static int cs_cnt_matches(size_t idx) xfree(buf); return nlines; -} /* cs_cnt_matches */ +} /// Creates the actual cscope command query from what the user entered. @@ -646,8 +653,8 @@ static char *cs_create_cmd(char *csoption, char *pattern) return NULL; } - /* Skip white space before the patter, except for text and pattern search, - * they may want to use the leading white space. */ + // Skip white space before the patter, except for text and pattern search, + // they may want to use the leading white space. pat = pattern; if (search != 4 && search != 6) while (ascii_iswhite(*pat)) @@ -658,7 +665,7 @@ static char *cs_create_cmd(char *csoption, char *pattern) (void)sprintf(cmd, "%d%s", search, pat); return cmd; -} /* cs_create_cmd */ +} /// This piece of code was taken/adapted from nvi. do we need to add @@ -694,15 +701,18 @@ err_closing: case -1: (void)EMSG(_("E622: Could not fork for cscope")); goto err_closing; - case 0: /* child: run cscope. */ - if (dup2(to_cs[0], STDIN_FILENO) == -1) + case 0: // child: run cscope. + if (dup2(to_cs[0], STDIN_FILENO) == -1) { PERROR("cs_create_connection 1"); - if (dup2(from_cs[1], STDOUT_FILENO) == -1) + } + if (dup2(from_cs[1], STDOUT_FILENO) == -1) { PERROR("cs_create_connection 2"); - if (dup2(from_cs[1], STDERR_FILENO) == -1) + } + if (dup2(from_cs[1], STDERR_FILENO) == -1) { PERROR("cs_create_connection 3"); + } - /* close unused */ + // close unused (void)close(to_cs[1]); (void)close(from_cs[0]); #else @@ -735,14 +745,14 @@ err_closing: return CSCOPE_FAILURE; } #endif - /* expand the cscope exec for env var's */ + // expand the cscope exec for env var's prog = xmalloc(MAXPATHL + 1); expand_env(p_csprg, (char_u *)prog, MAXPATHL); - /* alloc space to hold the cscope command */ + // alloc space to hold the cscope command size_t len = strlen(prog) + strlen(csinfo[i].fname) + 32; if (csinfo[i].ppath) { - /* expand the prepend path for env var's */ + // expand the prepend path for env var's ppath = xmalloc(MAXPATHL + 1); expand_env((char_u *)csinfo[i].ppath, (char_u *)ppath, MAXPATHL); @@ -754,12 +764,12 @@ err_closing: cmd = xmalloc(len); - /* run the cscope command; is there execl for non-unix systems? */ + // run the cscope command; is there execl for non-unix systems? #if defined(UNIX) - (void)sprintf(cmd, "exec %s -dl -f %s", prog, csinfo[i].fname); + (void)snprintf(cmd, len, "exec %s -dl -f %s", prog, csinfo[i].fname); #else - /* WIN32 */ - (void)sprintf(cmd, "%s -dl -f %s", prog, csinfo[i].fname); + // WIN32 + (void)snprintf(cmd, len, "%s -dl -f %s", prog, csinfo[i].fname); #endif if (csinfo[i].ppath != NULL) { (void)strcat(cmd, " -P"); @@ -770,14 +780,14 @@ err_closing: (void)strcat(cmd, csinfo[i].flags); } # ifdef UNIX - /* on Win32 we still need prog */ + // on Win32 we still need prog xfree(prog); # endif xfree(ppath); #if defined(UNIX) # if defined(HAVE_SETSID) || defined(HAVE_SETPGID) - /* Change our process group to avoid cscope receiving SIGWINCH. */ + // Change our process group to avoid cscope receiving SIGWINCH. # if defined(HAVE_SETSID) (void)setsid(); # else @@ -789,18 +799,18 @@ err_closing: PERROR(_("cs_create_connection exec failed")); exit(127); - /* NOTREACHED */ - default: /* parent. */ - /* - * Save the file descriptors for later duplication, and - * reopen as streams. - */ - if ((csinfo[i].to_fp = fdopen(to_cs[1], "w")) == NULL) + // NOTREACHED + default: // parent. + // Save the file descriptors for later duplication, and + // reopen as streams. + if ((csinfo[i].to_fp = fdopen(to_cs[1], "w")) == NULL) { PERROR(_("cs_create_connection: fdopen for to_fp failed")); - if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL) + } + if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL) { PERROR(_("cs_create_connection: fdopen for fr_fp failed")); + } - /* close unused */ + // close unused (void)close(to_cs[0]); (void)close(from_cs[1]); @@ -808,11 +818,11 @@ err_closing: } #else - /* WIN32 */ - /* Create a new process to run cscope and use pipes to talk with it */ + // WIN32 + // Create a new process to run cscope and use pipes to talk with it GetStartupInfo(&si); si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; - si.wShowWindow = SW_HIDE; /* Hide child application window */ + si.wShowWindow = SW_HIDE; // Hide child application window si.hStdOutput = stdout_wr; si.hStdError = stdout_wr; si.hStdInput = stdin_rd; @@ -826,7 +836,7 @@ err_closing: (void)EMSG(_("E623: Could not spawn cscope process")); goto err_closing; } - /* else */ + // else csinfo[i].pid = pi.dwProcessId; csinfo[i].hProc = pi.hProcess; CloseHandle(pi.hThread); @@ -844,10 +854,10 @@ err_closing: CloseHandle(stdin_rd); CloseHandle(stdout_wr); -#endif /* !UNIX */ +#endif // !UNIX return CSCOPE_SUCCESS; -} /* cs_create_connection */ +} /// Query cscope using command line interface. Parse the output and use tselect @@ -882,9 +892,9 @@ static int cs_find(exarg_T *eap) if (NUL == eap->arg[i]) eap->arg[i] = ' '; - return cs_find_common(opt, pat, eap->forceit, TRUE, - eap->cmdidx == CMD_lcscope, *eap->cmdlinep); -} /* cs_find */ + return cs_find_common(opt, pat, eap->forceit, true, + eap->cmdidx == CMD_lcscope, *eap->cmdlinep); +} /// Common code for cscope find, shared by cs_find() and ex_cstag(). @@ -897,7 +907,7 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose, char cmdletter; char *qfpos; - /* get cmd letter */ + // get cmd letter switch (opt[0]) { case '0': cmdletter = 's'; @@ -933,10 +943,10 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose, qfpos = (char *)vim_strchr(p_csqf, cmdletter); if (qfpos != NULL) { qfpos++; - /* next symbol must be + or - */ + // next symbol must be + or - if (strchr(CSQF_FLAGS, *qfpos) == NULL) { char *nf = _("E469: invalid cscopequickfix flag %c for %c"); - /* strlen will be enough because we use chars */ + // strlen will be enough because we use chars char *buf = xmalloc(strlen(nf)); sprintf(buf, nf, *qfpos, *(qfpos-1)); @@ -954,23 +964,24 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose, } } - /* create the actual command to send to cscope */ + // create the actual command to send to cscope cmd = cs_create_cmd(opt, pat); if (cmd == NULL) return FALSE; nummatches = xmalloc(sizeof(int) * csinfo_size); - /* Send query to all open connections, then count the total number - * of matches so we can alloc all in one swell foop. */ - for (size_t i = 0; i < csinfo_size; i++) + // Send query to all open connections, then count the total number + // of matches so we can alloc all in one swell foop. + for (size_t i = 0; i < csinfo_size; i++) { nummatches[i] = 0; + } totmatches = 0; for (size_t i = 0; i < csinfo_size; i++) { if (csinfo[i].fname == NULL || csinfo[i].to_fp == NULL) continue; - /* send cmd to cscope */ + // send cmd to cscope (void)fprintf(csinfo[i].to_fp, "%s\n", cmd); (void)fflush(csinfo[i].to_fp); @@ -1014,8 +1025,9 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose, } else { cs_file_results(f, nummatches); fclose(f); - if (use_ll) /* Use location list */ + if (use_ll) { // Use location list wp = curwin; + } // '-' starts a new error list if (qf_init(wp, tmp, (char_u *)"%f%*\\t%l%*\\t%m", *qfpos == '-', cmdline, NULL) > 0) { @@ -1046,7 +1058,7 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose, char **matches = NULL, **contexts = NULL; size_t matched = 0; - /* read output */ + // read output cs_fill_results((char *)pat, totmatches, nummatches, &matches, &contexts, &matched); xfree(nummatches); @@ -1057,8 +1069,7 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose, return do_tag((char_u *)pat, DT_CSCOPE, 0, forceit, verbose); } - -} /* cs_find_common */ +} /// Print help. static int cs_help(exarg_T *eap) @@ -1070,9 +1081,10 @@ static int cs_help(exarg_T *eap) char *help = _(cmdp->help); int space_cnt = 30 - vim_strsize((char_u *)help); - /* Use %*s rather than %30s to ensure proper alignment in utf-8 */ - if (space_cnt < 0) + // Use %*s rather than %30s to ensure proper alignment in utf-8 + if (space_cnt < 0) { space_cnt = 0; + } (void)smsg(_("%-5s: %s%*s (Usage: %s)"), cmdp->name, help, space_cnt, " ", @@ -1094,7 +1106,7 @@ static int cs_help(exarg_T *eap) wait_return(TRUE); return CSCOPE_SUCCESS; -} /* cs_help */ +} static void clear_csinfo(size_t i) @@ -1124,7 +1136,7 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags, } if (csinfo[j].fname == NULL && !empty_found) { - i = j; /* remember first empty entry */ + i = j; // remember first empty entry empty_found = true; } } @@ -1132,13 +1144,13 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags, if (!empty_found) { i = csinfo_size; if (csinfo_size == 0) { - /* First time allocation: allocate only 1 connection. It should - * be enough for most users. If more is needed, csinfo will be - * reallocated. */ + // First time allocation: allocate only 1 connection. It should + // be enough for most users. If more is needed, csinfo will be + // reallocated. csinfo_size = 1; csinfo = xcalloc(1, sizeof(csinfo_T)); } else { - /* Reallocate space for more connections. */ + // Reallocate space for more connections. csinfo_size *= 2; csinfo = xrealloc(csinfo, sizeof(csinfo_T)*csinfo_size); } @@ -1165,7 +1177,7 @@ static int cs_insert_filelist(char *fname, char *ppath, char *flags, os_fileinfo_id(file_info, &(csinfo[i].file_id)); assert(i <= INT_MAX); return (int)i; -} /* cs_insert_filelist */ +} /// Find cscope command in command table. @@ -1178,7 +1190,7 @@ static cscmd_T * cs_lookup_cmd(exarg_T *eap) if (eap->arg == NULL) return NULL; - /* Store length of eap->arg before it gets modified by strtok(). */ + // Store length of eap->arg before it gets modified by strtok(). eap_arg_len = (int)STRLEN(eap->arg); if ((stok = strtok((char *)(eap->arg), (const char *)" ")) == NULL) @@ -1190,7 +1202,7 @@ static cscmd_T * cs_lookup_cmd(exarg_T *eap) return cmdp; } return NULL; -} /* cs_lookup_cmd */ +} /// Nuke em. @@ -1247,13 +1259,13 @@ static int cs_kill(exarg_T *eap) } return CSCOPE_SUCCESS; -} /* cs_kill */ +} /// Actually kills a specific cscope connection. static void cs_kill_execute( - size_t i, /* cscope table index */ - char *cname /* cscope database name */ + size_t i, // cscope table index + char *cname // cscope database name ) { if (p_csverbose) { @@ -1284,17 +1296,16 @@ static void cs_kill_execute( static char *cs_make_vim_style_matches(char *fname, char *slno, char *search, char *tagstr) { - /* vim style is ctags: - * - * <tagstr>\t<filename>\t<linenum_or_search>"\t<extra> - * - * but as mentioned above, we'll always use the line number and - * put the search pattern (if one exists) as "extra" - * - * buf is used as part of vim's method of handling tags, and - * (i think) vim frees it when you pop your tags and get replaced - * by new ones on the tag stack. - */ + // vim style is ctags: + // + // <tagstr>\t<filename>\t<linenum_or_search>"\t<extra> + // + // but as mentioned above, we'll always use the line number and + // put the search pattern (if one exists) as "extra" + // + // buf is used as part of vim's method of handling tags, and + // (i think) vim frees it when you pop your tags and get replaced + // by new ones on the tag stack. char *buf; size_t amt; @@ -1311,7 +1322,7 @@ static char *cs_make_vim_style_matches(char *fname, char *slno, char *search, } return buf; -} /* cs_make_vim_style_matches */ +} /// This is kind of hokey, but i don't see an easy way round this. @@ -1381,7 +1392,7 @@ static char *cs_manage_matches(char **matches, char **contexts, } return p; -} /* cs_manage_matches */ +} /// Parse cscope output. @@ -1408,7 +1419,7 @@ retry: return NULL; } - /* If the line's too long for the buffer, discard it. */ + // If the line's too long for the buffer, discard it. if ((p = strchr(buf, '\n')) == NULL) { while ((ch = getc(csinfo[cnumber].fr_fp)) != EOF && ch != '\n') ; @@ -1427,15 +1438,15 @@ retry: return NULL; if ((*linenumber = strtok(NULL, (const char *)" ")) == NULL) return NULL; - *search = *linenumber + strlen(*linenumber) + 1; /* +1 to skip \0 */ + *search = *linenumber + strlen(*linenumber) + 1; // +1 to skip \0 - /* --- nvi --- - * If the file is older than the cscope database, that is, - * the database was built since the file was last modified, - * or there wasn't a search string, use the line number. - */ - if (strcmp(*search, "<unknown>") == 0) + // --- nvi --- + // If the file is older than the cscope database, that is, + // the database was built since the file was last modified, + // or there wasn't a search string, use the line number. + if (strcmp(*search, "<unknown>") == 0) { *search = NULL; + } name = cs_resolve_file(cnumber, name); return name; @@ -1474,11 +1485,10 @@ static void cs_file_results(FILE *f, int *nummatches_a) xfree(context); xfree(fullname); - } /* for all matches */ + } // for all matches (void)cs_read_prompt(i); - - } /* for all cscope connections */ + } // for all cscope connections xfree(buf); } @@ -1539,10 +1549,10 @@ static void cs_fill_results(char *tagstr, size_t totmatches, int *nummatches_a, *cntxts_p = cntxts; xfree(buf); -} // cs_fill_results +} -/* get the requested path components */ +// get the requested path components static char *cs_pathcomponents(char *path) { if (p_cspc == 0) { @@ -1688,7 +1698,7 @@ static int cs_read_prompt(size_t i) static char *eprompt = "Press the RETURN key to continue:"; size_t epromptlen = strlen(eprompt); - /* compute maximum allowed len for Cscope error message */ + // compute maximum allowed len for Cscope error message assert(IOSIZE >= cs_emsg_len); size_t maxlen = IOSIZE - cs_emsg_len; @@ -1738,11 +1748,12 @@ static int cs_read_prompt(size_t i) } if (ch == EOF) { PERROR("cs_read_prompt EOF"); - if (buf != NULL && buf[0] != NUL) + if (buf != NULL && buf[0] != NUL) { (void)EMSG2(cs_emsg, buf); - else if (p_csverbose) - cs_reading_emsg(i); /* don't have additional information */ - cs_release_csp(i, TRUE); + } else if (p_csverbose) { + cs_reading_emsg(i); // don't have additional information + } + cs_release_csp(i, true); xfree(buf); return CSCOPE_FAILURE; } @@ -1753,9 +1764,10 @@ static int cs_read_prompt(size_t i) } } - if (ch == EOF) - continue; /* didn't find the prompt */ - break; /* did find the prompt */ + if (ch == EOF) { + continue; // didn't find the prompt + } + break; // did find the prompt } xfree(buf); @@ -1766,8 +1778,9 @@ static int cs_read_prompt(size_t i) /* * Used to catch and ignore SIGALRM below. */ -static void sig_handler(int s) { - /* do nothing */ +static void sig_handler(int s) +{ + // do nothing return; } @@ -1775,7 +1788,7 @@ static void sig_handler(int s) { /// Does the actual free'ing for the cs ptr with an optional flag of whether /// or not to free the filename. Called by cs_kill and cs_reset. -static void cs_release_csp(size_t i, int freefnpp) +static void cs_release_csp(size_t i, bool freefnpp) { // Trying to exit normally (not sure whether it is fit to Unix cscope) if (csinfo[i].to_fp != NULL) { @@ -1791,7 +1804,7 @@ static void cs_release_csp(size_t i, int freefnpp) # if defined(HAVE_SIGACTION) struct sigaction sa, old; - /* Use sigaction() to limit the waiting time to two seconds. */ + // Use sigaction() to limit the waiting time to two seconds. sigemptyset(&sa.sa_mask); sa.sa_handler = sig_handler; # ifdef SA_NODEFER @@ -1800,27 +1813,28 @@ static void cs_release_csp(size_t i, int freefnpp) sa.sa_flags = 0; # endif sigaction(SIGALRM, &sa, &old); - alarm(2); /* 2 sec timeout */ + alarm(2); // 2 sec timeout - /* Block until cscope exits or until timer expires */ + // Block until cscope exits or until timer expires pid = waitpid(csinfo[i].pid, &pstat, 0); waitpid_errno = errno; - /* cancel pending alarm if still there and restore signal */ + // cancel pending alarm if still there and restore signal alarm(0); sigaction(SIGALRM, &old, NULL); # else int waited; - /* Can't use sigaction(), loop for two seconds. First yield the CPU - * to give cscope a chance to exit quickly. */ + // Can't use sigaction(), loop for two seconds. First yield the CPU + // to give cscope a chance to exit quickly. sleep(0); for (waited = 0; waited < 40; ++waited) { pid = waitpid(csinfo[i].pid, &pstat, WNOHANG); waitpid_errno = errno; - if (pid != 0) - break; /* break unless the process is still running */ - os_delay(50L, false); /* sleep 50 ms */ + if (pid != 0) { + break; // break unless the process is still running + } + os_delay(50L, false); // sleep 50 ms } # endif /* @@ -1830,7 +1844,7 @@ static void cs_release_csp(size_t i, int freefnpp) */ if (pid < 0 && csinfo[i].pid > 1) { # ifdef ECHILD - int alive = TRUE; + bool alive = true; if (waitpid_errno == ECHILD) { /* @@ -1845,13 +1859,13 @@ static void cs_release_csp(size_t i, int freefnpp) int waited; sleep(0); - for (waited = 0; waited < 40; ++waited) { - /* Check whether cscope process is still alive */ + for (waited = 0; waited < 40; waited++) { + // Check whether cscope process is still alive if (kill(csinfo[i].pid, 0) != 0) { - alive = FALSE; /* cscope process no longer exists */ + alive = false; // cscope process no longer exists break; } - os_delay(50L, false); /* sleep 50ms */ + os_delay(50L, false); // sleep 50ms } } if (alive) @@ -1862,11 +1876,12 @@ static void cs_release_csp(size_t i, int freefnpp) } } } -#else /* !UNIX */ +#else // !UNIX if (csinfo[i].hProc != NULL) { - /* Give cscope a chance to exit normally */ - if (WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT) + // Give cscope a chance to exit normally + if (WaitForSingleObject(csinfo[i].hProc, 1000) == WAIT_TIMEOUT) { TerminateProcess(csinfo[i].hProc, 0); + } CloseHandle(csinfo[i].hProc); } #endif @@ -1883,7 +1898,7 @@ static void cs_release_csp(size_t i, int freefnpp) } clear_csinfo(i); -} /* cs_release_csp */ +} /// Calls cs_kill on all cscope connections then reinits. @@ -1895,7 +1910,7 @@ static int cs_reset(exarg_T *eap) if (csinfo_size == 0) return CSCOPE_SUCCESS; - /* malloc our db and ppath list */ + // malloc our db and ppath list dblist = xmalloc(csinfo_size * sizeof(char *)); pplist = xmalloc(csinfo_size * sizeof(char *)); fllist = xmalloc(csinfo_size * sizeof(char *)); @@ -1908,15 +1923,14 @@ static int cs_reset(exarg_T *eap) cs_release_csp(i, FALSE); } - /* rebuild the cscope connection list */ + // rebuild the cscope connection list for (size_t i = 0; i < csinfo_size; i++) { if (dblist[i] != NULL) { cs_add_common(dblist[i], pplist[i], fllist[i]); if (p_csverbose) { - /* don't use smsg_attr() because we want to display the - * connection number in the same line as - * "Added cscope database..." - */ + // don't use smsg_attr() because we want to display the + // connection number in the same line as + // "Added cscope database..." snprintf(buf, ARRAY_SIZE(buf), " (#%zu)", i); MSG_PUTS_ATTR(buf, HL_ATTR(HLF_R)); } @@ -1933,7 +1947,7 @@ static int cs_reset(exarg_T *eap) msg_attr(_("All cscope databases reset"), HL_ATTR(HLF_R) | MSG_HIST); } return CSCOPE_SUCCESS; -} /* cs_reset */ +} /// Construct the full pathname to a file found in the cscope database. @@ -1954,11 +1968,11 @@ static char *cs_resolve_file(size_t i, char *name) * copied into the tag buffer used by Vim. */ size_t len = strlen(name) + 2; - if (csinfo[i].ppath != NULL) + if (csinfo[i].ppath != NULL) { len += strlen(csinfo[i].ppath); - else if (p_csre && csinfo[i].fname != NULL) { - /* If 'cscoperelative' is set and ppath is not set, use cscope.out - * path in path resolution. */ + } else if (p_csre && csinfo[i].fname != NULL) { + // If 'cscoperelative' is set and ppath is not set, use cscope.out + // path in path resolution. csdir = xmalloc(MAXPATHL); STRLCPY(csdir, csinfo[i].fname, path_tail((char_u *)csinfo[i].fname) @@ -1966,9 +1980,9 @@ static char *cs_resolve_file(size_t i, char *name) len += STRLEN(csdir); } - /* Note/example: this won't work if the cscope output already starts - * "../.." and the prefix path is also "../..". if something like this - * happens, you are screwed up and need to fix how you're using cscope. */ + // Note/example: this won't work if the cscope output already starts + // "../.." and the prefix path is also "../..". if something like this + // happens, you are screwed up and need to fix how you're using cscope. if (csinfo[i].ppath != NULL && (strncmp(name, csinfo[i].ppath, strlen(csinfo[i].ppath)) != 0) && (name[0] != '/') @@ -1976,9 +1990,9 @@ static char *cs_resolve_file(size_t i, char *name) fullname = xmalloc(len); (void)sprintf(fullname, "%s/%s", csinfo[i].ppath, name); } else if (csdir != NULL && csinfo[i].fname != NULL && *csdir != NUL) { - /* Check for csdir to be non empty to avoid empty path concatenated to - * cscope output. */ - fullname = concat_fnames((char *)csdir, name, TRUE); + // Check for csdir to be non empty to avoid empty path concatenated to + // cscope output. + fullname = concat_fnames((char *)csdir, name, true); } else { fullname = xstrdup(name); } @@ -2013,7 +2027,7 @@ static int cs_show(exarg_T *eap) wait_return(TRUE); return CSCOPE_SUCCESS; -} /* cs_show */ +} /// Only called when VIM exits to quit any cscope sessions. @@ -2025,4 +2039,4 @@ void cs_end(void) csinfo_size = 0; } -/* the end */ +// the end diff --git a/src/nvim/if_cscope_defs.h b/src/nvim/if_cscope_defs.h index fa18866840..d2d8b0fb62 100644 --- a/src/nvim/if_cscope_defs.h +++ b/src/nvim/if_cscope_defs.h @@ -1,19 +1,16 @@ #ifndef NVIM_IF_CSCOPE_DEFS_H #define NVIM_IF_CSCOPE_DEFS_H -/* - * CSCOPE support for Vim added by Andy Kahn <kahn@zk3.dec.com> - * Ported to Win32 by Sergey Khorev <sergey.khorev@gmail.com> - * - * 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. If this is a problem and requires inclusion of the annoying - * BSD license, then sue me; I'm not worth much anyway. - */ - +// CSCOPE support for Vim added by Andy Kahn <kahn@zk3.dec.com> +// Ported to Win32 by Sergey Khorev <sergey.khorev@gmail.com> +// +// 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. If this is a problem and requires inclusion of the annoying +// BSD license, then sue me; I'm not worth much anyway. #if defined(UNIX) -# include <sys/types.h> /* pid_t */ +# include <sys/types.h> // pid_t #endif #include "nvim/os/os_defs.h" @@ -33,13 +30,13 @@ typedef struct { int (*func)(exarg_T *eap); char * help; char * usage; - int cansplit; /* if supports splitting window */ + int cansplit; // if supports splitting window } cscmd_T; typedef struct csi { - char * fname; /* cscope db name */ - char * ppath; /* path to prepend (the -P option) */ - char * flags; /* additional cscope flags/options (e.g, -p2) */ + char * fname; // cscope db name + char * ppath; // path to prepend (the -P option) + char * flags; // additional cscope flags/options (e.g, -p2) #if defined(UNIX) pid_t pid; // PID of the connected cscope process #else @@ -51,8 +48,8 @@ typedef struct csi { #endif FileID file_id; - FILE * fr_fp; /* from cscope: FILE. */ - FILE * to_fp; /* to cscope: FILE. */ + FILE * fr_fp; // from cscope: FILE. + FILE * to_fp; // to cscope: FILE. } csinfo_T; typedef enum { Add, Find, Help, Kill, Reset, Show } csid_e; diff --git a/src/nvim/indent.c b/src/nvim/indent.c index f8018c039d..7f17fb0035 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -56,7 +56,8 @@ int get_indent_buf(buf_T *buf, linenr_T lnum) // Count the size (in window cells) of the indent in line "ptr", with // 'tabstop' at "ts". // If @param list is TRUE, count only screen size for tabs. -int get_indent_str(char_u *ptr, int ts, int list) +int get_indent_str(const char_u *ptr, int ts, int list) + FUNC_ATTR_NONNULL_ALL { int count = 0; @@ -375,12 +376,12 @@ int get_number_indent(linenr_T lnum) * parameters into account. Window must be specified, since it is not * necessarily always the current one. */ -int get_breakindent_win(win_T *wp, char_u *line) - FUNC_ATTR_NONNULL_ARG(1) +int get_breakindent_win(win_T *wp, const char_u *line) + FUNC_ATTR_NONNULL_ALL { static int prev_indent = 0; // Cached indent value. static long prev_ts = 0; // Cached tabstop value. - static char_u *prev_line = NULL; // cached pointer to line. + static const char_u *prev_line = NULL; // cached pointer to line. static varnumber_T prev_tick = 0; // Changedtick of cached value. int bri = 0; // window width minus window margin space, i.e. what rests for text @@ -389,7 +390,7 @@ int get_breakindent_win(win_T *wp, char_u *line) && (vim_strchr(p_cpo, CPO_NUMCOL) == NULL) ? number_width(wp) + 1 : 0); - /* used cached indent, unless pointer or 'tabstop' changed */ + // used cached indent, unless pointer or 'tabstop' changed if (prev_line != line || prev_ts != wp->w_buffer->b_p_ts || prev_tick != buf_get_changedtick(wp->w_buffer)) { prev_line = line; @@ -399,21 +400,22 @@ int get_breakindent_win(win_T *wp, char_u *line) } bri = prev_indent + wp->w_p_brishift; - /* indent minus the length of the showbreak string */ - if (wp->w_p_brisbr) + // indent minus the length of the showbreak string + if (wp->w_p_brisbr) { bri -= vim_strsize(p_sbr); - - /* Add offset for number column, if 'n' is in 'cpoptions' */ + } + // Add offset for number column, if 'n' is in 'cpoptions' bri += win_col_off2(wp); - /* never indent past left window margin */ - if (bri < 0) + // never indent past left window margin + if (bri < 0) { bri = 0; - /* always leave at least bri_min characters on the left, - * if text width is sufficient */ - else if (bri > eff_wwidth - wp->w_p_brimin) + } else if (bri > eff_wwidth - wp->w_p_brimin) { + // always leave at least bri_min characters on the left, + // if text width is sufficient bri = (eff_wwidth - wp->w_p_brimin < 0) ? 0 : eff_wwidth - wp->w_p_brimin; + } return bri; } diff --git a/src/nvim/keymap.h b/src/nvim/keymap.h index d3e887badc..ada9bc5780 100644 --- a/src/nvim/keymap.h +++ b/src/nvim/keymap.h @@ -13,7 +13,7 @@ * For MSDOS some keys produce codes larger than 0xff. They are split into two * chars, the first one is K_NUL. */ -#define K_NUL (0xce) /* for MSDOS: special key follows */ +#define K_NUL (0xce) // for MSDOS: special key follows /* * K_SPECIAL is the first byte of a special key code and is always followed by @@ -78,13 +78,13 @@ #define KS_SELECT 245 #define K_SELECT_STRING (char_u *)"\200\365X" -/* Used a termcap entry that produces a normal character. */ +// Used a termcap entry that produces a normal character. #define KS_KEY 242 -/* Used for click in a tab pages label. */ +// Used for click in a tab pages label. #define KS_TABLINE 240 -/* Used for menu in a tab pages line. */ +// Used for menu in a tab pages line. #define KS_TABMENU 239 /* @@ -274,13 +274,13 @@ enum key_extra { #define K_TAB TERMCAP2KEY(KS_EXTRA, KE_TAB) #define K_S_TAB TERMCAP2KEY('k', 'B') -/* extra set of function keys F1-F4, for vt100 compatible xterm */ +// extra set of function keys F1-F4, for vt100 compatible xterm #define K_XF1 TERMCAP2KEY(KS_EXTRA, KE_XF1) #define K_XF2 TERMCAP2KEY(KS_EXTRA, KE_XF2) #define K_XF3 TERMCAP2KEY(KS_EXTRA, KE_XF3) #define K_XF4 TERMCAP2KEY(KS_EXTRA, KE_XF4) -/* extra set of cursor keys for vt100 compatible xterm */ +// extra set of cursor keys for vt100 compatible xterm #define K_XUP TERMCAP2KEY(KS_EXTRA, KE_XUP) #define K_XDOWN TERMCAP2KEY(KS_EXTRA, KE_XDOWN) #define K_XLEFT TERMCAP2KEY(KS_EXTRA, KE_XLEFT) @@ -327,7 +327,7 @@ enum key_extra { #define K_F36 TERMCAP2KEY('F', 'Q') #define K_F37 TERMCAP2KEY('F', 'R') -/* extra set of shifted function keys F1-F4, for vt100 compatible xterm */ +// extra set of shifted function keys F1-F4, for vt100 compatible xterm #define K_S_XF1 TERMCAP2KEY(KS_EXTRA, KE_S_XF1) #define K_S_XF2 TERMCAP2KEY(KS_EXTRA, KE_S_XF2) #define K_S_XF3 TERMCAP2KEY(KS_EXTRA, KE_S_XF3) @@ -346,7 +346,7 @@ enum key_extra { #define K_S_F11 TERMCAP2KEY(KS_EXTRA, KE_S_F11) #define K_S_F12 TERMCAP2KEY(KS_EXTRA, KE_S_F12) -/* K_S_F13 to K_S_F37 are currently not used */ +// K_S_F13 to K_S_F37 are currently not used #define K_HELP TERMCAP2KEY('%', '1') #define K_UNDO TERMCAP2KEY('&', '8') @@ -443,8 +443,8 @@ enum key_extra { #define K_EVENT TERMCAP2KEY(KS_EXTRA, KE_EVENT) #define K_COMMAND TERMCAP2KEY(KS_EXTRA, KE_COMMAND) -/* Bits for modifier mask */ -/* 0x01 cannot be used, because the modifier must be 0x02 or higher */ +// Bits for modifier mask +// 0x01 cannot be used, because the modifier must be 0x02 or higher #define MOD_MASK_SHIFT 0x02 #define MOD_MASK_CTRL 0x04 #define MOD_MASK_ALT 0x08 // aka META diff --git a/src/nvim/macros.h b/src/nvim/macros.h index f6c8c0a4a0..3df7fa768d 100644 --- a/src/nvim/macros.h +++ b/src/nvim/macros.h @@ -36,38 +36,34 @@ #define BUFEMPTY() (curbuf->b_ml.ml_line_count == 1 && *ml_get((linenr_T)1) == \ NUL) -/* - * toupper() and tolower() that use the current locale. - * Careful: Only call TOUPPER_LOC() and TOLOWER_LOC() with a character in the - * range 0 - 255. toupper()/tolower() on some systems can't handle others. - * Note: It is often better to use mb_tolower() and mb_toupper(), because many - * toupper() and tolower() implementations only work for ASCII. - */ +// toupper() and tolower() that use the current locale. +// Careful: Only call TOUPPER_LOC() and TOLOWER_LOC() with a character in the +// range 0 - 255. toupper()/tolower() on some systems can't handle others. +// Note: It is often better to use mb_tolower() and mb_toupper(), because many +// toupper() and tolower() implementations only work for ASCII. #define TOUPPER_LOC toupper #define TOLOWER_LOC tolower -/* toupper() and tolower() for ASCII only and ignore the current locale. */ +// toupper() and tolower() for ASCII only and ignore the current locale. # define TOUPPER_ASC(c) (((c) < 'a' || (c) > 'z') ? (c) : (c) - ('a' - 'A')) # define TOLOWER_ASC(c) (((c) < 'A' || (c) > 'Z') ? (c) : (c) + ('a' - 'A')) -/* Like isalpha() but reject non-ASCII characters. Can't be used with a - * special key (negative value). */ +// Like isalpha() but reject non-ASCII characters. Can't be used with a +// special key (negative value). # define ASCII_ISLOWER(c) ((unsigned)(c) >= 'a' && (unsigned)(c) <= 'z') # define ASCII_ISUPPER(c) ((unsigned)(c) >= 'A' && (unsigned)(c) <= 'Z') # define ASCII_ISALPHA(c) (ASCII_ISUPPER(c) || ASCII_ISLOWER(c)) # define ASCII_ISALNUM(c) (ASCII_ISALPHA(c) || ascii_isdigit(c)) -/* Returns empty string if it is NULL. */ +// Returns empty string if it is NULL. #define EMPTY_IF_NULL(x) ((x) ? (x) : (char_u *)"") -/* - * Adjust chars in a language according to 'langmap' option. - * NOTE that there is no noticeable overhead if 'langmap' is not set. - * When set the overhead for characters < 256 is small. - * Don't apply 'langmap' if the character comes from the Stuff buffer or from a - * mapping and the langnoremap option was set. - * The do-while is just to ignore a ';' after the macro. - */ +// Adjust chars in a language according to 'langmap' option. +// NOTE that there is no noticeable overhead if 'langmap' is not set. +// When set the overhead for characters < 256 is small. +// Don't apply 'langmap' if the character comes from the Stuff buffer or from a +// mapping and the langnoremap option was set. +// The do-while is just to ignore a ';' after the macro. # define LANGMAP_ADJUST(c, condition) \ do { \ if (*p_langmap \ @@ -83,12 +79,12 @@ } \ } while (0) -#define WRITEBIN "wb" /* no CR-LF translation */ +#define WRITEBIN "wb" // no CR-LF translation #define READBIN "rb" #define APPENDBIN "ab" -/* mch_open_rw(): invoke os_open() with third argument for user R/W. */ -#if defined(UNIX) /* open in rw------- mode */ +// mch_open_rw(): invoke os_open() with third argument for user R/W. +#if defined(UNIX) // open in rw------- mode # define mch_open_rw(n, f) os_open((n), (f), (mode_t)0600) #elif defined(WIN32) # define mch_open_rw(n, f) os_open((n), (f), S_IREAD | S_IWRITE) @@ -100,7 +96,7 @@ # define UTF_COMPOSINGLIKE(p1, p2) utf_composinglike((p1), (p2)) -/* Whether to draw the vertical bar on the right side of the cell. */ +// Whether to draw the vertical bar on the right side of the cell. # define CURSOR_BAR_RIGHT (curwin->w_p_rl && (!(State & CMDLINE) || cmdmsg_rl)) // MB_PTR_ADV(): advance a pointer to the next character, taking care of diff --git a/src/nvim/memline.c b/src/nvim/memline.c index fa7c39cc65..b695d0e139 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -1504,16 +1504,15 @@ static time_t swapfile_info(char_u *fname) int fd; struct block0 b0; time_t x = (time_t)0; - char *p; #ifdef UNIX char uname[B0_UNAME_SIZE]; #endif - /* print the swap file date */ + // print the swap file date FileInfo file_info; if (os_fileinfo((char *)fname, &file_info)) { #ifdef UNIX - /* print name of owner of the file */ + // print name of owner of the file if (os_get_uname(file_info.stat.st_uid, uname, B0_UNAME_SIZE) == OK) { MSG_PUTS(_(" owned by: ")); msg_outtrans((char_u *)uname); @@ -1522,11 +1521,8 @@ static time_t swapfile_info(char_u *fname) #endif MSG_PUTS(_(" dated: ")); x = file_info.stat.st_mtim.tv_sec; - p = ctime(&x); // includes '\n' - if (p == NULL) - MSG_PUTS("(invalid)\n"); - else - MSG_PUTS(p); + char ctime_buf[50]; + MSG_PUTS(os_ctime_r(&x, ctime_buf, sizeof(ctime_buf))); } /* @@ -3267,15 +3263,13 @@ attention_message ( ) { assert(buf->b_fname != NULL); - time_t x, sx; - char *p; ++no_wait_return; (void)EMSG(_("E325: ATTENTION")); MSG_PUTS(_("\nFound a swap file by the name \"")); msg_home_replace(fname); MSG_PUTS("\"\n"); - sx = swapfile_info(fname); + const time_t swap_mtime = swapfile_info(fname); MSG_PUTS(_("While opening file \"")); msg_outtrans(buf->b_fname); MSG_PUTS("\"\n"); @@ -3284,14 +3278,12 @@ attention_message ( MSG_PUTS(_(" CANNOT BE FOUND")); } else { MSG_PUTS(_(" dated: ")); - x = file_info.stat.st_mtim.tv_sec; - p = ctime(&x); // includes '\n' - if (p == NULL) - MSG_PUTS("(invalid)\n"); - else - MSG_PUTS(p); - if (sx != 0 && x > sx) + time_t x = file_info.stat.st_mtim.tv_sec; + char ctime_buf[50]; + MSG_PUTS(os_ctime_r(&x, ctime_buf, sizeof(ctime_buf))); + if (swap_mtime != 0 && x > swap_mtime) { MSG_PUTS(_(" NEWER than swap file!\n")); + } } /* Some of these messages are long to allow translation to * other languages. */ diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index 8c19a2de66..e7fb38e801 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -73,7 +73,8 @@ static garray_T ga_users = GA_EMPTY_INIT_VALUE; * If "include_space" is set, include trailing whitespace while calculating the * length. */ -int get_leader_len(char_u *line, char_u **flags, int backward, int include_space) +int get_leader_len(char_u *line, char_u **flags, + bool backward, bool include_space) { int i, j; int result; diff --git a/src/nvim/move.c b/src/nvim/move.c index e7ed98d4f0..d4f82bc601 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -86,6 +86,7 @@ static void comp_botline(win_T *wp) /* wp->w_botline is the line that is just below the window */ wp->w_botline = lnum; wp->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP; + wp->w_viewport_invalid = true; set_empty_rows(wp, done); @@ -151,6 +152,7 @@ void update_topline(void) curwin->w_topline = curwin->w_cursor.lnum; curwin->w_botline = curwin->w_topline; curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP; + curwin->w_viewport_invalid = true; curwin->w_scbind_pos = 1; return; } @@ -175,6 +177,7 @@ void update_topline(void) curwin->w_topline = 1; curwin->w_botline = 2; curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP; + curwin->w_viewport_invalid = true; curwin->w_scbind_pos = 1; } /* @@ -311,6 +314,7 @@ void update_topline(void) } } curwin->w_valid |= VALID_TOPLINE; + curwin->w_viewport_invalid = true; win_check_anchored_floats(curwin); /* @@ -407,6 +411,7 @@ void check_cursor_moved(win_T *wp) |VALID_CHEIGHT|VALID_CROW|VALID_TOPLINE); wp->w_valid_cursor = wp->w_cursor; wp->w_valid_leftcol = wp->w_leftcol; + wp->w_viewport_invalid = true; } else if (wp->w_cursor.col != wp->w_valid_cursor.col || wp->w_leftcol != wp->w_valid_leftcol || wp->w_cursor.coladd != wp->w_valid_cursor.coladd @@ -415,6 +420,7 @@ void check_cursor_moved(win_T *wp) wp->w_valid_cursor.col = wp->w_cursor.col; wp->w_valid_leftcol = wp->w_leftcol; wp->w_valid_cursor.coladd = wp->w_cursor.coladd; + wp->w_viewport_invalid = true; } } @@ -1458,6 +1464,7 @@ void scroll_cursor_top(int min_scroll, int always) curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP); curwin->w_valid |= VALID_TOPLINE; + curwin->w_viewport_invalid = true; } } @@ -1662,6 +1669,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) curwin->w_valid = old_valid; } curwin->w_valid |= VALID_TOPLINE; + curwin->w_viewport_invalid = true; } /// Recompute topline to put the cursor halfway across the window @@ -1818,6 +1826,7 @@ void cursor_correct(void) } } curwin->w_valid |= VALID_TOPLINE; + curwin->w_viewport_invalid = true; } diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 6c92b136da..58993426dd 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -615,7 +615,9 @@ static void normal_redraw_mode_message(NormalState *s) kmsg = keep_msg; keep_msg = NULL; - // showmode() will clear keep_msg, but we want to use it anyway + // Showmode() will clear keep_msg, but we want to use it anyway. + // First update w_topline. + setcursor(); update_screen(0); // now reset it, otherwise it's put in the history again keep_msg = kmsg; @@ -623,6 +625,7 @@ static void normal_redraw_mode_message(NormalState *s) xfree(kmsg); } setcursor(); + ui_cursor_shape(); // show different cursor shape ui_flush(); if (msg_scroll || emsg_on_display) { os_delay(1000L, true); // wait at least one second @@ -1964,8 +1967,8 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) break; case OP_FOLD: - VIsual_reselect = false; /* don't reselect now */ - foldCreate(oap->start.lnum, oap->end.lnum); + VIsual_reselect = false; // don't reselect now + foldCreate(curwin, oap->start.lnum, oap->end.lnum); break; case OP_FOLDOPEN: @@ -1983,9 +1986,9 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank) case OP_FOLDDEL: case OP_FOLDDELREC: - VIsual_reselect = false; /* don't reselect now */ - deleteFold(oap->start.lnum, oap->end.lnum, - oap->op_type == OP_FOLDDELREC, oap->is_VIsual); + VIsual_reselect = false; // don't reselect now + deleteFold(curwin, oap->start.lnum, oap->end.lnum, + oap->op_type == OP_FOLDDELREC, oap->is_VIsual); break; case OP_NR_ADD: @@ -4121,6 +4124,7 @@ void scroll_redraw(int up, long count) } if (curwin->w_cursor.lnum != prev_lnum) coladvance(curwin->w_curswant); + curwin->w_viewport_invalid = true; redraw_later(VALID); } @@ -4341,11 +4345,12 @@ dozet: /* "zD": delete fold at cursor recursively */ case 'd': case 'D': if (foldManualAllowed(false)) { - if (VIsual_active) + if (VIsual_active) { nv_operator(cap); - else - deleteFold(curwin->w_cursor.lnum, - curwin->w_cursor.lnum, nchar == 'D', false); + } else { + deleteFold(curwin, curwin->w_cursor.lnum, + curwin->w_cursor.lnum, nchar == 'D', false); + } } break; @@ -4353,11 +4358,11 @@ dozet: case 'E': if (foldmethodIsManual(curwin)) { clearFolding(curwin); changed_window_setting(); - } else if (foldmethodIsMarker(curwin)) - deleteFold((linenr_T)1, curbuf->b_ml.ml_line_count, - true, false); - else + } else if (foldmethodIsMarker(curwin)) { + deleteFold(curwin, (linenr_T)1, curbuf->b_ml.ml_line_count, true, false); + } else { EMSG(_("E352: Cannot erase folds with current 'foldmethod'")); + } break; /* "zn": fold none: reset 'foldenable' */ diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 5457400b76..a70224f98b 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -261,7 +261,7 @@ void op_shift(oparg_T *oap, int curs_top, int amount) sprintf((char *)IObuff, _("%" PRId64 " lines %sed %d times"), (int64_t)oap->line_count, s, amount); } - msg(IObuff); + msg_attr_keep(IObuff, 0, true, false); } /* diff --git a/src/nvim/option.c b/src/nvim/option.c index 43a4a9fdf9..86a7d9b3c2 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -3668,7 +3668,7 @@ static char_u *set_chars_option(win_T *wp, char_u **varp, bool set) } // first round: check for valid value, second round: assign values - for (round = 0; round <= set ? 1 : 0; round++) { + for (round = 0; round <= (set ? 1 : 0); round++) { if (round > 0) { // After checking that the value is valid: set defaults for (i = 0; i < entries; i++) { @@ -3843,11 +3843,12 @@ static char_u *did_set_spell_option(bool is_spellfile) * Return error message when failed, NULL when OK. */ static char_u *compile_cap_prog(synblock_T *synblock) + FUNC_ATTR_NONNULL_ALL { regprog_T *rp = synblock->b_cap_prog; char_u *re; - if (*synblock->b_p_spc == NUL) { + if (synblock->b_p_spc == NULL || *synblock->b_p_spc == NUL) { synblock->b_cap_prog = NULL; } else { // Prepend a ^ so that we only match at one column diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index ae922e4040..873b611151 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -1147,6 +1147,30 @@ bool os_fileid_equal_fileinfo(const FileID *file_id, && file_id->device_id == file_info->stat.st_dev; } +/// Return the canonicalized absolute pathname. +/// +/// @param[in] name Filename to be canonicalized. +/// @param[out] buf Buffer to store the canonicalized values. A minimum length +// of MAXPATHL+1 is required. If it is NULL, memory is +// allocated. In that case, the caller should deallocate this +// buffer. +/// +/// @return pointer to the buf on success, or NULL. +char *os_realpath(const char *name, char *buf) + FUNC_ATTR_NONNULL_ARG(1) +{ + uv_fs_t request; + int result = uv_fs_realpath(&fs_loop, &request, name, NULL); + if (result == kLibuvSuccess) { + if (buf == NULL) { + buf = xmallocz(MAXPATHL); + } + xstrlcpy(buf, request.ptr, MAXPATHL + 1); + } + uv_fs_req_cleanup(&request); + return result == kLibuvSuccess ? buf : NULL; +} + #ifdef WIN32 # include <shlobj.h> @@ -1233,4 +1257,49 @@ shortcut_end: return rfname; } +#define is_path_sep(c) ((c) == L'\\' || (c) == L'/') +/// Returns true if the path contains a reparse point (junction or symbolic +/// link). Otherwise false in returned. +bool os_is_reparse_point_include(const char *path) +{ + wchar_t *p, *q, *utf16_path; + wchar_t buf[MAX_PATH]; + DWORD attr; + bool result = false; + + const int r = utf8_to_utf16(path, -1, &utf16_path); + if (r != 0) { + EMSG2("utf8_to_utf16 failed: %d", r); + return false; + } + + p = utf16_path; + if (isalpha(p[0]) && p[1] == L':' && is_path_sep(p[2])) { + p += 3; + } else if (is_path_sep(p[0]) && is_path_sep(p[1])) { + p += 2; + } + + while (*p != L'\0') { + q = wcspbrk(p, L"\\/"); + if (q == NULL) { + p = q = utf16_path + wcslen(utf16_path); + } else { + p = q + 1; + } + if (q - utf16_path >= MAX_PATH) { + break; + } + wcsncpy(buf, utf16_path, (size_t)(q - utf16_path)); + buf[q - utf16_path] = L'\0'; + attr = GetFileAttributesW(buf); + if (attr != INVALID_FILE_ATTRIBUTES + && (attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0) { + result = true; + break; + } + } + xfree(utf16_path); + return result; +} #endif diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c index 4dd0614fe2..346e40e02e 100644 --- a/src/nvim/os/time.c +++ b/src/nvim/os/time.c @@ -2,9 +2,6 @@ // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include <assert.h> -#include <stdint.h> -#include <stdbool.h> -#include <time.h> #include <limits.h> #include <uv.h> @@ -13,7 +10,7 @@ #include "nvim/os/time.h" #include "nvim/os/input.h" #include "nvim/event/loop.h" -#include "nvim/vim.h" +#include "nvim/os/os.h" #include "nvim/main.h" static uv_mutex_t delay_mutex; @@ -112,6 +109,10 @@ void os_microdelay(uint64_t us, bool ignoreinput) uv_mutex_unlock(&delay_mutex); } +// Cache of the current timezone name as retrieved from TZ, or an empty string +// where unset, up to 64 octets long including trailing null byte. +static char tz_cache[64]; + /// Portable version of POSIX localtime_r() /// /// @return NULL in case of error @@ -120,6 +121,19 @@ struct tm *os_localtime_r(const time_t *restrict clock, { #ifdef UNIX // POSIX provides localtime_r() as a thread-safe version of localtime(). + // + // Check to see if the environment variable TZ has changed since the last run. + // Call tzset(3) to update the global timezone variables if it has. + // POSIX standard doesn't require localtime_r() implementations to do that + // as it does with localtime(), and we don't want to call tzset() every time. + const char *tz = os_getenv("TZ"); + if (tz == NULL) { + tz = ""; + } + if (strncmp(tz_cache, tz, sizeof(tz_cache) - 1) != 0) { + tzset(); + xstrlcpy(tz_cache, tz, sizeof(tz_cache)); + } return localtime_r(clock, result); // NOLINT(runtime/threadsafe_fn) #else // Windows version of localtime() is thread-safe. @@ -144,6 +158,39 @@ struct tm *os_localtime(struct tm *result) FUNC_ATTR_NONNULL_ALL return os_localtime_r(&rawtime, result); } +/// Portable version of POSIX ctime_r() +/// +/// @param clock[in] +/// @param result[out] Pointer to a 'char' where the result should be placed +/// @param result_len length of result buffer +/// @return human-readable string of current local time +char *os_ctime_r(const time_t *restrict clock, char *restrict result, + size_t result_len) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET +{ + struct tm clock_local; + struct tm *clock_local_ptr = os_localtime_r(clock, &clock_local); + // MSVC returns NULL for an invalid value of seconds. + if (clock_local_ptr == NULL) { + snprintf(result, result_len, "%s\n", _("(Invalid)")); + } else { + strftime(result, result_len, "%a %b %d %H:%M:%S %Y\n", clock_local_ptr); + } + return result; +} + +/// Gets the current Unix timestamp and adjusts it to local time. +/// +/// @param result[out] Pointer to a 'char' where the result should be placed +/// @param result_len length of result buffer +/// @return human-readable string of current local time +char *os_ctime(char *result, size_t result_len) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET +{ + time_t rawtime = time(NULL); + return os_ctime_r(&rawtime, result, result_len); +} + /// Obtains the current Unix timestamp. /// /// @return Seconds since epoch. diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index c444326533..484168e798 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -5134,6 +5134,7 @@ theend: // Restore current working directory to "dirname_start" if they differ, taking // into account whether it is set locally or globally. static void restore_start_dir(char_u *dirname_start) + FUNC_ATTR_NONNULL_ALL { char_u *dirname_now = xmalloc(MAXPATHL); @@ -5251,8 +5252,29 @@ load_dummy_buffer ( // directory to "dirname_start" prior to returning, if autocmds or the // 'autochdir' option have changed it. static void wipe_dummy_buffer(buf_T *buf, char_u *dirname_start) + FUNC_ATTR_NONNULL_ALL { - if (curbuf != buf) { // safety check + // If any autocommand opened a window on the dummy buffer, close that + // window. If we can't close them all then give up. + while (buf->b_nwindows > 0) { + bool did_one = false; + + if (firstwin->w_next != NULL) { + for (win_T *wp = firstwin; wp != NULL; wp = wp->w_next) { + if (wp->w_buffer == buf) { + if (win_close(wp, false) == OK) { + did_one = true; + } + break; + } + } + } + if (!did_one) { + return; + } + } + + if (curbuf != buf && buf->b_nwindows == 0) { // safety check cleanup_T cs; // Reset the error/interrupt/exception state here so that aborting() diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index 90dc8ab90f..5ad7ce9a16 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -6491,20 +6491,24 @@ typedef struct { static regsubmatch_T rsm; // can only be used when can_f_submatch is true -/// Put the submatches in "argv[0]" which is a list passed into call_func() by -/// vim_regsub_both(). -static int fill_submatch_list(int argc, typval_T *argv, int argcount) +/// Put the submatches in "argv[argskip]" which is a list passed into +/// call_func() by vim_regsub_both(). +static int fill_submatch_list(int argc FUNC_ATTR_UNUSED, typval_T *argv, + int argskip, int argcount) + FUNC_ATTR_NONNULL_ALL { - if (argcount == 0) { - // called function doesn't take an argument - return 0; + typval_T *listarg = argv + argskip; + + if (argcount == argskip) { + // called function doesn't take a submatches argument + return argskip; } // Relies on sl_list to be the first item in staticList10_T. - tv_list_init_static10((staticList10_T *)argv->vval.v_list); + tv_list_init_static10((staticList10_T *)listarg->vval.v_list); // There are always 10 list items in staticList10_T. - listitem_T *li = tv_list_first(argv->vval.v_list); + listitem_T *li = tv_list_first(listarg->vval.v_list); for (int i = 0; i < 10; i++) { char_u *s = rsm.sm_match->startp[i]; if (s == NULL || rsm.sm_match->endp[i] == NULL) { @@ -6516,7 +6520,7 @@ static int fill_submatch_list(int argc, typval_T *argv, int argcount) TV_LIST_ITEM_TV(li)->vval.v_string = s; li = TV_LIST_ITEM_NEXT(argv->vval.v_list, li); } - return 1; + return argskip + 1; } static void clear_submatch_list(staticList10_T *sl) @@ -6679,10 +6683,15 @@ static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest, // fill_submatch_list() was called. clear_submatch_list(&matchList); } - char buf[NUMBUFLEN]; - eval_result = (char_u *)tv_get_string_buf_chk(&rettv, buf); - if (eval_result != NULL) { - eval_result = vim_strsave(eval_result); + if (rettv.v_type == VAR_UNKNOWN) { + // something failed, no need to report another error + eval_result = NULL; + } else { + char buf[NUMBUFLEN]; + eval_result = (char_u *)tv_get_string_buf_chk(&rettv, buf); + if (eval_result != NULL) { + eval_result = vim_strsave(eval_result); + } } tv_clear(&rettv); } else { diff --git a/src/nvim/regexp_defs.h b/src/nvim/regexp_defs.h index 5e5b19b63f..116bfee91e 100644 --- a/src/nvim/regexp_defs.h +++ b/src/nvim/regexp_defs.h @@ -91,7 +91,7 @@ typedef struct { char_u *regmust; int regmlen; char_u reghasz; - char_u program[1]; /* actually longer.. */ + char_u program[1]; // actually longer.. } bt_regprog_T; // Structure representing a NFA state. @@ -102,7 +102,7 @@ struct nfa_state { nfa_state_T *out; nfa_state_T *out1; int id; - int lastlist[2]; /* 0: normal, 1: recursive */ + int lastlist[2]; // 0: normal, 1: recursive int val; }; @@ -116,19 +116,19 @@ typedef struct { unsigned re_engine; unsigned re_flags; ///< Second argument for vim_regcomp(). - nfa_state_T *start; /* points into state[] */ + nfa_state_T *start; // points into state[] - int reganch; /* pattern starts with ^ */ - int regstart; /* char at start of pattern */ - char_u *match_text; /* plain text to match with */ + int reganch; // pattern starts with ^ + int regstart; // char at start of pattern + char_u *match_text; // plain text to match with - int has_zend; /* pattern contains \ze */ - int has_backref; /* pattern contains \1 .. \9 */ + int has_zend; // pattern contains \ze + int has_backref; // pattern contains \1 .. \9 int reghasz; char_u *pattern; - int nsubexp; /* number of () */ + int nsubexp; // number of () int nstate; - nfa_state_T state[1]; /* actually longer.. */ + nfa_state_T state[1]; // actually longer.. } nfa_regprog_T; /* diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 2e2c6ca737..9c590efdbc 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -417,7 +417,7 @@ int update_screen(int type) need_wait_return = false; } - win_ui_flush_positions(); + win_ui_flush(); msg_ext_check_clear(); /* reset cmdline_row now (may have been changed temporarily) */ @@ -1629,6 +1629,7 @@ static void win_update(win_T *wp) * changes are relevant). */ wp->w_valid |= VALID_BOTLINE; + wp->w_viewport_invalid = true; if (wp == curwin && wp->w_botline != old_botline && !recursive) { recursive = TRUE; curwin->w_valid &= ~VALID_TOPLINE; @@ -1648,7 +1649,7 @@ static void win_update(win_T *wp) /* restore got_int, unless CTRL-C was hit while redrawing */ if (!got_int) got_int = save_got_int; -} +} // NOLINT(readability/fn_size) /// Returns width of the signcolumn that should be used for the whole window /// @@ -2219,7 +2220,6 @@ win_line ( int tocol = MAXCOL; // end of inverting int fromcol_prev = -2; // start of inverting after cursor bool noinvcur = false; // don't invert the cursor - pos_T *top, *bot; int lnum_in_visual_area = false; pos_T pos; long v; @@ -2419,6 +2419,8 @@ win_line ( // handle Visual active in this window if (VIsual_active && wp->w_buffer == curwin->w_buffer) { + pos_T *top, *bot; + if (ltoreq(curwin->w_cursor, VIsual)) { // Visual is after curwin->w_cursor top = &curwin->w_cursor; @@ -3159,8 +3161,8 @@ win_line ( shl->endcol += (*mb_ptr2len)(line + shl->endcol); } - /* Loop to check if the match starts at the - * current position */ + // Loop to check if the match starts at the + // current position continue; } } @@ -5731,12 +5733,11 @@ static void end_search_hl(void) * Init for calling prepare_search_hl(). */ static void init_search_hl(win_T *wp) + FUNC_ATTR_NONNULL_ALL { - matchitem_T *cur; - - /* Setup for match and 'hlsearch' highlighting. Disable any previous - * match */ - cur = wp->w_match_head; + // Setup for match and 'hlsearch' highlighting. Disable any previous + // match + matchitem_T *cur = wp->w_match_head; while (cur != NULL) { cur->hl.rm = cur->match; if (cur->hlg_id == 0) @@ -5746,7 +5747,7 @@ static void init_search_hl(win_T *wp) cur->hl.buf = wp->w_buffer; cur->hl.lnum = 0; cur->hl.first_lnum = 0; - /* Set the time limit to 'redrawtime'. */ + // Set the time limit to 'redrawtime'. cur->hl.tm = profile_setlimit(p_rdt); cur = cur->next; } @@ -5762,18 +5763,16 @@ static void init_search_hl(win_T *wp) * Advance to the match in window "wp" line "lnum" or past it. */ static void prepare_search_hl(win_T *wp, linenr_T lnum) + FUNC_ATTR_NONNULL_ALL { - matchitem_T *cur; /* points to the match list */ - match_T *shl; /* points to search_hl or a match */ - int shl_flag; /* flag to indicate whether search_hl - has been processed or not */ - int n; - - /* - * When using a multi-line pattern, start searching at the top - * of the window or just after a closed fold. - * Do this both for search_hl and the match list. - */ + matchitem_T *cur; // points to the match list + match_T *shl; // points to search_hl or a match + bool shl_flag; // flag to indicate whether search_hl + // has been processed or not + + // When using a multi-line pattern, start searching at the top + // of the window or just after a closed fold. + // Do this both for search_hl and the match list. cur = wp->w_match_head; shl_flag = false; while (cur != NULL || shl_flag == false) { @@ -5800,7 +5799,7 @@ static void prepare_search_hl(win_T *wp, linenr_T lnum) } bool pos_inprogress = true; // mark that a position match search is // in progress - n = 0; + int n = 0; while (shl->first_lnum < lnum && (shl->rm.regprog != NULL || (cur != NULL && pos_inprogress))) { next_search_hl(wp, shl, shl->first_lnum, (colnr_T)n, @@ -5838,6 +5837,7 @@ next_search_hl ( colnr_T mincol, /* minimal column for a match */ matchitem_T *cur /* to retrieve match positions if any */ ) + FUNC_ATTR_NONNULL_ARG(2) { linenr_T l; colnr_T matchcol; @@ -5845,11 +5845,10 @@ next_search_hl ( int save_called_emsg = called_emsg; if (shl->lnum != 0) { - /* Check for three situations: - * 1. If the "lnum" is below a previous match, start a new search. - * 2. If the previous match includes "mincol", use it. - * 3. Continue after the previous match. - */ + // Check for three situations: + // 1. If the "lnum" is below a previous match, start a new search. + // 2. If the previous match includes "mincol", use it. + // 3. Continue after the previous match. l = shl->lnum + shl->rm.endpos[0].lnum - shl->rm.startpos[0].lnum; if (lnum > l) shl->lnum = 0; @@ -5863,22 +5862,21 @@ next_search_hl ( */ called_emsg = FALSE; for (;; ) { - /* Stop searching after passing the time limit. */ + // Stop searching after passing the time limit. if (profile_passed_limit(shl->tm)) { shl->lnum = 0; /* no match found in time */ break; } - /* Three situations: - * 1. No useful previous match: search from start of line. - * 2. Not Vi compatible or empty match: continue at next character. - * Break the loop if this is beyond the end of the line. - * 3. Vi compatible searching: continue at end of previous match. - */ - if (shl->lnum == 0) + // Three situations: + // 1. No useful previous match: search from start of line. + // 2. Not Vi compatible or empty match: continue at next character. + // Break the loop if this is beyond the end of the line. + // 3. Vi compatible searching: continue at end of previous match. + if (shl->lnum == 0) { matchcol = 0; - else if (vim_strchr(p_cpo, CPO_SEARCH) == NULL - || (shl->rm.endpos[0].lnum == 0 - && shl->rm.endpos[0].col <= shl->rm.startpos[0].col)) { + } else if (vim_strchr(p_cpo, CPO_SEARCH) == NULL + || (shl->rm.endpos[0].lnum == 0 + && shl->rm.endpos[0].col <= shl->rm.startpos[0].col)) { char_u *ml; matchcol = shl->rm.startpos[0].col; @@ -5895,8 +5893,8 @@ next_search_hl ( shl->lnum = lnum; if (shl->rm.regprog != NULL) { - /* Remember whether shl->rm is using a copy of the regprog in - * cur->match. */ + // Remember whether shl->rm is using a copy of the regprog in + // cur->match. bool regprog_is_copy = (shl != &search_hl && cur != NULL && shl == &cur->hl @@ -5925,7 +5923,7 @@ next_search_hl ( nmatched = next_search_hl_pos(shl, lnum, &(cur->pos), matchcol); } if (nmatched == 0) { - shl->lnum = 0; /* no match found */ + shl->lnum = 0; // no match found break; } if (shl->rm.startpos[0].lnum > 0 @@ -5933,7 +5931,7 @@ next_search_hl ( || nmatched > 1 || shl->rm.endpos[0].col > mincol) { shl->lnum += shl->rm.startpos[0].lnum; - break; /* useful match found */ + break; // useful match found } // Restore called_emsg for assert_fails(). @@ -5950,6 +5948,7 @@ next_search_hl_pos( posmatch_T *posmatch, // match positions colnr_T mincol // minimal column for a match ) + FUNC_ATTR_NONNULL_ALL { int i; int found = -1; @@ -6104,9 +6103,10 @@ void check_for_delay(int check_msg_scroll) && emsg_silent == 0) { ui_flush(); os_delay(1000L, true); - emsg_on_display = FALSE; - if (check_msg_scroll) - msg_scroll = FALSE; + emsg_on_display = false; + if (check_msg_scroll) { + msg_scroll = false; + } } } diff --git a/src/nvim/search.c b/src/nvim/search.c index 7d00785c74..23086c629b 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -1192,6 +1192,7 @@ int do_search( len = STRLEN(p) + off_len + 3; } + xfree(msgbuf); msgbuf = xmalloc(len); { memset(msgbuf, ' ', len); diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 6cb8d01f51..180073ade1 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -2827,9 +2827,6 @@ void spell_suggest(int count) smsg(_("Sorry, only %" PRId64 " suggestions"), (int64_t)sug.su_ga.ga_len); } else { - XFREE_CLEAR(repl_from); - XFREE_CLEAR(repl_to); - // When 'rightleft' is set the list is drawn right-left. cmdmsg_rl = curwin->w_p_rl; if (cmdmsg_rl) @@ -2909,6 +2906,9 @@ void spell_suggest(int count) if (selected > 0 && selected <= sug.su_ga.ga_len && u_save_cursor() == OK) { // Save the from and to text for :spellrepall. + XFREE_CLEAR(repl_from); + XFREE_CLEAR(repl_to); + stp = &SUG(sug.su_ga, selected - 1); if (sug.su_badlen > stp->st_orglen) { // Replacing less than "su_badlen", append the remainder to @@ -5761,19 +5761,22 @@ cleanup_suggestions ( int maxscore, int keep // nr of suggestions to keep ) + FUNC_ATTR_NONNULL_ALL { suggest_T *stp = &SUG(*gap, 0); - // Sort the list. - qsort(gap->ga_data, (size_t)gap->ga_len, sizeof(suggest_T), sug_compare); + if (gap->ga_len > 0) { + // Sort the list. + qsort(gap->ga_data, (size_t)gap->ga_len, sizeof(suggest_T), sug_compare); - // Truncate the list to the number of suggestions that will be displayed. - if (gap->ga_len > keep) { - for (int i = keep; i < gap->ga_len; ++i) { - xfree(stp[i].st_word); + // Truncate the list to the number of suggestions that will be displayed. + if (gap->ga_len > keep) { + for (int i = keep; i < gap->ga_len; i++) { + xfree(stp[i].st_word); + } + gap->ga_len = keep; + return stp[keep - 1].st_score; } - gap->ga_len = keep; - return stp[keep - 1].st_score; } return maxscore; } diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 57bb43c846..ff07a00952 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -2540,7 +2540,9 @@ parse_match( } p += 2; // skip ";\"" if (*p++ == TAB) { - while (ASCII_ISALPHA(*p)) { + // Accept ASCII alphabetic kind characters and any multi-byte + // character. + while (ASCII_ISALPHA(*p) || utfc_ptr2len(p) > 1) { if (STRNCMP(p, "kind:", 5) == 0) { tagp->tagkind = p + 5; } else if (STRNCMP(p, "user_data:", 10) == 0) { @@ -2559,19 +2561,22 @@ parse_match( } if (pt == NULL) break; - p = pt + 1; + p = pt; + MB_PTR_ADV(p); } } } if (tagp->tagkind != NULL) { for (p = tagp->tagkind; - *p && *p != '\t' && *p != '\r' && *p != '\n'; ++p) - ; + *p && *p != '\t' && *p != '\r' && *p != '\n'; + MB_PTR_ADV(p)) { + } tagp->tagkind_end = p; } if (tagp->user_data != NULL) { for (p = tagp->user_data; - *p && *p != '\t' && *p != '\r' && *p != '\n'; p++) { + *p && *p != '\t' && *p != '\r' && *p != '\n'; + MB_PTR_ADV(p)) { } tagp->user_data_end = p; } @@ -3181,7 +3186,8 @@ int get_tags(list_T *list, char_u *pat, char_u *buf_fname) if (tp.command_end != NULL) { for (char_u *p = tp.command_end + 3; - *p != NUL && *p != '\n' && *p != '\r'; p++) { + *p != NUL && *p != '\n' && *p != '\r'; + MB_PTR_ADV(p)) { if (p == tp.tagkind || (p + 5 == tp.tagkind && STRNCMP(p, "kind:", 5) == 0)) { // skip "kind:<kind>" and "<kind>" diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index c5e756905a..a37cc60928 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -992,8 +992,9 @@ static void mouse_action(Terminal *term, int button, int row, int col, static bool send_mouse_event(Terminal *term, int c) { int row = mouse_row, col = mouse_col, grid = mouse_grid; + int offset; win_T *mouse_win = mouse_find_win(&grid, &row, &col); - if (mouse_win == NULL) { + if (mouse_win == NULL || (offset = win_col_off(mouse_win)) > col) { goto end; } @@ -1015,7 +1016,7 @@ static bool send_mouse_event(Terminal *term, int c) default: return false; } - mouse_action(term, button, row, col, drag, 0); + mouse_action(term, button, row, col - offset, drag, 0); size_t len = vterm_output_read(term->vt, term->textbuf, sizeof(term->textbuf)); terminal_send(term, term->textbuf, (size_t)len); diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index e3547aea5b..954e5d875f 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -1072,6 +1072,40 @@ func Test_Cmd_Autocmds() enew! endfunc +func s:ReadFile() + setl noswapfile nomodified + let filename = resolve(expand("<afile>:p")) + execute 'read' fnameescape(filename) + 1d_ + exe 'file' fnameescape(filename) + setl buftype=acwrite +endfunc + +func s:WriteFile() + let filename = resolve(expand("<afile>:p")) + setl buftype= + noautocmd execute 'write' fnameescape(filename) + setl buftype=acwrite + setl nomodified +endfunc + +func Test_BufReadCmd() + autocmd BufReadCmd *.test call s:ReadFile() + autocmd BufWriteCmd *.test call s:WriteFile() + + call writefile(['one', 'two', 'three'], 'Xcmd.test') + edit Xcmd.test + call assert_match('Xcmd.test" line 1 of 3', execute('file')) + normal! Gofour + write + call assert_equal(['one', 'two', 'three', 'four'], readfile('Xcmd.test')) + + bwipe! + call delete('Xcmd.test') + au! BufReadCmd + au! BufWriteCmd +endfunc + func SetChangeMarks(start, end) exe a:start. 'mark [' exe a:end. 'mark ]' @@ -1786,3 +1820,46 @@ func Test_FileChangedShell_reload() bwipe! call delete('Xchanged') endfunc + +" Test for FileReadCmd autocmd +func Test_autocmd_FileReadCmd() + func ReadFileCmd() + call append(line('$'), "v:cmdarg = " .. v:cmdarg) + endfunc + augroup FileReadCmdTest + au! + au FileReadCmd Xtest call ReadFileCmd() + augroup END + + new + read ++bin Xtest + read ++nobin Xtest + read ++edit Xtest + read ++bad=keep Xtest + read ++bad=drop Xtest + read ++bad=- Xtest + read ++ff=unix Xtest + read ++ff=dos Xtest + read ++ff=mac Xtest + read ++enc=utf-8 Xtest + + call assert_equal(['', + \ 'v:cmdarg = ++bin', + \ 'v:cmdarg = ++nobin', + \ 'v:cmdarg = ++edit', + \ 'v:cmdarg = ++bad=keep', + \ 'v:cmdarg = ++bad=drop', + \ 'v:cmdarg = ++bad=-', + \ 'v:cmdarg = ++ff=unix', + \ 'v:cmdarg = ++ff=dos', + \ 'v:cmdarg = ++ff=mac', + \ 'v:cmdarg = ++enc=utf-8'], getline(1, '$')) + + close! + augroup FileReadCmdTest + au! + augroup END + delfunc ReadFileCmd +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_digraph.vim b/src/nvim/testdir/test_digraph.vim index 5da05e85b5..1792dcc00b 100644 --- a/src/nvim/testdir/test_digraph.vim +++ b/src/nvim/testdir/test_digraph.vim @@ -433,6 +433,18 @@ func Test_digraphs_output() call assert_equal('Z% Ж 1046', matchstr(out, '\C\<Z%\D*1046\>')) call assert_equal('u- ū 363', matchstr(out, '\C\<u-\D*363\>')) call assert_equal('SH ^A 1', matchstr(out, '\C\<SH\D*1\>')) + call assert_notmatch('Latin supplement', out) + + let out_bang_without_custom = execute(':digraph!') + digraph lt 60 + let out_bang_with_custom = execute(':digraph!') + call assert_notmatch('lt', out_bang_without_custom) + call assert_match("^\n" + \ .. "NU ^@ 10 .*\n" + \ .. "Latin supplement\n" + \ .. "!I ¡ 161 .*\n" + \ .. ".*\n" + \ .. 'Custom\n.*\<lt < 60\>', out_bang_with_custom) bw! endfunc diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim index dd546dbf71..264d8b000f 100644 --- a/src/nvim/testdir/test_expr.vim +++ b/src/nvim/testdir/test_expr.vim @@ -475,6 +475,8 @@ func Test_funcref() let OneByRef = funcref('One') call assert_equal(2, OneByRef()) call assert_fails('echo funcref("{")', 'E475:') + let OneByRef = funcref("One", repeat(["foo"], 20)) + call assert_fails('let OneByRef = funcref("One", repeat(["foo"], 21))', 'E118:') endfunc func Test_empty_concatenate() diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim index 9605348389..c3ddce7914 100644 --- a/src/nvim/testdir/test_filetype.vim +++ b/src/nvim/testdir/test_filetype.vim @@ -79,6 +79,7 @@ let s:filename_checks = { \ 'bib': ['file.bib'], \ 'bindzone': ['named.root'], \ 'blank': ['file.bl'], + \ 'bsdl': ['file.bsd', 'file.bsdl'], \ 'bst': ['file.bst'], \ 'bzr': ['bzr_log.any'], \ 'c': ['enlightenment/file.cfg', 'file.qc', 'file.c'], @@ -436,7 +437,7 @@ let s:filename_checks = { \ 'swiftgyb': ['file.swift.gyb'], \ 'sil': ['file.sil'], \ 'sysctl': ['/etc/sysctl.conf', '/etc/sysctl.d/file.conf'], - \ 'systemd': ['any/systemd/file.automount', 'any/systemd/file.mount', 'any/systemd/file.path', 'any/systemd/file.service', 'any/systemd/file.socket', 'any/systemd/file.swap', 'any/systemd/file.target', 'any/systemd/file.timer', '/etc/systemd/system/some.d/file.conf', '/etc/systemd/system/some.d/.#file'], + \ 'systemd': ['any/systemd/file.automount', 'any/systemd/file.mount', 'any/systemd/file.path', 'any/systemd/file.service', 'any/systemd/file.socket', 'any/systemd/file.swap', 'any/systemd/file.target', 'any/systemd/file.timer', '/etc/systemd/system/some.d/file.conf', '/etc/systemd/system/some.d/.#file', '/home/user/.config/systemd/user/some.d/mine.conf', '/home/user/.config/systemd/user/some.d/.#file'], \ 'systemverilog': ['file.sv', 'file.svh'], \ 'tags': ['tags'], \ 'tak': ['file.tak'], @@ -480,7 +481,7 @@ let s:filename_checks = { \ 'verilog': ['file.v'], \ 'verilogams': ['file.va', 'file.vams'], \ 'vgrindefs': ['vgrindefs'], - \ 'vhdl': ['file.hdl', 'file.vhd', 'file.vhdl', 'file.vbe', 'file.vst', 'file.vhdl_123'], + \ 'vhdl': ['file.hdl', 'file.vhd', 'file.vhdl', 'file.vbe', 'file.vst', 'file.vhdl_123', 'file.vho'], \ 'vim': ['file.vim', 'file.vba', '.exrc', '_exrc'], \ 'viminfo': ['.viminfo', '_viminfo'], \ 'vmasm': ['file.mar'], diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim index 7822507f86..bd5cb6ad19 100644 --- a/src/nvim/testdir/test_functions.vim +++ b/src/nvim/testdir/test_functions.vim @@ -186,6 +186,32 @@ func Test_strftime() call assert_fails('call strftime([])', 'E730:') call assert_fails('call strftime("%Y", [])', 'E745:') + + " Check that the time changes after we change the timezone + " Save previous timezone value, if any + if exists('$TZ') + let tz = $TZ + endif + + " Force EST and then UTC, save the current hour (24-hour clock) for each + let $TZ = 'EST' | let est = strftime('%H') + let $TZ = 'UTC' | let utc = strftime('%H') + + " Those hours should be two bytes long, and should not be the same; if they + " are, a tzset(3) call may have failed somewhere + call assert_equal(strlen(est), 2) + call assert_equal(strlen(utc), 2) + " TODO: this fails on MS-Windows + if has('unix') + call assert_notequal(est, utc) + endif + + " If we cached a timezone value, put it back, otherwise clear it + if exists('tz') + let $TZ = tz + else + unlet $TZ + endif endfunc func Test_resolve() @@ -640,6 +666,16 @@ func Test_getbufvar() call assert_equal('iso-8859-2', getbufvar(bufnr('%'), '&fenc')) close + " Get the b: dict. + let b:testvar = 'one' + new + let b:testvar = 'two' + let thebuf = bufnr() + wincmd w + call assert_equal('two', getbufvar(thebuf, 'testvar')) + call assert_equal('two', getbufvar(thebuf, '').testvar) + bwipe! + set fileformats& endfunc diff --git a/src/nvim/testdir/test_hardcopy.vim b/src/nvim/testdir/test_hardcopy.vim index ced13b107c..6125f9b993 100644 --- a/src/nvim/testdir/test_hardcopy.vim +++ b/src/nvim/testdir/test_hardcopy.vim @@ -1,39 +1,137 @@ " Test :hardcopy -func Test_printoptions_parsing() - " Only test that this doesn't throw an error. - set printoptions=left:5in,right:10pt,top:8mm,bottom:2pc - set printoptions=left:2in,top:30pt,right:16mm,bottom:3pc - set printoptions=header:3,syntax:y,number:7,wrap:n - set printoptions=duplex:short,collate:n,jobsplit:y,portrait:n - set printoptions=paper:10x14 - set printoptions=paper:A3 - set printoptions=paper:A4 - set printoptions=paper:A5 - set printoptions=paper:B4 - set printoptions=paper:B5 - set printoptions=paper:executive - set printoptions=paper:folio - set printoptions=paper:ledger - set printoptions=paper:legal - set printoptions=paper:letter - set printoptions=paper:quarto - set printoptions=paper:statement - set printoptions=paper:tabloid - set printoptions=formfeed:y - set printoptions= - set printoptions& +func Test_printoptions() + edit test_hardcopy.vim + syn on + + for opt in ['left:5in,right:10pt,top:8mm,bottom:2pc', + \ 'left:2in,top:30pt,right:16mm,bottom:3pc', + \ 'header:3,syntax:y,number:y,wrap:n', + \ 'header:3,syntax:n,number:y,wrap:y', + \ 'duplex:short,collate:n,jobsplit:y,portrait:n', + \ 'duplex:long,collate:y,jobsplit:n,portrait:y', + \ 'paper:10x14', + \ 'paper:A3', + \ 'paper:A4', + \ 'paper:A5', + \ 'paper:B4', + \ 'paper:B5', + \ 'paper:executive', + \ 'paper:folio', + \ 'paper:ledger', + \ 'paper:legal', + \ 'paper:letter', + \ 'paper:quarto', + \ 'paper:statement', + \ 'paper:tabloid', + \ 'formfeed:y', + \ ''] + exe 'set printoptions=' .. opt + if has('postscript') + hardcopy > Xhardcopy_printoptions + let lines = readfile('Xhardcopy_printoptions') + call assert_true(len(lines) > 20, opt) + call assert_true(lines[0] =~ 'PS-Adobe', opt) + call delete('Xhardcopy_printoptions') + endif + endfor call assert_fails('set printoptions=paper', 'E550:') call assert_fails('set printoptions=shredder:on', 'E551:') call assert_fails('set printoptions=left:no', 'E552:') + set printoptions& + bwipe endfunc -func Test_printmbfont_parsing() - " Only test that this doesn't throw an error. - set printmbfont=r:WadaMin-Regular,b:WadaMin-Bold,i:WadaMin-Italic,o:WadaMin-Bold-Italic,c:yes,a:no - set printmbfont= +func Test_printmbfont() + " Print a small help page which contains tabs to cover code that expands tabs to spaces. + help help + syn on + + for opt in [':WadaMin-Regular,b:WadaMin-Bold,i:WadaMin-Italic,o:WadaMin-Bold-Italic,c:yes,a:no', + \ ''] + exe 'set printmbfont=' .. opt + if has('postscript') + hardcopy > Xhardcopy_printmbfont + let lines = readfile('Xhardcopy_printmbfont') + call assert_true(len(lines) > 20, opt) + call assert_true(lines[0] =~ 'PS-Adobe', opt) + call delete('Xhardcopy_printmbfont') + endif + endfor set printmbfont& + bwipe +endfunc + +func Test_printexpr() + if !has('unix') + return + endif + + " Not a very useful printexpr value, but enough to test + " hardcopy with 'printexpr'. + function PrintFile(fname) + call writefile(['Test printexpr: ' .. v:cmdarg], + \ 'Xhardcopy_printexpr') + call delete(a:fname) + return 0 + endfunc + set printexpr=PrintFile(v:fname_in) + + help help + hardcopy dummy args + call assert_equal(['Test printexpr: dummy args'], + \ readfile('Xhardcopy_printexpr')) + call delete('Xhardcopy_printexpr') + + " Function return 1 to test print failure. + function PrintFails(fname) + call delete(a:fname) + return 1 + endfunc + set printexpr=PrintFails(v:fname_in) + call assert_fails('hardcopy', 'E365:') + + set printexpr& + bwipe +endfunc + +func Test_errors() + " FIXME: Windows fails differently than Unix. + if has('unix') + edit test_hardcopy.vim + call assert_fails('hardcopy >', 'E324:') + bwipe + endif +endfunc + +func Test_dark_background() + edit test_hardcopy.vim + syn on + + for bg in ['dark', 'light'] + exe 'set background=' .. bg + + if has('postscript') + hardcopy > Xhardcopy_dark_background + let lines = readfile('Xhardcopy_dark_background') + call assert_true(len(lines) > 20) + call assert_true(lines[0] =~ 'PS-Adobe') + call delete('Xhardcopy_dark_background') + endif + endfor + + set background& + bwipe +endfun + +func Test_empty_buffer() + " FIXME: Unclear why this fails on Windows. + if has('unix') + new + call assert_equal("\nNo text to be printed", execute('hardcopy')) + bwipe + endif endfunc func Test_printheader_parsing() @@ -46,22 +144,6 @@ func Test_printheader_parsing() set printheader& endfunc -" Test that :hardcopy produces a non-empty file. -" We don't check much of the contents. -func Test_with_syntax() - if has('postscript') - edit test_hardcopy.vim - set printoptions=syntax:y - syn on - hardcopy > Xhardcopy - let lines = readfile('Xhardcopy') - call assert_true(len(lines) > 20) - call assert_true(lines[0] =~ 'PS-Adobe') - call delete('Xhardcopy') - set printoptions& - endif -endfunc - func Test_fname_with_spaces() if !has('postscript') return @@ -86,4 +168,3 @@ func Test_illegal_byte() bwipe! call delete('Xpstest') endfunc - diff --git a/src/nvim/testdir/test_maparg.vim b/src/nvim/testdir/test_maparg.vim index 0b941d51ec..5f73bd80ad 100644 --- a/src/nvim/testdir/test_maparg.vim +++ b/src/nvim/testdir/test_maparg.vim @@ -41,6 +41,11 @@ function Test_maparg() map abc y<S-char-114>y call assert_equal("yRy", maparg('abc')) + omap { w + let d = maparg('{', 'o', 0, 1) + call assert_equal(['{', 'w', 'o'], [d.lhs, d.rhs, d.mode]) + ounmap { + map abc <Nop> call assert_equal("<Nop>", maparg('abc')) unmap abc @@ -62,3 +67,5 @@ function Test_range_map() execute "normal a\uf040\<Esc>" call assert_equal("abcd", getline(1)) endfunction + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_mapping.vim b/src/nvim/testdir/test_mapping.vim index f14f292a92..82562339f6 100644 --- a/src/nvim/testdir/test_mapping.vim +++ b/src/nvim/testdir/test_mapping.vim @@ -390,3 +390,77 @@ func Test_motionforce_omap() delfunc Select delfunc GetCommand endfunc + +" Test for mapping errors +func Test_map_error() + call assert_fails('unmap', 'E474:') + call assert_fails("exe 'map ' .. repeat('a', 51) .. ' :ls'", 'E474:') + call assert_fails('unmap abc', 'E31:') + call assert_fails('unabbr abc', 'E24:') + call assert_equal('', maparg('')) + call assert_fails('echo maparg("abc", [])', 'E730:') + + " unique map + map ,w /[#&!]<CR> + call assert_fails("map <unique> ,w /[#&!]<CR>", 'E227:') + " unique buffer-local map + call assert_fails("map <buffer> <unique> ,w /[.,;]<CR>", 'E225:') + unmap ,w + + " unique abbreviation + abbr SP special + call assert_fails("abbr <unique> SP special", 'E226:') + " unique buffer-local map + call assert_fails("abbr <buffer> <unique> SP special", 'E224:') + unabbr SP + + call assert_fails('mapclear abc', 'E474:') + call assert_fails('abclear abc', 'E474:') +endfunc + +" Test for <special> key mapping +func Test_map_special() + throw 'skipped: Nvim does not support cpoptions flag "<"' + new + let old_cpo = &cpo + set cpo+=< + imap <F12> Blue + call feedkeys("i\<F12>", "x") + call assert_equal("<F12>", getline(1)) + call feedkeys("ddi<F12>", "x") + call assert_equal("Blue", getline(1)) + iunmap <F12> + imap <special> <F12> Green + call feedkeys("ddi\<F12>", "x") + call assert_equal("Green", getline(1)) + call feedkeys("ddi<F12>", "x") + call assert_equal("<F12>", getline(1)) + iunmap <special> <F12> + let &cpo = old_cpo + %bwipe! +endfunc + +" Test for hasmapto() +func Test_hasmapto() + call assert_equal(0, hasmapto('/^\k\+ (')) + call assert_equal(0, hasmapto('/^\k\+ (', 'n')) + nmap ,f /^\k\+ (<CR> + call assert_equal(1, hasmapto('/^\k\+ (')) + call assert_equal(1, hasmapto('/^\k\+ (', 'n')) + call assert_equal(0, hasmapto('/^\k\+ (', 'v')) + + call assert_equal(0, hasmapto('/^\k\+ (', 'n', 1)) +endfunc + +" Test for command-line completion of maps +func Test_mapcomplete() + call assert_equal(['<buffer>', '<expr>', '<nowait>', '<script>', + \ '<silent>', '<special>', '<unique>'], + \ getcompletion('', 'mapping')) + call assert_equal([], getcompletion(',d', 'mapping')) + + call feedkeys(":abbr! \<C-A>\<C-B>\"\<CR>", 'tx') + call assert_match("abbr! \x01", @:) +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_profile.vim b/src/nvim/testdir/test_profile.vim index f3eb88abf0..4b0097617e 100644 --- a/src/nvim/testdir/test_profile.vim +++ b/src/nvim/testdir/test_profile.vim @@ -16,6 +16,7 @@ func Test_profile_func() while l:count > 0 let l:count = l:count - 1 endwhile + sleep 1m endfunc func! Foo3() endfunc @@ -51,7 +52,7 @@ func Test_profile_func() " - Unlike Foo3(), Foo2() should not be deleted since there is a check " for v:profiling. " - Bar() is not reported since it does not match "profile func Foo*". - call assert_equal(30, len(lines)) + call assert_equal(31, len(lines)) call assert_equal('FUNCTION Foo1()', lines[0]) call assert_match('Defined:.*Xprofile_func.vim:3', lines[1]) @@ -71,17 +72,18 @@ func Test_profile_func() call assert_match('^\s*101\s\+.*\swhile l:count > 0$', lines[16]) call assert_match('^\s*100\s\+.*\s let l:count = l:count - 1$', lines[17]) call assert_match('^\s*101\s\+.*\sendwhile$', lines[18]) - call assert_equal('', lines[19]) - call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[20]) - call assert_equal('count total (s) self (s) function', lines[21]) - call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$', lines[22]) - call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$', lines[23]) - call assert_equal('', lines[24]) - call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[25]) - call assert_equal('count total (s) self (s) function', lines[26]) - call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$', lines[27]) - call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$', lines[28]) - call assert_equal('', lines[29]) + call assert_match('^\s*1\s\+.\+sleep 1m$', lines[19]) + call assert_equal('', lines[20]) + call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[21]) + call assert_equal('count total (s) self (s) function', lines[22]) + call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$', lines[23]) + call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$', lines[24]) + call assert_equal('', lines[25]) + call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[26]) + call assert_equal('count total (s) self (s) function', lines[27]) + call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$', lines[28]) + call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$', lines[29]) + call assert_equal('', lines[30]) call delete('Xprofile_func.vim') call delete('Xprofile_func.log') diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index 015f771435..35555ca9d3 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -3318,6 +3318,14 @@ func Test_lvimgrep_crash() enew | only endfunc +func Test_lvimgrep_crash2() + au BufNewFile x sfind + call assert_fails('lvimgrep x x', 'E480:') + call assert_fails('lvimgrep x x x', 'E480:') + + au! BufNewFile +endfunc + " Test for the position of the quickfix and location list window func Test_qfwin_pos() " Open two windows diff --git a/src/nvim/testdir/test_quotestar.vim b/src/nvim/testdir/test_quotestar.vim index ce5a9ee827..77a5153a81 100644 --- a/src/nvim/testdir/test_quotestar.vim +++ b/src/nvim/testdir/test_quotestar.vim @@ -108,7 +108,8 @@ func Do_test_quotestar_for_x11() call remote_send(name, ":gui -f\<CR>") endif " Wait for the server in the GUI to be up and answering requests. - call WaitForAssert({-> assert_match("1", remote_expr(name, "has('gui_running')", "", 1))}) + " On some systems and with valgrind this can be very slow. + call WaitForAssert({-> assert_match("1", remote_expr(name, "has('gui_running')", "", 1))}, 10000) call remote_send(name, ":let @* = 'maybe'\<CR>") call WaitForAssert({-> assert_equal("maybe", remote_expr(name, "@*", "", 2))}) diff --git a/src/nvim/testdir/test_substitute.vim b/src/nvim/testdir/test_substitute.vim index e94bd22cea..ff07d8eceb 100644 --- a/src/nvim/testdir/test_substitute.vim +++ b/src/nvim/testdir/test_substitute.vim @@ -613,6 +613,25 @@ func Test_sub_replace_10() call assert_equal('1aaa', substitute('123', '1\zs\|[23]', 'a', 'g')) endfunc +func SubReplacer(text, submatches) + return a:text .. a:submatches[0] .. a:text +endfunc +func SubReplacer20(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, submatches) + return a:t3 .. a:submatches[0] .. a:t11 +endfunc + +func Test_substitute_partial() + call assert_equal('1foo2foo3', substitute('123', '2', function('SubReplacer', ['foo']), 'g')) + + " 19 arguments plus one is just OK + let Replacer = function('SubReplacer20', repeat(['foo'], 19)) + call assert_equal('1foo2foo3', substitute('123', '2', Replacer, 'g')) + + " 20 arguments plus one is too many + let Replacer = function('SubReplacer20', repeat(['foo'], 20)) + call assert_fails("call substitute('123', '2', Replacer, 'g')", 'E118') +endfunc + func Test_sub_cmd_9() new let input = ['1 aaa', '2 aaa', '3 aaa'] diff --git a/src/nvim/testdir/test_taglist.vim b/src/nvim/testdir/test_taglist.vim index cb54ace695..d4ff42fd68 100644 --- a/src/nvim/testdir/test_taglist.vim +++ b/src/nvim/testdir/test_taglist.vim @@ -7,6 +7,7 @@ func Test_taglist() \ "BFoo\tXbar\t1", \ "BBar\tXbar\t2", \ "Kindly\tXbar\t3;\"\tv\tfile:", + \ "Lambda\tXbar\t3;\"\tλ\tfile:", \ "Command\tXbar\tcall cursor(3, 4)|;\"\td", \ ], 'Xtags') set tags=Xtags @@ -17,12 +18,16 @@ func Test_taglist() call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo", "Xfoo"), {i, v -> v.name})) call assert_equal(['BFoo', 'FFoo'], map(taglist("Foo", "Xbar"), {i, v -> v.name})) - let kind = taglist("Kindly") - call assert_equal(1, len(kind)) - call assert_equal('v', kind[0]['kind']) - call assert_equal('3', kind[0]['cmd']) - call assert_equal(1, kind[0]['static']) - call assert_equal('Xbar', kind[0]['filename']) + let kindly = taglist("Kindly") + call assert_equal(1, len(kindly)) + call assert_equal('v', kindly[0]['kind']) + call assert_equal('3', kindly[0]['cmd']) + call assert_equal(1, kindly[0]['static']) + call assert_equal('Xbar', kindly[0]['filename']) + + let lambda = taglist("Lambda") + call assert_equal(1, len(lambda)) + call assert_equal('λ', lambda[0]['kind']) let cmd = taglist("Command") call assert_equal(1, len(cmd)) diff --git a/src/nvim/tui/terminfo.c b/src/nvim/tui/terminfo.c index 7dfe7ab953..ff2a357752 100644 --- a/src/nvim/tui/terminfo.c +++ b/src/nvim/tui/terminfo.c @@ -31,7 +31,10 @@ bool terminfo_is_term_family(const char *term, const char *family) return tlen >= flen && 0 == memcmp(term, family, flen) // Per commentary in terminfo, minus is the only valid suffix separator. - && ('\0' == term[flen] || '-' == term[flen]); + // The screen terminfo may have a terminal name like screen.xterm. By making + // the dot(.) a valid separator, such terminal names will also be the + // terminal family of the screen. + && ('\0' == term[flen] || '-' == term[flen] || '.' == term[flen]); } bool terminfo_is_bsd_console(const char *term) diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 99abdd033b..8bcdb681a2 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -1637,6 +1637,11 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, // per the screen manual; 2017-04 terminfo.src lacks these. unibi_set_if_empty(ut, unibi_to_status_line, "\x1b_"); unibi_set_if_empty(ut, unibi_from_status_line, "\x1b\\"); + // Fix an issue where smglr is inherited by TERM=screen.xterm. + if (unibi_get_str(ut, unibi_set_lr_margin)) { + ILOG("Disabling smglr with TERM=screen.xterm for screen."); + unibi_set_str(ut, unibi_set_lr_margin, NULL); + } } else if (tmux) { unibi_set_if_empty(ut, unibi_to_status_line, "\x1b_"); unibi_set_if_empty(ut, unibi_from_status_line, "\x1b\\"); @@ -1903,7 +1908,7 @@ static void augment_terminfo(TUIData *data, const char *term, // would use a tmux control sequence and an extra if(screen) test. data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str( ut, NULL, TMUX_WRAP(tmux, "\033]Pl%p1%06x\033\\")); - } else if ((xterm || rxvt || alacritty) + } else if ((xterm || rxvt || tmux || alacritty) && (vte_version == 0 || vte_version >= 3900)) { // Supported in urxvt, newer VTE. data->unibi_ext.set_cursor_color = (int)unibi_add_ext_str( @@ -1968,7 +1973,23 @@ static void flush_buf(UI *ui) uv_buf_t *bufp = &bufs[0]; TUIData *data = ui->data; - if (data->bufpos <= 0 && data->busy == data->is_invisible) { + // The content of the output for each condition is shown in the following + // table. Therefore, if data->bufpos == 0 and N/A or invis + norm, there is + // no need to output it. + // + // | is_invisible | !is_invisible + // ------+-----------------+--------------+--------------- + // busy | want_invisible | N/A | invis + // | !want_invisible | N/A | invis + // ------+-----------------+--------------+--------------- + // !busy | want_invisible | N/A | invis + // | !want_invisible | norm | invis + norm + // ------+-----------------+--------------+--------------- + // + if (data->bufpos <= 0 + && ((data->is_invisible && data->busy) + || (data->is_invisible && !data->busy && data->want_invisible) + || (!data->is_invisible && !data->busy && !data->want_invisible))) { return; } @@ -1995,8 +2016,8 @@ static void flush_buf(UI *ui) bufp->base = data->norm; bufp->len = UV_BUF_LEN(data->normlen); bufp++; + data->is_invisible = false; } - data->is_invisible = false; } uv_write(&req, STRUCT_CAST(uv_stream_t, &data->output_handle), diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 0f841760d6..3a5aa95ad3 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -424,7 +424,7 @@ int ui_current_col(void) void ui_flush(void) { cmdline_ui_flush(); - win_ui_flush_positions(); + win_ui_flush(); msg_ext_ui_flush(); msg_scroll_flush(); diff --git a/src/nvim/version.c b/src/nvim/version.c index 6412d4caae..9c14ced2ad 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -135,7 +135,7 @@ static const int included_patches[] = { 1786, 1785, 1784, - // 1783, + 1783, 1782, 1781, 1780, @@ -331,7 +331,7 @@ static const int included_patches[] = { 1590, // 1589, // 1588, - // 1587, + 1587, 1586, 1585, 1584, @@ -496,7 +496,7 @@ static const int included_patches[] = { 1425, 1424, 1423, - // 1422, + 1422, 1421, 1420, 1419, @@ -547,7 +547,7 @@ static const int included_patches[] = { 1374, 1373, 1372, - // 1371, + 1371, 1370, 1369, 1368, @@ -560,11 +560,11 @@ static const int included_patches[] = { 1361, 1360, 1359, - // 1358, + 1358, 1357, 1356, - // 1355, - // 1354, + 1355, + 1354, 1353, 1352, 1351, @@ -573,7 +573,7 @@ static const int included_patches[] = { 1348, 1347, 1346, - // 1345, + 1345, 1344, 1343, 1342, @@ -631,7 +631,7 @@ static const int included_patches[] = { 1290, 1289, 1288, - // 1287, + 1287, 1286, 1285, 1284, diff --git a/src/nvim/window.c b/src/nvim/window.c index fb3f1e0c9f..a89715ff79 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -773,6 +773,21 @@ static void ui_ext_win_position(win_T *wp) } +void ui_ext_win_viewport(win_T *wp) +{ + if ((wp == curwin || ui_has(kUIMultigrid)) && wp->w_viewport_invalid) { + int botline = wp->w_botline; + if (botline == wp->w_buffer->b_ml.ml_line_count+1 + && wp->w_empty_rows == 0) { + // TODO(bfredl): The might be more cases to consider, like how does this + // interact with incomplete final line? Diff filler lines? + botline = wp->w_buffer->b_ml.ml_line_count; + } + ui_call_win_viewport(wp->w_grid.handle, wp->handle, wp->w_topline-1, + botline, wp->w_cursor.lnum-1, wp->w_cursor.col); + wp->w_viewport_invalid = false; + } +} static bool parse_float_anchor(String anchor, FloatAnchor *out) { @@ -4688,6 +4703,7 @@ static win_T *win_alloc(win_T *after, int hidden) new_wp->w_scbind_pos = 1; new_wp->w_floating = 0; new_wp->w_float_config = FLOAT_CONFIG_INIT; + new_wp->w_viewport_invalid = true; // use global option for global-local options new_wp->w_p_so = -1; @@ -6528,10 +6544,12 @@ void restore_buffer(bufref_T *save_curbuf) /// @param[in] id a desired ID 'id' can be specified /// (greater than or equal to 1). -1 must be specified if no /// particular ID is desired +/// @param[in] conceal_char pointer to conceal replacement char /// @return ID of added match, -1 on failure. int match_add(win_T *wp, const char *const grp, const char *const pat, int prio, int id, list_T *pos_list, const char *const conceal_char) + FUNC_ATTR_NONNULL_ARG(1, 2) { matchitem_T *cur; matchitem_T *prev; @@ -6568,7 +6586,7 @@ int match_add(win_T *wp, const char *const grp, const char *const pat, return -1; } - /* Find available match ID. */ + // Find available match ID. while (id == -1) { cur = wp->w_match_head; while (cur != NULL && cur->id != wp->w_next_match_id) @@ -6578,7 +6596,7 @@ int match_add(win_T *wp, const char *const grp, const char *const pat, wp->w_next_match_id++; } - /* Build new match. */ + // Build new match. m = xcalloc(1, sizeof(matchitem_T)); m->id = id; m->priority = prio; @@ -6686,9 +6704,9 @@ int match_add(win_T *wp, const char *const grp, const char *const pat, rtype = VALID; } } - - /* Insert new match. The match list is in ascending order with regard to - * the match priorities. */ + + // Insert new match. The match list is in ascending order with regard to + // the match priorities. cur = wp->w_match_head; prev = cur; while (cur != NULL && prio >= cur->priority) { @@ -6992,7 +7010,7 @@ void get_framelayout(const frame_T *fr, list_T *l, bool outer) } } -void win_ui_flush_positions(void) +void win_ui_flush(void) { FOR_ALL_TAB_WINDOWS(tp, wp) { if (wp->w_pos_changed && wp->w_grid.chars != NULL) { @@ -7003,6 +7021,9 @@ void win_ui_flush_positions(void) } wp->w_pos_changed = false; } + if (tp == curtab) { + ui_ext_win_viewport(wp); + } } } diff --git a/src/nvim/xdiff/xdiff.h b/src/nvim/xdiff/xdiff.h index bc26fb64fd..8ff4a05bfb 100644 --- a/src/nvim/xdiff/xdiff.h +++ b/src/nvim/xdiff/xdiff.h @@ -25,9 +25,9 @@ #ifdef __cplusplus extern "C" { -#endif /* #ifdef __cplusplus */ +#endif // #ifdef __cplusplus -/* xpparm_t.flags */ +// xpparm_t.flags #define XDF_NEED_MINIMAL (1 << 0) #define XDF_IGNORE_WHITESPACE (1 << 1) @@ -48,22 +48,22 @@ extern "C" { #define XDF_INDENT_HEURISTIC (1 << 23) -/* xdemitconf_t.flags */ +// xdemitconf_t.flags #define XDL_EMIT_FUNCNAMES (1 << 0) #define XDL_EMIT_FUNCCONTEXT (1 << 2) -/* merge simplification levels */ +// merge simplification levels #define XDL_MERGE_MINIMAL 0 #define XDL_MERGE_EAGER 1 #define XDL_MERGE_ZEALOUS 2 #define XDL_MERGE_ZEALOUS_ALNUM 3 -/* merge favor modes */ +// merge favor modes #define XDL_MERGE_FAVOR_OURS 1 #define XDL_MERGE_FAVOR_THEIRS 2 #define XDL_MERGE_FAVOR_UNION 3 -/* merge output styles */ +// merge output styles #define XDL_MERGE_DIFF3 1 typedef struct s_mmfile { @@ -79,7 +79,7 @@ typedef struct s_mmbuffer { typedef struct s_xpparam { unsigned long flags; - /* See Documentation/diff-options.txt. */ + // See Documentation/diff-options.txt. char **anchors; size_t anchors_nr; } xpparam_t; @@ -126,9 +126,9 @@ typedef struct s_xmparam { int level; int favor; int style; - const char *ancestor; /* label for orig */ - const char *file1; /* label for mf1 */ - const char *file2; /* label for mf2 */ + const char *ancestor; // label for orig + const char *file1; // label for mf1 + const char *file2; // label for mf2 } xmparam_t; #define DEFAULT_CONFLICT_MARKER_SIZE 7 @@ -138,6 +138,6 @@ int xdl_merge(mmfile_t *orig, mmfile_t *mf1, mmfile_t *mf2, #ifdef __cplusplus } -#endif /* #ifdef __cplusplus */ +#endif // #ifdef __cplusplus -#endif /* #if !defined(XDIFF_H) */ +#endif // #if !defined(XDIFF_H) diff --git a/src/nvim/xdiff/xdiffi.c b/src/nvim/xdiff/xdiffi.c index 96d5277027..3806903986 100644 --- a/src/nvim/xdiff/xdiffi.c +++ b/src/nvim/xdiff/xdiffi.c @@ -418,24 +418,24 @@ static int xget_indent(xrecord_t *rec) ret += 1; else if (c == '\t') ret += 8 - ret % 8; - /* ignore other whitespace characters */ + // ignore other whitespace characters if (ret >= MAX_INDENT) return MAX_INDENT; } - /* The line contains only whitespace. */ + // The line contains only whitespace. return -1; } /* - * If more than this number of consecutive blank rows are found, just return this - * value. This avoids requiring O(N^2) work for pathological cases, and also - * ensures that the output of score_split fits in an int. + * If more than this number of consecutive blank rows are found, just return + * this value. This avoids requiring O(N^2) work for pathological cases, and + * also ensures that the output of score_split fits in an int. */ #define MAX_BLANKS 20 -/* Characteristics measured about a hypothetical split position. */ +// Characteristics measured about a hypothetical split position. struct split_measurement { /* * Is the split at the end of the file (aside from any blank lines)? @@ -472,10 +472,10 @@ struct split_measurement { }; struct split_score { - /* The effective indent of this split (smaller is preferred). */ + // The effective indent of this split (smaller is preferred). int effective_indent; - /* Penalty for this split (smaller is preferred). */ + // Penalty for this split (smaller is preferred). int penalty; }; @@ -534,16 +534,16 @@ static void measure_split(const xdfile_t *xdf, long split, * integer math. */ -/* Penalty if there are no non-blank lines before the split */ +// Penalty if there are no non-blank lines before the split #define START_OF_FILE_PENALTY 1 -/* Penalty if there are no non-blank lines after the split */ +// Penalty if there are no non-blank lines after the split #define END_OF_FILE_PENALTY 21 -/* Multiplier for the number of blank lines around the split */ +// Multiplier for the number of blank lines around the split #define TOTAL_BLANK_WEIGHT (-30) -/* Multiplier for the number of blank lines after the split */ +// Multiplier for the number of blank lines after the split #define POST_BLANK_WEIGHT 6 /* @@ -610,7 +610,7 @@ static void score_add_split(const struct split_measurement *m, struct split_scor post_blank = (m->indent == -1) ? 1 + m->post_blank : 0; total_blank = m->pre_blank + post_blank; - /* Penalties based on nearby blank lines: */ + // Penalties based on nearby blank lines: s->penalty += TOTAL_BLANK_WEIGHT * total_blank; s->penalty += POST_BLANK_WEIGHT * post_blank; @@ -621,13 +621,13 @@ static void score_add_split(const struct split_measurement *m, struct split_scor any_blanks = (total_blank != 0); - /* Note that the effective indent is -1 at the end of the file: */ + // Note that the effective indent is -1 at the end of the file: s->effective_indent += indent; if (indent == -1) { - /* No additional adjustments needed. */ + // No additional adjustments needed. } else if (m->pre_indent == -1) { - /* No additional adjustments needed. */ + // No additional adjustments needed. } else if (indent > m->pre_indent) { /* * The line is indented more than its predecessor. @@ -669,7 +669,7 @@ static void score_add_split(const struct split_measurement *m, struct split_scor static int score_cmp(struct split_score *s1, struct split_score *s2) { - /* -1 if s1.effective_indent < s2->effective_indent, etc. */ + // -1 if s1.effective_indent < s2->effective_indent, etc. int cmp_indents = ((s1->effective_indent > s2->effective_indent) - (s1->effective_indent < s2->effective_indent)); @@ -809,7 +809,7 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) { group_init(xdfo, &go); while (1) { - /* If the group is empty in the to-be-compacted file, skip it: */ + // If the group is empty in the to-be-compacted file, skip it: if (g.end == g.start) goto next; @@ -828,7 +828,7 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) { */ end_matching_other = -1; - /* Shift the group backward as much as possible: */ + // Shift the group backward as much as possible: while (!group_slide_up(xdf, &g, flags)) if (group_previous(xdfo, &go)) xdl_bug("group sync broken sliding up"); @@ -842,7 +842,7 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) { if (go.end > go.start) end_matching_other = g.end; - /* Now shift the group forward as far as possible: */ + // Now shift the group forward as far as possible: while (1) { if (group_slide_down(xdf, &g, flags)) break; @@ -863,7 +863,7 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) { */ if (g.end == earliest_end) { - /* no shifting was possible */ + // no shifting was possible } else if (end_matching_other != -1) { /* * Move the possibly merged group of changes back to line @@ -921,7 +921,7 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) { } next: - /* Move past the just-processed group: */ + // Move past the just-processed group: if (group_next(xdf, &g)) break; if (group_next(xdfo, &go)) diff --git a/src/nvim/xdiff/xdiffi.h b/src/nvim/xdiff/xdiffi.h index 8f1c7c8b04..467a1e85cd 100644 --- a/src/nvim/xdiff/xdiffi.h +++ b/src/nvim/xdiff/xdiffi.h @@ -61,4 +61,4 @@ int xdl_do_patience_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, int xdl_do_histogram_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdfenv_t *env); -#endif /* #if !defined(XDIFFI_H) */ +#endif // #if !defined(XDIFFI_H) diff --git a/src/nvim/xdiff/xemit.c b/src/nvim/xdiff/xemit.c index d8a6f1ed38..f1a45139cc 100644 --- a/src/nvim/xdiff/xemit.c +++ b/src/nvim/xdiff/xemit.c @@ -54,9 +54,9 @@ xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg) xdchange_t *xch, *xchp, *lxch; long max_common = 2 * xecfg->ctxlen + xecfg->interhunkctxlen; long max_ignorable = xecfg->ctxlen; - unsigned long ignored = 0; /* number of ignored blank lines */ + unsigned long ignored = 0; // number of ignored blank lines - /* remove ignorable changes that are too far before other changes */ + // remove ignorable changes that are too far before other changes for (xchp = *xscr; xchp && xchp->ignore; xchp = xchp->next) { xch = xchp->next; @@ -99,9 +99,9 @@ xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg) static long def_ff(const char *rec, long len, char *buf, long sz, void *priv UNUSED) { if (len > 0 && - (isalpha((unsigned char)*rec) || /* identifier? */ - *rec == '_' || /* also identifier? */ - *rec == '$')) { /* identifiers from VMS and other esoterico */ + (isalpha((unsigned char)*rec) || // identifier? + *rec == '_' || // also identifier? + *rec == '$')) { // identifiers from VMS and other esoterico if (len > sz) len = sz; while (0 < len && isspace((unsigned char)rec[len - 1])) @@ -197,7 +197,7 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, if (xecfg->flags & XDL_EMIT_FUNCCONTEXT) { long fs1, i1 = xch->i1; - /* Appended chunk? */ + // Appended chunk? if (i1 >= xe->xdf1.nrec) { long i2 = xch->i2; diff --git a/src/nvim/xdiff/xemit.h b/src/nvim/xdiff/xemit.h index 1b9887e670..3ce7e3dd50 100644 --- a/src/nvim/xdiff/xemit.h +++ b/src/nvim/xdiff/xemit.h @@ -33,4 +33,4 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, -#endif /* #if !defined(XEMIT_H) */ +#endif // #if !defined(XEMIT_H) diff --git a/src/nvim/xdiff/xhistogram.c b/src/nvim/xdiff/xhistogram.c index 3fb8974dd4..28cf8258e5 100644 --- a/src/nvim/xdiff/xhistogram.c +++ b/src/nvim/xdiff/xhistogram.c @@ -55,8 +55,8 @@ struct histindex { struct record { unsigned int ptr, cnt; struct record *next; - } **records, /* an occurrence */ - **line_map; /* map of line to record chain */ + } **records, // an occurrence + **line_map; // map of line to record chain chastore_t rcha; unsigned int *next_ptrs; unsigned int table_bits, @@ -128,7 +128,7 @@ static int scanA(struct histindex *index, int line1, int count1) */ NEXT_PTR(index, ptr) = rec->ptr; rec->ptr = ptr; - /* cap rec->cnt at MAX_CNT */ + // cap rec->cnt at MAX_CNT rec->cnt = XDL_MIN(MAX_CNT, rec->cnt + 1); LINE_MAP(index, ptr) = rec; goto continue_scan; @@ -154,7 +154,7 @@ static int scanA(struct histindex *index, int line1, int count1) LINE_MAP(index, ptr) = rec; continue_scan: - ; /* no op */ + ; // no op } return 0; @@ -266,7 +266,7 @@ static int find_lcs(xpparam_t const *xpp, xdfenv_t *env, index.records = NULL; index.line_map = NULL; - /* in case of early xdl_cha_free() */ + // in case of early xdl_cha_free() index.rcha.head = NULL; index.table_bits = xdl_hashbits(count1); @@ -288,7 +288,7 @@ static int find_lcs(xpparam_t const *xpp, xdfenv_t *env, goto cleanup; memset(index.next_ptrs, 0, sz); - /* lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx() */ + // lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx() if (xdl_cha_init(&index.rcha, sizeof(struct record), count1 / 4 + 1) < 0) goto cleanup; diff --git a/src/nvim/xdiff/xinclude.h b/src/nvim/xdiff/xinclude.h index 46b8608314..5a359d1431 100644 --- a/src/nvim/xdiff/xinclude.h +++ b/src/nvim/xdiff/xinclude.h @@ -20,13 +20,13 @@ * */ -/* defines HAVE_ATTRIBUTE_UNUSED */ +// defines HAVE_ATTRIBUTE_UNUSED #ifdef HAVE_CONFIG_H # include "../auto/config.h" #endif -/* Mark unused function arguments with UNUSED, so that gcc -Wunused-parameter - * can be used to check for mistakes. */ +// Mark unused function arguments with UNUSED, so that gcc -Wunused-parameter +// can be used to check for mistakes. #ifdef HAVE_ATTRIBUTE_UNUSED # define UNUSED __attribute__((unused)) #else @@ -58,4 +58,4 @@ #include "xemit.h" -#endif /* #if !defined(XINCLUDE_H) */ +#endif // #if !defined(XINCLUDE_H) diff --git a/src/nvim/xdiff/xmacros.h b/src/nvim/xdiff/xmacros.h index 2809a28ca9..1167ebbb05 100644 --- a/src/nvim/xdiff/xmacros.h +++ b/src/nvim/xdiff/xmacros.h @@ -51,4 +51,4 @@ do { \ } while (0) -#endif /* #if !defined(XMACROS_H) */ +#endif // #if !defined(XMACROS_H) diff --git a/src/nvim/xdiff/xpatience.c b/src/nvim/xdiff/xpatience.c index 2c65aac386..f6c84c67d8 100644 --- a/src/nvim/xdiff/xpatience.c +++ b/src/nvim/xdiff/xpatience.c @@ -69,7 +69,7 @@ struct hashmap { */ unsigned anchor : 1; } *entries, *first, *last; - /* were common records found? */ + // were common records found? unsigned long has_matches; mmfile_t *file1, *file2; xdfenv_t *env; @@ -86,7 +86,7 @@ static int is_anchor(xpparam_t const *xpp, const char *line) return 0; } -/* The argument "pass" is 1 for the first file, 2 for the second. */ +// The argument "pass" is 1 for the first file, 2 for the second. static void insert_record(xpparam_t const *xpp, int line, struct hashmap *map, int pass) { @@ -155,7 +155,7 @@ static int fill_hashmap(mmfile_t *file1, mmfile_t *file2, result->xpp = xpp; result->env = env; - /* We know exactly how large we want the hash map */ + // We know exactly how large we want the hash map result->alloc = count1 * 2; result->entries = (struct entry *) xdl_malloc(result->alloc * sizeof(struct entry)); @@ -163,11 +163,11 @@ static int fill_hashmap(mmfile_t *file1, mmfile_t *file2, return -1; memset(result->entries, 0, result->alloc * sizeof(struct entry)); - /* First, fill with entries from the first file */ + // First, fill with entries from the first file while (count1--) insert_record(xpp, line1++, result, 1); - /* Then search for matches in the second file */ + // Then search for matches in the second file while (count2--) insert_record(xpp, line2++, result, 2); @@ -185,13 +185,13 @@ static int binary_search(struct entry **sequence, int longest, while (left + 1 < right) { int middle = left + (right - left) / 2; - /* by construction, no two entries can be equal */ + // by construction, no two entries can be equal if (sequence[middle]->line2 > entry->line2) right = middle; else left = middle; } - /* return the index in "sequence", _not_ the sequence length */ + // return the index in "sequence", _not_ the sequence length return left; } @@ -216,7 +216,7 @@ static struct entry *find_longest_common_sequence(struct hashmap *map) */ int anchor_i = -1; - /* Added to silence Coverity. */ + // Added to silence Coverity. if (sequence == NULL) return map->first; @@ -237,13 +237,13 @@ static struct entry *find_longest_common_sequence(struct hashmap *map) } } - /* No common unique lines were found */ + // No common unique lines were found if (!longest) { xdl_free(sequence); return NULL; } - /* Iterate starting at the last element, adjusting the "next" members */ + // Iterate starting at the last element, adjusting the "next" members entry = sequence[longest - 1]; entry->next = NULL; while (entry->previous) { @@ -273,7 +273,7 @@ static int walk_common_sequence(struct hashmap *map, struct entry *first, int next1, next2; for (;;) { - /* Try to grow the line ranges of common lines */ + // Try to grow the line ranges of common lines if (first) { next1 = first->line1; next2 = first->line2; @@ -292,7 +292,7 @@ static int walk_common_sequence(struct hashmap *map, struct entry *first, line2++; } - /* Recurse */ + // Recurse if (next1 > line1 || next2 > line2) { struct hashmap submap; @@ -343,7 +343,7 @@ static int patience_diff(mmfile_t *file1, mmfile_t *file2, struct entry *first; int result = 0; - /* trivial case: one side is empty */ + // trivial case: one side is empty if (!count1) { while(count2--) env->xdf2.rchg[line2++ - 1] = 1; @@ -359,7 +359,7 @@ static int patience_diff(mmfile_t *file1, mmfile_t *file2, line1, count1, line2, count2)) return -1; - /* are there any matching lines at all? */ + // are there any matching lines at all? if (!map.has_matches) { while(count1--) env->xdf1.rchg[line1++ - 1] = 1; @@ -387,7 +387,7 @@ int xdl_do_patience_diff(mmfile_t *file1, mmfile_t *file2, if (xdl_prepare_env(file1, file2, xpp, env) < 0) return -1; - /* environment is cleaned up in xdl_diff() */ + // environment is cleaned up in xdl_diff() return patience_diff(file1, file2, xpp, env, 1, env->xdf1.nrec, 1, env->xdf2.nrec); } diff --git a/src/nvim/xdiff/xprepare.h b/src/nvim/xdiff/xprepare.h index 947d9fc1bb..b67b3b25ab 100644 --- a/src/nvim/xdiff/xprepare.h +++ b/src/nvim/xdiff/xprepare.h @@ -31,4 +31,4 @@ void xdl_free_env(xdfenv_t *xe); -#endif /* #if !defined(XPREPARE_H) */ +#endif // #if !defined(XPREPARE_H) diff --git a/src/nvim/xdiff/xtypes.h b/src/nvim/xdiff/xtypes.h index 8442bd436e..026999c1bf 100644 --- a/src/nvim/xdiff/xtypes.h +++ b/src/nvim/xdiff/xtypes.h @@ -64,4 +64,4 @@ typedef struct s_xdfenv { -#endif /* #if !defined(XTYPES_H) */ +#endif // #if !defined(XTYPES_H) diff --git a/src/nvim/xdiff/xutils.c b/src/nvim/xdiff/xutils.c index 25a090fb73..e8c7d2f884 100644 --- a/src/nvim/xdiff/xutils.c +++ b/src/nvim/xdiff/xutils.c @@ -168,7 +168,7 @@ static int ends_with_optional_cr(const char *l, long s, long i) s--; if (s == i) return 1; - /* do not ignore CR at the end of an incomplete line */ + // do not ignore CR at the end of an incomplete line if (complete && s == i + 1 && l[i] == '\r') return 1; return 0; @@ -208,7 +208,7 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags) } else if (flags & XDF_IGNORE_WHITESPACE_CHANGE) { while (i1 < s1 && i2 < s2) { if (XDL_ISSPACE(l1[i1]) && XDL_ISSPACE(l2[i2])) { - /* Skip matching spaces and try again */ + // Skip matching spaces and try again while (i1 < s1 && XDL_ISSPACE(l1[i1])) i1++; while (i2 < s2 && XDL_ISSPACE(l2[i2])) @@ -224,7 +224,7 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags) i2++; } } else if (flags & XDF_IGNORE_CR_AT_EOL) { - /* Find the first difference and see how the line ends */ + // Find the first difference and see how the line ends while (i1 < s1 && i2 < s2 && l1[i1] == l2[i2]) { i1++; i2++; @@ -261,7 +261,7 @@ static unsigned long xdl_hash_record_with_whitespace(char const **data, for (; ptr < top && *ptr != '\n'; ptr++) { if (cr_at_eol_only) { - /* do not ignore CR at the end of an incomplete line */ + // do not ignore CR at the end of an incomplete line if (*ptr == '\r' && (ptr + 1 < top && ptr[1] == '\n')) continue; @@ -274,7 +274,7 @@ static unsigned long xdl_hash_record_with_whitespace(char const **data, ptr++; at_eol = (top <= ptr + 1 || ptr[1] == '\n'); if (flags & XDF_IGNORE_WHITESPACE) - ; /* already handled */ + ; // already handled else if (flags & XDF_IGNORE_WHITESPACE_CHANGE && !at_eol) { ha += (ha << 5); diff --git a/src/nvim/xdiff/xutils.h b/src/nvim/xdiff/xutils.h index fba7bae03c..0bebd93022 100644 --- a/src/nvim/xdiff/xutils.h +++ b/src/nvim/xdiff/xutils.h @@ -44,4 +44,4 @@ int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp, -#endif /* #if !defined(XUTILS_H) */ +#endif // #if !defined(XUTILS_H) diff --git a/src/tree_sitter/language.c b/src/tree_sitter/language.c index e240ef2a53..a396b4b0b6 100644 --- a/src/tree_sitter/language.c +++ b/src/tree_sitter/language.c @@ -72,8 +72,10 @@ const char *ts_language_symbol_name( return "ERROR"; } else if (symbol == ts_builtin_sym_error_repeat) { return "_ERROR"; - } else { + } else if (symbol < ts_language_symbol_count(self)) { return self->symbol_names[symbol]; + } else { + return NULL; } } @@ -119,7 +121,7 @@ const char *ts_language_field_name_for_id( TSFieldId id ) { uint32_t count = ts_language_field_count(self); - if (count) { + if (count && id <= count) { return self->field_names[id]; } else { return NULL; diff --git a/src/tree_sitter/node.c b/src/tree_sitter/node.c index b03e2fc979..576f3ef38e 100644 --- a/src/tree_sitter/node.c +++ b/src/tree_sitter/node.c @@ -150,7 +150,9 @@ static inline TSNode ts_node__child( while (ts_node_child_iterator_next(&iterator, &child)) { if (ts_node__is_relevant(child, include_anonymous)) { if (index == child_index) { - ts_tree_set_cached_parent(self.tree, &child, &self); + if (ts_node__is_relevant(self, true)) { + ts_tree_set_cached_parent(self.tree, &child, &self); + } return child; } index++; diff --git a/src/tree_sitter/parser.c b/src/tree_sitter/parser.c index 0fa0c4195b..d4b227308b 100644 --- a/src/tree_sitter/parser.c +++ b/src/tree_sitter/parser.c @@ -324,6 +324,12 @@ static bool ts_parser__can_reuse_first_leaf( TSStateId leaf_state = ts_subtree_leaf_parse_state(tree); TSLexMode leaf_lex_mode = self->language->lex_modes[leaf_state]; + // At the end of a non-terminal extra node, the lexer normally returns + // NULL, which indicates that the parser should look for a reduce action + // at symbol `0`. Avoid reusing tokens in this situation to ensure that + // the same thing happens when incrementally reparsing. + if (current_lex_mode.lex_state == (uint16_t)(-1)) return false; + // If the token was created in a state with the same set of lookaheads, it is reusable. if ( table_entry->action_count > 0 && @@ -593,6 +599,10 @@ static Subtree ts_parser__reuse_node( uint32_t byte_offset = reusable_node_byte_offset(&self->reusable_node); uint32_t end_byte_offset = byte_offset + ts_subtree_total_bytes(result); + // Do not reuse an EOF node if the included ranges array has changes + // later on in the file. + if (ts_subtree_is_eof(result)) end_byte_offset = UINT32_MAX; + if (byte_offset > position) { LOG("before_reusable_node symbol:%s", TREE_NAME(result)); break; @@ -1605,8 +1615,8 @@ static unsigned ts_parser__condense_stack(TSParser *self) { static bool ts_parser_has_outstanding_parse(TSParser *self) { return ( - self->lexer.current_position.bytes > 0 || - ts_stack_state(self->stack, 0) != 1 + ts_stack_state(self->stack, 0) != 1 || + ts_stack_node_count_since_error(self->stack, 0) != 0 ); } diff --git a/src/tree_sitter/query.c b/src/tree_sitter/query.c index 053882cf68..92a8006179 100644 --- a/src/tree_sitter/query.c +++ b/src/tree_sitter/query.c @@ -35,15 +35,21 @@ typedef struct { * captured in this pattern. * - `depth` - The depth where this node occurs in the pattern. The root node * of the pattern has depth zero. + * - `repeat_step_index` - If this step is part of a repetition, the index of + * the beginning of the repetition. A `NONE` value means this step is not + * part of a repetition. */ typedef struct { TSSymbol symbol; TSFieldId field; uint16_t capture_ids[MAX_STEP_CAPTURE_COUNT]; - uint16_t depth: 13; + uint16_t repeat_step_index; + uint16_t depth: 11; bool contains_captures: 1; + bool is_pattern_start: 1; bool is_immediate: 1; bool is_last: 1; + bool is_repeated: 1; } QueryStep; /* @@ -85,23 +91,27 @@ typedef struct { * represented as one of these states. */ typedef struct { + uint32_t id; uint16_t start_depth; uint16_t pattern_index; uint16_t step_index; - uint16_t capture_count; - uint16_t capture_list_id; uint16_t consumed_capture_count; - uint32_t id; + uint16_t repeat_match_count; + uint16_t step_index_on_failure; + uint8_t capture_list_id; + bool seeking_non_match; } QueryState; +typedef Array(TSQueryCapture) CaptureList; + /* * CaptureListPool - A collection of *lists* of captures. Each QueryState - * needs to maintain its own list of captures. They are all represented as - * slices of one shared array. The CaptureListPool keeps track of which - * parts of the shared array are currently in use by a QueryState. + * needs to maintain its own list of captures. To avoid repeated allocations, + * the reuses a fixed set of capture lists, and keeps track of which ones + * are currently in use. */ typedef struct { - Array(TSQueryCapture) list; + CaptureList list[32]; uint32_t usage_map; } CaptureListPool; @@ -119,7 +129,6 @@ struct TSQuery { Array(Slice) predicates_by_pattern; Array(uint32_t) start_bytes_by_pattern; const TSLanguage *language; - uint16_t max_capture_count; uint16_t wildcard_root_pattern_count; TSSymbol *symbol_map; }; @@ -233,24 +242,25 @@ static void stream_scan_identifier(Stream *stream) { static CaptureListPool capture_list_pool_new(void) { return (CaptureListPool) { - .list = array_new(), .usage_map = UINT32_MAX, }; } -static void capture_list_pool_reset(CaptureListPool *self, uint16_t list_size) { +static void capture_list_pool_reset(CaptureListPool *self) { self->usage_map = UINT32_MAX; - uint32_t total_size = MAX_STATE_COUNT * list_size; - array_reserve(&self->list, total_size); - self->list.size = total_size; + for (unsigned i = 0; i < 32; i++) { + array_clear(&self->list[i]); + } } static void capture_list_pool_delete(CaptureListPool *self) { - array_delete(&self->list); + for (unsigned i = 0; i < 32; i++) { + array_delete(&self->list[i]); + } } -static TSQueryCapture *capture_list_pool_get(CaptureListPool *self, uint16_t id) { - return &self->list.contents[id * (self->list.size / MAX_STATE_COUNT)]; +static CaptureList *capture_list_pool_get(CaptureListPool *self, uint16_t id) { + return &self->list[id]; } static bool capture_list_pool_is_empty(const CaptureListPool *self) { @@ -269,6 +279,7 @@ static uint16_t capture_list_pool_acquire(CaptureListPool *self) { } static void capture_list_pool_release(CaptureListPool *self, uint16_t id) { + array_clear(&self->list[id]); self->usage_map |= bitmask_for_index(id); } @@ -331,6 +342,67 @@ static uint16_t symbol_table_insert_name( return self->slices.size - 1; } +static uint16_t symbol_table_insert_name_with_escapes( + SymbolTable *self, + const char *escaped_name, + uint32_t escaped_length +) { + Slice slice = { + .offset = self->characters.size, + .length = 0, + }; + array_grow_by(&self->characters, escaped_length + 1); + + // Copy the contents of the literal into the characters buffer, processing escape + // sequences like \n and \". This needs to be done before checking if the literal + // is already present, in order to do the string comparison. + bool is_escaped = false; + for (unsigned i = 0; i < escaped_length; i++) { + const char *src = &escaped_name[i]; + char *dest = &self->characters.contents[slice.offset + slice.length]; + if (is_escaped) { + switch (*src) { + case 'n': + *dest = '\n'; + break; + case 'r': + *dest = '\r'; + break; + case 't': + *dest = '\t'; + break; + case '0': + *dest = '\0'; + break; + default: + *dest = *src; + break; + } + is_escaped = false; + slice.length++; + } else { + if (*src == '\\') { + is_escaped = true; + } else { + *dest = *src; + slice.length++; + } + } + } + + // If the string is already present, remove the redundant content from the characters + // buffer and return the existing id. + int id = symbol_table_id_for_name(self, &self->characters.contents[slice.offset], slice.length); + if (id >= 0) { + self->characters.size -= (escaped_length + 1); + return id; + } + + self->characters.contents[slice.offset + slice.length] = 0; + array_push(&self->slices, slice); + return self->slices.size - 1; +} + /************ * QueryStep ************/ @@ -346,7 +418,11 @@ static QueryStep query_step__new( .field = 0, .capture_ids = {NONE, NONE, NONE, NONE}, .contains_captures = false, + .is_repeated = false, + .is_last = false, + .is_pattern_start = false, .is_immediate = is_immediate, + .repeat_step_index = NONE, }; } @@ -523,9 +599,22 @@ static TSQueryError ts_query__parse_predicate( stream_advance(stream); // Parse the string content + bool is_escaped = false; const char *string_content = stream->input; - while (stream->next != '"') { - if (stream->next == '\n' || !stream_advance(stream)) { + for (;;) { + if (is_escaped) { + is_escaped = false; + } else { + if (stream->next == '\\') { + is_escaped = true; + } else if (stream->next == '"') { + break; + } else if (stream->next == '\n') { + stream_reset(stream, string_content - 1); + return TSQueryErrorSyntax; + } + } + if (!stream_advance(stream)) { stream_reset(stream, string_content - 1); return TSQueryErrorSyntax; } @@ -533,7 +622,7 @@ static TSQueryError ts_query__parse_predicate( uint32_t length = stream->input - string_content; // Add a step for the node - uint16_t id = symbol_table_insert_name( + uint16_t id = symbol_table_insert_name_with_escapes( &self->predicate_values, string_content, length @@ -624,7 +713,7 @@ static TSQueryError ts_query__parse_pattern( // Parse the wildcard symbol if (stream->next == '*') { - symbol = NAMED_WILDCARD_SYMBOL; + symbol = depth > 0 ? NAMED_WILDCARD_SYMBOL : WILDCARD_SYMBOL; stream_advance(stream); } @@ -768,27 +857,43 @@ static TSQueryError ts_query__parse_pattern( stream_skip_whitespace(stream); - // Parse an '@'-prefixed capture pattern - while (stream->next == '@') { - stream_advance(stream); + // Parse suffixes modifiers for this pattern + for (;;) { + QueryStep *step = &self->steps.contents[starting_step_index]; - // Parse the capture name - if (!stream_is_ident_start(stream)) return TSQueryErrorSyntax; - const char *capture_name = stream->input; - stream_scan_identifier(stream); - uint32_t length = stream->input - capture_name; + if (stream->next == '+') { + stream_advance(stream); + step->is_repeated = true; + array_back(&self->steps)->repeat_step_index = starting_step_index; + stream_skip_whitespace(stream); + } - // Add the capture id to the first step of the pattern - uint16_t capture_id = symbol_table_insert_name( - &self->captures, - capture_name, - length - ); - QueryStep *step = &self->steps.contents[starting_step_index]; - query_step__add_capture(step, capture_id); - (*capture_count)++; + // Parse an '@'-prefixed capture pattern + else if (stream->next == '@') { + stream_advance(stream); - stream_skip_whitespace(stream); + // Parse the capture name + if (!stream_is_ident_start(stream)) return TSQueryErrorSyntax; + const char *capture_name = stream->input; + stream_scan_identifier(stream); + uint32_t length = stream->input - capture_name; + + // Add the capture id to the first step of the pattern + uint16_t capture_id = symbol_table_insert_name( + &self->captures, + capture_name, + length + ); + query_step__add_capture(step, capture_id); + (*capture_count)++; + + stream_skip_whitespace(stream); + } + + // No more suffix modifiers + else { + break; + } } return 0; @@ -838,16 +943,14 @@ TSQuery *ts_query_new( .predicates_by_pattern = array_new(), .symbol_map = symbol_map, .wildcard_root_pattern_count = 0, - .max_capture_count = 0, .language = language, }; // Parse all of the S-expressions in the given string. Stream stream = stream_new(source, source_len); stream_skip_whitespace(&stream); - uint32_t start_step_index; while (stream.input < stream.end) { - start_step_index = self->steps.size; + uint32_t start_step_index = self->steps.size; uint32_t capture_count = 0; array_push(&self->start_bytes_by_pattern, stream.input - source); array_push(&self->predicates_by_pattern, ((Slice) { @@ -865,7 +968,19 @@ TSQuery *ts_query_new( return NULL; } + // If a pattern has a wildcard at its root, optimize the matching process + // by skipping matching the wildcard. + if ( + self->steps.contents[start_step_index].symbol == WILDCARD_SYMBOL + ) { + QueryStep *second_step = &self->steps.contents[start_step_index + 1]; + if (second_step->symbol != WILDCARD_SYMBOL && second_step->depth != PATTERN_DONE_MARKER) { + start_step_index += 1; + } + } + // Maintain a map that can look up patterns for a given root symbol. + self->steps.contents[start_step_index].is_pattern_start = true; ts_query__pattern_map_insert( self, self->steps.contents[start_step_index].symbol, @@ -874,13 +989,6 @@ TSQuery *ts_query_new( if (self->steps.contents[start_step_index].symbol == WILDCARD_SYMBOL) { self->wildcard_root_pattern_count++; } - - // Keep track of the maximum number of captures in pattern, because - // that numer determines how much space is needed to store each capture - // list. - if (capture_count > self->max_capture_count) { - self->max_capture_count = capture_count; - } } ts_query__finalize_steps(self); @@ -1015,7 +1123,7 @@ void ts_query_cursor_exec( array_clear(&self->states); array_clear(&self->finished_states); ts_tree_cursor_reset(&self->cursor, node); - capture_list_pool_reset(&self->capture_list_pool, query->max_capture_count); + capture_list_pool_reset(&self->capture_list_pool); self->next_state_id = 0; self->depth = 0; self->ascending = false; @@ -1059,12 +1167,12 @@ static bool ts_query_cursor__first_in_progress_capture( bool result = false; for (unsigned i = 0; i < self->states.size; i++) { const QueryState *state = &self->states.contents[i]; - if (state->capture_count > 0) { - const TSQueryCapture *captures = capture_list_pool_get( - &self->capture_list_pool, - state->capture_list_id - ); - uint32_t capture_byte = ts_node_start_byte(captures[0].node); + const CaptureList *captures = capture_list_pool_get( + &self->capture_list_pool, + state->capture_list_id + ); + if (captures->size > 0) { + uint32_t capture_byte = ts_node_start_byte(captures->contents[0].node); if ( !result || capture_byte < *byte_offset || @@ -1087,6 +1195,19 @@ static bool ts_query__cursor_add_state( TSQueryCursor *self, const PatternEntry *pattern ) { + QueryStep *step = &self->query->steps.contents[pattern->step_index]; + + // If this pattern begins with a repetition, then avoid creating + // new states after already matching the repetition one or more times. + // The query should only one match for the repetition - the one that + // started the earliest. + if (step->is_repeated) { + for (unsigned i = 0; i < self->states.size; i++) { + QueryState *state = &self->states.contents[i]; + if (state->step_index == pattern->step_index) return true; + } + } + uint32_t list_id = capture_list_pool_acquire(&self->capture_list_pool); // If there are no capture lists left in the pool, then terminate whichever @@ -1112,14 +1233,20 @@ static bool ts_query__cursor_add_state( } } - LOG(" start state. pattern:%u\n", pattern->pattern_index); + LOG( + " start state. pattern:%u, step:%u\n", + pattern->pattern_index, + pattern->step_index + ); array_push(&self->states, ((QueryState) { .capture_list_id = list_id, .step_index = pattern->step_index, .pattern_index = pattern->pattern_index, - .start_depth = self->depth, - .capture_count = 0, + .start_depth = self->depth - step->depth, .consumed_capture_count = 0, + .repeat_match_count = 0, + .step_index_on_failure = NONE, + .seeking_non_match = false, })); return true; } @@ -1133,15 +1260,15 @@ static QueryState *ts_query__cursor_copy_state( array_push(&self->states, *state); QueryState *new_state = array_back(&self->states); new_state->capture_list_id = new_list_id; - TSQueryCapture *old_captures = capture_list_pool_get( + CaptureList *old_captures = capture_list_pool_get( &self->capture_list_pool, state->capture_list_id ); - TSQueryCapture *new_captures = capture_list_pool_get( + CaptureList *new_captures = capture_list_pool_get( &self->capture_list_pool, new_list_id ); - memcpy(new_captures, old_captures, state->capture_count * sizeof(TSQueryCapture)); + array_push_all(new_captures, old_captures); return new_state; } @@ -1298,6 +1425,24 @@ static inline bool ts_query_cursor__advance(TSQueryCursor *self) { } if (!node_does_match) { + // If this QueryState has processed a repeating sequence, and that repeating + // sequence has ended, move on to the *next* step of this state's pattern. + if ( + state->step_index_on_failure != NONE && + (!later_sibling_can_match || step->is_repeated) + ) { + LOG( + " finish repetition state. pattern:%u, step:%u\n", + state->pattern_index, + state->step_index + ); + state->step_index = state->step_index_on_failure; + state->step_index_on_failure = NONE; + state->repeat_match_count = 0; + i--; + continue; + } + if (!later_sibling_can_match) { LOG( " discard state. pattern:%u, step:%u\n", @@ -1312,9 +1457,17 @@ static inline bool ts_query_cursor__advance(TSQueryCursor *self) { i--; n--; } + + state->seeking_non_match = false; continue; } + // The `seeking_non_match` flag indicates that a previous QueryState + // has already begun processing this repeating sequence, so that *this* + // QueryState should not begin matching until a separate repeating sequence + // is found. + if (state->seeking_non_match) continue; + // Some patterns can match their root node in multiple ways, // capturing different children. If this pattern step could match // later children within the same parent, then this query state @@ -1324,11 +1477,20 @@ static inline bool ts_query_cursor__advance(TSQueryCursor *self) { // siblings. QueryState *next_state = state; if ( - step->depth > 0 && + !step->is_pattern_start && step->contains_captures && - later_sibling_can_match + later_sibling_can_match && + state->repeat_match_count == 0 ) { QueryState *copy = ts_query__cursor_copy_state(self, state); + + // The QueryState that matched this node has begun matching a repeating + // sequence. The QueryState that *skipped* this node should not start + // matching later elements of the same repeating sequence. + if (step->is_repeated) { + state->seeking_non_match = true; + } + if (copy) { LOG( " split state. pattern:%u, step:%u\n", @@ -1337,55 +1499,71 @@ static inline bool ts_query_cursor__advance(TSQueryCursor *self) { ); next_state = copy; } else { - LOG(" canot split state.\n"); + LOG(" cannot split state.\n"); } } - LOG( - " advance state. pattern:%u, step:%u\n", - next_state->pattern_index, - next_state->step_index - ); - // If the current node is captured in this pattern, add it to the // capture list. for (unsigned j = 0; j < MAX_STEP_CAPTURE_COUNT; j++) { uint16_t capture_id = step->capture_ids[j]; if (step->capture_ids[j] == NONE) break; - LOG( - " capture node. pattern:%u, capture_id:%u\n", - next_state->pattern_index, - capture_id - ); - TSQueryCapture *capture_list = capture_list_pool_get( + CaptureList *capture_list = capture_list_pool_get( &self->capture_list_pool, next_state->capture_list_id ); - capture_list[next_state->capture_count++] = (TSQueryCapture) { + array_push(capture_list, ((TSQueryCapture) { node, capture_id - }; + })); + LOG( + " capture node. pattern:%u, capture_id:%u, capture_count:%u\n", + next_state->pattern_index, + capture_id, + capture_list->size + ); } - // If the pattern is now done, then remove it from the list of - // in-progress states, and add it to the list of finished states. - next_state->step_index++; - QueryStep *next_step = step + 1; - if (next_step->depth == PATTERN_DONE_MARKER) { - LOG(" finish pattern %u\n", next_state->pattern_index); + // If this is the end of a repetition, then jump back to the beginning + // of that repetition. + if (step->repeat_step_index != NONE) { + next_state->step_index_on_failure = next_state->step_index + 1; + next_state->step_index = step->repeat_step_index; + next_state->repeat_match_count++; + LOG( + " continue repeat. pattern:%u, match_count:%u\n", + next_state->pattern_index, + next_state->repeat_match_count + ); + } else { + next_state->step_index++; + LOG( + " advance state. pattern:%u, step:%u\n", + next_state->pattern_index, + next_state->step_index + ); - next_state->id = self->next_state_id++; - array_push(&self->finished_states, *next_state); - if (next_state == state) { - array_erase(&self->states, i); - i--; - n--; - } else { - self->states.size--; + QueryStep *next_step = step + 1; + + // If the pattern is now done, then remove it from the list of + // in-progress states, and add it to the list of finished states. + if (next_step->depth == PATTERN_DONE_MARKER) { + LOG(" finish pattern %u\n", next_state->pattern_index); + + next_state->id = self->next_state_id++; + array_push(&self->finished_states, *next_state); + if (next_state == state) { + array_erase(&self->states, i); + i--; + n--; + } else { + self->states.size--; + } } } } + // Continue descending if possible. if (ts_tree_cursor_goto_first_child(&self->cursor)) { self->depth++; @@ -1411,11 +1589,12 @@ bool ts_query_cursor_next_match( QueryState *state = &self->finished_states.contents[0]; match->id = state->id; match->pattern_index = state->pattern_index; - match->capture_count = state->capture_count; - match->captures = capture_list_pool_get( + CaptureList *captures = capture_list_pool_get( &self->capture_list_pool, state->capture_list_id ); + match->captures = captures->contents; + match->capture_count = captures->size; capture_list_pool_release(&self->capture_list_pool, state->capture_list_id); array_erase(&self->finished_states, 0); return true; @@ -1468,13 +1647,13 @@ bool ts_query_cursor_next_capture( uint32_t first_finished_pattern_index = first_unfinished_pattern_index; for (unsigned i = 0; i < self->finished_states.size; i++) { const QueryState *state = &self->finished_states.contents[i]; - if (state->capture_count > state->consumed_capture_count) { - const TSQueryCapture *captures = capture_list_pool_get( - &self->capture_list_pool, - state->capture_list_id - ); + CaptureList *captures = capture_list_pool_get( + &self->capture_list_pool, + state->capture_list_id + ); + if (captures->size > state->consumed_capture_count) { uint32_t capture_byte = ts_node_start_byte( - captures[state->consumed_capture_count].node + captures->contents[state->consumed_capture_count].node ); if ( capture_byte < first_finished_capture_byte || @@ -1506,11 +1685,12 @@ bool ts_query_cursor_next_capture( ]; match->id = state->id; match->pattern_index = state->pattern_index; - match->capture_count = state->capture_count; - match->captures = capture_list_pool_get( + CaptureList *captures = capture_list_pool_get( &self->capture_list_pool, state->capture_list_id ); + match->captures = captures->contents; + match->capture_count = captures->size; *capture_index = state->consumed_capture_count; state->consumed_capture_count++; return true; diff --git a/src/tree_sitter/utf16.c b/src/tree_sitter/utf16.c deleted file mode 100644 index 3956c01cb9..0000000000 --- a/src/tree_sitter/utf16.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "./utf16.h" - -utf8proc_ssize_t utf16_iterate( - const utf8proc_uint8_t *string, - utf8proc_ssize_t length, - utf8proc_int32_t *code_point -) { - if (length < 2) { - *code_point = -1; - return 0; - } - - uint16_t *units = (uint16_t *)string; - uint16_t unit = units[0]; - - if (unit < 0xd800 || unit >= 0xe000) { - *code_point = unit; - return 2; - } - - if (unit < 0xdc00) { - if (length >= 4) { - uint16_t next_unit = units[1]; - if (next_unit >= 0xdc00 && next_unit < 0xe000) { - *code_point = 0x10000 + ((unit - 0xd800) << 10) + (next_unit - 0xdc00); - return 4; - } - } - } - - *code_point = -1; - return 2; -} diff --git a/src/tree_sitter/utf16.h b/src/tree_sitter/utf16.h deleted file mode 100644 index 32fd05e6db..0000000000 --- a/src/tree_sitter/utf16.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef TREE_SITTER_UTF16_H_ -#define TREE_SITTER_UTF16_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdint.h> -#include <stdlib.h> -#include "utf8proc.h" - -// Analogous to utf8proc's utf8proc_iterate function. Reads one code point from -// the given UTF16 string and stores it in the location pointed to by `code_point`. -// Returns the number of bytes in `string` that were read. -utf8proc_ssize_t utf16_iterate(const utf8proc_uint8_t *, utf8proc_ssize_t, utf8proc_int32_t *); - -#ifdef __cplusplus -} -#endif - -#endif // TREE_SITTER_UTF16_H_ diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index 5ce4bf2973..ca74d185cd 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -341,6 +341,22 @@ describe('lua stdlib', function() and vim.tbl_count(b) == 2 and tostring(a) ~= tostring(b) ]])) + + ok(exec_lua([[ + local f1 = function() return 1 end + local f2 = function() return 2 end + local t1 = {f = f1} + local t2 = vim.deepcopy(t1) + t1.f = f2 + return t1.f() ~= t2.f() + ]])) + + eq('Error executing lua: .../shared.lua: Cannot deepcopy object of type thread', + pcall_err(exec_lua, [[ + local thread = coroutine.create(function () return 0 end) + local t = {thr = thread} + vim.deepcopy(t) + ]])) end) it('vim.pesc', function() diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 369b826adf..b21e344acd 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -812,4 +812,37 @@ describe('LSP', function() }, buf_lines(1)) end) end) + + describe('completion_list_to_complete_items', function() + -- Completion option precedence: + -- textEdit.newText > insertText > label + -- https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion + it('should choose right completion option', function () + local prefix = 'foo' + local completion_list = { + -- resolves into label + { label='foobar' }, + { label='foobar', textEdit={} }, + -- resolves into insertText + { label='foocar', insertText='foobar' }, + { label='foocar', insertText='foobar', textEdit={} }, + -- resolves into textEdit.newText + { label='foocar', insertText='foodar', textEdit={newText='foobar'} }, + { label='foocar', textEdit={newText='foobar'} } + } + local completion_list_items = {items=completion_list} + local expected = { + { abbr = 'foobar', dup = 1, empty = 1, icase = 1, info = ' ', kind = '', menu = '', word = 'foobar'}, + { abbr = 'foobar', dup = 1, empty = 1, icase = 1, info = ' ', kind = '', menu = '', word = 'foobar'}, + { abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = '', menu = '', word = 'foobar'}, + { abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = '', menu = '', word = 'foobar'}, + { abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = '', menu = '', word = 'foobar'}, + { abbr = 'foocar', dup = 1, empty = 1, icase = 1, info = ' ', kind = '', menu = '', word = 'foobar'}, + } + + eq(expected, exec_lua([[return vim.lsp.util.text_document_completion_list_to_complete_items(...)]], completion_list, prefix)) + eq(expected, exec_lua([[return vim.lsp.util.text_document_completion_list_to_complete_items(...)]], completion_list_items, prefix)) + eq({}, exec_lua([[return vim.lsp.util.text_document_completion_list_to_complete_items(...)]], {}, prefix)) + end) + end) end) diff --git a/test/functional/terminal/mouse_spec.lua b/test/functional/terminal/mouse_spec.lua index ee3db7ae97..0eb5901b3b 100644 --- a/test/functional/terminal/mouse_spec.lua +++ b/test/functional/terminal/mouse_spec.lua @@ -87,6 +87,36 @@ describe(':terminal mouse', function() {3:-- TERMINAL --} | ]]) end) + + it('will forward mouse clicks to the program with the correct even if set nu', function() + if helpers.pending_win32(pending) then return end + nvim('command', 'set number') + -- When the display area such as a number is clicked, it returns to the + -- normal mode. + feed('<LeftMouse><3,0>') + eq('n', eval('mode()')) + screen:expect([[ + {7: 11 }^line28 | + {7: 12 }line29 | + {7: 13 }line30 | + {7: 14 }mouse enabled | + {7: 15 }rows: 6, cols: 46 | + {7: 16 }{2: } | + | + ]]) + -- If click on the coordinate (0,1) of the region of the terminal + -- (i.e. the coordinate (4,1) of vim), 'CSI !"' is sent to the terminal. + feed('i<LeftMouse><4,1>') + screen:expect([[ + {7: 11 }line28 | + {7: 12 }line29 | + {7: 13 }line30 | + {7: 14 }mouse enabled | + {7: 15 }rows: 6, cols: 46 | + {7: 16 } !"{1: } | + {3:-- TERMINAL --} | + ]]) + end) end) describe('with a split window and other buffer', function() @@ -148,7 +178,7 @@ describe(':terminal mouse', function() end) it('wont lose focus if another window is scrolled', function() - feed('<ScrollWheelUp><0,0><ScrollWheelUp><0,0>') + feed('<ScrollWheelUp><4,0><ScrollWheelUp><4,0>') screen:expect([[ {7: 21 }line │line30 | {7: 22 }line │rows: 5, cols: 25 | @@ -158,7 +188,7 @@ describe(':terminal mouse', function() ========== ========== | {3:-- TERMINAL --} | ]]) - feed('<S-ScrollWheelDown><0,0>') + feed('<S-ScrollWheelDown><4,0>') screen:expect([[ {7: 26 }line │line30 | {7: 27 }line │rows: 5, cols: 25 | diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua index 7a5569c14b..639e311ae6 100644 --- a/test/functional/ui/float_spec.lua +++ b/test/functional/ui/float_spec.lua @@ -976,6 +976,28 @@ describe('floatwin', function() {2:~ }| ]], float_pos={ [5] = {{id = 1002}, "NE", 4, 0, 50, true} + }, win_viewport = { + [2] = { + topline = 0, + botline = 3, + curline = 0, + curcol = 3, + win = { id = 1000 } + }, + [4] = { + topline = 0, + botline = 3, + curline = 0, + curcol = 3, + win = { id = 1001 } + }, + [5] = { + topline = 0, + botline = 2, + curline = 0, + curcol = 0, + win = { id = 1002 } + } }} else screen:expect([[ diff --git a/test/functional/ui/multigrid_spec.lua b/test/functional/ui/multigrid_spec.lua index 01ffe80be3..e4d1187dea 100644 --- a/test/functional/ui/multigrid_spec.lua +++ b/test/functional/ui/multigrid_spec.lua @@ -1962,4 +1962,191 @@ describe('ext_multigrid', function() {1:~ }| ]]} end) + + it('has viewport information', function() + screen:try_resize(48, 8) + screen:expect{grid=[[ + ## grid 1 + [2:------------------------------------------------]| + [2:------------------------------------------------]| + [2:------------------------------------------------]| + [2:------------------------------------------------]| + [2:------------------------------------------------]| + [2:------------------------------------------------]| + {11:[No Name] }| + [3:------------------------------------------------]| + ## grid 2 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + | + ]], win_viewport={ + [2] = {win = { id = 1000 }, topline = 0, botline = 2, curline = 0, curcol = 0} + }} + insert([[ + Lorem ipsum dolor sit amet, consectetur + adipisicing elit, sed do eiusmod tempor + incididunt ut labore et dolore magna aliqua. + Ut enim ad minim veniam, quis nostrud + exercitation ullamco laboris nisi ut aliquip ex + ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum + dolore eu fugiat nulla pariatur. Excepteur sint + occaecat cupidatat non proident, sunt in culpa + qui officia deserunt mollit anim id est + laborum.]]) + + screen:expect{grid=[[ + ## grid 1 + [2:------------------------------------------------]| + [2:------------------------------------------------]| + [2:------------------------------------------------]| + [2:------------------------------------------------]| + [2:------------------------------------------------]| + [2:------------------------------------------------]| + {11:[No Name] [+] }| + [3:------------------------------------------------]| + ## grid 2 + ea commodo consequat. Duis aute irure dolor in | + reprehenderit in voluptate velit esse cillum | + dolore eu fugiat nulla pariatur. Excepteur sint | + occaecat cupidatat non proident, sunt in culpa | + qui officia deserunt mollit anim id est | + laborum^. | + ## grid 3 + | + ]], win_viewport={ + [2] = {win = {id = 1000}, topline = 5, botline = 11, curline = 10, curcol = 7}, + }} + + + feed('<c-u>') + screen:expect{grid=[[ + ## grid 1 + [2:------------------------------------------------]| + [2:------------------------------------------------]| + [2:------------------------------------------------]| + [2:------------------------------------------------]| + [2:------------------------------------------------]| + [2:------------------------------------------------]| + {11:[No Name] [+] }| + [3:------------------------------------------------]| + ## grid 2 + incididunt ut labore et dolore magna aliqua. | + Ut enim ad minim veniam, quis nostrud | + exercitation ullamco laboris nisi ut aliquip ex | + ea commodo consequat. Duis aute irure dolor in | + reprehenderit in voluptate velit esse cillum | + ^dolore eu fugiat nulla pariatur. Excepteur sint | + ## grid 3 + | + ]], win_viewport={ + [2] = {win = {id = 1000}, topline = 2, botline = 9, curline = 7, curcol = 0}, + }} + + command("split") + screen:expect{grid=[[ + ## grid 1 + [4:------------------------------------------------]| + [4:------------------------------------------------]| + [4:------------------------------------------------]| + {11:[No Name] [+] }| + [2:------------------------------------------------]| + [2:------------------------------------------------]| + {12:[No Name] [+] }| + [3:------------------------------------------------]| + ## grid 2 + reprehenderit in voluptate velit esse cillum | + dolore eu fugiat nulla pariatur. Excepteur sint | + ## grid 3 + | + ## grid 4 + ea commodo consequat. Duis aute irure dolor in | + reprehenderit in voluptate velit esse cillum | + ^dolore eu fugiat nulla pariatur. Excepteur sint | + ]], win_viewport={ + [2] = {win = {id = 1000}, topline = 6, botline = 9, curline = 7, curcol = 0}, + [4] = {win = {id = 1001}, topline = 5, botline = 9, curline = 7, curcol = 0}, + }} + + feed("b") + screen:expect{grid=[[ + ## grid 1 + [4:------------------------------------------------]| + [4:------------------------------------------------]| + [4:------------------------------------------------]| + {11:[No Name] [+] }| + [2:------------------------------------------------]| + [2:------------------------------------------------]| + {12:[No Name] [+] }| + [3:------------------------------------------------]| + ## grid 2 + reprehenderit in voluptate velit esse cillum | + dolore eu fugiat nulla pariatur. Excepteur sint | + ## grid 3 + | + ## grid 4 + ea commodo consequat. Duis aute irure dolor in | + reprehenderit in voluptate velit esse ^cillum | + dolore eu fugiat nulla pariatur. Excepteur sint | + ]], win_viewport={ + [2] = {win = {id = 1000}, topline = 6, botline = 9, curline = 7, curcol = 0}, + [4] = {win = {id = 1001}, topline = 5, botline = 9, curline = 6, curcol = 38}, + }} + + feed("2k") + screen:expect{grid=[[ + ## grid 1 + [4:------------------------------------------------]| + [4:------------------------------------------------]| + [4:------------------------------------------------]| + {11:[No Name] [+] }| + [2:------------------------------------------------]| + [2:------------------------------------------------]| + {12:[No Name] [+] }| + [3:------------------------------------------------]| + ## grid 2 + reprehenderit in voluptate velit esse cillum | + dolore eu fugiat nulla pariatur. Excepteur sint | + ## grid 3 + | + ## grid 4 + exercitation ullamco laboris nisi ut a^liquip ex | + ea commodo consequat. Duis aute irure dolor in | + reprehenderit in voluptate velit esse cillum | + ]], win_viewport={ + [2] = {win = {id = 1000}, topline = 6, botline = 9, curline = 7, curcol = 0}, + [4] = {win = {id = 1001}, topline = 4, botline = 8, curline = 4, curcol = 38}, + }} + + -- handles non-current window + meths.win_set_cursor(1000, {1, 10}) + screen:expect{grid=[[ + ## grid 1 + [4:------------------------------------------------]| + [4:------------------------------------------------]| + [4:------------------------------------------------]| + {11:[No Name] [+] }| + [2:------------------------------------------------]| + [2:------------------------------------------------]| + {12:[No Name] [+] }| + [3:------------------------------------------------]| + ## grid 2 + Lorem ipsum dolor sit amet, consectetur | + adipisicing elit, sed do eiusmod tempor | + ## grid 3 + | + ## grid 4 + exercitation ullamco laboris nisi ut a^liquip ex | + ea commodo consequat. Duis aute irure dolor in | + reprehenderit in voluptate velit esse cillum | + ]], win_viewport={ + [2] = {win = {id = 1000}, topline = 0, botline = 3, curline = 0, curcol = 10}, + [4] = {win = {id = 1001}, topline = 4, botline = 8, curline = 4, curcol = 38}, + }} + end) end) diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua index 64f784afe3..bf979e89f4 100644 --- a/test/functional/ui/screen.lua +++ b/test/functional/ui/screen.lua @@ -158,6 +158,7 @@ function Screen.new(width, height) wildmenu_items = nil, wildmenu_selected = nil, win_position = {}, + win_viewport = {}, float_pos = {}, msg_grid = nil, msg_grid_pos = nil, @@ -254,7 +255,7 @@ end -- canonical order of ext keys, used to generate asserts local ext_keys = { 'popupmenu', 'cmdline', 'cmdline_block', 'wildmenu_items', 'wildmenu_pos', - 'messages', 'showmode', 'showcmd', 'ruler', 'float_pos', + 'messages', 'showmode', 'showcmd', 'ruler', 'float_pos', 'win_viewport' } -- Asserts that the screen state eventually matches an expected state. @@ -421,6 +422,9 @@ screen:redraw_debug() to show all intermediate screen states. ]]) if expected.mode ~= nil then extstate.mode = self.mode end + if expected.win_viewport == nil then + extstate.win_viewport = nil + end -- Convert assertion errors into invalid screen state descriptions. for _, k in ipairs(concat_tables(ext_keys, {'mode'})) do @@ -726,6 +730,7 @@ function Screen:_handle_grid_destroy(grid) self._grids[grid] = nil if self._options.ext_multigrid then self.win_position[grid] = nil + self.win_viewport[grid] = nil end end @@ -746,14 +751,24 @@ function Screen:_handle_grid_cursor_goto(grid, row, col) end function Screen:_handle_win_pos(grid, win, startrow, startcol, width, height) - self.win_position[grid] = { - win = win, - startrow = startrow, - startcol = startcol, - width = width, - height = height - } - self.float_pos[grid] = nil + self.win_position[grid] = { + win = win, + startrow = startrow, + startcol = startcol, + width = width, + height = height + } + self.float_pos[grid] = nil +end + +function Screen:_handle_win_viewport(grid, win, topline, botline, curline, curcol) + self.win_viewport[grid] = { + win = win, + topline = topline, + botline = botline, + curline = curline, + curcol = curcol + } end function Screen:_handle_win_float_pos(grid, ...) @@ -1130,6 +1145,8 @@ function Screen:_extstate_repr(attr_state) messages[i] = {kind=entry[1], content=self:_chunks_repr(entry[2], attr_state)} end + local win_viewport = (next(self.win_viewport) and self.win_viewport) or nil + return { popupmenu=self.popupmenu, cmdline=cmdline, @@ -1141,7 +1158,8 @@ function Screen:_extstate_repr(attr_state) showcmd=self:_chunks_repr(self.showcmd, attr_state), ruler=self:_chunks_repr(self.ruler, attr_state), msg_history=msg_history, - float_pos=self.float_pos + float_pos=self.float_pos, + win_viewport=win_viewport, } end @@ -1216,10 +1234,6 @@ function Screen:render(headers, attr_state, preview) return rv end -local remove_all_metatables = function(item, path) - if path[#path] ~= inspect.METATABLE then return item end -end - -- Returns the current screen state in the form of a screen:expect() -- keyword-args map. function Screen:get_snapshot(attrs, ignore) @@ -1269,6 +1283,26 @@ function Screen:get_snapshot(attrs, ignore) return kwargs, ext_state, attr_state end +local function fmt_ext_state(name, state) + if name == "win_viewport" then + local str = "{\n" + for k,v in pairs(state) do + str = (str.." ["..k.."] = {win = {id = "..v.win.id.."}, topline = " + ..v.topline..", botline = "..v.botline..", curline = "..v.curline + ..", curcol = "..v.curcol.."},\n") + end + return str .. "}" + else + -- TODO(bfredl): improve formatting of more states + local function remove_all_metatables(item, path) + if path[#path] ~= inspect.METATABLE then + return item + end + end + return inspect(state,{process=remove_all_metatables}) + end +end + function Screen:print_snapshot(attrs, ignore) local kwargs, ext_state, attr_state = self:get_snapshot(attrs, ignore) local attrstr = "" @@ -1291,9 +1325,8 @@ function Screen:print_snapshot(attrs, ignore) print(kwargs.grid) io.stdout:write( "]]"..attrstr) for _, k in ipairs(ext_keys) do - if ext_state[k] ~= nil then - -- TODO(bfredl): improve formatting - io.stdout:write(", "..k.."="..inspect(ext_state[k],{process=remove_all_metatables})) + if ext_state[k] ~= nil and not (k == "win_viewport" and not self.options.ext_multigrid) then + io.stdout:write(", "..k.."="..fmt_ext_state(k, ext_state[k])) end end print("}\n") diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt index a321840fef..153028bb2b 100644 --- a/third-party/CMakeLists.txt +++ b/third-party/CMakeLists.txt @@ -35,7 +35,6 @@ option(USE_BUNDLED_LIBTERMKEY "Use the bundled libtermkey." ${USE_BUNDLED}) option(USE_BUNDLED_LIBVTERM "Use the bundled libvterm." ${USE_BUNDLED}) option(USE_BUNDLED_LIBUV "Use the bundled libuv." ${USE_BUNDLED}) option(USE_BUNDLED_MSGPACK "Use the bundled msgpack." ${USE_BUNDLED}) -option(USE_BUNDLED_UTF8PROC "Use the bundled utf8proc." ${USE_BUNDLED}) option(USE_BUNDLED_LUAJIT "Use the bundled version of luajit." ${USE_BUNDLED}) option(USE_BUNDLED_LUAROCKS "Use the bundled version of luarocks." ${USE_BUNDLED}) option(USE_BUNDLED_LUV "Use the bundled version of luv." ${USE_BUNDLED}) @@ -197,9 +196,6 @@ set(GETTEXT_SHA256 66415634c6e8c3fa8b71362879ec7575e27da43da562c798a8a2f223e6e47 set(LIBICONV_URL https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.15.tar.gz) set(LIBICONV_SHA256 ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178) -set(UTF8PROC_URL https://github.com/JuliaStrings/utf8proc/archive/v2.2.0.tar.gz) -set(UTF8PROC_SHA256 3f8fd1dbdb057ee5ba584a539d5cd1b3952141c0338557cb0bdf8cb9cfed5dbf) - set(TREESITTER_C_URL https://github.com/tree-sitter/tree-sitter-c/archive/6002fcd.tar.gz) set(TREESITTER_C_SHA256 46f8d44fa886d9ddb92571bb6fa8b175992c8758eca749cb1217464e512b6e97) @@ -254,10 +250,6 @@ if(USE_BUNDLED_LIBICONV) include(BuildLibiconv) endif() -if(USE_BUNDLED_UTF8PROC) - include(BuildUtf8proc) -endif() - if(USE_BUNDLED_TS_PARSERS) include(BuildTreesitterParsers) endif() diff --git a/third-party/cmake/BuildUtf8proc.cmake b/third-party/cmake/BuildUtf8proc.cmake deleted file mode 100644 index d5743d36e2..0000000000 --- a/third-party/cmake/BuildUtf8proc.cmake +++ /dev/null @@ -1,68 +0,0 @@ -include(CMakeParseArguments) - -# BuildUtf8proc(CONFIGURE_COMMAND ... BUILD_COMMAND ... INSTALL_COMMAND ...) -# Reusable function to build utf8proc, wraps ExternalProject_Add. -# Failing to pass a command argument will result in no command being run -function(BuildUtf8proc) - cmake_parse_arguments(_utf8proc - "" - "" - "CONFIGURE_COMMAND;BUILD_COMMAND;INSTALL_COMMAND" - ${ARGN}) - - if(NOT _utf8proc_CONFIGURE_COMMAND AND NOT _utf8proc_BUILD_COMMAND - AND NOT _utf8proc_INSTALL_COMMAND) - message(FATAL_ERROR "Must pass at least one of CONFIGURE_COMMAND, BUILD_COMMAND, INSTALL_COMMAND") - endif() - - ExternalProject_Add(utf8proc - PREFIX ${DEPS_BUILD_DIR} - URL ${UTF8PROC_URL} - DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/utf8proc - DOWNLOAD_COMMAND ${CMAKE_COMMAND} - -DPREFIX=${DEPS_BUILD_DIR} - -DDOWNLOAD_DIR=${DEPS_DOWNLOAD_DIR}/utf8proc - -DURL=${UTF8PROC_URL} - -DEXPECTED_SHA256=${UTF8PROC_SHA256} - -DTARGET=utf8proc - -DUSE_EXISTING_SRC_DIR=${USE_EXISTING_SRC_DIR} - -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/DownloadAndExtractFile.cmake - CONFIGURE_COMMAND "${_utf8proc_CONFIGURE_COMMAND}" - BUILD_COMMAND "${_utf8proc_BUILD_COMMAND}" - INSTALL_COMMAND "${_utf8proc_INSTALL_COMMAND}") -endfunction() - -set(UTF8PROC_CONFIGURE_COMMAND ${CMAKE_COMMAND} ${DEPS_BUILD_DIR}/src/utf8proc - -DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} - -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - "-DCMAKE_C_FLAGS:STRING=${CMAKE_C_COMPILER_ARG1} -fPIC" - -DCMAKE_GENERATOR=${CMAKE_GENERATOR}) - -set(UTF8PROC_BUILD_COMMAND ${CMAKE_COMMAND} --build . --config ${CMAKE_BUILD_TYPE}) -set(UTF8PROC_INSTALL_COMMAND ${CMAKE_COMMAND} --build . --target install --config ${CMAKE_BUILD_TYPE}) - -if(MINGW AND CMAKE_CROSSCOMPILING) - get_filename_component(TOOLCHAIN ${CMAKE_TOOLCHAIN_FILE} REALPATH) - set(UTF8PROC_CONFIGURE_COMMAND ${CMAKE_COMMAND} ${DEPS_BUILD_DIR}/src/utf8proc - -DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} - # Pass toolchain - -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN} - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - # Hack to avoid -rdynamic in Mingw - -DCMAKE_SHARED_LIBRARY_LINK_C_FLAGS="") -elseif(MSVC) - # Same as Unix without fPIC - set(UTF8PROC_CONFIGURE_COMMAND ${CMAKE_COMMAND} ${DEPS_BUILD_DIR}/src/utf8proc - -DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} - -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} - "-DCMAKE_C_FLAGS:STRING=${CMAKE_C_COMPILER_ARG1}" - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - # Make sure we use the same generator, otherwise we may - # accidentally end up using different MSVC runtimes - -DCMAKE_GENERATOR=${CMAKE_GENERATOR}) -endif() - -BuildUtf8proc(CONFIGURE_COMMAND ${UTF8PROC_CONFIGURE_COMMAND} - BUILD_COMMAND ${UTF8PROC_BUILD_COMMAND} - INSTALL_COMMAND ${UTF8PROC_INSTALL_COMMAND}) |