voldikss / vim-floaterm

:computer: Terminal manager for (neo)vim
MIT License
2.48k stars 78 forks source link

feat: add g:floaterm_openoverride global option #413

Closed lucobellic closed 11 months ago

lucobellic commented 1 year ago

Hello.

I'd like to add the ability to completely control the floaterm popup UI style while using all floaterm features.

So this change add a g:floaterm_openoverride global option to override the behavior of floaterm#window#open instead of calling open_float or open_split, ...

This way, I can have a visual style that integrates better with other plugins like Telescope, and it allows any kind of behavior to be implemented, such as having a title color based on the current float index.

Screenshots example | Terminal | Lazygit | | :---------: | :--------: | | ![floaterm_terminal](https://github.com/voldikss/vim-floaterm/assets/6067072/056ace75-d365-4732-b390-66704134d303) | ![floaterm_lazygit](https://github.com/voldikss/vim-floaterm/assets/6067072/2ac37947-2c42-4b4a-9d74-3795fbe70cab) |
Example of lua code snippet with nui popup for the screenshot above ```lua --- Function to override the floaterm#window#open function ---@param bufnr number ---@param config any @floaterm configuration ---@return number winid local function open_popup(bufnr, config) local highlights = { 'TelescopePromptTitle', 'TelescopeResultsTitle', 'TelescopePreviewTitle', } --- Get popup highlight string with title highlight based on index value --- Find the first digit as index from the provided string ---@param index string ---@return string local function get_highlight(index) local term_index = tonumber(index:match('%d') or '1') - 1 local highlight_index = (term_index % #highlights) + 1 local highlight = highlights[highlight_index] return ("Normal:Normal,FloatBorder:FloatBorder,FloatTitle:%s"):format(highlight) end --- Extract title and index from floaterm title ---@param title string @Title provided by floaterm, expected format: "Title 1/2" ---@return {title:string, index:string} local function extract_title_and_index(title) local tokens = title.gmatch(title, "[^%s]+") return { title = tokens() or '', index = tokens() or '' } end local parsed_title = extract_title_and_index(config.title) local Popup = require("nui.popup") local NuiText = require("nui.text") local popup = Popup({ position = "50%", bufnr = bufnr, size = { width = config.width, height = config.height, }, enter = true, focusable = true, zindex = 50, relative = "editor", border = { padding = { top = 0, bottom = 0, left = 0, right = 0, }, style = "rounded", text = { top = ' ' .. parsed_title.title .. ' ', top_align = "center", bottom = NuiText(' ' .. parsed_title.index .. ' ', "TelescopePromptCounter"), bottom_align = "right", }, }, buf_options = { modifiable = true, readonly = false, }, win_options = { winhighlight = get_highlight(parsed_title.index), }, }) popup:mount() return popup.winid end ``` and ```lua vim.g.floaterm_openoverride = open_popup ``` > **Note** > This code snippet is just an example and might not be 100% correct (there is no event callback to trigger `popup:unmount()`)

Note Lower case naming style of the floaterm options do not allow direct storage of Funcref. that's why I only added a global option but this could be changed.

Feel free to close the pull request if it goes beyond what you want to add to floaterm. Let me know if you want to add any other changes (add documentation, pass the override function like any other parameter, ...)

lucobellic commented 11 months ago

I'm closing this pull request as it doesn't contain any significant changes. However, it can still serve as an example for those who would like a more complete customization of floaterm.