about summary refs log tree commit diff
diff options
context:
space:
mode:
authoriurii plugatarov <[email protected]>2024-08-02 23:01:35 +0200
committeriurii plugatarov <[email protected]>2024-08-02 23:01:35 +0200
commitf4a1319352d466308cd85eb1263aef9fd2c54293 (patch)
tree335eac92b9f9f47cec3d9bf60d7699d9fa8d66d7
downloadsketchbook.nvim-f4a1319352d466308cd85eb1263aef9fd2c54293.tar.gz
init
-rw-r--r--README.md58
-rw-r--r--config.lua88
-rw-r--r--create_note.lua20
-rw-r--r--git_sync.lua36
-rw-r--r--init.lua15
-rw-r--r--quick_note.lua91
-rw-r--r--search_notes.lua10
-rw-r--r--select_template.lua71
-rw-r--r--update_index.lua22
9 files changed, 411 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..f67702d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,58 @@
+# sketchbook.nvim - simple notetaking
+
+Motivationg behind this thing, that I tried lots of notetaking tools but nothing really clicked.
+I didn't want to leave nvim and it's not really convenient to manage ~/notes directory. 
+
+
+## Warn
+
+This was quick and dirty implementation, so not everything will perfectly because currently its in "works on my machine" state.
+
+
+## Features
+
+- **Quick Note Creation**: Quickly create and manage notes.
+- **Template Selection**: Choose from predefined templates for your notes.
+- **Note Searching**: Search through your notes easily.
+- **Git Integration**: Commit and push your notes to a Git repository.
+- **Floating Windows**: Use floating windows for quick notes.
+
+## Installation
+
+You can install Sketchbook using [lazy.nvim](https://github.com/folke/lazy.nvim).
+
+### Using [lazy.nvim](https://github.com/folke/lazy.nvim)
+
+Add the following to your `lazy.nvim` configuration:
+
+```lua
+require('lazy').setup({
+    {
+        'makefunstuff/sketchbook.nvim',
+        config = function()
+            require('sketchbook').setup({
+                notes_directory = "~/my_notes/",
+                templates_directory = "~/my_notes/templates/",
+                keymaps = {
+                    create_note = "<leader>nc",
+                    update_index = "<leader>ni",
+                    search_notes = "<leader>ns",
+                    select_template = "<leader>nt",
+                    create_quick_note = "<leader>nq",
+                    toggle_quick_note = "<leader>qc", -- Keymap for toggling quick note window
+                    open_entire_quick_note = "<leader>nqe",
+                    commit_notes = "<leader>ngc",  -- Keymap for committing notes
+                    push_notes = "<leader>ngp",    -- Keymap for pushing notes
+                }
+            })
+        end
+    }
+})
+
+```
+
+## TODO:
+
+- [ ] improve git Integration
+- [ ] fix telescope issues with indexing
+- [ ] add auto indexing
diff --git a/config.lua b/config.lua
new file mode 100644
index 0000000..999245d
--- /dev/null
+++ b/config.lua
@@ -0,0 +1,88 @@
+local M = {}
+
+-- Default configuration
+M.defaults = {
+  notes_directory = "~/notes",
+  templates_directory = "~/notes/templates/",
+  keymaps = {
+    create_note = "<leader>tnn",
+    update_index = "<leader>tui",
+    search_notes = "<leader>tns",
+    select_template = "<leader>ttn",
+    toggle_quick_note = "<leader>qc",
+    create_quick_note = "<leader>nq",
+    open_entire_quick_note = "<leader>qo",
+    commit_notes = "<leader>tgc",
+    push_notes = "<leader>tgp", -- New keymap for pushing notes
+  },
+}
+
+M.config = {}
+
+function M.setup(user_config)
+  M.config = vim.tbl_deep_extend("force", {}, M.defaults, user_config or {})
+  vim.g.notes_directory = M.config.notes_directory
+  vim.g.notes_templates_dir = M.config.templates_directory
+  M.set_keymaps()
+end
+
+function M.set_keymaps()
+  local keymaps = M.config.keymaps
+
+  vim.api.nvim_set_keymap(
+    "n",
+    keymaps.create_note,
+    ':lua require("sketchbook.create_note").create_new_note()<CR>',
+    { noremap = true, silent = true, desc = "Create a new note" }
+  )
+  vim.api.nvim_set_keymap(
+    "n",
+    keymaps.update_index,
+    ':lua require("sketchbook.update_index").update_index()<CR>',
+    { noremap = true, silent = true, desc = "Update notes index" }
+  )
+  vim.api.nvim_set_keymap(
+    "n",
+    keymaps.search_notes,
+    ':lua require("sketchbook.search_notes").search_notes()<CR>',
+    { noremap = true, silent = true, desc = "Search notes" }
+  )
+  vim.api.nvim_set_keymap(
+    "n",
+    keymaps.select_template,
+    ':lua require("sketchbook.select_template").select_template()<CR>',
+    { noremap = true, silent = true, desc = "Select a note template" }
+  )
+  vim.api.nvim_set_keymap(
+    "n",
+    keymaps.create_quick_note,
+    ':lua require("sketchbook.quick_note").create_quick_note_window()<CR>',
+    { noremap = true, silent = true, desc = "Create a quick note buffer" }
+  )
+  vim.api.nvim_set_keymap(
+    "n",
+    keymaps.toggle_quick_note,
+    ':lua require("sketchbook.quick_note").toggle_quick_note_window()<CR>',
+    { noremap = true, silent = true, desc = "Toggle quick note window" }
+  )
+  vim.api.nvim_set_keymap(
+    "n",
+    keymaps.open_entire_quick_note,
+    ':lua require("sketchbook.quick_note").open_entire_quick_note()<CR>',
+    { noremap = true, silent = true, desc = "Open entire quick note" }
+  )
+  vim.api.nvim_set_keymap(
+    "n",
+    keymaps.commit_notes,
+    ':lua require("sketchbook.git_sync").commit_notes()<CR>',
+    { noremap = true, silent = true, desc = "Commit notes to Git" }
+  )
+  vim.api.nvim_set_keymap(
+    "n",
+    keymaps.push_notes,
+    ':lua require("sketchbook.git_sync").push_notes()<CR>',
+    { noremap = true, silent = true, desc = "Push notes to remote Git repository" }
+  )
+end
+
+return M
diff --git a/create_note.lua b/create_note.lua
new file mode 100644
index 0000000..d85e267
--- /dev/null
+++ b/create_note.lua
@@ -0,0 +1,20 @@
+local M = {}
+
+function M.create_new_note()
+  local notes_dir = vim.g.notes_directory or "~/notes/"
+  local filename = os.date "%Y-%m-%d_%H-%M-%S" .. ".md"
+  local filepath = vim.fn.expand(notes_dir) .. filename
+  local title = "Title " .. os.date "%Y-%m-%d %H:%M:%S"
+  local template = {
+    "# " .. title,
+    "",
+  }
+  local file = io.open(filepath, "w")
+  for _, line in ipairs(template) do
+    file:write(line .. "\n")
+  end
+  file:close()
+  vim.cmd("edit " .. filepath)
+end
+
+return M
diff --git a/git_sync.lua b/git_sync.lua
new file mode 100644
index 0000000..d19f024
--- /dev/null
+++ b/git_sync.lua
@@ -0,0 +1,36 @@
+local M = {}
+
+function M.is_git_repo(path)
+  local git_dir = vim.fn.systemlist("git -C " .. path .. " rev-parse --is-inside-work-tree")[1]
+  return git_dir == "true"
+end
+
+function M.commit_notes()
+  local notes_dir = vim.g.notes_directory or "~/notes/"
+  notes_dir = vim.fn.expand(notes_dir)
+
+  if not M.is_git_repo(notes_dir) then
+    vim.notify("Note folder is not a Git repository.", vim.log.levels.WARN)
+    return
+  end
+
+  local commit_message = "Update notes: " .. os.date "%Y-%m-%d %H:%M:%S"
+  vim.fn.system("git -C " .. notes_dir .. " add .")
+  vim.fn.system("git -C " .. notes_dir .. " commit -m '" .. commit_message .. "'")
+  vim.notify("Notes committed to Git repository.", vim.log.levels.INFO)
+end
+
+function M.push_notes()
+  local notes_dir = vim.g.notes_directory or "~/notes/"
+  notes_dir = vim.fn.expand(notes_dir)
+
+  if not M.is_git_repo(notes_dir) then
+    vim.notify("Note folder is not a Git repository.", vim.log.levels.WARN)
+    return
+  end
+
+  vim.fn.system("git -C " .. notes_dir .. " push")
+  vim.notify("Notes pushed to remote repository.", vim.log.levels.INFO)
+end
+
+return M
diff --git a/init.lua b/init.lua
new file mode 100644
index 0000000..0afcfe4
--- /dev/null
+++ b/init.lua
@@ -0,0 +1,15 @@
+local config = require "sketchbook.config"
+local create_note = require "sketchbook.create_note"
+local update_index = require "sketchbook.update_index"
+local search_notes = require "sketchbook.search_notes"
+local select_template = require "sketchbook.select_template"
+local quick_note = require "sketchbook.quick_note"
+local git_support = require "sketchbook.git_sync"
+
+local M = {}
+
+function M.setup(user_config)
+  config.setup(user_config)
+end
+
+return M
diff --git a/quick_note.lua b/quick_note.lua
new file mode 100644
index 0000000..1196faf
--- /dev/null
+++ b/quick_note.lua
@@ -0,0 +1,91 @@
+local M = {}
+local floating_win = nil
+
+local function get_win_config()
+  local width = math.floor(vim.o.columns * 0.8)
+  local height = math.floor(vim.o.lines * 0.8)
+  local row = math.floor((vim.o.lines - height) / 2)
+  local col = math.floor((vim.o.columns - width) / 2)
+  return {
+    relative = "editor",
+    width = width,
+    height = height,
+    row = row,
+    col = col,
+    style = "minimal",
+    border = "rounded",
+  }
+end
+
+function M.create_quick_note_window()
+  if floating_win and vim.api.nvim_win_is_valid(floating_win) then
+    vim.api.nvim_set_current_win(floating_win)
+    return
+  end
+
+  local buf = vim.api.nvim_create_buf(false, true)
+  floating_win = vim.api.nvim_open_win(buf, true, get_win_config())
+
+  vim.api.nvim_buf_set_option(buf, "buftype", "acwrite")
+  vim.api.nvim_buf_set_name(buf, "QuickNote")
+end
+
+function M.toggle_quick_note_window()
+  if floating_win and vim.api.nvim_win_is_valid(floating_win) then
+    M.close_quick_note_window()
+  else
+    M.create_quick_note_window()
+  end
+end
+
+function M.close_quick_note_window()
+  if floating_win and vim.api.nvim_win_is_valid(floating_win) then
+    local buf = vim.api.nvim_win_get_buf(floating_win)
+    M.prepend_to_quick_note()
+    vim.api.nvim_win_close(floating_win, true)
+    vim.api.nvim_buf_delete(buf, { force = true })
+  end
+end
+
+function M.prepend_to_quick_note()
+  local notes_dir = vim.g.notes_directory or "~/notes/"
+  local filepath = vim.fn.expand(notes_dir) .. "/quick_note.md"
+  local buf = vim.api.nvim_win_get_buf(floating_win)
+  local content = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
+
+  -- Add a separator and timestamp before the new content
+  local separator = "------------------------"
+  local timestamp = os.date "%Y-%m-%d %H:%M:%S"
+  table.insert(content, 1, "")
+  table.insert(content, 1, separator)
+  table.insert(content, 1, timestamp)
+  table.insert(content, 1, separator)
+  table.insert(content, 1, "")
+
+  -- Check if quick_note.md exists, create it if it doesn't
+  if vim.fn.filereadable(filepath) == 0 then
+    vim.fn.writefile({}, filepath)
+  end
+
+  local file_content = vim.fn.readfile(filepath)
+  for i = #file_content, 1, -1 do
+    table.insert(content, 1, file_content[i])
+  end
+
+  vim.fn.writefile(content, filepath)
+  print "Prepended content to quick_note.md"
+end
+
+function M.open_entire_quick_note()
+  local notes_dir = vim.g.notes_directory or "~/notes/"
+  local filepath = vim.fn.expand(notes_dir) .. "/quick_note.md"
+
+  if vim.fn.filereadable(filepath) == 0 then
+    print "No quick_note.md file found."
+    return
+  end
+
+  vim.cmd("edit " .. filepath)
+end
+
+return M
diff --git a/search_notes.lua b/search_notes.lua
new file mode 100644
index 0000000..152355e
--- /dev/null
+++ b/search_notes.lua
@@ -0,0 +1,10 @@
+local M = {}
+
+function M.search_notes()
+  local notes_dir = vim.g.notes_directory or "~/notes/"
+  require("telescope.builtin").live_grep {
+    search_dirs = { vim.fn.expand(notes_dir) },
+  }
+end
+
+return M
diff --git a/select_template.lua b/select_template.lua
new file mode 100644
index 0000000..e0c9f7e
--- /dev/null
+++ b/select_template.lua
@@ -0,0 +1,71 @@
+local M = {}
+
+local templates_dir = vim.g.notes_templates_dir or "~/notes/templates/"
+
+function M.select_template()
+  templates_dir = vim.fn.expand(templates_dir)
+  local templates = vim.fn.readdir(templates_dir, function(name)
+    return name:match "%.md$"
+  end)
+
+  if vim.tbl_isempty(templates) then
+    M.create_note_from_template(nil)
+  else
+    local template_files = {}
+    for _, template in ipairs(templates) do
+      table.insert(template_files, templates_dir .. template)
+    end
+
+    require("telescope.pickers")
+      .new({}, {
+        prompt_title = "Select Template",
+        finder = require("telescope.finders").new_table {
+          results = template_files,
+          entry_maker = function(entry)
+            return {
+              value = entry,
+              display = vim.fn.fnamemodify(entry, ":t"),
+              ordinal = entry,
+            }
+          end,
+        },
+        sorter = require("telescope.config").values.generic_sorter {},
+        attach_mappings = function(prompt_bufnr, map)
+          local actions = require "telescope.actions"
+          local action_state = require "telescope.actions.state"
+
+          actions.select_default:replace(function()
+            actions.close(prompt_bufnr)
+            local selection = action_state.get_selected_entry()
+            M.create_note_from_template(selection.value)
+          end)
+
+          return true
+        end,
+      })
+      :find()
+  end
+end
+
+function M.create_note_from_template(template_path)
+  local notes_dir = vim.g.notes_directory or "~/notes/"
+  local filename = os.date "%Y-%m-%d_%H-%M-%S" .. ".md"
+  local filepath = vim.fn.expand(notes_dir) .. filename
+  vim.cmd("edit " .. filepath)
+  if template_path then
+    vim.cmd("0r " .. template_path)
+  else
+    local title = "Title " .. os.date "%Y-%m-%d %H:%M:%S"
+    local template = {
+      "# " .. title,
+      "",
+    }
+    local file = io.open(filepath, "w")
+    for _, line in ipairs(template) do
+      file:write(line .. "\n")
+    end
+    file:close()
+  end
+end
+
+return M
diff --git a/update_index.lua b/update_index.lua
new file mode 100644
index 0000000..1a6044e
--- /dev/null
+++ b/update_index.lua
@@ -0,0 +1,22 @@
+local M = {}
+
+function M.update_index()
+  local notes_dir = vim.g.notes_directory or "~/notes/"
+  notes_dir = vim.fn.expand(notes_dir)
+  local index_file = notes_dir .. "index.md"
+  local notes = vim.fn.globpath(notes_dir, "*.md", false, true)
+  local content = { "# Index", "" }
+  for _, note in ipairs(notes) do
+    if vim.fn.fnamemodify(note, ":t") ~= "index.md" then
+      table.insert(content, "- [" .. vim.fn.fnamemodify(note, ":t:r") .. "](" .. note .. ")")
+    end
+  end
+  local file = io.open(index_file, "w")
+  for _, line in ipairs(content) do
+    file:write(line .. "\n")
+  end
+  file:close()
+  print "Index updated"
+end
+
+return M