├── README.md └── after └── ftplugin └── vimwiki.vim /README.md: -------------------------------------------------------------------------------- 1 | # vimwiki-sync 2 | 3 | This plugin: 4 | 5 | - automatically synchronize Vimwiki notes directory on Vimwiki startup and exit using Git. 6 | - it also synchronizes Task Warrior automatically 7 | - changed files are auto-committed. 8 | 9 | # Install 10 | 11 | Use your Vim plugin manager, for example using Vundle, add this line to your `.vimrc`: 12 | 13 | Plugin 'git@github.com:michal-h21/vimwiki-sync.git' 14 | 15 | ### vim-plug 16 | 17 | Plug 'michal-h21/vimwiki-sync' 18 | 19 | # Usage 20 | 21 | This plugin automatically commit changes in Vimwiki directories. You need to initialize 22 | Git repository in these directories by hand. 23 | 24 | Vimwiki directories can be configured using these `g:vimwiki_list` variable in `.vimrc`, 25 | for example: 26 | 27 | let g:vimwiki_list = [{'path':'$HOME/notes'}] 28 | 29 | This configuration declares the `$HOME/notes` as Vimwiki directory. You can initialize 30 | Git directory using: 31 | 32 | $ cd ~/notes 33 | $ git init 34 | 35 | You can add remote repository for your project. `Vimwiki-sync` will push all changes to your 36 | remote on Vim exit, and pull changes on Vimwiki startup. 37 | 38 | $ git remote add origin git@github.com:username/repo.git 39 | 40 | # Configuration 41 | 42 | ## Git branch 43 | 44 | By default, we push and pull from the current branch of the remove Git 45 | repository. You can set the `g:vimwiki_sync_branch` to select specific branch: 46 | 47 | let g:vimwiki_sync_branch = "main" 48 | 49 | ## Commit message 50 | 51 | You can change the commig message using `g:vimwiki_sync_commit_message` variable. It uses the 52 | [strftime](https://renenyffenegger.ch/notes/development/vim/script/vimscript/functions/strftime) 53 | function for the formatting, so it supports insertion of time stamps. The default value is 54 | following: 55 | 56 | let g:vimwiki_sync_commit_message = 'Auto commit + push. %c' 57 | 58 | # Taskwiki support 59 | 60 | Vimwiki-sync automatically synchronize [Taskwiki](https://github.com/tools-life/taskwiki) 61 | using [Taskwarrior](https://taskwarrior.org/). To disable it, set the following variable: 62 | 63 | 64 | let g:sync_taskwarrior = 0 65 | -------------------------------------------------------------------------------- /after/ftplugin/vimwiki.vim: -------------------------------------------------------------------------------- 1 | augroup vimwiki 2 | if !exists('g:zettel_synced') 3 | let g:zettel_synced = 0 4 | else 5 | finish 6 | endif 7 | 8 | " g:zettel_dir is defined by vim_zettel 9 | if !exists('g:zettel_dir') 10 | let g:zettel_dir = vimwiki#vars#get_wikilocal('path') "VimwikiGet('path',g:vimwiki_current_idx) 11 | endif 12 | 13 | " make the Git branch used for synchronization configurable 14 | if !exists('g:vimwiki_sync_branch') 15 | let g:vimwiki_sync_branch = "HEAD" 16 | endif 17 | 18 | " enable disabling of Taskwarrior synchronization 19 | if !exists("g:sync_taskwarrior") 20 | let g:sync_taskwarrior = 1 21 | endif 22 | 23 | " don't try to start synchronization if the opend file is not in vimwiki 24 | " path 25 | let current_dir = expand("%:p:h") 26 | if !current_dir ==# fnamemodify(g:zettel_dir, ":h") 27 | finish 28 | endif 29 | 30 | if !exists('g:vimwiki_sync_commit_message') 31 | let g:vimwiki_sync_commit_message = 'Auto commit + push. %c' 32 | endif 33 | 34 | " don't sync temporary wiki 35 | if vimwiki#vars#get_wikilocal('is_temporary_wiki') == 1 36 | finish 37 | endif 38 | 39 | 40 | " execute vim function. because vimwiki can be started from any directory, 41 | " we must use pushd and popd commands to execute git commands in wiki root 42 | " dir. silent is used to disable necessity to press after each 43 | " command. the downside is that the command output is not displayed at all. 44 | " One idea: what about running git asynchronously? 45 | function! s:git_action(action) 46 | execute ':silent !' . a:action 47 | " prevent screen artifacts 48 | redraw! 49 | endfunction 50 | 51 | function! My_exit_cb(channel,msg ) 52 | echom "[vimiwiki sync] Sync done" 53 | execute 'checktime' 54 | redraw! 55 | endfunction 56 | 57 | function! My_close_cb(channel) 58 | " it seems this callback is necessary to really pull the repo 59 | endfunction 60 | 61 | 62 | " pull changes from git origin and sync task warrior for taskwiki 63 | " using asynchronous jobs 64 | " we should add some error handling 65 | function! s:pull_changes() 66 | if g:zettel_synced==0 67 | echom "[vimwiki sync] pulling changes" 68 | let g:zettel_synced = 1 69 | if has("nvim") 70 | let gitjob = jobstart("git -C " . g:zettel_dir . " pull origin " . g:vimwiki_sync_branch, {"exit_cb": "My_exit_cb", "close_cb": "My_close_cb"}) 71 | if g:sync_taskwarrior==1 72 | let taskjob = jobstart("task sync") 73 | endif 74 | else 75 | let gitjob = job_start("git -C " . g:zettel_dir . " pull origin " . g:vimwiki_sync_branch, {"exit_cb": "My_exit_cb", "close_cb": "My_close_cb"}) 76 | if g:sync_taskwarrior==1 77 | let taskjob = job_start("task sync") 78 | endif 79 | endif 80 | endif 81 | endfunction 82 | 83 | " push changes 84 | " it seems that Vim terminates before it is executed, so it needs to be 85 | " fixed 86 | function! s:push_changes() 87 | if has("nvim") 88 | let gitjob = jobstart("git -C " . g:zettel_dir . " push origin " . g:vimwiki_sync_branch) 89 | if g:sync_taskwarrior==1 90 | let taskjob = jobstart("task sync") 91 | endif 92 | else 93 | let gitjob = job_start("git -C " . g:zettel_dir . " push origin " . g:vimwiki_sync_branch) 94 | if g:sync_taskwarrior==1 95 | let taskjob = job_start("task sync") 96 | endif 97 | endif 98 | endfunction 99 | 100 | " detect if there are some merge issues in the repository 101 | " https://github.com/michal-h21/vimwiki-sync/issues/13 102 | function! s:no_conflicts() 103 | " first check if we are inside git repository 104 | let result = system("git -C " . g:zettel_dir . " rev-parse --is-inside-work-tree") 105 | if result !=? "true\n" 106 | return 0 107 | end 108 | " this command should return empty string 109 | let result = system("git -C " . g:zettel_dir . " diff --name-only --diff-filter=U") 110 | echom "calling system: " . result 111 | return result ==? "" 112 | endfunction 113 | 114 | function! s:commit_changes() 115 | " commit only when there are no issues 116 | if no_conflicts() 117 | call git_action("git -C " . g:zettel_dir . " add . ; git -C " . g:zettel_dir . " commit -m \"" . strftime(g:vimwiki_sync_commit_message) . "\"") 118 | endif 119 | endfunction 120 | 121 | " sync changes at the start 122 | au! VimEnter * call pull_changes() 123 | au! BufRead * call pull_changes() 124 | au! BufEnter * call pull_changes() 125 | " auto commit changes on each file change 126 | au! BufWritePost * call commit_changes() 127 | " push changes only on at the end 128 | au! VimLeave * call git_action("git -C " . g:zettel_dir . " push origin " . g:vimwiki_sync_branch) 129 | " au! VimLeave * call push_changes() 130 | augroup END 131 | --------------------------------------------------------------------------------