Skip to content

Merge user setup function, module rename #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Mar 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions ci/mini-doc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ require("mini.doc").setup({

local input_files = {
"plugin/ninjection.lua",
"lua/ninjection.lua",
"lua/ninjection/init.lua",
"lua/ninjection/config.lua",
"lua/ninjection/types.lua",
"lua/ninjection/health.lua",
"lua/ninjection/treesitter.lua",
"lua/ninjection/parse.lua",
"lua/ninjection/buffer.lua",
}
require("mini.doc").generate(input_files, "doc/ninjection.txt")
97 changes: 85 additions & 12 deletions doc/ninjection.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ Getting started with ninjection:
`:Ninjection select` - should highlight the entire injected code block.
`:Ninjection edit` - should open a floating window with the injected text
and attach the appropriate LSP.
`:Ninjection restore` - should apply any changes in the editing buffer to
`:Ninjection replace` - should apply any changes in the editing buffer to
the original buffer.
You can also test functionality with:
`:lua require("ninjection.ninjection").select()`
`:lua require("ninjection.ninjection").edit()`
`:lua require("ninjection.ninjection").replace()`
`:lua require("ninjection").select()`
`:lua require("ninjection").edit()`
`:lua require("ninjection").replace()`
3. Ninjection provides keymap plugs for you to map keybindings
of your choosing:
`<Plug>(NinjectionEdit)`
Expand Down Expand Up @@ -309,11 +309,11 @@ Return ~


==============================================================================
"ninjection.treesitter"
"ninjection.parse"

The treesitter module contains all treesitter related functions for ninjection.
The parse module contains all treesitter related functions for ninjection.

*ninjection.treesitter.qet_query()*
*ninjection.parse.qet_query()*

Retrieves a parsed query from Treesitter given a language and pattern.

Expand All @@ -325,7 +325,7 @@ Return ~
`(vim.treesitter.Query)` `(optional)` parsed_query, string? err
parsed Treesitter Query object

*ninjection.treesitter.get_root()*
*ninjection.parse.get_root()*

Parses the root tree for a language in a buffer.

Expand All @@ -337,7 +337,7 @@ Return ~
`(TSNode)` `(optional)` root, string? err
Root node of the TSTree for the language.

*ninjection.treesitter.get_node_table()*
*ninjection.parse.get_node_table()*

Identifies the injected language node at the current cursor position
with start and ending coordinates.
Expand All @@ -352,8 +352,8 @@ Returns a table containing:
- node: `TSNode` - the Treesitter node element (see :h TSNode).
- range: `NJRange` - row/col ranges for the node.
NOTE: Coordinates may not match the actual text locations
(see: `ninjection.treesitter.get_visual_range()` for this).
*ninjection.treesitter.get_inj_lang()*
(see: `ninjection.parse.get_visual_range()` for this).
*ninjection.parse.get_inj_lang()*

Parse an injected content node for an associated language comment.

Expand All @@ -366,7 +366,7 @@ injections in.
Return ~
`(string)` `(optional)` inj_lang , string? err - Injected language identified.

*ninjection.treesitter.get_visual_range()*
*ninjection.parse.get_visual_range()*

Gets an adjusted "visual" range for a node by approximating the
range of text that is actually seen (as returned by get_node_text).
Expand All @@ -388,4 +388,77 @@ Return ~
`(NJRange)` `(optional)` vs_range, string? err - Range of text selected.


==============================================================================
"ninjection.buffer"

The buffer module contains helper functions utilized by the main ninjection
module for creating and editing injected text in buffers.

*ninjection.buffer.get_indents()*

Finds whitespace indents (top, bottom, left) in the provided buffer.

Parameters ~
{bufnr} `(integer)` - Buffer handle.

Return ~
`(NJIndents)` `(optional)` indents, string? err
Returns, on success, a table containing:
- `t_indent`: number of blank lines at the top.
- `b_indent`: number of blank lines at the bottom.
- `l_indent`: minimum number of leading spaces on nonempty lines.

