diff --git a/presser/init.lua b/presser/init.lua new file mode 100644 index 0000000..6b49ec0 --- /dev/null +++ b/presser/init.lua @@ -0,0 +1,124 @@ +local popup = require'plenary.popup' +local utils = require'presser.utils' +local ctx = require('presser.context_manager') + +local api = vim.api + +local presser = {} -- list of functions to be exported + + +-- :@Dev: close all Presser windows that may be open for all contexts +presser.close = function () + ctx.flush() -- invoke the context manager to flush the table +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 ( _ctx, label, opts ) + -- create new context in the manager if it doesn't already exist + ctx.create( _ctx ) + + local opts = opts or {} + if not opts.placeholder then + opts["placeholder"] = "" + end + + 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( opts.placeholder, buf_opts ) + ctx.update( _ctx, obj ) + -- :TODO: call update function in context manager +-- 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() + -- 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 = { + placeholder = "Find & Replace", + window = { + line = 12, + border = false, + minwidth = 82, + padding = { 0, 1, 1, 1 } + }, + keybinds = keymap, + } + local tab_title = new( ctx, "presser_fr_title", opts ) + + -- options for the replace buffer + local opts = { + window = { + line = 18, + title = "Replace", + }, + keybinds = keymap, + } + local replace = new( ctx, "replace_buf", opts ) + + -- modify options for find buffer + opts["window"]["line"] = 15 + opts["window"]["title"] = "Find" + local find = new ( ctx, "find_buf", opts ) + + api.nvim_feedkeys('A', 'n', false) +end + + +return presser diff --git a/presser/utils.lua b/presser/utils.lua new file mode 100644 index 0000000..98573fc --- /dev/null +++ b/presser/utils.lua @@ -0,0 +1,40 @@ +local M = {} + +M.iter_table_dump = function ( 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 +M.clean_buf = function ( 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 + + +return M