calendar support!!!!!!!!!

This commit is contained in:
Rene Schallner
2021-11-23 04:02:22 +01:00
parent b7d2a4bf06
commit 65b212c4e9
3 changed files with 204 additions and 33 deletions

View File

@@ -1,7 +1,10 @@
# Backlog # Backlog
- vimhelp
- yt video
## Dones ## Dones
- [x] awesome calendar support
- [x] maybe choose template in create note: - [x] maybe choose template in create note:
- `new_templated_note()` first asks for title, then brings up a telescope picker of all template files in new `ZkCfg.template_dir`. - `new_templated_note()` first asks for title, then brings up a telescope picker of all template files in new `ZkCfg.template_dir`.
- [x] highlights oneline - [x] highlights oneline

View File

@@ -4,6 +4,8 @@ A Neovim (lua) plugin for working with a markdown zettelkasten, based on telesco
Find notes by name, daily and weekly notes by date, search within all notes, place and follow links to your notes or create new ones. Current daily and weekly notes are (optionally) created if not present when searching for dailies or weeklies. Following a link to a non-existing note can also create the missing note (optional). Find notes by name, daily and weekly notes by date, search within all notes, place and follow links to your notes or create new ones. Current daily and weekly notes are (optionally) created if not present when searching for dailies or weeklies. Following a link to a non-existing note can also create the missing note (optional).
It can optionally plug into [calendar-vim](https://github.com/mattn/calendar-vim): Selecting a day in the calendar will open up a telescope search with preview that lets you open the daily note (or cancel out). The daily note will be created if it doesn't exist. Days with daily notes get marked in the calendar.
## Search-based navigation ## Search-based navigation
Every navigation action, like following a link, is centered around a Telescope search: a Telescope search popup is opened, and in the case of following a link, the search-text is pre-filled with the target. So, instead of opening the linked note, you get a preview in Telescope and can decide if you actually want to go there. Since the search is often likely to show up more than one result, you can preview related notes immediately. Every navigation action, like following a link, is centered around a Telescope search: a Telescope search popup is opened, and in the case of following a link, the search-text is pre-filled with the target. So, instead of opening the linked note, you get a preview in Telescope and can decide if you actually want to go there. Since the search is often likely to show up more than one result, you can preview related notes immediately.
@@ -30,15 +32,26 @@ If rg isn't found at `setup()` time, it will not be used. In that case, the sort
If you can't use `rg`, I recommend using `goto_today()` and `goto_thisweek()` instead of `find_daily_notes()` and `find_weekly_notes()`, as this pre-fills the search field, which makes the results list look a bit more sane. If you can't use `rg`, I recommend using `goto_today()` and `goto_thisweek()` instead of `find_daily_notes()` and `find_weekly_notes()`, as this pre-fills the search field, which makes the results list look a bit more sane.
#### calendar-vim Plugin (optional)
Telekasten.nvim can optionally plug into [calendar-vim](https://github.com/mattn/calendar-vim): Selecting a day in the calendar will open up a telescope search with preview that lets you open the daily note (or cancel out). The daily note will be created if it doesn't exist. Days with daily notes get marked in the calendar.
See below for installing and using it.
### 1. Install the plugin ### 1. Install the plugin
Install with your plugin manager of choice. Mine is [Vundle](https://github.com/VundleVim/Vundle.vim). Install with your plugin manager of choice. Mine is [Vundle](https://github.com/VundleVim/Vundle.vim).
```vimscript ```vim
Plugin 'renerocksai/telekasten.nvim' Plugin 'renerocksai/telekasten.nvim'
``` ```
I higly recommend using the calendar integration. For that you'll need [calendar-vim](https://github.com/mattn/calendar-vim):
```vim
Plugin 'mattn/calendar-vim'
```
### 2. Configure telekasten.nvim ### 2. Configure telekasten.nvim
Somewhere in your vim config, put a snippet like this: Somewhere in your vim config, put a snippet like this:
@@ -66,6 +79,17 @@ require('telekasten').setup({
-- template for newly created weekly notes (goto_thisweek) -- template for newly created weekly notes (goto_thisweek)
template_new_weekly= home .. '/' .. 'templates/weekly.md', template_new_weekly= home .. '/' .. 'templates/weekly.md',
-- integrate with calendar-vim
plug_into_calendar = true,
calendar_opts = {
-- calendar week display mode: 1 .. 'WK01', 2 .. 'WK 1', 3 .. 'KW01', 4 .. 'KW 1', 5 .. '1'
weeknm = 4,
-- use monday as first day of week: 1 .. true, 0 .. false
calendar_monday = 1,
-- calendar mark: where to put mark for marked days: 'left', 'right', 'left-fit'
calendar_mark = 'left-fit',
}
}) })
END END
``` ```
@@ -79,9 +103,27 @@ END
| `follow_creates_nonexisting` | following a link to a non-existing note will create it | true | | `follow_creates_nonexisting` | following a link to a non-existing note will create it | true |
| `dailies_create_nonexisting` | following a link to a non-existing daily note will create it | true | | `dailies_create_nonexisting` | following a link to a non-existing daily note will create it | true |
| `weekly_create_nonexisting` | following a link to a non-existing weekly note will create it | true | | `weekly_create_nonexisting` | following a link to a non-existing weekly note will create it | true |
| `template_new_note` | markdown template for new notes | ~/zettelkasten/templates/new_note.md | | `template_new_note` | markdown template for new notes | ~/zettelkasten/templates/new_note.md' |
| `template_new_daily` | markdown template for new daily notes | ~/zettelkasten/templates/daily.md | | `template_new_daily` | markdown template for new daily notes | ~/zettelkasten/templates/daily.md |
| `template_new_weekly` | markdown template for new weekly notes | ~/zettelkasten/templates/weekly.md | | `template_new_weekly` | markdown template for new weekly notes | ~/zettelkasten/templates/weekly.md |
| `plug_into_calendar` | activate calendar support if true (needs calendar-vim plugin) | true |
| `calendar_opts` | options for calendar, see below | see below |
The calendar support has its own options, contained in `calendar_opts`:
| calendar setting | description | example |
| --- | --- | --- |
| `weeknm` | calendar week display mode | 1 |
| | 1 .. 'WK01' | |
| | 2 .. 'WK 1' | |
| | 3 .. 'KW01' | |
| | 4 .. 'KW 1' | |
| | 5 .. '1' | |
| `calendar_monday` | use monday as start of week if 1 | 1 |
| `calendar_mark` | where to put marks to mark days with daily notes | 'left-fit' |
| | 'left' : ugly | |
| | 'left-fit' : mark to the left of the day| |
| | 'right' : mark to the right of the day| |
### 3. Configure your own colors ### 3. Configure your own colors
@@ -124,11 +166,12 @@ The plugin defines the following functions.
- `insert_link()` : select a note by name, via Telescope, and place a `[[link]]` at the current cursor position - `insert_link()` : select a note by name, via Telescope, and place a `[[link]]` at the current cursor position
- `follow_link()`: take text between brackets (linked note) and open a Telescope file finder with it: selects note to open (incl. preview) - with optional note creation for non-existing notes, honoring the configured template - `follow_link()`: take text between brackets (linked note) and open a Telescope file finder with it: selects note to open (incl. preview) - with optional note creation for non-existing notes, honoring the configured template
- `yank_notelink()` : yank a link to the current note, ready to paste - `yank_notelink()` : yank a link to the current note, ready to paste
- `show_calendar()` : opens up the calendar in a properly-sized vertical split at the very right
- `setup(opts)`: used for configuring paths, file extension, etc. - `setup(opts)`: used for configuring paths, file extension, etc.
To use one of the functions above, just run them with the `:lua ...` command. To use one of the functions above, just run them with the `:lua ...` command.
```vimscript ```vim
:lua require("telekasten").find_daily_notes() :lua require("telekasten").find_daily_notes()
``` ```
@@ -205,6 +248,14 @@ date: {{hdate}}
## Sunday link ## Sunday link
``` ```
### Using the calendar
When invoking `show_calendar()`, a calendar showing the previous, current, and next month is shown at the right side of vim.
- days that have a daily note associated with them are marked with a + sign and a different color
- pressing enter on a day will open up a telescope finder with the associated daily note selected and previewed. The daily note will be created if it doesn't exist. If you choose to not open the note, you will return to the calender so you can preview other notes.
## Bind it ## Bind it
Usually, you would set up some key bindings, though: Usually, you would set up some key bindings, though:

View File

@@ -27,6 +27,17 @@ ZkCfg = {
template_new_note = home .. '/' .. 'templates/new_note.md', template_new_note = home .. '/' .. 'templates/new_note.md',
template_new_daily = home .. '/' .. 'templates/daily_tk.md', template_new_daily = home .. '/' .. 'templates/daily_tk.md',
template_new_weekly = home .. '/' .. 'templates/weekly_tk.md', template_new_weekly = home .. '/' .. 'templates/weekly_tk.md',
-- integrate with calendar-vim
plug_into_calendar = true,
calendar_opts = {
-- calendar week display mode: 1 .. 'WK01', 2 .. 'WK 1', 3 .. 'KW01', 4 .. 'KW 1', 5 .. '1'
weeknm = 4,
-- use monday as first day of week: 1 .. true, 0 .. false
calendar_monday = 1,
-- calendar mark: where to put mark for marked days: 'left', 'right', 'left-fit'
calendar_mark = 'left-fit',
}
} }
-- ---------------------------------------------------------------------------- -- ----------------------------------------------------------------------------
@@ -39,7 +50,7 @@ local note_type_templates = {
local function file_exists(fname) local function file_exists(fname)
local f=io.open(fname,"r") local f=io.open(fname,"r")
print("checking for " .. fname) -- print("checking for " .. fname)
if f~=nil then io.close(f) return true else return false end if f~=nil then io.close(f) return true else return false end
end end
@@ -97,7 +108,7 @@ end
-- Select from daily notes -- Select from daily notes
-- --
FindDailyNotes = function(opts) FindDailyNotes = function(opts)
opts = {} or opts opts = opts or {}
local today = os.date("%Y-%m-%d") local today = os.date("%Y-%m-%d")
local fname = ZkCfg.dailies .. '/' .. today .. ZkCfg.extension local fname = ZkCfg.dailies .. '/' .. today .. ZkCfg.extension
@@ -121,7 +132,7 @@ end
-- Select from daily notes -- Select from daily notes
-- --
FindWeeklyNotes = function(opts) FindWeeklyNotes = function(opts)
opts = {} or opts opts = opts or {}
local title = os.date("%Y-W%V") local title = os.date("%Y-W%V")
local fname = ZkCfg.weeklies .. '/' .. title .. ZkCfg.extension local fname = ZkCfg.weeklies .. '/' .. title .. ZkCfg.extension
@@ -145,7 +156,7 @@ end
-- Select from all notes and put a link in the current buffer -- Select from all notes and put a link in the current buffer
-- --
InsertLink = function(opts) InsertLink = function(opts)
opts = {} or opts opts = opts or {}
builtin.find_files({ builtin.find_files({
prompt_title = "Insert link to note", prompt_title = "Insert link to note",
cwd = ZkCfg.home, cwd = ZkCfg.home,
@@ -171,7 +182,7 @@ end
-- find the file linked to by the word under the cursor -- find the file linked to by the word under the cursor
-- --
FollowLink = function(opts) FollowLink = function(opts)
opts = {} or opts opts = opts or {}
vim.cmd('normal yi]') vim.cmd('normal yi]')
local title = vim.fn.getreg('"0') local title = vim.fn.getreg('"0')
@@ -214,8 +225,8 @@ end
-- find today's daily note and create it if necessary. -- find today's daily note and create it if necessary.
-- --
GotoToday = function(opts) GotoToday = function(opts)
opts = {} or opts opts = opts or {}
local word = os.date("%Y-%m-%d") local word = opts.today or os.date("%Y-%m-%d")
local fname = ZkCfg.dailies .. '/' .. word .. ZkCfg.extension local fname = ZkCfg.dailies .. '/' .. word .. ZkCfg.extension
local fexists = file_exists(fname) local fexists = file_exists(fname)
@@ -224,10 +235,23 @@ GotoToday = function(opts)
end end
builtin.find_files({ builtin.find_files({
prompt_title = "Goto today", prompt_title = "Goto day",
cwd = ZkCfg.home, cwd = ZkCfg.home,
default_text = word, default_text = word,
find_command = ZkCfg.find_command, find_command = ZkCfg.find_command,
attach_mappings = function(prompt_bufnr, map)
map = map -- get rid of lsp error
actions.select_default:replace(function()
actions.close(prompt_bufnr)
-- open the new note
if (opts.calendar == true) then
vim.cmd('wincmd w')
end
vim.cmd('e ' .. fname)
end)
return true
end,
}) })
end end
@@ -239,7 +263,7 @@ end
-- Select from notes -- Select from notes
-- --
FindNotes = function(opts) FindNotes = function(opts)
opts = {} or opts opts = opts or {}
builtin.find_files({ builtin.find_files({
prompt_title = "Find notes by name", prompt_title = "Find notes by name",
cwd = ZkCfg.home, cwd = ZkCfg.home,
@@ -255,7 +279,7 @@ end
-- find the file linked to by the word under the cursor -- find the file linked to by the word under the cursor
-- --
SearchNotes = function(opts) SearchNotes = function(opts)
opts = {} or opts opts = opts or {}
builtin.live_grep({ builtin.live_grep({
prompt_title = "Search in notes", prompt_title = "Search in notes",
@@ -291,7 +315,7 @@ local function on_create(title)
end end
CreateNote = function(opts) CreateNote = function(opts)
opts = {} or opts opts = opts or {}
vim.ui.input({prompt = 'Title: '}, on_create) vim.ui.input({prompt = 'Title: '}, on_create)
end end
@@ -333,19 +357,19 @@ local function on_create_with_template(title)
end end
CreateNoteSelectTemplate = function(opts) CreateNoteSelectTemplate = function(opts)
opts = {} or opts opts = opts or {}
vim.ui.input({prompt = 'Title: '}, on_create_with_template) vim.ui.input({prompt = 'Title: '}, on_create_with_template)
end end
-- --
-- GotoThisWeek: -- GotoThisWeek:
-- ---------- -- -------------
-- --
-- find this week's weekly note and create it if necessary. -- find this week's weekly note and create it if necessary.
-- --
GotoThisWeek = function(opts) GotoThisWeek = function(opts)
opts = {} or opts opts = opts or {}
local title = os.date("%Y-W%V") local title = os.date("%Y-W%V")
local fname = ZkCfg.weeklies .. '/' .. title .. ZkCfg.extension local fname = ZkCfg.weeklies .. '/' .. title .. ZkCfg.extension
@@ -363,6 +387,85 @@ GotoThisWeek = function(opts)
end end
--
-- Calendar Stuff
-- --------------
-- return if a daily 'note exists' indicator (sign) should be displayed for a particular day
CalendarSignDay = function(day, month, year)
local fn = ZkCfg.dailies .. '/' .. string.format('%04d-%02d-%02d', year, month, day) .. ZkCfg.extension
if file_exists(fn) then
return 1
end
return 0
end
-- action on enter on a specific day: preview in telescope, stay in calendar on cancel, open note in other window on accept
CalendarAction = function(day, month, year, week, dir)
-- lsp
week = week
dir = dir
local today = string.format('%04d-%02d-%02d', year, month, day)
local opts = {}
opts.today = today
opts.calendar = true
GotoToday(opts)
end
ShowCalendar = function(opts)
local defaults = {}
defaults.cmd = 'CalendarVR'
defaults.vertical_resize = 1
opts = opts or defaults
vim.cmd(opts.cmd)
if (opts.vertical_resize) then
vim.cmd('vertical resize +' .. opts.vertical_resize)
end
end
-- set up calendar integration: forward to our lua functions
SetupCalendar = function(opts)
local defaults = ZkCfg.calendar_opts
opts = opts or defaults
local cmd = [[
function! MyCalSign(day, month, year)
return luaeval('CalendarSignDay(_A[1], _A[2], _A[3])', [a:day, a:month, a:year])
endfunction
function! MyCalAction(day, month, year, weekday, dir)
" day : day
" month : month
" year year
" weekday : day of week (monday=1)
" dir : direction of calendar
return luaeval('CalendarAction(_A[1], _A[2], _A[3], _A[4], _A[5])', [a:day, a:month, a:year, a:weekday, a:dir])
endfunction
function! MyCalBegin()
" too early, windown doesn't exist yet
" cannot resize
endfunction
let g:calendar_sign = 'MyCalSign'
let g:calendar_action = 'MyCalAction'
" let g:calendar_begin = 'MyCalBegin'
let g:calendar_monday = {{calendar_monday}}
let g:calendar_mark = '{{calendar_mark}}'
let g:calendar_weeknm = {{weeknm}}
]]
for k, v in pairs(opts) do
cmd = cmd:gsub('{{' .. k .. '}}', v)
end
vim.cmd(cmd)
end
-- Setup(cfg) -- Setup(cfg)
-- --
-- Overrides config with elements from cfg. See top of file for defaults. -- Overrides config with elements from cfg. See top of file for defaults.
@@ -370,13 +473,26 @@ end
Setup = function(cfg) Setup = function(cfg)
cfg = cfg or {} cfg = cfg or {}
for k, v in pairs(cfg) do for k, v in pairs(cfg) do
-- merge everything but calendar opts
-- they will be merged later
if (k ~= 'calendar_opts') then
ZkCfg[k] = v ZkCfg[k] = v
end end
end
if vim.fn.executable('rg') then if vim.fn.executable('rg') then
ZkCfg.find_command = { 'rg', '--files', '--sortr', 'created', } ZkCfg.find_command = { 'rg', '--files', '--sortr', 'created', }
else else
ZkCfg.find_command = nil ZkCfg.find_command = nil
end end
-- this looks a little messy
if (ZkCfg.plug_into_calendar) then
ZkCfg.calendar_opts = ZkCfg.calendar_opts or {}
ZkCfg.calendar_opts.weeknm = cfg.calendar_opts.weeknm or ZkCfg.calendar_opts.weeknm
ZkCfg.calendar_opts.calendar_monday = cfg.calendar_opts.calendar_monday or ZkCfg.calendar_opts.calendar_monday
ZkCfg.calendar_opts.calendar_mark = cfg.calendar_opts.calendar_mark or ZkCfg.calendar_opts.calendar_mark
SetupCalendar(ZkCfg.calendar_opts)
end
end end
local M = { local M = {
@@ -393,6 +509,7 @@ local M = {
find_weekly_notes = FindWeeklyNotes, find_weekly_notes = FindWeeklyNotes,
yank_notelink = YankLink, yank_notelink = YankLink,
create_note_sel_template = CreateNoteSelectTemplate, create_note_sel_template = CreateNoteSelectTemplate,
show_calendar = ShowCalendar,
} }
return M return M