From 4c6b7b2e34284d4dda0b94909812d5343f3fdbfc Mon Sep 17 00:00:00 2001 From: Rene Schallner Date: Sun, 21 Nov 2021 19:13:54 +0100 Subject: [PATCH] follo links optionally creates non-existing notes, honoring templates --- BACKLOG.md | 3 +- lua/telekasten.lua | 268 +++++++++++++++++++++++++++++---------------- 2 files changed, 176 insertions(+), 95 deletions(-) diff --git a/BACKLOG.md b/BACKLOG.md index 2497dc7..2d954e1 100644 --- a/BACKLOG.md +++ b/BACKLOG.md @@ -1,10 +1,11 @@ # Backlog -- follow links: create non-existing ones +- create new note dialog: choose template - extend markdown syntax highlights for [[links]] - get rid of `daily_finder.sh` ## Dones +- [x] follow links: create non-existing ones - [x] ,[ to insert link --> we can escape out and type double brackets - [x] shortcuts for todo and done in init.vim - [x] Readme search based navigation diff --git a/lua/telekasten.lua b/lua/telekasten.lua index 9d4449c..a7f00e8 100644 --- a/lua/telekasten.lua +++ b/lua/telekasten.lua @@ -4,10 +4,12 @@ local actions = require("telescope.actions") local action_state = require "telescope.actions.state" -- declare locals for the nvim api stuff to avoid more lsp warnings -local vim = vim -local api = api +local vim = vim + +-- ---------------------------------------------------------------------------- -- DEFAULT CONFIG +-- ---------------------------------------------------------------------------- ZkCfg = { home = vim.fn.expand("~/zettelkasten"), dailies = vim.fn.expand("~/zettelkasten/daily"), @@ -21,17 +23,39 @@ ZkCfg = { -- download tool for daily_finder installation: curl or wget downloader = 'curl', -- downloader = 'wget', -- wget is supported, too - } + + -- following a link to a non-existing note will create it + follow_creates_nonexisting = true, + + -- templates for new notes + template_new_note = ZkCfg.home .. '/' .. 'templates/new_note.md', + -- currently unused, hardcoded in daily_finder.sh: + template_new_daily = ZkCfg.home .. '/' .. 'templates/daily.md', + -- currently unused + template_new_weekly= ZkCfg.home .. '/' .. 'templates/weekly.md', +} +-- ---------------------------------------------------------------------------- local downloader2cmd = { curl = 'curl -o', wget = 'wget -O', } +local note_type_templates = { + normal = ZkCfg.template_new_note, + daily = ZkCfg.template_new_daily, + weekly = ZkCfg.template_new_weekly, +} --- InstallDailyFinder + + +-- +-- InstallDailyFinder: +-- ------------------- +-- -- downloads the daily finder scripts to the configured `my_bin` directory -- and makes it executable +-- InstallDailyFinder = function() local destpath = ZkCfg.my_bin .. '/' .. ZkCfg.daily_finder local cmd = downloader2cmd[ZkCfg.downloader] @@ -62,8 +86,11 @@ local check_local_finder = function() -- return vim.fn.executable(ZkCfg.daily_finder) == 1 end + + -- -- FindDailyNotes: +-- --------------- -- -- Select from daily notes -- @@ -76,69 +103,140 @@ FindDailyNotes = function(opts) find_command = { ZkCfg.daily_finder }, entry_maker = zk_entry_maker, }) + else + print("Daily finder not found. Try :lua require('telekasten').install_daily_finder()") end end + -- -- InsertLink: +-- ----------- -- -- Select from all notes and put a link in the current buffer -- InsertLink = function(opts) opts = {} or opts - builtin.find_files({ - prompt_title = "Insert link to note", - cwd = ZkCfg.home, - attach_mappings = function(prompt_bufnr, map) - map = map -- get rid of lsp error - actions.select_default:replace(function() - actions.close(prompt_bufnr) - local selection = action_state.get_selected_entry() - local fn = path_to_linkname(selection.value) - vim.api.nvim_put({ "[["..fn.."]]" }, "", false, true) - end) - return true - end, - find_command = { ZkCfg.daily_finder }, - entry_maker = zk_entry_maker, - }) + if (check_local_finder() == true) then + builtin.find_files({ + prompt_title = "Insert link to note", + cwd = ZkCfg.home, + attach_mappings = function(prompt_bufnr, map) + map = map -- get rid of lsp error + actions.select_default:replace(function() + actions.close(prompt_bufnr) + local selection = action_state.get_selected_entry() + local fn = path_to_linkname(selection.value) + vim.api.nvim_put({ "[["..fn.."]]" }, "", false, true) + end) + return true + end, + find_command = { ZkCfg.daily_finder }, + entry_maker = zk_entry_maker, + }) + else + print("Daily finder not found. Try :lua require('telekasten').install_daily_finder()") + end end + + -- -- FollowLink: +-- ----------- -- -- find the file linked to by the word under the cursor -- -FollowLink = function(opts) - opts = {} or opts - vim.cmd('normal yi]') - local word = vim.fn.getreg('"0') - builtin.find_files({ - prompt_title = "Follow link to note...", - cwd = ZkCfg.home, - default_text = word, - find_command = { ZkCfg.daily_finder }, - entry_maker = zk_entry_maker, - }) +local function file_exists(fname) + local f=io.open(fname,"r") + if f~=nil then io.close(f) return true else return false end +end + +local function linesubst(line, title) + local substs = { + date = os.date('%Y-%m-%d'), + title = title, + } + for k, v in pairs(substs) do + line = line:gsub("{{"..k.."}}", v) + end + + return line +end + +local create_note_from_template = function (title, filepath, templatefn) + -- first, read the template file + local lines = {} + for line in io.lines(templatefn) do + lines[#lines+1] = line + end + + -- now write the output file, substituting vars line by line + local ofile = io.open(filepath, 'a') + for _, line in pairs(lines) do + ofile:write(linesubst(line, title) .. '\n') + end + + ofile:close() end +FollowLink = function(opts) + opts = {} or opts + vim.cmd('normal yi]') + local title = vim.fn.getreg('"0') + local fname = ZkCfg.home .. '/' .. title .. ZkCfg.extension + + local fexists = file_exists(fname) + if ((fexists ~= true) and ((opts.follow_creates_nonexisting == true) or ZkCfg.follow_creates_nonexisting == true)) then + create_note_from_template(title, fname, note_type_templates.normal) + end + + if (check_local_finder() == true) then + builtin.find_files({ + prompt_title = "Follow link to note...", + cwd = ZkCfg.home, + default_text = title, + find_command = { ZkCfg.daily_finder }, + entry_maker = zk_entry_maker, + }) + else + print("Daily finder not found. Try :lua require('telekasten').install_daily_finder()") + end +end + + + +-- +-- GotoToday: +-- ---------- +-- +-- find today's daily note and create it if necessary. +-- GotoToday = function(opts) print('local version') opts = {} or opts local word = os.date("%Y-%m-%d") - builtin.find_files({ - prompt_title = "Follow link to note...", - cwd = ZkCfg.home, - default_text = word, - find_command = { ZkCfg.daily_finder }, - entry_maker = zk_entry_maker, - }) + + if (check_local_finder() == true) then + builtin.find_files({ + prompt_title = "Follow link to note...", + cwd = ZkCfg.home, + default_text = word, + find_command = { ZkCfg.daily_finder }, + entry_maker = zk_entry_maker, + }) + else + print("Daily finder not found. Try :lua require('telekasten').install_daily_finder()") + end end + + -- -- FindNotes: +-- ---------- -- -- Select from notes -- @@ -152,73 +250,33 @@ FindNotes = function(opts) }) end + + -- -- SearchNotes: +-- ------------ -- -- find the file linked to by the word under the cursor -- SearchNotes = function(opts) opts = {} or opts - builtin.live_grep({ - prompt_title = "Search in notes", - cwd = ZkCfg.home, - search_dirs = { ZkCfg.home }, - default_text = vim.fn.expand(""), - find_command = { ZkCfg.daily_finder }, - }) + + if (check_local_finder() == true) then + builtin.live_grep({ + prompt_title = "Search in notes", + cwd = ZkCfg.home, + search_dirs = { ZkCfg.home }, + default_text = vim.fn.expand(""), + find_command = { ZkCfg.daily_finder }, + }) + else + print("Daily finder not found. Try :lua require('telekasten').install_daily_finder()") + end end -local function file_exists(name) - local f=io.open(name,"r") - if f~=nil then io.close(f) return true else return false end -end - -local create_note_by_tilte = function (title) - -- set the filename based on the current date - -- local filepath = vim.g['wiki_root']..'journal/'..os.date('%Y-%m-%d')..'.md' - local filepath = ZkCfg.home - - -- if the file doesn't exist - -- then created file and write date to the top of the file - if not file_exists(filepath) then - local file = io.open(filepath, 'a') - io.output(file) - io.write(os.date("# %a, %d %B '%y")) - io.close(file) - end - api.nvim_command('edit '..filepath) -end - ---[[ --- interesting snippet: - function file_exists(name) - local f=io.open(name,"r") - if f~=nil then io.close(f) return true else return false end - end - - local api = vim.api - local M = {} - function M.currentEntry() - - -- set the filename based on the current date - local filepath = vim.g['wiki_root']..'journal/'..os.date('%Y-%m-%d')..'.md' - - -- if the file doesn't exist - -- then created file and write date to the top of the file - if not file_exists(filepath) then - file = io.open(filepath, 'a') - io.output(file) - io.write(os.date("# %a, %d %B '%y")) - io.close(file) - end - api.nvim_command('edit '..filepath) - end - return M ---]] - --- setup(cfg) +-- Setup(cfg) -- -- Overrides config with elements from cfg -- Valid keys are: @@ -248,3 +306,25 @@ local M = { } print('local version') return M + + + + +--[[ +-- interesting snippet: + -- set the filename based on the current date + local filepath = vim.g['wiki_root']..'journal/'..os.date('%Y-%m-%d')..'.md' + + -- if the file doesn't exist + -- then created file and write date to the top of the file + if not file_exists(filepath) then + file = io.open(filepath, 'a') + io.output(file) + io.write(os.date("# %a, %d %B '%y")) + io.close(file) + end + api.nvim_command('edit '..filepath) + end + return M +--]] +