*ninjection.buffer.restore_indents()*

Restores the recorded whitespace indents (top, bottom, and left indent)
for the provided text.

Parameters ~
{text} `(string|table<integer,string>)` The text to restore indents to.
Can be either a string (with newline separators) or a table of lines.
{indents} `(NJIndents)` Table with indent values for t, b, l

Return ~
`(string[])` `(optional)` restored_lines, string? err
Lines with the indents restored.

*ninjection.buffer.create_child_buf()*

Creates a child buffer to edit injected language text.

Parameters ~
{p_bufnr} `(integer)` - Buffer handle for parent buffer.
{p_name} `(string)` - Name for parent buffer.
{p_range} `(NJRange)` - Text range for the injected text.
{root_dir} `(string)` - Root directory for project, or cwd.
{text} `(string)` - Text to populate the child buffer with.
{lang} `(string)` - Language to configure buffer for.

Return ~
`({ bufnr: integer?, win: integer?, indents: NJIndents })` c_table, string? err
*ninjection.buffer.set_child_cur()*

Sets the child cursor to the same relative position as in the parent window.

Parameters ~
{c_win} `(integer)` Handle for child window to set the cursor in.
{p_cursor} `(integer[])` Parent cursor pos.
{s_row} `(integer)` Starting row from the parent to offset the child cursor by.
{indents} `(NJIndents?)` Indents to calculate additional offsets with.

Return ~
`(string)` `(optional)` err

*ninjection.buffer.start_lsp()*

Starts an appropriate LSP for the provided language.

Parameters ~
{lang} `(string)` - The filetype of the injected language (e.g., "lua", "python").
{root_dir} `(string)` - The root directory for the buffer.

Return ~
`(NJLspStatus)` `(optional)` result, string? err - The LSP status.


