diff --git a/CHANGELOG.md b/CHANGELOG.md index c2acbed3..5d30cd67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added function `obsidian.api.set_checkbox` + - api function `set_checkbox [state]` takes an optional state param, if no param is + passed then it takes the next char input as the state and validates that + against `Obsidian.opts.checkbox.order` - Allow custom directory and ID logic for templates - When filling out a template with user-provided substitution functions, pass a "context" object to each invocation so that users can respond accordingly. - Added `obsidian.InsertTemplateContext` and `obsidian.CloneTemplateContext` as these new "context" objects. diff --git a/lua/obsidian/api.lua b/lua/obsidian/api.lua index 10bd4b51..134f0baa 100644 --- a/lua/obsidian/api.lua +++ b/lua/obsidian/api.lua @@ -722,4 +722,60 @@ M.smart_action = function() return legacy and "ObsidianToggleCheckbox" or "Obsidian toggle_checkbox" end +---Set the checkbox on the current line to a specific state. +--- +---@param state string|nil Optional string of state to set the checkbox to (e.g., " ", "x"). +M.set_checkbox = function(state) + if not util.in_node { "list", "paragraph" } or util.in_node "block_quote" then + return + end + + if state == nil then + local ok, key = pcall(vim.fn.getchar) + if not ok then + log.err "set_checkbox: unable to get state input" + return + end + state = string.char(key + 0) + end + + local found = false + for _, value in ipairs(Obsidian.opts.checkbox.order) do + if value == state then + found = true + end + end + + if not found then + log.err( + "state passed '" + .. state + .. "' is not part of the available states: " + .. vim.inspect(Obsidian.opts.checkbox.order) + ) + return + end + + local cur_line = vim.api.nvim_get_current_line() + + if util.is_checkbox(cur_line) then + if string.match(cur_line, "^.* %[.%].*") then + cur_line = string.gsub(cur_line, "%[.%]", "[" .. state .. "]", 1) + end + elseif Obsidian.opts.checkbox.create_new then + local unordered_list_pattern = "^(%s*)[-*+] (.*)" + if string.match(cur_line, unordered_list_pattern) then + cur_line = string.gsub(cur_line, unordered_list_pattern, "%1- [" .. state .. "] %2") + else + cur_line = string.gsub(cur_line, "^(%s*)", "%1- [" .. state .. "] ") + end + else + goto out + end + + local line_num = vim.fn.getpos(".")[2] + vim.api.nvim_buf_set_lines(0, line_num - 1, line_num, true, { cur_line }) + ::out:: +end + return M diff --git a/lua/obsidian/commands/init.lua b/lua/obsidian/commands/init.lua index 9095e887..ef0ed468 100644 --- a/lua/obsidian/commands/init.lua +++ b/lua/obsidian/commands/init.lua @@ -260,6 +260,8 @@ M.register("follow_link", { nargs = "?", note_action = true }) M.register("toggle_checkbox", { nargs = 0, range = true, note_action = true }) +M.register("set_checkbox", { nargs = "?", range = true, note_action = true }) + M.register("rename", { nargs = "?", note_action = true }) M.register("paste_img", { nargs = "?", note_action = true })