From 5f6839ca43b4be52131a2a97e1c10c8745ad7e35 Mon Sep 17 00:00:00 2001 From: TheOnePath Date: Sun, 8 Jan 2023 22:31:34 +0000 Subject: [PATCH] Updated init.lua Script has been refactor and now easily allows for the creation of new windows/buffers upon function call. Tracking windows/buffers previously was invalid and lead to visual glitches of buffers. Windows/buffers now belong to a context manager found within Vim's global scope, due to ease of accessibility. Created function `new()` which is responsible for constructing new windows/buffers, updating the global context manager of newly added windows/buffers, and allowing for customisation given by plenary.popup. --- init.lua | 194 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 112 insertions(+), 82 deletions(-) diff --git a/init.lua b/init.lua index 169110c..b93939f 100644 --- a/init.lua +++ b/init.lua @@ -1,100 +1,130 @@ -local plenary = require'plenary' -local popup = plenary.popup - -local presser = {} -windows = {} +local popup = require'plenary.popup' +local utils = require'presser.utils' local api = vim.api -local function _iter_table_dump( arr ) - for k, v in pairs(arr) do - print("Table:", k, v) - end -end - -local escape_chars = function ( text ) - return string.gsub(text, "[%(|%)|\\|%[|%]|%-|%{%}|%?|%+|%*|%^|%$|%.]", { - ["\\"] = "\\\\", - ["-"] = "\\-", - ["("] = "\\(", - [")"] = "\\)", - ["["] = "\\[", - ["]"] = "\\]", - ["{"] = "\\{", - ["}"] = "\\}", - ["?"] = "\\?", - ["+"] = "\\+", - ["*"] = "\\*", - ["^"] = "\\^", - ["$"] = "\\$", - ["."] = "\\.", - }) -end - --- :@dev: clean the text once it has been fetched from buffer -local function _clean_buf ( text ) - if not type(text) == "string" or text == nil then - print("[DEBUG - _clean_buf] Given input is not of type string.") - return - end - - return escape_chars( text ) - :match( "^%s*(.-)%s*$" ) -end - -function presser.destroy_windows() --- api.nvim_win_close(0, true) - - for k,v in pairs(windows) do --- api.nvim_win_close(v, true) - print(k, v) - table.remove(windows, k) +local presser = {} -- list of functions to be exported +local g = vim.g + +g.presser_buf_ctx = {} -- setup a new global context manager for windows/buffers + +-- :@Dev: close all Presser windows that may be open for all contexts +presser.close = function () + for _type, ctx in pairs( g.presser_buf_ctx ) do + for _, win_id in pairs( ctx ) do + api.nvim_win_close( win_id, true ) -- buffer contents are irrelevant in this context to save + end + end + + g.presser_buf_ctx = {} -- clear the global context manager +end + +-- @Description: Construct a new instance of a window and buffer using the 'plenary.popup' module. +-- @Params: +-- + `_type` ~ string denoting which context manager is owner of the window. +-- + `placeholder` ~ string allowing for placeholder text to be placed within the buffer when constructed. +-- + `opts` ~ a table of additional options to be provided when constructing the window. +-- @Returns: nil. Constructs a new window and stores the window's ID in a global table. +-- +-- @Dev: This function is to be as generic for creating a window whilst allowing for as much customisation over the +-- window/buffer which are to be constructed. Users are to access this function so is not part of the module export. +-- However, it's used by all internal built-ins which are meant to be used by users. Consider a class constructor in +-- C++, this function is akin to that behaviour and is responsible for constructing the window/buffer and ensuring it +-- can be tracked by Vim itself. +local new = function ( _type, placeholder, opts ) + -- create new manager for handling windows in the + local manager = g.presser_buf_ctx + -- create specific context manager if it doesn't exist + if not manager[_type] then + manager[_type] = {} + g.presser_buf_ctx = manager + end + + local opts = opts or {} + local placeholder = placeholder or "" + + local buf_opts = { + minwidth = 80, -- getwin_w() / 2 - ((getwin_w() % 2) / 2), + borderchars = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" }, + } + + if opts.window then + for k,v in pairs( opts.window ) do + buf_opts[k] = v + end + end + + local obj = popup.create( placeholder, buf_opts ) + table.insert( manager[_type], obj ) + g.presser_buf_ctx = manager + + -- :@Dev: handle for keybindings (TODO: any future stuff below here once window is made) + local buf_id = function () + return api.nvim_win_get_buf(obj) + end + + -- handle for key bindings + if opts.keybinds then + for mode, mode_map in pairs( opts.keybinds ) do + mode = string.lower(mode) + + for key_bind, key_action in pairs(mode_map) do + local key_bind = api.nvim_replace_termcodes(key_bind, true, false, true), + api.nvim_buf_set_keymap(buf_id(), mode, key_bind, key_action, + { noremap = true, silent = true } + ) + end + end end end +-- @Description: Find and replace words within the current buffer. +-- @Params: +-- @Returns: nil. +-- +-- @Dev: function is responsible to creating all required buffers to allow full user interaction. +-- +-- @Future: implementation may allow for greater user customisation similar to what's found with +-- extensions such as Telescope. For now, it should provide a concrete UI for purpose of design. function presser.find_replace() - local padding = 128 - local buf_width = api.nvim_win_get_width(0) - padding + -- define the context which these windows will belong to in the context manager. + local ctx = "find_replace" + + local keymap = { + n = { + [""] = "lua require'presser'.close()", + }, + } + -- options for the title buffer of the built-in local opts = { - minwidth = buf_width, - borderchars = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" }, + window = { + line = 12, + border = false, + minwidth = 82, + padding = { 0, 1, 1, 1 } + }, + keybinds = keymap, } + local tab_title = new( ctx, "Find & Replace", opts ) - local win_title_opts = { - height = 3, - minwidth = buf_width + 2, - line = 9, - padding = { 1, 1, 1, 1 }, + -- options for the replace buffer + local opts = { + window = { + line = 18, + title = "Replace", + }, + keybinds = keymap, } + local replace = new( ctx, nil, opts ) - if not placeholder == nil then - vim.tbl_extend( "force", opts, { padding = { 0, buf_padding, 0, } } ) - end + -- modify options for find buffer + opts["window"]["line"] = 15 + opts["window"]["title"] = "Find" + local find = new ( ctx, nil, opts ) - local win_title = popup.create( { "Find & Replace" }, win_title_opts ) - local win_b = popup.create({ "" }, vim.tbl_extend("force", opts, { title = "Replace", line = 16 })) - local win_t = popup.create({ "" }, vim.tbl_extend("force", opts, { title = "Find", line = 13 })) - print(win_t, win_b) - - table.insert(windows, win_t) - table.insert(windows, win_b) - table.insert(windows, win_title) - - --api.nvim_feedkeys(api.nvim_replace_termcodes("A", true, false, true), 'n', true) - - local win_t_buf = api.nvim_win_get_buf(win_t) - local win_b_buf = api.nvim_win_get_buf(win_b) - -- :lua require('presser').destroy_windows() - api.nvim_buf_set_keymap(win_t_buf, "n", "", ":lua require('presser').destroy_windows()", { noremap = true, silent = true }) - api.nvim_buf_set_keymap(win_b_buf, "n", "", ":close!", { noremap = true, silent = true }) - print(win_t_buf) - - local text = api.nvim_buf_get_lines(win_t_buf, 0, -1, false) - print(_clean_buf(text[1])) - + api.nvim_feedkeys('A', 'n', false) end -presser.find_replace() return presser