From 1bb28df3cfc241b961331f00dcb8d5b45fe3e4f0 Mon Sep 17 00:00:00 2001 From: Sofronie Cristian <53446505+cristiansofronie@users.noreply.github.com> Date: Sat, 30 Mar 2024 06:05:03 +0200 Subject: [PATCH] feat(actions): support scrolling and selecting with the mouse (#2687) * feat(scrolling and mouse support): support scrolling and selecting with the mouse * fix ascending sorting_strategy mouse clicks --------- Co-authored-by: James Trew --- lua/telescope/actions/init.lua | 79 ++++++++++++++++++++++++++++++++++ lua/telescope/mappings.lua | 63 ++++++++++++++++++++++++++- lua/telescope/pickers.lua | 9 ++++ 3 files changed, 150 insertions(+), 1 deletion(-) diff --git a/lua/telescope/actions/init.lua b/lua/telescope/actions/init.lua index 0d336e0..928c287 100644 --- a/lua/telescope/actions/init.lua +++ b/lua/telescope/actions/init.lua @@ -1494,6 +1494,85 @@ end actions.nop = function(_) end +actions.mouse_scroll_up = function(prompt_bufnr) + local picker = action_state.get_current_picker(prompt_bufnr) + + local mouse_win = vim.fn.getmousepos().winid + if picker.results_win == mouse_win then + vim.schedule(function() + actions.move_selection_next(prompt_bufnr) + end) + return "" + else + return "" + end +end + +actions.mouse_scroll_down = function(prompt_bufnr) + local picker = action_state.get_current_picker(prompt_bufnr) + + local mouse_win = vim.fn.getmousepos().winid + if mouse_win == picker.results_win then + vim.schedule(function() + actions.move_selection_previous(prompt_bufnr) + end) + return "" + else + return "" + end +end + +actions.mouse_scroll_right = function(prompt_bufnr) + local picker = action_state.get_current_picker(prompt_bufnr) + + local mouse_win = vim.fn.getmousepos().winid + if mouse_win == picker.results_win then + return "" + else + return "" + end +end + +actions.mouse_scroll_left = function(prompt_bufnr) + local picker = action_state.get_current_picker(prompt_bufnr) + + local mouse_win = vim.fn.getmousepos().winid + if mouse_win == picker.results_win then + return "" + else + return "" + end +end + +actions.mouse_click = function(prompt_bufnr) + local picker = action_state.get_current_picker(prompt_bufnr) + + local pos = vim.fn.getmousepos() + if pos.winid == picker.results_win then + vim.schedule(function() + picker:set_selection(pos.line - 1) + end) + elseif pos.winid == picker.preview_win then + vim.schedule(function() + actions.select_default(prompt_bufnr) + end) + end + return "" +end + +actions.double_mouse_click = function(prompt_bufnr) + local picker = action_state.get_current_picker(prompt_bufnr) + + local pos = vim.fn.getmousepos() + if pos.winid == picker.results_win then + vim.schedule(function() + picker:set_selection(pos.line - 1) + actions.select_default(prompt_bufnr) + end) + end + return "" +end + -- ================================================== -- Transforms modules and sets the correct metatables. -- ================================================== diff --git a/lua/telescope/mappings.lua b/lua/telescope/mappings.lua index f006109..b4b6473 100644 --- a/lua/telescope/mappings.lua +++ b/lua/telescope/mappings.lua @@ -133,6 +133,37 @@ local mappings = {} mappings.default_mappings = config.values.default_mappings or { i = { + [""] = { + actions.mouse_scroll_up, + type = "action", + opts = { expr = true }, + }, + [""] = { + actions.mouse_scroll_down, + type = "action", + opts = { expr = true }, + }, + [""] = { + actions.mouse_scroll_right, + type = "action", + opts = { expr = true }, + }, + [""] = { + actions.mouse_scroll_left, + type = "action", + opts = { expr = true }, + }, + [""] = { + actions.mouse_click, + type = "action", + opts = { expr = true }, + }, + ["<2-LeftMouse>"] = { + actions.double_mouse_click, + type = "action", + opts = { expr = true }, + }, + [""] = actions.move_selection_next, [""] = actions.move_selection_previous, @@ -169,8 +200,38 @@ mappings.default_mappings = config.values.default_mappings -- disable c-j because we dont want to allow new lines #2123 [""] = actions.nop, }, - n = { + [""] = { + actions.mouse_scroll_up, + type = "action", + opts = { expr = true }, + }, + [""] = { + actions.mouse_scroll_down, + type = "action", + opts = { expr = true }, + }, + [""] = { + actions.mouse_scroll_right, + type = "action", + opts = { expr = true }, + }, + [""] = { + actions.mouse_scroll_left, + type = "action", + opts = { expr = true }, + }, + [""] = { + actions.mouse_click, + type = "action", + opts = { expr = true }, + }, + ["<2-LeftMouse>"] = { + actions.double_mouse_click, + type = "action", + opts = { expr = true }, + }, + [""] = actions.close, [""] = actions.select_default, [""] = actions.select_horizontal, diff --git a/lua/telescope/pickers.lua b/lua/telescope/pickers.lua index c0ebbab..d52ffff 100644 --- a/lua/telescope/pickers.lua +++ b/lua/telescope/pickers.lua @@ -73,6 +73,7 @@ local function default_create_layout(picker) local popup_opts = picker:get_window_options(vim.o.columns, line_count) -- `popup.nvim` massaging so people don't have to remember minheight shenanigans + popup_opts.results.focusable = true popup_opts.results.minheight = popup_opts.results.height popup_opts.results.highlight = "TelescopeResultsNormal" popup_opts.results.borderhighlight = "TelescopeResultsBorder" @@ -81,7 +82,9 @@ local function default_create_layout(picker) popup_opts.prompt.highlight = "TelescopePromptNormal" popup_opts.prompt.borderhighlight = "TelescopePromptBorder" popup_opts.prompt.titlehighlight = "TelescopePromptTitle" + if popup_opts.preview then + popup_opts.preview.focusable = true popup_opts.preview.minheight = popup_opts.preview.height popup_opts.preview.highlight = "TelescopePreviewNormal" popup_opts.preview.borderhighlight = "TelescopePreviewBorder" @@ -165,6 +168,7 @@ local function default_create_layout(picker) popup.move(results_win, popup_opts.results) popup.move(preview_win, popup_opts.preview) else + popup_opts.preview.focusable = true popup_opts.preview.highlight = "TelescopePreviewNormal" popup_opts.preview.borderhighlight = "TelescopePreviewBorder" popup_opts.preview.titlehighlight = "TelescopePreviewTitle" @@ -528,6 +532,9 @@ function Picker:find() self:close_existing_pickers() self:reset_selection() + self.__original_mousemoveevent = vim.o.mousemoveevent + vim.o.mousemoveevent = true + self.original_win_id = a.nvim_get_current_win() _, self.original_cword = pcall(vim.fn.expand, "") @@ -1626,6 +1633,8 @@ function pickers.on_close_prompt(prompt_bufnr) buffer = prompt_bufnr, } picker.close_windows(status) + + vim.o.mousemoveevent = picker.__original_mousemoveevent end function pickers.on_resize_window(prompt_bufnr)