diff --git a/.github/scripts/labeler_configuration.yml b/.github/scripts/labeler_configuration.yml index 933e0bcbbd..b548d96afc 100644 --- a/.github/scripts/labeler_configuration.yml +++ b/.github/scripts/labeler_configuration.yml @@ -46,6 +46,10 @@ folds: - changed-files: - any-glob-to-any-file: [ src/nvim/fold* ] +image: + - changed-files: + - any-glob-to-any-file: [ '**/ui/img*' ] + lsp: - changed-files: - any-glob-to-any-file: [ runtime/lua/vim/lsp.lua, runtime/lua/vim/lsp/* ] diff --git a/.github/workflows/labeler_issue.yml b/.github/workflows/labeler_issue.yml index 02e5a6e3b1..0c49689b66 100644 --- a/.github/workflows/labeler_issue.yml +++ b/.github/workflows/labeler_issue.yml @@ -17,7 +17,14 @@ jobs: script: | const title = context.payload.issue.title; const titleSplit = title.split(/\b/).map(e => e.toLowerCase()); - const keywords = ['api', 'lsp', 'treesitter', 'ui', 'ui2']; + const keywords = [ + 'api', + 'image', + 'lsp', + 'treesitter', + 'ui', + 'ui2' + ]; var labels = new Set(); for (const keyword of keywords) { diff --git a/runtime/doc/api.txt b/runtime/doc/api.txt index c8b99e3838..a7dc0d556d 100644 --- a/runtime/doc/api.txt +++ b/runtime/doc/api.txt @@ -154,7 +154,7 @@ indices, end-inclusive): - |nvim_buf_get_extmarks()| - |nvim_buf_set_extmark()| - *api-fast* *schedule* + *api-fast* *deferred* *schedule* Most API functions are deferred: they are queued ("scheduled") on the main loop and processed sequentially with normal input. If the editor is waiting for user input in a "modal" fashion (e.g. an |input()| prompt), a deferred diff --git a/runtime/doc/dev_vimpatch.txt b/runtime/doc/dev_vimpatch.txt index f6b7cffe69..e696416758 100644 --- a/runtime/doc/dev_vimpatch.txt +++ b/runtime/doc/dev_vimpatch.txt @@ -6,15 +6,13 @@ Merging patches from Vim *dev-vimpatch* Nvim was forked from Vim 7.4.160; it is kept up-to-date with relevant Vim -patches in order to avoid duplicate work. Run `vim-patch.sh` -https://github.com/neovim/neovim/blob/master/scripts/vim-patch.sh to see the -status of Vim patches: ->bash +patches in order to avoid duplicate work. Run `vim-patch.sh` to see the status +of Vim patches: >bash ./scripts/vim-patch.sh -l < -Everyone is welcome to |dev-vimpatch-pull-requests| for relevant Vim -patches, but some types of patches are |dev-vimpatch-not-applicable|. -See |dev-vimpatch-quickstart| to get started immediately. +Everyone is welcome to |dev-vimpatch-pull-requests| for relevant Vim patches, +but some types of patches are |dev-vimpatch-not-applicable|. See +|dev-vimpatch-quickstart| to get started immediately. Type |gO| to see the table of contents. diff --git a/runtime/doc/gui.txt b/runtime/doc/gui.txt index 2453fe605f..b21f072e33 100644 --- a/runtime/doc/gui.txt +++ b/runtime/doc/gui.txt @@ -47,6 +47,15 @@ can connect to any Nvim instance). Example: this sets "g:gui" to the value of the UI's "rgb" field: > :autocmd UIEnter * let g:gui = filter(nvim_list_uis(),{k,v-> v.chan==v:event.chan})[0].rgb < + *ui-lifecycle* +Nvim's |clientserver| architecture allows you to |:restart|, |:detach| (Nvim +continues in the background), or |:connect| to another instance. + +Use cases: +- keep the session running on remote machines after (unexpected) SSH disconnect +- open files in an existing session from your OS file explorer +- run Nvim as a background process (daemon/service), atttach/detach as needed + ------------------------------------------------------------------------------ Stop or detach the current UI diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 1b9f2be9e7..0cce01eef6 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -442,7 +442,7 @@ VIMSCRIPT • |v:vim_did_init| is set after sourcing |init.vim| but before |load-plugins|. • |prompt_appendbuf()| appends text to prompt-buffer. • |v:exitreason| is set before |QuitPre|. -• |v:starttime| is the process start time (monotonic nanoseconds). +• |v:starttime| is the process start time (nanoseconds since UNIX epoch). ============================================================================== CHANGED FEATURES *news-changed* diff --git a/runtime/doc/vvars.txt b/runtime/doc/vvars.txt index 6a885f6a4f..e61bc78624 100644 --- a/runtime/doc/vvars.txt +++ b/runtime/doc/vvars.txt @@ -635,11 +635,11 @@ v:stacktrace *v:starttime* *starttime-variable* v:starttime - Timestamp (monotonic nanoseconds) when the Nvim process + Timestamp (nanoseconds since UNIX epoch) when the Nvim process started. To see the current "uptime": >lua - vim.print(('uptime: %d seconds'):format((vim.uv.hrtime() - vim.v.starttime) / 1e9)) + vim.print(('uptime: %d seconds'):format(os.time() - (vim.v.starttime / 1e9))) < Read-only. diff --git a/runtime/lua/vim/_meta/vvars.gen.lua b/runtime/lua/vim/_meta/vvars.gen.lua index 7b5ca0e417..543d4169c1 100644 --- a/runtime/lua/vim/_meta/vvars.gen.lua +++ b/runtime/lua/vim/_meta/vvars.gen.lua @@ -667,13 +667,13 @@ vim.v.shell_error = ... --- @type table[] vim.v.stacktrace = ... ---- Timestamp (monotonic nanoseconds) when the Nvim process +--- Timestamp (nanoseconds since UNIX epoch) when the Nvim process --- started. --- --- To see the current "uptime": --- --- ```lua ---- vim.print(('uptime: %d seconds'):format((vim.uv.hrtime() - vim.v.starttime) / 1e9)) +--- vim.print(('uptime: %d seconds'):format(os.time() - (vim.v.starttime / 1e9))) --- ``` --- --- Read-only. diff --git a/runtime/lua/vim/lsp/inline_completion.lua b/runtime/lua/vim/lsp/inline_completion.lua index 5bf4ba920e..e759562747 100644 --- a/runtime/lua/vim/lsp/inline_completion.lua +++ b/runtime/lua/vim/lsp/inline_completion.lua @@ -73,21 +73,21 @@ setmetatable(Completor, Capability) Capability.all[Completor.name] = Completor ---@package ----@param bufnr integer +---@param buf integer ---@return vim.lsp.inline_completion.Completor -function Completor:new(bufnr) - self = Capability.new(self, bufnr) +function Completor:new(buf) + self = Capability.new(self, buf) self.client_state = {} api.nvim_create_autocmd({ 'InsertEnter', 'CursorMovedI', 'TextChangedP' }, { group = self.augroup, - buf = bufnr, + buf = buf, callback = function() self:automatic_request() end, }) api.nvim_create_autocmd({ 'InsertLeave' }, { group = self.augroup, - buf = bufnr, + buf = buf, callback = function() self:abort() end, diff --git a/runtime/lua/vim/lsp/linked_editing_range.lua b/runtime/lua/vim/lsp/linked_editing_range.lua index 07cc6fb740..1a542ddade 100644 --- a/runtime/lua/vim/lsp/linked_editing_range.lua +++ b/runtime/lua/vim/lsp/linked_editing_range.lua @@ -191,43 +191,42 @@ end ---Construct a new LinkedEditor for the buffer. --- ---@private ----@param bufnr integer +---@param buf integer ---@return vim.lsp.linked_editing_range.LinkedEditor -function LinkedEditor.new(bufnr) +function LinkedEditor.new(buf) local self = setmetatable({}, { __index = LinkedEditor }) - self.bufnr = bufnr - local augroup = - api.nvim_create_augroup('nvim.lsp.linked_editing_range:' .. bufnr, { clear = true }) + self.bufnr = buf + local augroup = api.nvim_create_augroup('nvim.lsp.linked_editing_range:' .. buf, { clear = true }) self.augroup = augroup self.client_states = {} api.nvim_create_autocmd({ 'TextChanged', 'TextChangedI' }, { - buf = bufnr, + buf = buf, group = augroup, callback = function() for _, client_state in pairs(self.client_states) do - update_ranges(bufnr, client_state) + update_ranges(buf, client_state) end self:refresh() end, }) api.nvim_create_autocmd('CursorMoved', { group = augroup, - buf = bufnr, + buf = buf, callback = function() self:refresh() end, }) api.nvim_create_autocmd('LspDetach', { group = augroup, - buf = bufnr, + buf = buf, callback = function(ev) self:detach(ev.data.client_id) end, }) - LinkedEditor.active[bufnr] = self + LinkedEditor.active[buf] = self return self end diff --git a/src/gen/lint.lua b/src/gen/lint.lua index ee7a61456f..442e5c2b9a 100644 --- a/src/gen/lint.lua +++ b/src/gen/lint.lua @@ -6,6 +6,7 @@ local M = {} --- Apply to parameter names, keyset keys, and function name parts. local banned_nouns = { buffer = 'buf', + bufnr = 'buf', -- channel = 'chan', command = 'cmd', directory = 'dir', @@ -13,6 +14,7 @@ local banned_nouns = { position = 'pos', process = 'proc', window = 'win', + winnr = 'win', } --- Banned verbs. See `:help dev-name-common`. @@ -55,31 +57,140 @@ local legacy_names = { nvim_list_uis = true, nvim_list_wins = true, }, + ['runtime/lua/vim/diagnostic.lua'] = { + count = true, + get = true, + hide = true, + reset = true, + set = true, + show = true, + status = true, + }, + ['runtime/lua/editorconfig.lua'] = { + config = true, + }, + ['runtime/lua/vim/uri.lua'] = { + uri_from_bufnr = true, + uri_to_bufnr = true, + }, + ['runtime/lua/vim/snippet.lua'] = { + new = true, + }, + ['runtime/lua/vim/hl.lua'] = { + range = true, + }, + ['runtime/lua/vim/filetype.lua'] = { + _getline = true, + _getlines = true, + _nextnonblank = true, + }, + ['runtime/lua/vim/_meta/regex.lua'] = { + match_line = true, + }, + ['runtime/lua/vim/_inspector.lua'] = { + ['vim.inspect_pos'] = true, + ['vim.show_pos'] = true, + }, ['runtime/lua/vim/_core/shared.lua'] = { _ensure_list = true, _list_insert = true, _list_remove = true, + _resolve_bufnr = true, list_contains = true, tbl_contains = true, }, ['runtime/lua/vim/lsp.lua'] = { + _buf_get_full_text = true, + _buf_get_line_ending = true, + _set_defaults = true, + buf_attach_client = true, + buf_detach_client = true, + buf_is_attached = true, buf_notify = true, + buf_request = true, + buf_request_all = true, + buf_request_sync = true, + }, + ['runtime/lua/vim/lsp/_folding_range.lua'] = { + new = true, + }, + ['runtime/lua/vim/lsp/_changetracking.lua'] = { + _send_did_save = true, + flush = true, + init = true, + reset_buf = true, + send_changes = true, + }, + ['runtime/lua/vim/lsp/_capability.lua'] = { + new = true, + }, + ['runtime/lua/vim/lsp/semantic_tokens.lua'] = { + _start = true, + force_refresh = true, + get_at_pos = true, + highlight_token = true, + new = true, + }, + ['runtime/lua/vim/lsp/document_color.lua'] = { + new = true, + }, + ['runtime/lua/vim/lsp/diagnostic.lua'] = { + _enable = true, + _refresh = true, + get_line_diagnostics = true, + }, + ['runtime/lua/vim/lsp/completion.lua'] = { + enable = true, + request = true, + }, + ['runtime/lua/vim/lsp/codelens.lua'] = { + new = true, }, ['runtime/lua/vim/lsp/client.lua'] = { + _get_registrations = true, + _on_detach = true, _on_exit = true, _process_request = true, _process_static_registrations = true, _remove_workspace_folder = true, + _text_document_did_open_handler = true, + on_attach = true, + request = true, + request_sync = true, + supports_method = true, }, ['runtime/lua/vim/lsp/util.lua'] = { + _make_line_range_params = true, + apply_text_edits = true, + buf_clear_references = true, buf_highlight_references = true, + get_effective_tabstop = true, + make_given_range_params = true, make_position_params = true, + make_text_document_params = true, + symbols_to_items = true, }, ['runtime/lua/vim/lsp/rpc.lua'] = { _notify = true, }, ['runtime/lua/vim/treesitter.lua'] = { + _create_parser = true, + get_captures_at_cursor = true, + get_captures_at_pos = true, + get_parser = true, node_contains = true, + start = true, + stop = true, + }, + ['runtime/lua/vim/treesitter/languagetree.lua'] = { + _on_bytes = true, + }, + ['runtime/lua/vim/treesitter/dev.lua'] = { + draw = true, + new = true, + }, + ['runtime/lua/vim/treesitter/_fold.lua'] = { + new = true, }, ['runtime/lua/vim/treesitter/highlighter.lua'] = { for_each_highlight_state = true, @@ -105,10 +216,33 @@ local legacy_names = { --- --- @type table> local legacy_fields = { + ['vim.Diagnostic'] = { + bufnr = true, + }, + ['vim.lsp.Capability'] = { + bufnr = true, + }, + ['vim.lsp.inlay_hint.enable.Filter'] = { + bufnr = true, + }, + ['vim.lsp.inlay_hint.get.Filter'] = { + bufnr = true, + }, + ['vim.lsp.inlay_hint.get.ret'] = { + bufnr = true, + }, + ['TS.Heading'] = { + bufnr = true, + }, + ['vim.treesitter.get_node.Opts'] = { + bufnr = true, + }, ['vim.treesitter.dev.inspect_tree.Opts'] = { + bufnr = true, command = true, }, ['vim.undotree.opts'] = { + bufnr = true, command = true, }, } @@ -148,12 +282,14 @@ function M.lint_names(source, api_funs, keysets, classes) local src_legacy = legacy_names[source] or {} for _, fun in ipairs(api_funs) do if fun.name and fun.params and not fun.deprecated and not fun.deprecated_since then - -- Positional parameter names: always checked (no "legacy" allowed). - for _, p in ipairs(fun.params) do - local want_name = banned_nouns[p.name] - if want_name then - local msg = '%s: %s(): param "%s" should be renamed to "%s"' - errors[#errors + 1] = fmt(msg, source, fun.name, p.name, want_name) + -- Positional parameter names. + if not src_legacy[fun.name] then + for _, p in ipairs(fun.params) do + local want_name = banned_nouns[p.name] + if want_name then + local msg = '%s: %s(): param "%s" should be renamed to "%s"' + errors[#errors + 1] = fmt(msg, source, fun.name, p.name, want_name) + end end end diff --git a/src/nvim/main.c b/src/nvim/main.c index 02cfc59849..96696f65ae 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -197,7 +197,7 @@ void early_init(mparm_T *paramp) estack_init(); cmdline_init(); eval_init(); // init global variables - set_vim_var_nr(VV_STARTTIME, (varnumber_T)os_hrtime()); + set_vim_var_nr(VV_STARTTIME, (varnumber_T)os_realtime()); init_path(argv0 ? argv0 : "nvim"); init_normal_cmds(); // Init the table of Normal mode commands. runtime_init(); diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c index f243eda047..2e6bf3e56d 100644 --- a/src/nvim/os/time.c +++ b/src/nvim/os/time.c @@ -32,6 +32,25 @@ uint64_t os_hrtime(void) return uv_hrtime(); } +/// Obtain the current system time from a high-resolution +/// real-time clock source. +/// +/// The real-time clock counts from the UNIX epoch (1970-01-01) +/// and is subject to time adjustments; it can jump back in time. +/// +/// @return Nanoseconds since epoch or 0 +int64_t os_realtime(void) + FUNC_ATTR_WARN_UNUSED_RESULT +{ + uv_timespec64_t ts = { 0 }; + int error_number; + if ((error_number = uv_clock_gettime(UV_CLOCK_REALTIME, &ts)) != 0) { + ELOG("uv_clock_gettime failed: %d %s", error_number, uv_err_name(error_number)); + return 0; + } + return ts.tv_sec * 1000000000L + ts.tv_nsec; +} + /// Gets a millisecond-resolution, monotonically-increasing time relative to an /// arbitrary time in the past. /// diff --git a/src/nvim/vvars.lua b/src/nvim/vvars.lua index 648e5f1310..db87bcda28 100644 --- a/src/nvim/vvars.lua +++ b/src/nvim/vvars.lua @@ -756,11 +756,11 @@ M.vars = { starttime = { type = 'integer', desc = [=[ - Timestamp (monotonic nanoseconds) when the Nvim process + Timestamp (nanoseconds since UNIX epoch) when the Nvim process started. To see the current "uptime": >lua - vim.print(('uptime: %d seconds'):format((vim.uv.hrtime() - vim.v.starttime) / 1e9)) + vim.print(('uptime: %d seconds'):format(os.time() - (vim.v.starttime / 1e9))) < Read-only. ]=],