Skip to content

Commit 05d5693

Browse files
committed
fix: Ignore section headings in md codeblocks
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.
1 parent 6ccfffe commit 05d5693

File tree

3 files changed

+30
-9
lines changed

3 files changed

+30
-9
lines changed

lua/mkdnflow/cursor.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ local go_to_heading = function(anchor_text, reverse)
144144
-- Record which line we're on; chances are the link goes to something later,
145145
-- so we'll start looking from here onwards and then circle back to the beginning
146146
local position = vim.api.nvim_win_get_cursor(0)
147-
local starting_row, continue, in_fenced_code_block = position[1], true, false
147+
local starting_row, continue = position[1], true
148+
local in_fenced_code_block = utils.cursorInCodeBlock(starting_row, reverse)
148149
local row = (reverse and starting_row - 1) or starting_row + 1
149150
while continue do
150151
local line = (reverse and vim.api.nvim_buf_get_lines(0, row - 1, row, false))

lua/mkdnflow/folds.lua

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
1616

1717
local M = {}
18+
local utils = require('mkdnflow').utils
1819

1920
M.getHeadingLevel = function(line)
2021
local level
@@ -31,7 +32,7 @@ local get_section_range = function(start_row)
3132
vim.api.nvim_buf_line_count(0)
3233
local heading_level = M.getHeadingLevel(line)
3334
if heading_level > 0 then
34-
local continue, in_fenced_code_block = true, false
35+
local continue, in_fenced_code_block = true, utils.cursorInCodeBlock(start_row)
3536
local end_row = start_row + 1
3637
while continue do
3738
local next_line = vim.api.nvim_buf_get_lines(0, end_row - 1, end_row, false)
@@ -57,7 +58,7 @@ end
5758

5859
local get_nearest_heading = function()
5960
local row = vim.api.nvim_win_get_cursor(0)[1] - 1
60-
local continue, in_fenced_code_block = true, false
61+
local continue, in_fenced_code_block = true, utils.cursorInCodeBlock(row)
6162
while continue and row > 0 do
6263
local prev_line = vim.api.nvim_buf_get_lines(0, row - 1, row, false)[1]
6364
if string.find(prev_line, "^```") then
@@ -74,8 +75,9 @@ local get_nearest_heading = function()
7475
end
7576

7677
M.foldSection = function()
77-
local line = vim.api.nvim_get_current_line()
78-
if M.getHeadingLevel(line) < 99 then
78+
local row, line = vim.api.nvim_win_get_cursor(0)[1], vim.api.nvim_get_current_line()
79+
local in_fenced_code_block = utils.cursorInCodeBlock(row)
80+
if M.getHeadingLevel(line) < 99 and not in_fenced_code_block then
7981
local range = get_section_range()
8082
if range then
8183
vim.cmd(tostring(range[1]) .. ',' .. tostring(range[2]) .. 'fold')

lua/mkdnflow/utils.lua

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,19 +262,37 @@ M.betterGmatch = function(text, pattern, start)
262262
start = start ~= nil and start or 1
263263
return function()
264264
if not text then
265-
return nil -- Handle nil text gracefully
265+
return nil -- Handle nil text gracefully
266266
end
267267
while start <= #text do
268268
local match_start, match_end, match = string.find(text, pattern, start)
269269
if match_start then
270-
start = match_end + 1 -- Update the start for the next search
270+
start = match_end + 1 -- Update the start for the next search
271271
return match_start, match_end, match
272272
else
273-
break -- No more matches, exit loop
273+
break -- No more matches, exit loop
274274
end
275275
end
276-
return nil -- Explicitly return nil when no more data to iterate
276+
return nil -- Explicitly return nil when no more data to iterate
277277
end
278278
end
279279

280+
M.cursorInCodeBlock = function(cursor_row, reverse)
281+
if reverse == nil or reverse == false then
282+
reverse = false
283+
else
284+
reverse = true
285+
end
286+
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)
287+
local fences = 0
288+
for _, line_text in ipairs(lines) do
289+
local _, count = string.gsub(line_text, "^```", "```")
290+
fences = fences + count
291+
end
292+
if fences % 2 == 0 then
293+
return false
294+
end
295+
return true
296+
end
297+
280298
return M

0 commit comments

Comments
 (0)