diff options
author | dundargoc <gocdundar@gmail.com> | 2024-05-16 18:33:09 +0200 |
---|---|---|
committer | dundargoc <33953936+dundargoc@users.noreply.github.com> | 2024-05-24 11:08:00 +0200 |
commit | d123202ae6ef3f046d5b6579c194dca82ddb8a8f (patch) | |
tree | dfb64b7bb09076a58962cb7c41f36f80c02fa992 | |
parent | f864b68c5b0fe1482249167712cd16ff2b50ec45 (diff) | |
download | rneovim-d123202ae6ef3f046d5b6579c194dca82ddb8a8f.tar.gz rneovim-d123202ae6ef3f046d5b6579c194dca82ddb8a8f.tar.bz2 rneovim-d123202ae6ef3f046d5b6579c194dca82ddb8a8f.zip |
fix: change deprecation presentation
Deprecation with vim.deprecate is currently too noisy. Show the
following warning instead:
[function] is deprecated. Run ":checkhealth vim.deprecated" for more information.
The important part is that the full message needs to be short enough to
fit in one line in order to not trigger the "Press ENTER or type command
to continue" prompt.
The full information and stack trace for the deprecated functions will
be shown in the new healthcheck `vim.deprecated`.
-rw-r--r-- | runtime/lua/vim/_editor.lua | 76 | ||||
-rw-r--r-- | runtime/lua/vim/deprecated/health.lua | 42 | ||||
-rw-r--r-- | runtime/lua/vim/diagnostic.lua | 4 | ||||
-rw-r--r-- | test/functional/lua/vim_spec.lua | 42 | ||||
-rw-r--r-- | test/functional/plugin/health_spec.lua | 2 |
5 files changed, 122 insertions, 44 deletions
diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index ad2b3f5dab..5e9be509c8 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -1031,6 +1031,42 @@ function vim._cs_remote(rcid, server_addr, connect_error, args) } end +do + local function truncated_echo(msg) + -- Truncate message to avoid hit-enter-prompt + local max_width = vim.o.columns * math.max(vim.o.cmdheight - 1, 0) + vim.v.echospace + local msg_truncated = string.sub(msg, 1, max_width) + vim.api.nvim_echo({ { msg_truncated, 'WarningMsg' } }, true, {}) + end + + local notified = false + + function vim._truncated_echo_once(msg) + if not notified then + truncated_echo(msg) + notified = true + return true + end + return false + end +end + +--- This is basically the same as debug.traceback(), except the full paths are shown. +local function traceback() + local level = 4 + local backtrace = { 'stack traceback:' } + while true do + local info = debug.getinfo(level, 'Sl') + if not info then + break + end + local msg = (' %s:%s'):format(info.source:sub(2), info.currentline) + table.insert(backtrace, msg) + level = level + 1 + end + return table.concat(backtrace, '\n') +end + --- Shows a deprecation message to the user. --- ---@param name string Deprecated feature (function, API, etc.). @@ -1043,12 +1079,12 @@ end ---@return string|nil # Deprecated message, or nil if no message was shown. function vim.deprecate(name, alternative, version, plugin, backtrace) plugin = plugin or 'Nvim' - local will_be_removed = 'will be removed' - - -- Only issue warning if feature is hard-deprecated as specified by MAINTAIN.md. - -- Example: if removal_version is 0.12 (soft-deprecated since 0.10-dev), show warnings starting at - -- 0.11, including 0.11-dev if plugin == 'Nvim' then + require('vim.deprecated.health').add(name, version, traceback(), alternative) + + -- Only issue warning if feature is hard-deprecated as specified by MAINTAIN.md. + -- Example: if removal_version is 0.12 (soft-deprecated since 0.10-dev), show warnings starting at + -- 0.11, including 0.11-dev local major, minor = version:match('(%d+)%.(%d+)') major, minor = tonumber(major), tonumber(minor) @@ -1059,8 +1095,12 @@ function vim.deprecate(name, alternative, version, plugin, backtrace) return end - local removal_version = string.format('nvim-%d.%d', major, minor) - will_be_removed = vim.fn.has(removal_version) == 1 and 'was removed' or will_be_removed + local msg = ('%s is deprecated. Run ":checkhealth vim.deprecated" for more information'):format( + name + ) + + local displayed = vim._truncated_echo_once(msg) + return displayed and msg or nil else vim.validate { name = { name, 'string' }, @@ -1068,22 +1108,16 @@ function vim.deprecate(name, alternative, version, plugin, backtrace) version = { version, 'string', true }, plugin = { plugin, 'string', true }, } - end - local msg = ('%s is deprecated'):format(name) - msg = alternative and ('%s, use %s instead.'):format(msg, alternative) or (msg .. '.') - msg = ('%s%s\nFeature %s in %s %s'):format( - msg, - (plugin == 'Nvim' and ' :help deprecated' or ''), - will_be_removed, - plugin, - version - ) - local displayed = vim.notify_once(msg, vim.log.levels.WARN) - if displayed and backtrace ~= false then - vim.notify(debug.traceback('', 2):sub(2), vim.log.levels.WARN) + local msg = ('%s is deprecated'):format(name) + msg = alternative and ('%s, use %s instead.'):format(msg, alternative) or (msg .. '.') + msg = ('%s\nFeature will be removed in %s %s'):format(msg, plugin, version) + local displayed = vim.notify_once(msg, vim.log.levels.WARN) + if displayed and backtrace ~= false then + vim.notify(debug.traceback('', 2):sub(2), vim.log.levels.WARN) + end + return displayed and msg or nil end - return displayed and msg or nil end require('vim._options') diff --git a/runtime/lua/vim/deprecated/health.lua b/runtime/lua/vim/deprecated/health.lua new file mode 100644 index 0000000000..0f6b1f578c --- /dev/null +++ b/runtime/lua/vim/deprecated/health.lua @@ -0,0 +1,42 @@ +local M = {} +local health = vim.health + +local deprecated = {} + +function M.check() + if next(deprecated) == nil then + health.ok('No deprecated functions detected') + return + end + + for name, v in vim.spairs(deprecated) do + health.start('') + + local version, backtraces, alternative = v[1], v[2], v[3] + local major, minor = version:match('(%d+)%.(%d+)') + major, minor = tonumber(major), tonumber(minor) + local removal_version = string.format('nvim-%d.%d', major, minor) + local will_be_removed = vim.fn.has(removal_version) == 1 and 'was removed' or 'will be removed' + + local msg = ('%s is deprecated. Feature %s in Nvim %s'):format(name, will_be_removed, version) + local msg_alternative = alternative and ('use %s instead.'):format(alternative) + local advice = { msg_alternative } + table.insert(advice, backtraces) + advice = vim.iter(advice):flatten():totable() + health.warn(msg, advice) + end +end + +function M.add(name, version, backtrace, alternative) + if deprecated[name] == nil then + deprecated[name] = { version, { backtrace }, alternative } + return + end + + local it = vim.iter(deprecated[name][2]) + if it:find(backtrace) == nil then + table.insert(deprecated[name][2], backtrace) + end +end + +return M diff --git a/runtime/lua/vim/diagnostic.lua b/runtime/lua/vim/diagnostic.lua index b5146e5beb..348204abb7 100644 --- a/runtime/lua/vim/diagnostic.lua +++ b/runtime/lua/vim/diagnostic.lua @@ -1279,9 +1279,7 @@ M.handlers.signs = { vim.deprecate( 'Defining diagnostic signs with :sign-define or sign_define()', 'vim.diagnostic.config()', - '0.12', - nil, - false -- suppress backtrace + '0.12' ) if not opts.signs.text then diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index dd0c3d3868..c8f94c6ffa 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -135,42 +135,46 @@ describe('lua stdlib', function() -- See MAINTAIN.md for the soft/hard deprecation policy describe(('vim.deprecate prerel=%s,'):format(prerel or 'nil'), function() - it('plugin=nil', function() - local curver = exec_lua('return vim.version()') --[[@as {major:number, minor:number}]] - -- "0.10" or "0.10-dev+xxx" - local curstr = ('%s.%s%s'):format(curver.major, curver.minor, prerel or '') - -- "0.10" or "0.11" - local nextver = ('%s.%s'):format(curver.major, curver.minor + (prerel and 0 or 1)) - local was_removed = prerel and 'was removed' or 'will be removed' - + local curver = exec_lua('return vim.version()') --[[@as {major:number, minor:number}]] + -- "0.10" or "0.10-dev+xxx" + local curstr = ('%s.%s%s'):format(curver.major, curver.minor, prerel or '') + -- "0.10" or "0.11" + local nextver = ('%s.%s'):format(curver.major, curver.minor + (prerel and 0 or 1)) + local was_removed = prerel and 'was removed' or 'will be removed' + + it('plugin=nil, same message skipped', function() eq( - dedent([[ - foo.bar() is deprecated, use zub.wooo{ok=yay} instead. :help deprecated - Feature was removed in Nvim %s]]):format(curstr), + dedent( + [[ + foo.bar() is deprecated. Run ":checkhealth vim.deprecated" for more information]] + ):format(curstr), exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', curstr) ) -- Same message as above; skipped this time. eq(vim.NIL, exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', curstr)) + end) - -- No error if soft-deprecated. + it('plugin=nil, no error if soft-deprecated', function() eq( vim.NIL, exec_lua('return vim.deprecate(...)', 'foo.baz()', 'foo.better_baz()', '0.99.0') ) + end) - -- Show error if hard-deprecated. + it('plugin=nil, show error if hard-deprecated', function() eq( - dedent([[ - foo.hard_dep() is deprecated, use vim.new_api() instead. :help deprecated - Feature %s in Nvim %s]]):format(was_removed, nextver), + dedent( + [[ + foo.hard_dep() is deprecated. Run ":checkhealth vim.deprecated" for more information]] + ):format(was_removed, nextver), exec_lua('return vim.deprecate(...)', 'foo.hard_dep()', 'vim.new_api()', nextver) ) + end) - -- To be deleted in the next major version (1.0) + it('plugin=nil, to be deleted in the next major version (1.0)', function() eq( dedent [[ - foo.baz() is deprecated. :help deprecated - Feature will be removed in Nvim 1.0]], + foo.baz() is deprecated. Run ":checkhealth vim.deprecated" for more information]], exec_lua [[ return vim.deprecate('foo.baz()', nil, '1.0') ]] ) end) diff --git a/test/functional/plugin/health_spec.lua b/test/functional/plugin/health_spec.lua index 7aa5c99a60..9c7c953fb0 100644 --- a/test/functional/plugin/health_spec.lua +++ b/test/functional/plugin/health_spec.lua @@ -42,7 +42,7 @@ describe(':checkhealth', function() it('completions can be listed via getcompletion()', function() clear() - eq('vim.health', getcompletion('vim', 'checkhealth')[1]) + eq('vim.deprecated', getcompletion('vim', 'checkhealth')[1]) eq('vim.provider', getcompletion('vim.prov', 'checkhealth')[1]) eq('vim.lsp', getcompletion('vim.ls', 'checkhealth')[1]) end) |