From efd467700d0bd09360c46205043b24c80d60c84a Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Wed, 21 Jul 2021 13:49:39 -0600 Subject: [PATCH 1/9] Add extmarks inserter --- lua/snippets/inserters/extmarks.lua | 188 ++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 lua/snippets/inserters/extmarks.lua diff --git a/lua/snippets/inserters/extmarks.lua b/lua/snippets/inserters/extmarks.lua new file mode 100644 index 0000000..bb501f3 --- /dev/null +++ b/lua/snippets/inserters/extmarks.lua @@ -0,0 +1,188 @@ +local api = vim.api +local U = require("snippets/common") + +local ns = api.nvim_create_namespace("") + +local M = {} + +-- These are user-configurable +M.marker_with_placeholder_format = "${%d:%s}" +M.post_transform_marker_format = "${|%s}" +M.zero_pattern = "$0" +M.hl_group = "Visual" + +local function update_structure(evaluator, resolved_inputs) + local S = evaluator.evaluate_structure(resolved_inputs) + + local placeholders = evaluator.evaluate_inputs(resolved_inputs) + for i, v in ipairs(evaluator.inputs) do + if not resolved_inputs[i] then + S[v.first_index] = M.marker_with_placeholder_format:format(v.id, placeholders[i]) + end + end + + for i, v in ipairs(evaluator.structure) do + if U.is_variable(v) and v.transform and not v.id then + S[i] = M.post_transform_marker_format:format(i) + end + end + + if evaluator.zero_index then + S[evaluator.zero_index] = M.zero_pattern + end + + return S +end + +local function set_extmark(id, line, col, end_line, end_col, hl_group) + local _ = api.nvim_buf_set_extmark(0, ns, line, col, { + id = id, + end_line = end_line, + end_col = end_col, + hl_group = hl_group, + right_gravity = false, + end_right_gravity = true, + }) +end + +local function get_extmark_pos(id) + local row, col, details = unpack(api.nvim_buf_get_extmark_by_id(0, ns, id, { details = true })) + return row, col, details and details.end_row or row, details and details.end_col or col +end + +local function set_extmark_text(id, text) + local row, col, end_row, end_col = get_extmark_pos(id) + api.nvim_buf_set_text(0, row, col, end_row, end_col, vim.split(text, "\n")) +end + +local function entrypoint(structure) + local evaluator = U.evaluate_snippet(structure) + + local S = update_structure(evaluator, {}) + + local cursor_mark_id + + do + local lnum, col = unpack(api.nvim_win_get_cursor(0)) + + local current_line = api.nvim_get_current_line() + local prefix = current_line:sub(1, col) + local suffix = current_line:sub(col + 1) + + local lines = vim.split(table.concat(S), "\n") + lines[1] = prefix .. lines[1] + lines[#lines] = lines[#lines] .. suffix + api.nvim_buf_set_lines(0, lnum - 1, lnum, true, lines) + + for i, v in ipairs(evaluator.structure) do + local s = S[i] + if i == evaluator.zero_index then + cursor_mark_id = i + end + + if U.is_variable(v) then + set_extmark(i, lnum - 1, col, nil, col + #s) + end + + local tail = s:gsub("[^\n]*\n", function() + lnum = lnum + 1 + col = 0 + return "" + end) + + col = col + #tail + end + + if not cursor_mark_id then + cursor_mark_id = api.nvim_buf_set_extmark(0, ns, lnum - 1, col, {}) + end + end + + local current_index = 0 + local resolved_inputs = {} + + local R + R = { + advance = function(offset) + offset = offset or 1 + current_index = math.max(math.min(current_index + offset, #evaluator.inputs + 1), 0) + if current_index == 0 then + R.aborted = true + api.nvim_buf_clear_namespace(0, ns, 0, -1) + vim.register_keystroke_callback(nil, ns) + return true + end + + -- User has moved past the last variable, so apply transformations and move the cursor to the + -- zero point + if current_index > #evaluator.inputs then + for i, v in pairs(evaluator.structure) do + if U.is_variable(v) and v.transform and not v.id then + set_extmark_text(i, S[i]) + end + end + + -- Move cursor to zero point + local cur_row, cur_col, cur_end_row, cur_end_col = get_extmark_pos(cursor_mark_id) + api.nvim_buf_set_text(0, cur_row, cur_col, cur_end_row, cur_end_col, {}) + api.nvim_win_set_cursor(0, { cur_row + 1, cur_col }) + + -- Clear all extmarks + api.nvim_buf_clear_namespace(0, ns, 0, -1) + vim.register_keystroke_callback(nil, ns) + + R.finished = true + return true + end + + local var = evaluator.inputs[current_index] + + -- Clear highlights on all extmarks except those for current variable + for i, v in ipairs(evaluator.structure) do + if U.is_variable(v) then + local hl_group = v.order == current_index and M.hl_group or nil + local row, col, end_row, end_col = get_extmark_pos(i) + set_extmark(i, row, col, end_row, end_col, hl_group) + end + end + + -- Move the cursor to the next variable and update the placeholder text + set_extmark_text(var.first_index, var.default) + local mark_row, mark_col, _, mark_end_col = get_extmark_pos(var.first_index) + api.nvim_win_set_cursor(0, { mark_row + 1, mark_end_col }) + + vim.register_keystroke_callback( + vim.schedule_wrap(function() + if R.finished or R.aborted then + return + end + + mark_row, mark_col, _, mark_end_col = get_extmark_pos(var.first_index) + local line = api.nvim_buf_get_lines(0, mark_row, mark_row + 1, true)[1] + local mark_text = line:sub(mark_col + 1, mark_end_col) + + resolved_inputs[var.id] = mark_text + S = evaluator.evaluate_structure(resolved_inputs) + + for i = var.first_index + 1, #evaluator.structure do + local v = evaluator.structure[i] + if U.is_variable(v) and v.id == var.id then + set_extmark_text(i, S[i]) + end + end + end), + ns + ) + end, + finished = false, + aborted = false, + } + + return R +end + +return setmetatable(M, { + __call = function(_, ...) + return entrypoint(...) + end, +}) From f611ea5b43a0d18bbcf4663606a274d6fd3d6e94 Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Fri, 23 Jul 2021 10:16:17 -0600 Subject: [PATCH 2/9] Move cleanup into separate function --- lua/snippets/inserters/extmarks.lua | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lua/snippets/inserters/extmarks.lua b/lua/snippets/inserters/extmarks.lua index bb501f3..bad0910 100644 --- a/lua/snippets/inserters/extmarks.lua +++ b/lua/snippets/inserters/extmarks.lua @@ -35,7 +35,7 @@ local function update_structure(evaluator, resolved_inputs) end local function set_extmark(id, line, col, end_line, end_col, hl_group) - local _ = api.nvim_buf_set_extmark(0, ns, line, col, { + api.nvim_buf_set_extmark(0, ns, line, col, { id = id, end_line = end_line, end_col = end_col, @@ -55,6 +55,11 @@ local function set_extmark_text(id, text) api.nvim_buf_set_text(0, row, col, end_row, end_col, vim.split(text, "\n")) end +local function cleanup() + api.nvim_buf_clear_namespace(0, ns, 0, -1) + vim.register_keystroke_callback(nil, ns) +end + local function entrypoint(structure) local evaluator = U.evaluate_snippet(structure) @@ -81,7 +86,7 @@ local function entrypoint(structure) end if U.is_variable(v) then - set_extmark(i, lnum - 1, col, nil, col + #s) + set_extmark(i, lnum - 1, col, lnum - 1, col + #s) end local tail = s:gsub("[^\n]*\n", function() @@ -108,8 +113,7 @@ local function entrypoint(structure) current_index = math.max(math.min(current_index + offset, #evaluator.inputs + 1), 0) if current_index == 0 then R.aborted = true - api.nvim_buf_clear_namespace(0, ns, 0, -1) - vim.register_keystroke_callback(nil, ns) + cleanup() return true end @@ -127,10 +131,7 @@ local function entrypoint(structure) api.nvim_buf_set_text(0, cur_row, cur_col, cur_end_row, cur_end_col, {}) api.nvim_win_set_cursor(0, { cur_row + 1, cur_col }) - -- Clear all extmarks - api.nvim_buf_clear_namespace(0, ns, 0, -1) - vim.register_keystroke_callback(nil, ns) - + cleanup() R.finished = true return true end From f401e230823cee05e566d1bbe750a43bcda57e9a Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Fri, 23 Jul 2021 10:16:37 -0600 Subject: [PATCH 3/9] Correctly handle advancing backwards When moving backward to a previous variable, don't replace it with its default value if it's already been resolved. Also reset any unresolved variables back to their placeholder values. This commit also contains some minor refactoring and comment additions. --- lua/snippets/inserters/extmarks.lua | 176 ++++++++++++++-------------- 1 file changed, 90 insertions(+), 86 deletions(-) diff --git a/lua/snippets/inserters/extmarks.lua b/lua/snippets/inserters/extmarks.lua index bad0910..31dbb0c 100644 --- a/lua/snippets/inserters/extmarks.lua +++ b/lua/snippets/inserters/extmarks.lua @@ -11,29 +11,6 @@ M.post_transform_marker_format = "${|%s}" M.zero_pattern = "$0" M.hl_group = "Visual" -local function update_structure(evaluator, resolved_inputs) - local S = evaluator.evaluate_structure(resolved_inputs) - - local placeholders = evaluator.evaluate_inputs(resolved_inputs) - for i, v in ipairs(evaluator.inputs) do - if not resolved_inputs[i] then - S[v.first_index] = M.marker_with_placeholder_format:format(v.id, placeholders[i]) - end - end - - for i, v in ipairs(evaluator.structure) do - if U.is_variable(v) and v.transform and not v.id then - S[i] = M.post_transform_marker_format:format(i) - end - end - - if evaluator.zero_index then - S[evaluator.zero_index] = M.zero_pattern - end - - return S -end - local function set_extmark(id, line, col, end_line, end_col, hl_group) api.nvim_buf_set_extmark(0, ns, line, col, { id = id, @@ -63,10 +40,29 @@ end local function entrypoint(structure) local evaluator = U.evaluate_snippet(structure) - local S = update_structure(evaluator, {}) + -- Evalute the structure and insert placeholder markers for input variables + local S = evaluator.evaluate_structure({}) + + local placeholders = evaluator.evaluate_inputs({}) + for i, v in ipairs(evaluator.inputs) do + S[v.first_index] = M.marker_with_placeholder_format:format(v.id, placeholders[i]) + end + + -- Insert markers for anonymouse transformations + for i, v in ipairs(evaluator.structure) do + if U.is_variable(v) and v.transform and not v.id then + S[i] = M.post_transform_marker_format:format(i) + end + end + + -- If the snippet contains a $0, insert a marker for the where the cursor will end up + if evaluator.zero_index then + S[evaluator.zero_index] = M.zero_pattern + end local cursor_mark_id + -- Write the snippet to the buffer and create the extmarks do local lnum, col = unpack(api.nvim_win_get_cursor(0)) @@ -81,12 +77,11 @@ local function entrypoint(structure) for i, v in ipairs(evaluator.structure) do local s = S[i] - if i == evaluator.zero_index then - cursor_mark_id = i - end - if U.is_variable(v) then set_extmark(i, lnum - 1, col, lnum - 1, col + #s) + if i == evaluator.zero_index then + cursor_mark_id = i + end end local tail = s:gsub("[^\n]*\n", function() @@ -104,80 +99,89 @@ local function entrypoint(structure) end local current_index = 0 + local current_var local resolved_inputs = {} - local R - R = { - advance = function(offset) - offset = offset or 1 - current_index = math.max(math.min(current_index + offset, #evaluator.inputs + 1), 0) - if current_index == 0 then - R.aborted = true - cleanup() - return true - end + local R = { aborted = false, finished = false } - -- User has moved past the last variable, so apply transformations and move the cursor to the - -- zero point - if current_index > #evaluator.inputs then - for i, v in pairs(evaluator.structure) do - if U.is_variable(v) and v.transform and not v.id then - set_extmark_text(i, S[i]) - end + function R.advance(offset) + offset = offset or 1 + current_index = math.max(math.min(current_index + offset, #evaluator.inputs + 1), 0) + if current_index == 0 then + R.aborted = true + cleanup() + return true + end + + -- User has moved past the last variable, so apply transformations and move the cursor to the + -- zero point + if current_index > #evaluator.inputs then + for i, v in pairs(evaluator.structure) do + if U.is_variable(v) and v.transform and not v.id then + set_extmark_text(i, S[i]) end + end - -- Move cursor to zero point - local cur_row, cur_col, cur_end_row, cur_end_col = get_extmark_pos(cursor_mark_id) - api.nvim_buf_set_text(0, cur_row, cur_col, cur_end_row, cur_end_col, {}) - api.nvim_win_set_cursor(0, { cur_row + 1, cur_col }) + -- Move cursor to zero point + local cur_row, cur_col, cur_end_row, cur_end_col = get_extmark_pos(cursor_mark_id) + api.nvim_buf_set_text(0, cur_row, cur_col, cur_end_row, cur_end_col, {}) + api.nvim_win_set_cursor(0, { cur_row + 1, cur_col }) - cleanup() - R.finished = true - return true - end + R.finished = true + cleanup() + return true + end - local var = evaluator.inputs[current_index] + current_var = evaluator.inputs[current_index] - -- Clear highlights on all extmarks except those for current variable - for i, v in ipairs(evaluator.structure) do - if U.is_variable(v) then - local hl_group = v.order == current_index and M.hl_group or nil - local row, col, end_row, end_col = get_extmark_pos(i) - set_extmark(i, row, col, end_row, end_col, hl_group) + -- Clear highlights on all extmarks except those for current variable + for i, v in ipairs(evaluator.structure) do + if U.is_variable(v) then + local hl_group = v.order == current_index and M.hl_group or nil + local row, col, end_row, end_col = get_extmark_pos(i) + set_extmark(i, row, col, end_row, end_col, hl_group) + end + end + + -- Set unresolved variables to their placeholder values + placeholders = evaluator.evaluate_inputs(resolved_inputs) + for i, v in ipairs(evaluator.structure) do + if U.is_variable(v) and v.is_input and (not resolved_inputs[v.id] or resolved_inputs[v.id] == "") then + local text = placeholders[v.id] + if v.id ~= current_var.id then + text = M.marker_with_placeholder_format:format(v.id, text) end + set_extmark_text(i, text) end + end - -- Move the cursor to the next variable and update the placeholder text - set_extmark_text(var.first_index, var.default) - local mark_row, mark_col, _, mark_end_col = get_extmark_pos(var.first_index) - api.nvim_win_set_cursor(0, { mark_row + 1, mark_end_col }) + -- Move the cursor to the current variable + local mark_row, mark_col, _, mark_end_col = get_extmark_pos(current_var.first_index) + api.nvim_win_set_cursor(0, { mark_row + 1, mark_end_col }) - vim.register_keystroke_callback( - vim.schedule_wrap(function() - if R.finished or R.aborted then - return - end + vim.register_keystroke_callback( + vim.schedule_wrap(function() + if R.finished or R.aborted then + return + end - mark_row, mark_col, _, mark_end_col = get_extmark_pos(var.first_index) - local line = api.nvim_buf_get_lines(0, mark_row, mark_row + 1, true)[1] - local mark_text = line:sub(mark_col + 1, mark_end_col) + mark_row, mark_col, _, mark_end_col = get_extmark_pos(current_var.first_index) + local line = api.nvim_buf_get_lines(0, mark_row, mark_row + 1, true)[1] + local mark_text = line:sub(mark_col + 1, mark_end_col) - resolved_inputs[var.id] = mark_text - S = evaluator.evaluate_structure(resolved_inputs) + resolved_inputs[current_var.id] = mark_text + S = evaluator.evaluate_structure(resolved_inputs) - for i = var.first_index + 1, #evaluator.structure do - local v = evaluator.structure[i] - if U.is_variable(v) and v.id == var.id then - set_extmark_text(i, S[i]) - end + for i = current_var.first_index + 1, #evaluator.structure do + local v = evaluator.structure[i] + if U.is_variable(v) and v.id == current_var.id then + set_extmark_text(i, S[i]) end - end), - ns - ) - end, - finished = false, - aborted = false, - } + end + end), + ns + ) + end return R end From 795c2e4cb33591d9d76b8ad49d90ff82a390944e Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Mon, 26 Jul 2021 09:31:22 -0600 Subject: [PATCH 4/9] extmarks: set resolved input to default value --- lua/snippets/inserters/extmarks.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lua/snippets/inserters/extmarks.lua b/lua/snippets/inserters/extmarks.lua index 31dbb0c..f82e78f 100644 --- a/lua/snippets/inserters/extmarks.lua +++ b/lua/snippets/inserters/extmarks.lua @@ -159,6 +159,9 @@ local function entrypoint(structure) local mark_row, mark_col, _, mark_end_col = get_extmark_pos(current_var.first_index) api.nvim_win_set_cursor(0, { mark_row + 1, mark_end_col }) + -- Set resolved input to default value if one exists + resolved_inputs[current_var.id] = current_var.default + vim.register_keystroke_callback( vim.schedule_wrap(function() if R.finished or R.aborted then From 9bea26255119939a8495a584b292cfa6274558c4 Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Thu, 12 Aug 2021 08:17:17 -0600 Subject: [PATCH 5/9] extmarks: don't substitute transformations with placeholders I copied this from the text_markers inserter, but I don't think it's actually necessary. The anonymous transformations are expanded in the first called to 'evaluator.evaluate_structure', and since they don't depend on any other input variables we can go ahead and just expand them and insert them right at the beginning. --- lua/snippets/inserters/extmarks.lua | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lua/snippets/inserters/extmarks.lua b/lua/snippets/inserters/extmarks.lua index f82e78f..adfa3aa 100644 --- a/lua/snippets/inserters/extmarks.lua +++ b/lua/snippets/inserters/extmarks.lua @@ -7,7 +7,6 @@ local M = {} -- These are user-configurable M.marker_with_placeholder_format = "${%d:%s}" -M.post_transform_marker_format = "${|%s}" M.zero_pattern = "$0" M.hl_group = "Visual" @@ -48,13 +47,6 @@ local function entrypoint(structure) S[v.first_index] = M.marker_with_placeholder_format:format(v.id, placeholders[i]) end - -- Insert markers for anonymouse transformations - for i, v in ipairs(evaluator.structure) do - if U.is_variable(v) and v.transform and not v.id then - S[i] = M.post_transform_marker_format:format(i) - end - end - -- If the snippet contains a $0, insert a marker for the where the cursor will end up if evaluator.zero_index then S[evaluator.zero_index] = M.zero_pattern From c7e46d2648cd0518e2a5c22c1620292ba1ca8e50 Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Thu, 12 Aug 2021 09:39:11 -0600 Subject: [PATCH 6/9] extmarks: be explicit about buffer and window number --- lua/snippets/inserters/extmarks.lua | 59 ++++++++++++++++------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/lua/snippets/inserters/extmarks.lua b/lua/snippets/inserters/extmarks.lua index adfa3aa..fdbce4b 100644 --- a/lua/snippets/inserters/extmarks.lua +++ b/lua/snippets/inserters/extmarks.lua @@ -10,8 +10,8 @@ M.marker_with_placeholder_format = "${%d:%s}" M.zero_pattern = "$0" M.hl_group = "Visual" -local function set_extmark(id, line, col, end_line, end_col, hl_group) - api.nvim_buf_set_extmark(0, ns, line, col, { +local function set_extmark(bufnr, id, line, col, end_line, end_col, hl_group) + api.nvim_buf_set_extmark(bufnr, ns, line, col, { id = id, end_line = end_line, end_col = end_col, @@ -21,22 +21,25 @@ local function set_extmark(id, line, col, end_line, end_col, hl_group) }) end -local function get_extmark_pos(id) - local row, col, details = unpack(api.nvim_buf_get_extmark_by_id(0, ns, id, { details = true })) +local function get_extmark_pos(bufnr, id) + local row, col, details = unpack(api.nvim_buf_get_extmark_by_id(bufnr, ns, id, { details = true })) return row, col, details and details.end_row or row, details and details.end_col or col end -local function set_extmark_text(id, text) - local row, col, end_row, end_col = get_extmark_pos(id) - api.nvim_buf_set_text(0, row, col, end_row, end_col, vim.split(text, "\n")) +local function set_extmark_text(bufnr, id, text) + local row, col, end_row, end_col = get_extmark_pos(bufnr, id) + api.nvim_buf_set_text(bufnr, row, col, end_row, end_col, vim.split(text, "\n")) end -local function cleanup() - api.nvim_buf_clear_namespace(0, ns, 0, -1) +local function cleanup(bufnr) + api.nvim_buf_clear_namespace(bufnr, ns, 0, -1) vim.register_keystroke_callback(nil, ns) end local function entrypoint(structure) + local bufnr = vim.api.nvim_get_current_buf() + local win = vim.api.nvim_get_current_win() + local evaluator = U.evaluate_snippet(structure) -- Evalute the structure and insert placeholder markers for input variables @@ -56,7 +59,7 @@ local function entrypoint(structure) -- Write the snippet to the buffer and create the extmarks do - local lnum, col = unpack(api.nvim_win_get_cursor(0)) + local lnum, col = unpack(api.nvim_win_get_cursor(win)) local current_line = api.nvim_get_current_line() local prefix = current_line:sub(1, col) @@ -65,12 +68,12 @@ local function entrypoint(structure) local lines = vim.split(table.concat(S), "\n") lines[1] = prefix .. lines[1] lines[#lines] = lines[#lines] .. suffix - api.nvim_buf_set_lines(0, lnum - 1, lnum, true, lines) + api.nvim_buf_set_lines(bufnr, lnum - 1, lnum, true, lines) for i, v in ipairs(evaluator.structure) do local s = S[i] if U.is_variable(v) then - set_extmark(i, lnum - 1, col, lnum - 1, col + #s) + set_extmark(bufnr, i, lnum - 1, col, lnum - 1, col + #s) if i == evaluator.zero_index then cursor_mark_id = i end @@ -86,7 +89,7 @@ local function entrypoint(structure) end if not cursor_mark_id then - cursor_mark_id = api.nvim_buf_set_extmark(0, ns, lnum - 1, col, {}) + cursor_mark_id = api.nvim_buf_set_extmark(bufnr, ns, lnum - 1, col, {}) end end @@ -101,7 +104,7 @@ local function entrypoint(structure) current_index = math.max(math.min(current_index + offset, #evaluator.inputs + 1), 0) if current_index == 0 then R.aborted = true - cleanup() + cleanup(bufnr) return true end @@ -110,17 +113,17 @@ local function entrypoint(structure) if current_index > #evaluator.inputs then for i, v in pairs(evaluator.structure) do if U.is_variable(v) and v.transform and not v.id then - set_extmark_text(i, S[i]) + set_extmark_text(bufnr, i, S[i]) end end -- Move cursor to zero point - local cur_row, cur_col, cur_end_row, cur_end_col = get_extmark_pos(cursor_mark_id) - api.nvim_buf_set_text(0, cur_row, cur_col, cur_end_row, cur_end_col, {}) - api.nvim_win_set_cursor(0, { cur_row + 1, cur_col }) + local cur_row, cur_col, cur_end_row, cur_end_col = get_extmark_pos(bufnr, cursor_mark_id) + api.nvim_buf_set_text(bufnr, cur_row, cur_col, cur_end_row, cur_end_col, {}) + api.nvim_win_set_cursor(win, { cur_row + 1, cur_col }) R.finished = true - cleanup() + cleanup(bufnr) return true end @@ -130,8 +133,8 @@ local function entrypoint(structure) for i, v in ipairs(evaluator.structure) do if U.is_variable(v) then local hl_group = v.order == current_index and M.hl_group or nil - local row, col, end_row, end_col = get_extmark_pos(i) - set_extmark(i, row, col, end_row, end_col, hl_group) + local row, col, end_row, end_col = get_extmark_pos(bufnr, i) + set_extmark(bufnr, i, row, col, end_row, end_col, hl_group) end end @@ -143,13 +146,15 @@ local function entrypoint(structure) if v.id ~= current_var.id then text = M.marker_with_placeholder_format:format(v.id, text) end - set_extmark_text(i, text) + set_extmark_text(bufnr, i, text) end end -- Move the cursor to the current variable - local mark_row, mark_col, _, mark_end_col = get_extmark_pos(current_var.first_index) - api.nvim_win_set_cursor(0, { mark_row + 1, mark_end_col }) + do + local mark_row, _, _, mark_end_col = get_extmark_pos(bufnr, current_var.first_index) + api.nvim_win_set_cursor(win, { mark_row + 1, mark_end_col }) + end -- Set resolved input to default value if one exists resolved_inputs[current_var.id] = current_var.default @@ -160,8 +165,8 @@ local function entrypoint(structure) return end - mark_row, mark_col, _, mark_end_col = get_extmark_pos(current_var.first_index) - local line = api.nvim_buf_get_lines(0, mark_row, mark_row + 1, true)[1] + local mark_row, mark_col, _, mark_end_col = get_extmark_pos(bufnr, current_var.first_index) + local line = api.nvim_buf_get_lines(bufnr, mark_row, mark_row + 1, true)[1] local mark_text = line:sub(mark_col + 1, mark_end_col) resolved_inputs[current_var.id] = mark_text @@ -170,7 +175,7 @@ local function entrypoint(structure) for i = current_var.first_index + 1, #evaluator.structure do local v = evaluator.structure[i] if U.is_variable(v) and v.id == current_var.id then - set_extmark_text(i, S[i]) + set_extmark_text(bufnr, i, S[i]) end end end), From 7e180305ecb2e2f45f380cf1924bd1ae8277ca19 Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Thu, 12 Aug 2021 13:51:05 -0600 Subject: [PATCH 7/9] extmarks: update anonymous transformations in real time --- lua/snippets/inserters/extmarks.lua | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/lua/snippets/inserters/extmarks.lua b/lua/snippets/inserters/extmarks.lua index fdbce4b..308f881 100644 --- a/lua/snippets/inserters/extmarks.lua +++ b/lua/snippets/inserters/extmarks.lua @@ -111,12 +111,6 @@ local function entrypoint(structure) -- User has moved past the last variable, so apply transformations and move the cursor to the -- zero point if current_index > #evaluator.inputs then - for i, v in pairs(evaluator.structure) do - if U.is_variable(v) and v.transform and not v.id then - set_extmark_text(bufnr, i, S[i]) - end - end - -- Move cursor to zero point local cur_row, cur_col, cur_end_row, cur_end_col = get_extmark_pos(bufnr, cursor_mark_id) api.nvim_buf_set_text(bufnr, cur_row, cur_col, cur_end_row, cur_end_col, {}) @@ -150,8 +144,8 @@ local function entrypoint(structure) end end - -- Move the cursor to the current variable do + -- Move the cursor to the current variable local mark_row, _, _, mark_end_col = get_extmark_pos(bufnr, current_var.first_index) api.nvim_win_set_cursor(win, { mark_row + 1, mark_end_col }) end @@ -172,10 +166,13 @@ local function entrypoint(structure) resolved_inputs[current_var.id] = mark_text S = evaluator.evaluate_structure(resolved_inputs) - for i = current_var.first_index + 1, #evaluator.structure do - local v = evaluator.structure[i] - if U.is_variable(v) and v.id == current_var.id then - set_extmark_text(bufnr, i, S[i]) + for i, v in ipairs(evaluator.structure) do + if U.is_variable(v) then + -- Update variables related to the current variable as well as + -- anonymous transforms + if v.order == current_index or v.transform and not v.id then + set_extmark_text(bufnr, i, S[i]) + end end end end), From 7da8ee8a6246a25acfd4ecc03dcdedde023edebb Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Mon, 13 Sep 2021 12:41:44 -0600 Subject: [PATCH 8/9] Check for renamed 'on_key' function --- lua/snippets/inserters/extmarks.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lua/snippets/inserters/extmarks.lua b/lua/snippets/inserters/extmarks.lua index 308f881..df2b464 100644 --- a/lua/snippets/inserters/extmarks.lua +++ b/lua/snippets/inserters/extmarks.lua @@ -33,7 +33,8 @@ end local function cleanup(bufnr) api.nvim_buf_clear_namespace(bufnr, ns, 0, -1) - vim.register_keystroke_callback(nil, ns) + local F = vim.F.if_nil(vim.on_key, vim.register_keystroke_callback) + F(nil, ns) end local function entrypoint(structure) @@ -153,7 +154,8 @@ local function entrypoint(structure) -- Set resolved input to default value if one exists resolved_inputs[current_var.id] = current_var.default - vim.register_keystroke_callback( + local F = vim.F.if_nil(vim.on_key, vim.register_keystroke_callback) + F( vim.schedule_wrap(function() if R.finished or R.aborted then return From dbf5dd6a68b4a0db53632c77a9aaf07378996ae5 Mon Sep 17 00:00:00 2001 From: Gregory Anders Date: Wed, 10 Nov 2021 16:35:10 -0700 Subject: [PATCH 9/9] Replace placeholder values in extmarks inserter --- lua/snippets/inserters/extmarks.lua | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/lua/snippets/inserters/extmarks.lua b/lua/snippets/inserters/extmarks.lua index df2b464..dcf30c1 100644 --- a/lua/snippets/inserters/extmarks.lua +++ b/lua/snippets/inserters/extmarks.lua @@ -145,23 +145,33 @@ local function entrypoint(structure) end end - do - -- Move the cursor to the current variable - local mark_row, _, _, mark_end_col = get_extmark_pos(bufnr, current_var.first_index) - api.nvim_win_set_cursor(win, { mark_row + 1, mark_end_col }) - end + -- Move the cursor to the current variable + local mark_row, mark_col, _, mark_end_col = get_extmark_pos(bufnr, current_var.first_index) + api.nvim_win_set_cursor(win, { mark_row + 1, mark_end_col }) -- Set resolved input to default value if one exists resolved_inputs[current_var.id] = current_var.default + -- When a variable is highlighted, the first key pressed replaces the current value + -- with the user's input + local user_pressed_key = false + local F = vim.F.if_nil(vim.on_key, vim.register_keystroke_callback) F( - vim.schedule_wrap(function() + vim.schedule_wrap(function(key) if R.finished or R.aborted then return end - local mark_row, mark_col, _, mark_end_col = get_extmark_pos(bufnr, current_var.first_index) + if not user_pressed_key and key:match("^[%w%p]$") then + print(key) + set_extmark_text(bufnr, current_var.first_index, key) + user_pressed_key = true + api.nvim_win_set_cursor(win, { mark_row + 1, mark_col + #key }) + return + end + + mark_row, mark_col, _, mark_end_col = get_extmark_pos(bufnr, current_var.first_index) local line = api.nvim_buf_get_lines(bufnr, mark_row, mark_row + 1, true)[1] local mark_text = line:sub(mark_col + 1, mark_end_col)