aboutsummaryrefslogtreecommitdiff
path: root/lua/simple-denote
diff options
context:
space:
mode:
Diffstat (limited to 'lua/simple-denote')
-rw-r--r--lua/simple-denote/api.lua57
-rw-r--r--lua/simple-denote/cmd.lua26
-rw-r--r--lua/simple-denote/config.lua12
-rw-r--r--lua/simple-denote/init.lua15
-rw-r--r--lua/simple-denote/internal.lua106
-rw-r--r--lua/simple-denote/util.lua32
6 files changed, 248 insertions, 0 deletions
diff --git a/lua/simple-denote/api.lua b/lua/simple-denote/api.lua
new file mode 100644
index 0000000..f835b7b
--- /dev/null
+++ b/lua/simple-denote/api.lua
@@ -0,0 +1,57 @@
+local M = {}
+
+local internal = require("simple-denote.internal")
+local util = require("simple-denote.util")
+
+---@param options table
+---@param name string|nil
+---@param tags table|nil
+function M.note(options, name, tags)
+ if not name then
+ vim.ui.input({ prompt = "Note title: " }, function(input)
+ name = input
+ end)
+ end
+ if not tags then
+ vim.ui.input({ prompt = "Tags: " }, function(input)
+ if input ~= "" and input then
+ tags = util.splitspace(input)
+ end
+ end)
+ end
+ internal.note(options, name, tags)
+end
+
+---@param options table
+---@param filename string|nil
+---@param new_title string|nil
+function M.retitle(options, filename, new_title)
+ if not filename then
+ filename = vim.fn.expand("%")
+ end
+ if not new_title then
+ vim.ui.input({ prompt = "New title: " }, function(input)
+ new_title = input
+ end)
+ end
+ internal.retitle(options, filename, new_title)
+end
+
+---@param options table
+---@param filename string|nil
+---@param new_tags table|nil
+function M.retag(options, filename, new_tags)
+ if not filename then
+ filename = vim.fn.expand("%")
+ end
+ if not new_tags then
+ vim.ui.input({ prompt = "New tags: " }, function(input)
+ if input ~= "" and input then
+ new_tags = util.splitspace(input)
+ end
+ end)
+ end
+ internal.retag(options, filename, new_tags)
+end
+
+return M
diff --git a/lua/simple-denote/cmd.lua b/lua/simple-denote/cmd.lua
new file mode 100644
index 0000000..177db88
--- /dev/null
+++ b/lua/simple-denote/cmd.lua
@@ -0,0 +1,26 @@
+local M = {
+ commands = { "note", "retitle", "retag" },
+}
+
+local api = require("simple-denote.api")
+
+function M.load_cmd(options)
+ vim.api.nvim_create_user_command("Denote", function(opts)
+ if opts.fargs[1] == "note" then
+ api.note(options)
+ elseif opts.fargs[1] == "retitle" then
+ api.retitle(options)
+ elseif opts.fargs[1] == "retag" then
+ api.retag(options)
+ else
+ error("Unsupported operation " .. opts.fargs[1])
+ end
+ end, {
+ nargs = 1,
+ complete = function()
+ return M.commands
+ end,
+ })
+end
+
+return M
diff --git a/lua/simple-denote/config.lua b/lua/simple-denote/config.lua
new file mode 100644
index 0000000..e41c0a9
--- /dev/null
+++ b/lua/simple-denote/config.lua
@@ -0,0 +1,12 @@
+local M = {}
+
+M.defaults = {
+ ext = "md",
+ dir = "~/notes/",
+ add_heading = true,
+ retitle_heading = true,
+}
+
+M.options = M.defaults
+
+return M
diff --git a/lua/simple-denote/init.lua b/lua/simple-denote/init.lua
new file mode 100644
index 0000000..0d8654d
--- /dev/null
+++ b/lua/simple-denote/init.lua
@@ -0,0 +1,15 @@
+local M = {}
+
+local cmd = require("simple-denote.cmd")
+local config = require("simple-denote.config")
+
+---@param options? table user configuration
+function M.setup(options)
+ config.options = vim.tbl_deep_extend("force", config.defaults, options or {})
+ if config.options.dir:sub(-1) ~= "/" then
+ config.options.dir = config.options.dir .. "/"
+ end
+ cmd.load_cmd(config.options)
+end
+
+return M
diff --git a/lua/simple-denote/internal.lua b/lua/simple-denote/internal.lua
new file mode 100644
index 0000000..d3c3987
--- /dev/null
+++ b/lua/simple-denote/internal.lua
@@ -0,0 +1,106 @@
+local M = {}
+
+---@param options table
+---@param name string
+---@param tags table|nil
+--- Opens your note
+function M.note(options, name, tags)
+ local path = options.dir
+ local file = ""
+ local date = os.date("%Y%m%dT%H%M%S")
+ local tags_str = ""
+ local og_name = name
+ name = name:gsub("^%s*(.-)%s*$", "%1")
+ name = name:gsub("[^%w%s]","")
+ name = name:gsub("%s","-")
+ if tags then
+ for i, tag in pairs(tags) do
+ tag = tag:gsub("[^%w%s]","")
+ tags_str = tags_str .. tag
+ if i < #tags then
+ tags_str = tags_str .. "_"
+ end
+ end
+ end
+ file = date .. "--" .. name:lower()
+ if tags_str ~= "" then
+ file = file .. "__" .. tags_str:lower()
+ end
+ path = path .. file .. "." .. options.ext
+ vim.cmd("e " .. path)
+ if options.add_heading then
+ prefix = ""
+ if options.ext == "md" then
+ prefix = "# "
+ elseif options.ext == "org" or options.ext == "norg" then
+ prefix = "* "
+ end
+ vim.api.nvim_buf_set_lines(0, 0, 1, false, {prefix .. og_name})
+ vim.cmd("norm! o")
+ end
+ vim.cmd("startinsert")
+end
+
+---@param options table
+---@param filename string
+---@param new_title string
+--- Retitles the filename and changes the first heading of the note
+function M.retitle(options, filename, new_title)
+ local new_filename = filename:match("^(.*%d%d%d%d%d%d%d%dT%d%d%d%d%d%d).*")
+ local tags = filename:match(".*(__.*)%..*")
+ if new_filename == nil then
+ error("This file doesn't look like it has a Denote-style name")
+ end
+ new_title = new_title:gsub("^%s*(.-)%s*$", "%1") -- Trim whitespace
+
+ -- Replace first line with new heading
+ if options.retitle_heading and new_title ~= "" then
+ local first_char = vim.api.nvim_buf_get_lines(0, 0, 1, false)[1]:sub(1, 1)
+ if (first_char == "#" and options.ext == "md") or
+ (first_char == "*" and (options.ext == "org" or options.ext == "norg")) then
+ vim.api.nvim_buf_set_lines(0, 0, 1, false, {first_char .. " " .. new_title})
+ end
+ end
+ new_title = new_title:lower()
+ new_title = new_title:gsub("[^%w%s]","")
+ new_title = new_title:gsub("%s","-")
+ if new_title ~= "" then
+ new_title = "--" .. new_title
+ end
+ new_filename = new_filename .. new_title .. (tags or "") .. "." .. options.ext
+ if filename ~= new_filename then
+ vim.cmd('saveas ' .. new_filename)
+ vim.cmd('silent !rm ' .. filename)
+ end
+end
+
+---@param options table
+---@param filename string
+---@param new_tags table
+---Replaces the tags in filename with the tags in new_tags
+function M.retag(options, filename, new_tags)
+ local tags_str = ""
+ local new_filename = filename:match("^(.*)__.*$")
+ if new_filename == nil then
+ new_filename = filename:match("^(.*)%..*$")
+ end
+ if new_tags then
+ for i, tag in pairs(new_tags) do
+ tag = tag:gsub("[^%w%s]","")
+ tags_str = tags_str .. tag
+ if i < #new_tags then
+ tags_str = tags_str .. "_"
+ end
+ end
+ end
+ if tags_str ~= "" then
+ new_filename = new_filename .. "__" .. tags_str:lower()
+ end
+ new_filename = new_filename .. "." .. options.ext
+ if filename ~= new_filename then
+ vim.cmd('saveas ' .. new_filename)
+ vim.cmd('silent !rm ' .. filename)
+ end
+end
+
+return M
diff --git a/lua/simple-denote/util.lua b/lua/simple-denote/util.lua
new file mode 100644
index 0000000..643e2e7
--- /dev/null
+++ b/lua/simple-denote/util.lua
@@ -0,0 +1,32 @@
+local M = {}
+
+
+function M.splitspace(str)
+ local chunks = {}
+ for substring in str:gmatch("%S+") do
+ table.insert(chunks, #chunks, substring)
+ end
+ return chunks
+end
+
+function M.splitstring(str, delim)
+ local items = {}
+ local fulldelim = nil
+ if delim == "." or delim == "-" then
+ fulldelim = "%" .. delim
+ else
+ fulldelim = delim
+ end
+ str = str .. delim
+ for w in str:gmatch("(.-)" .. fulldelim) do
+ items[#items + 1] = w
+ end
+ return items
+end
+
+--- Escape a string to use as a lua pattern
+function M.escape(str)
+ return str:gsub("(%W)", "%%%1")
+end
+
+return M