vim:tw=78:ts=8:noet:ft=help:norl:
15 changes: 10 additions & 5 deletions doc/tags
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@ Ninjection.Subcommand ninjection.txt /*Ninjection.Subcommand*
config.reload() ninjection.txt /*config.reload()*
default_config ninjection.txt /*default_config*
lspconfig.Config ninjection.txt /*lspconfig.Config*
ninjection.buffer.create_child_buf() ninjection.txt /*ninjection.buffer.create_child_buf()*
ninjection.buffer.get_indents() ninjection.txt /*ninjection.buffer.get_indents()*
ninjection.buffer.restore_indents() ninjection.txt /*ninjection.buffer.restore_indents()*
ninjection.buffer.set_child_cur() ninjection.txt /*ninjection.buffer.set_child_cur()*
ninjection.buffer.start_lsp() ninjection.txt /*ninjection.buffer.start_lsp()*
ninjection.edit() ninjection.txt /*ninjection.edit()*
ninjection.health.validate_config() ninjection.txt /*ninjection.health.validate_config()*
ninjection.parse.get_inj_lang() ninjection.txt /*ninjection.parse.get_inj_lang()*
ninjection.parse.get_node_table() ninjection.txt /*ninjection.parse.get_node_table()*
ninjection.parse.get_root() ninjection.txt /*ninjection.parse.get_root()*
ninjection.parse.get_visual_range() ninjection.txt /*ninjection.parse.get_visual_range()*
ninjection.parse.qet_query() ninjection.txt /*ninjection.parse.qet_query()*
ninjection.replace() ninjection.txt /*ninjection.replace()*
ninjection.select() ninjection.txt /*ninjection.select()*
ninjection.treesitter.get_inj_lang() ninjection.txt /*ninjection.treesitter.get_inj_lang()*
ninjection.treesitter.get_node_table() ninjection.txt /*ninjection.treesitter.get_node_table()*
ninjection.treesitter.get_root() ninjection.txt /*ninjection.treesitter.get_root()*
ninjection.treesitter.get_visual_range() ninjection.txt /*ninjection.treesitter.get_visual_range()*
ninjection.treesitter.qet_query() ninjection.txt /*ninjection.treesitter.qet_query()*
50 changes: 24 additions & 26 deletions lua/ninjection/util.lua → lua/ninjection/buffer.lua
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
---@module "ninjection.util"
---@module "ninjection.buffer"
---@brief
--- The util module contains helper functions utilized by the main ninjection
--- module for getting and recording indentation, creating new child buffers,
--- creating new windows, setting cursor position, and starting and attaching
--- the appropriate LSP to the child buffer.
--- The buffer module contains helper functions utilized by the main ninjection
--- module for creating and editing injected text in buffers.
---
local M = {}
---@nodoc
---@type Ninjection.Config
local cfg = require("ninjection.config").cfg
local cfg = require("ninjection.config").values
local lspconfig = require("lspconfig")

-- We need to provide a way of recording and restoring whitespace from the parent
-- buffer to allow easily formatting the buffer without worrying about its
-- relative placement in the parent buffer.

---@tag ninjection.util.get_indents()
---@tag ninjection.buffer.get_indents()
---@brief
--- Finds whitespace indents (top, bottom, left) in the provided buffer.
---
Expand Down Expand Up @@ -45,9 +43,9 @@ M.get_indents = function(bufnr)
lines = raw_output

if #lines == 0 then
if cfg.suppress_warnings == false then
if cfg.debug then
vim.notify(
"ninjection.util.get_indents() warning: No lines returned "
"ninjection.buffer.get_indents() warning: No lines returned "
.. "from calling vim.api.nvim_buf_get_lines()",
vim.log.levels.WARN
)
Expand Down Expand Up @@ -100,7 +98,7 @@ M.get_indents = function(bufnr)
return indents, nil
end

---@tag ninjection.util.restore_indents()
---@tag ninjection.buffer.restore_indents()
---@brief
--- Restores the recorded whitespace indents (top, bottom, and left indent)
--- for the provided text.
Expand Down Expand Up @@ -130,9 +128,9 @@ M.restore_indents = function(text, indents)
---@cast raw_output string[]
lines = raw_output
if #lines == 0 then
if cfg.suppress_warnings == false then
if cfg.debug then
vim.notify(
"ninjection.util.restore_indents() warning: No lines " .. "returned from calling vim.split()",
"ninjection.buffer.restore_indents() warning: No lines " .. "returned from calling vim.split()",
vim.log.levels.WARN
)
end
Expand All @@ -141,7 +139,7 @@ M.restore_indents = function(text, indents)
elseif type(text) == "table" then
lines = text
else
error("ninjection.util.restore_indents() error: Text must be a string or " .. "a table of lines", 2)
error("ninjection.buffer.restore_indents() error: Text must be a string or " .. "a table of lines", 2)
end
---@cast lines string[]

Expand Down Expand Up @@ -264,7 +262,7 @@ local function create_child_win(bufnr, style)
return 0
end

---@tag ninjection.util.create_child_buf()
---@tag ninjection.buffer.create_child()
---@brief
--- Creates a child buffer to edit injected language text.
---
Expand All @@ -280,7 +278,7 @@ end
-- Returns table containing handles for the child buffer and window, if
-- available, and parent indents.
--
M.create_child_buf = function(p_bufnr, p_name, p_range, root_dir, text, lang)
M.create_child = function(p_bufnr, p_name, p_range, root_dir, text, lang)
---@type boolean, unknown, string?, integer?
local ok, raw_output, err, c_bufnr

Expand Down Expand Up @@ -337,7 +335,7 @@ M.create_child_buf = function(p_bufnr, p_name, p_range, root_dir, text, lang)
if cfg.preserve_indents then
p_indents, err = M.get_indents(0)
if not p_indents then
if not cfg.suppress_warnings then
if cfg.debug then
vim.notify(
"ninjection.edit() warning: Unable to preserve indentation "
.. "with get_indents(): "
Expand Down Expand Up @@ -367,7 +365,7 @@ M.create_child_buf = function(p_bufnr, p_name, p_range, root_dir, text, lang)
return vim.cmd("lua " .. cfg.format_cmd)
end)
if not ok then
if not cfg.suppress_warnings then
if cfg.debug then
err = tostring(raw_output)
vim.notify(
'ninjection.edit() warning: Calling vim.cmd("lua "' .. cfg.format_cmd .. ")\n" .. err,
Expand Down Expand Up @@ -397,7 +395,7 @@ M.create_child_buf = function(p_bufnr, p_name, p_range, root_dir, text, lang)
return { bufnr = c_bufnr, win = c_win, indents = p_indents }
end

---@tag ninjection.util.set_child_cur()
---@tag ninjection.buffer.set_child_cur()
---@brief
--- Sets the child cursor to the same relative position as in the parent window.
---
Expand Down Expand Up @@ -438,7 +436,7 @@ M.set_child_cur = function(c_win, p_cursor, s_row, indents)
return vim.api.nvim_win_set_cursor(c_win, offset_cur)
end)
if not ok then
if not cfg.suppress_warnings then
if cfg.debug then
err = tostring(raw_output)
vim.notify(
"ninjection.edit() warning: Calling vim.api.nvim_win_set_cursor"
Expand All @@ -457,7 +455,7 @@ end
-- Autocommands don't trigger properly when creating and arbitrarily assigning
-- filetypes to buffers, so we need a function to start the appropriate LSP.

---@tag ninjection.util.start_lsp()
---@tag ninjection.buffer.start_lsp()
---@brief
--- Starts an appropriate LSP for the provided language.
---
Expand All @@ -475,7 +473,7 @@ M.start_lsp = function(lang, root_dir)
lang_lsp = cfg.lsp_map[lang]
if not lang_lsp then
vim.notify(
"ninjection.util.start_lsp() warning: No LSP mapped to "
"ninjection.buffer.start_lsp() warning: No LSP mapped to "
.. "language: "
.. lang
.. " check your configuration.",
Expand All @@ -496,7 +494,7 @@ M.start_lsp = function(lang, root_dir)
local lsp_def = raw_output
if not lsp_def then
vim.notify(
"ninjection.util.start_lsp() warning: Could not find "
"ninjection.buffer.start_lsp() warning: Could not find "
.. "default_config for "
.. lang_lsp
.. ". Ensure it is installed and "
Expand All @@ -513,7 +511,7 @@ M.start_lsp = function(lang, root_dir)
local lsp_cmd = lsp_def.cmd
if not lsp_cmd or #lsp_cmd == 0 then
vim.notify(
"ninjection.util.start_lsp() warning: Command to execute "
"ninjection.buffer.start_lsp() warning: Command to execute "
.. lang_lsp
.. " does not exist. Ensure it is installed and configured.",
vim.log.levels.WARN
Expand All @@ -532,7 +530,7 @@ M.start_lsp = function(lang, root_dir)
end
if raw_output ~= 1 then
vim.notify(
"ninjection.util.start_lsp() warning: The LSP command: " .. lsp_cmd[1] .. " is not executable.",
"ninjection.buffer.start_lsp() warning: The LSP command: " .. lsp_cmd[1] .. " is not executable.",
vim.log.levels.WARN
)
return { "no-exec", -1 }
Expand All @@ -541,7 +539,7 @@ M.start_lsp = function(lang, root_dir)
-- The LSP must support our injected language
if not vim.tbl_contains(lsp_def.filetypes, lang) then
vim.notify(
"ninjection.util.start_lsp() warning: The configured LSP: "
"ninjection.buffer.start_lsp() warning: The configured LSP: "
.. lang_lsp
.. " does not support "
.. lang
Expand All @@ -566,7 +564,7 @@ M.start_lsp = function(lang, root_dir)
local client_id = raw_output
if client_id == nil then
vim.notify(
"ninjection.util.start_lsp() warning: The LSP: "
"ninjection.buffer.start_lsp() warning: The LSP: "
.. lang_lsp
.. " did not return a client_id, check your language client logs "
.. "(default ~/.local/state/nvim/lsp.log) for more information.",
Expand Down
Loading