Skip to content

Commit

Permalink
fix: Ignore section headings in md codeblocks
Browse files Browse the repository at this point in the history
This fix is related to issue #145. A new utility function is added which
checks whether the cursor is currently inside of a code block by
counting the instances of backticks before or after the cursor in the
buffer. If the cursor is in a code block, any headings (or things that
resemble headings, such as comments introduced by #) are ignored.
  • Loading branch information
jakewvincent committed Jun 5, 2024
1 parent 6ccfffe commit 05d5693
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 9 deletions.
3 changes: 2 additions & 1 deletion lua/mkdnflow/cursor.lua
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ local go_to_heading = function(anchor_text, reverse)
-- Record which line we're on; chances are the link goes to something later,
-- so we'll start looking from here onwards and then circle back to the beginning
local position = vim.api.nvim_win_get_cursor(0)
local starting_row, continue, in_fenced_code_block = position[1], true, false
local starting_row, continue = position[1], true
local in_fenced_code_block = utils.cursorInCodeBlock(starting_row, reverse)
local row = (reverse and starting_row - 1) or starting_row + 1
while continue do
local line = (reverse and vim.api.nvim_buf_get_lines(0, row - 1, row, false))
Expand Down
10 changes: 6 additions & 4 deletions lua/mkdnflow/folds.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
-- along with this program. If not, see <https://www.gnu.org/licenses/>.

local M = {}
local utils = require('mkdnflow').utils

M.getHeadingLevel = function(line)
local level
Expand All @@ -31,7 +32,7 @@ local get_section_range = function(start_row)
vim.api.nvim_buf_line_count(0)
local heading_level = M.getHeadingLevel(line)
if heading_level > 0 then
local continue, in_fenced_code_block = true, false
local continue, in_fenced_code_block = true, utils.cursorInCodeBlock(start_row)
local end_row = start_row + 1
while continue do
local next_line = vim.api.nvim_buf_get_lines(0, end_row - 1, end_row, false)
Expand All @@ -57,7 +58,7 @@ end

local get_nearest_heading = function()
local row = vim.api.nvim_win_get_cursor(0)[1] - 1
local continue, in_fenced_code_block = true, false
local continue, in_fenced_code_block = true, utils.cursorInCodeBlock(row)
while continue and row > 0 do
local prev_line = vim.api.nvim_buf_get_lines(0, row - 1, row, false)[1]
if string.find(prev_line, "^```") then
Expand All @@ -74,8 +75,9 @@ local get_nearest_heading = function()
end

M.foldSection = function()
local line = vim.api.nvim_get_current_line()
if M.getHeadingLevel(line) < 99 then
local row, line = vim.api.nvim_win_get_cursor(0)[1], vim.api.nvim_get_current_line()
local in_fenced_code_block = utils.cursorInCodeBlock(row)
if M.getHeadingLevel(line) < 99 and not in_fenced_code_block then
local range = get_section_range()
if range then
vim.cmd(tostring(range[1]) .. ',' .. tostring(range[2]) .. 'fold')
Expand Down
26 changes: 22 additions & 4 deletions lua/mkdnflow/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -262,19 +262,37 @@ M.betterGmatch = function(text, pattern, start)
start = start ~= nil and start or 1
return function()
if not text then
return nil -- Handle nil text gracefully
return nil -- Handle nil text gracefully
end
while start <= #text do
local match_start, match_end, match = string.find(text, pattern, start)
if match_start then
start = match_end + 1 -- Update the start for the next search
start = match_end + 1 -- Update the start for the next search
return match_start, match_end, match
else
break -- No more matches, exit loop
break -- No more matches, exit loop
end
end
return nil -- Explicitly return nil when no more data to iterate
return nil -- Explicitly return nil when no more data to iterate
end
end

M.cursorInCodeBlock = function(cursor_row, reverse)
if reverse == nil or reverse == false then
reverse = false
else
reverse = true
end
local lines = reverse and vim.api.nvim_buf_get_lines(0, cursor_row - 1, -1, false) or vim.api.nvim_buf_get_lines(0, 0, cursor_row, false)
local fences = 0
for _, line_text in ipairs(lines) do
local _, count = string.gsub(line_text, "^```", "```")
fences = fences + count
end
if fences % 2 == 0 then
return false
end
return true
end

return M

0 comments on commit 05d5693

Please sign in to comment.