feat: add on_click option to interact with mouse (#742)

* feat: add on_click option to interact with mouse

closes #706
This commit is contained in:
Shadman 2022-07-20 19:28:49 +06:00 committed by GitHub
parent 655411fb7a
commit 0ac721d376
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 93 additions and 7 deletions

View File

@ -418,6 +418,11 @@ sections = {
-- padding = { left = left_padding, right = right_padding }
fmt = nil, -- Format function, formats the component's output.
on_click = nil, -- takes a function that is called when component is clicked with mouse.
-- the function receives several arguments
-- - number of clicks incase of multiple clicks
-- - mouse button used (l(left)/r(right)/m(middle)/...)
-- - modifiers pressed (s(shift)/c(ctrl)/a(alt)/m(meta)...)
}
}
}

View File

@ -431,6 +431,11 @@ General component options These are options that control behavior
-- padding = { left = left_padding, right = right_padding }
fmt = nil, -- Format function, formats the component's output.
on_click = nil, -- takes a function that is called when component is clicked with mouse.
-- the function receives several arguments
-- - number of clicks incase of multiple clicks
-- - mouse button used (l(left)/r(right)/m(middle)/...)
-- - modifiers pressed (s(shift)/c(ctrl)/a(alt)/m(meta)...)
}
}
}

View File

@ -1,12 +1,17 @@
-- Copyright (c) 2020-2021 shadmansaleh
-- MIT license, see LICENSE for more details.
local require = require('lualine_require').require
local highlight = require('lualine.highlight')
local lualine_require = require('lualine_require')
local require = lualine_require.require
local M = require('lualine.utils.class'):extend()
local modules = lualine_require.lazy_require {
highlight = 'lualine.highlight',
utils_notices = 'lualine.utils.notices',
fn_store = 'lualine.utils.fn_store',
}
-- Used to provide a unique id for each component
local component_no = 1
function M._reset_component_id()
function M._reset_components()
component_no = 1
end
@ -34,6 +39,7 @@ function M:init(options)
self.component_no = component_no
self:set_separator()
self:create_option_highlights()
self:set_on_click()
end
---sets the default separator for component based on whether the component
@ -62,6 +68,20 @@ function M:create_option_highlights()
end
end
---Setup on click function so they can be added during drawing.
function M:set_on_click()
if self.options.on_click ~= nil then
if vim.fn.has('nvim-0.8') == 0 then
modules.utils_notices.add_notice(
'### Options.on_click\nSorry `on_click` can only be used in neovim 0.8 or higher.\n'
)
self.options.on_click = nil
return
end
self.on_click_id = modules.fn_store.register_fn(self.component_no, self.options.on_click)
end
end
---adds spaces to left and right of a component
function M:apply_padding()
local padding = self.options.padding
@ -181,6 +201,13 @@ function M:apply_section_separators()
end
end
---Add on click funtion description to already drawn item
function M:apply_on_click()
if self.on_click_id then
self.status = self:format_fn(self.on_click_id, self.status)
end
end
---remove separator from tail of this component.
---called by lualine.utils.sections.draw_section to manage unnecessary separators
function M:strip_separator()
@ -198,7 +225,7 @@ function M:get_default_hl()
elseif self.default_hl then
return self.default_hl
else
return highlight.format_highlight(self.options.self.section)
return modules.highlight.format_highlight(self.options.self.section)
end
end
@ -208,14 +235,22 @@ end
---@return table an identifier to later retrieve the hl for application
function M:create_hl(color, hint)
hint = hint and self.options.component_name .. '_' .. hint or self.options.component_name
return highlight.create_component_highlight_group(color, hint, self.options, false)
return modules.highlight.create_component_highlight_group(color, hint, self.options, false)
end
---Get stl formatted hl group for hl_token
---@param hl_token table identifier received from create_hl or create_component_highlight_group
---@return string stl formatted hl group for hl_token
function M:format_hl(hl_token)
return highlight.component_format_highlight(hl_token)
return modules.highlight.component_format_highlight(hl_token)
end
---Wrap str with click format for function of id
---@param id number
---@param str string
---@return string
function M:format_fn(id, str)
return string.format("%%%d@v:lua.require'lualine.utils.fn_store'.call_fn@%s%%T", id, str)
end
-- luacheck: push no unused args
@ -244,6 +279,7 @@ function M:draw(default_highlight, is_focused)
self:apply_icon()
self:apply_padding()
self:apply_highlights(default_highlight)
self:apply_on_click()
self:apply_section_separators()
self:apply_separator()
end

View File

@ -0,0 +1,38 @@
local M = {}
local fns = {}
---Store fn with id in fns so it can be later called
---@param id integer component id (for now we are only doing one fn per component)
---@param fn function the actual function to store.
---@return number same id that was provided.
function M.register_fn(id, fn)
vim.validate({
id = {id, 'n'},
fn = {fn, 'f'}
})
fns[id] = fn
return id
end
---Get the function with id
---@param id number id of the fn to retrive
---@return function
function M.get_fn(id)
vim.validate({ id = {id, 'n'} })
return fns[id] or function () end
end
---Call the function of id with args
---@param id number
---@param ... any
---@return any
function M.call_fn(id, ...)
return M.get_fn(id)(...)
end
---Clear the fns table
function M.clear_fns()
fns = {}
end
return M

View File

@ -6,6 +6,7 @@ local require = lualine_require.require
local modules = lualine_require.lazy_require {
utils = 'lualine.utils.utils',
notice = 'lualine.utils.notices',
fn_store = 'lualine.utils.fn_store',
}
local is_valid_filename = lualine_require.is_valid_filename
local sep = lualine_require.sep
@ -202,7 +203,8 @@ end
---loads sections and extensions or entire user config
---@param config table user config
local function load_all(config)
require('lualine.component')._reset_component_id()
require('lualine.component')._reset_components()
modules.fn_store.clear_fns()
load_components(config)
load_extensions(config)
end