Skip to content

Commit a523c28

Browse files
committed
Support for multiple directories with notes (related to issue #18)
Issue #18 on GitHub: #18
1 parent cbf4f3b commit a523c28

File tree

5 files changed

+146
-55
lines changed

5 files changed

+146
-55
lines changed

README.md

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,24 @@ Unzip the most recent [ZIP archive] [download] file inside your Vim profile dire
3131

3232
All options have reasonable defaults so if the plug-in works after installation you don't need to change any options. They're available for people who like to customize their directory layout. These options can be configured in your [vimrc script] [vimrc] by including a line like this:
3333

34-
:let g:notes_directory = '~/Documents/Notes'
34+
:let g:notes_directories = ['~/Documents/Notes', '~/Dropbox/Shared Notes']
3535

3636
Note that after changing an option in your [vimrc script] [vimrc] you have to restart Vim for the changes to take effect.
3737

38-
### The `g:notes_directory` option
38+
### The `g:notes_directories` option
3939

40-
All your notes are stored together in one directory. This option defines the path of this directory. The default value depends on circumstances but should work for most people:
40+
Your notes are stored in one or more directories. This option defines where you want to store your notes. Its value should be a list (there's an example above) with one or more pathnames. The default is a single value which depends on circumstances but should work for most people:
4141

4242
* If the profile directory where the plug-in is installed is writable, the directory `misc/notes/user` under the profile directory is used. This is for compatibility with [Pathogen] [pathogen]; the notes will be stored inside the plug-in's bundle.
4343

4444
* If the above doesn't work out, the default depends on the platform: `~/vimfiles/misc/notes/user` on Windows and `~/.vim/misc/notes/user` on other platforms.
4545

46+
#### Backwards compatibility
47+
48+
In the past the notes plug-in only supported a single directory and the corresponding option was called `g:notes_directory`. When support for multiple notes directories was introduced the option was renamed to `g:notes_directories` to reflect that the value is now a list of directory pathnames.
49+
50+
For backwards compatibility with old configurations (all of them as of this writing :-) the notes plug-in still uses `g:notes_directory` when it is defined (its no longer defined by the plug-in). However when the plug-in warns you to change your configuration you probably should because this compatibility will be removed at some point.
51+
4652
### The `g:notes_suffix` option
4753

4854
The suffix to add to generated filenames. The plug-in generates filenames for your notes based on the title (first line) of each note and by default these filenames don't include an extension like `.txt`. You can use this option to make the plug-in automatically append an extension without having to embed the extension in the note's title, e.g.:
@@ -103,28 +109,32 @@ This option defines the pathname of the text file that stores the list of known
103109

104110
## Commands
105111

106-
To edit one of your existing notes you can use Vim commands such as [:edit] [edit], [:split] [split] and [:tabedit] [tabedit] with a filename that starts with *note:* followed by (part of) the title of one of your notes, e.g.:
112+
To edit one of your existing notes (or create a new one) you can use Vim commands such as [:edit] [edit], [:split] [split] and [:tabedit] [tabedit] with a filename that starts with *note:* followed by (part of) the title of one of your notes, e.g.:
107113

108114
:edit note:todo
109115

110116
This shortcut also works from the command line:
111117

112118
$ gvim note:todo
113119

114-
When you don't follow *note:* with anything a new note is created.
120+
When you don't follow *note:* with anything a new note is created like when you execute `:Note` without any arguments.
115121

116122
### The `:Note` command
117123

118124
When executed without any arguments this command starts a new note in the current window. If you pass one or more arguments the command will edit an existing note containing the given words in the title. If more than one note is found you'll be asked which note you want to edit. If no notes are found a new note is started with the given word(s) as title.
119125

120126
This command will fail when changes have been made to the current buffer, unless you use `:Note!` which discards any changes.
121127

128+
When you are using multiple directories to store your notes and you run `:Note` while editing an existing note, a new note will inherit the directory of the note from which you started. Otherwise the note is created in the first directory in `g:notes_directories`.
129+
122130
*This command supports tab completion:* If you complete one word, all existing notes containing the given word somewhere in their title are suggested. If you type more than one word separated by spaces, the plug-in will complete only the missing words so that the resulting command line contains the complete note title and nothing more.
123131

124132
### The `:NoteFromSelectedText` command
125133

126134
Start a new note in the current window with the selected text as the title of the note. The name of this command isn't very well suited to daily use, that's because it's intended to be executed from a mapping. The default mapping for this command is `\en` (the backslash is actually the character defined by the [mapleader] [mapleader] variable).
127135

136+
When you are using multiple directories to store your notes and you run `:NoteFromSelectedText` while editing an existing note, the new note will inherit the directory of the note from which it was created.
137+
128138
### The `:SplitNoteFromSelectedText` command
129139

130140
Same as `:NoteFromSelectedText` but opens the new note in a vertical split window. The default mapping for this command is `\sn`.

autoload/xolox/notes.vim

Lines changed: 63 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
" Vim auto-load script
22
" Author: Peter Odding <peter@peterodding.com>
3-
" Last Change: May 6, 2013
3+
" Last Change: May 12, 2013
44
" URL: http://peterodding.com/code/vim/notes/
55

66
" Note: This file is encoded in UTF-8 including a byte order mark so
77
" that Vim loads the script using the right encoding transparently.
88

9-
let g:xolox#notes#version = '0.18.3'
9+
let g:xolox#notes#version = '0.19'
1010
let s:scriptdir = expand('<sfile>:p:h')
1111

1212
call xolox#misc#compat#check('notes', 2)
@@ -26,11 +26,17 @@ function! xolox#notes#init() " {{{1
2626
else
2727
let localdir = xolox#misc#path#absolute('~/.vim/misc/notes')
2828
endif
29+
" Backwards compatibility with old configurations.
30+
if exists('g:notes_directory')
31+
call xolox#misc#msg#warn("notes.vim %s: Please upgrade your configuration, see :help notes-backwards-compatibility", g:xolox#notes#version)
32+
let g:notes_directories = [g:notes_directory]
33+
unlet g:notes_directory
34+
endif
2935
" Define the default location where the user's notes are saved?
30-
if !exists('g:notes_directory')
31-
let g:notes_directory = xolox#misc#path#merge(localdir, 'user')
36+
if !exists('g:notes_directories')
37+
let g:notes_directories = [xolox#misc#path#merge(localdir, 'user')]
3238
endif
33-
call s:create_notes_directory()
39+
call s:create_notes_directories()
3440
" Define the default location of the shadow directory with predefined notes?
3541
if !exists('g:notes_shadowdir')
3642
let g:notes_shadowdir = xolox#misc#path#merge(systemdir, 'shadow')
@@ -82,15 +88,16 @@ function! xolox#notes#init() " {{{1
8288
endif
8389
endfunction
8490

85-
function! s:create_notes_directory()
86-
let notes_directory = expand(g:notes_directory)
87-
if !isdirectory(notes_directory)
88-
call xolox#misc#msg#info("notes.vim %s: Creating notes directory (first run?) ..", g:xolox#notes#version)
89-
call mkdir(notes_directory, 'p')
90-
endif
91-
if filewritable(notes_directory) != 2
92-
call xolox#misc#msg#warn("notes.vim %s: The notes directory (%s) is not writable!", g:xolox#notes#version, notes_directory)
93-
endif
91+
function! s:create_notes_directories()
92+
for directory in xolox#notes#find_directories(0)
93+
if !isdirectory(directory)
94+
call xolox#misc#msg#info("notes.vim %s: Creating notes directory %s (first run?) ..", g:xolox#notes#version, directory)
95+
call mkdir(directory, 'p')
96+
endif
97+
if filewritable(directory) != 2
98+
call xolox#misc#msg#warn("notes.vim %s: The notes directory %s is not writable!", g:xolox#notes#version, directory)
99+
endif
100+
endfor
94101
endfunction
95102

96103
function! xolox#notes#shortcut() " {{{1
@@ -595,6 +602,17 @@ endfunction
595602

596603
" Miscellaneous functions. {{{1
597604

605+
function! xolox#notes#find_directories(include_shadow_directory) " {{{2
606+
" Generate a list of absolute pathnames of all notes directories.
607+
let directories = copy(g:notes_directories)
608+
" Add the shadow directory?
609+
if a:include_shadow_directory
610+
call add(directories, g:notes_shadowdir)
611+
endif
612+
" Return the expanded directory pathnames.
613+
return map(directories, 'expand(v:val)')
614+
endfunction
615+
598616
function! xolox#notes#set_filetype() " {{{2
599617
" Load the notes file type if not already loaded.
600618
if &filetype != 'notes'
@@ -646,7 +664,14 @@ endfunction
646664

647665
function! xolox#notes#buffer_is_note() " {{{2
648666
" Check whether the current buffer is a note (with the correct file type and path).
649-
return xolox#notes#filetype_is_note(&ft) && xolox#misc#path#equals(expand('%:p:h'), g:notes_directory)
667+
let bufpath = expand('%:p:h')
668+
if xolox#notes#filetype_is_note(&ft)
669+
for directory in xolox#notes#find_directories(1)
670+
if xolox#misc#path#equals(bufpath, directory)
671+
return 1
672+
endif
673+
endfor
674+
endif
650675
endfunction
651676

652677
function! xolox#notes#current_title() " {{{2
@@ -771,10 +796,13 @@ function! s:python_command(...) " {{{2
771796
if !(executable(python) && filereadable(script))
772797
call xolox#misc#msg#debug("notes.vim %s: We can't execute the %s script!", g:xolox#notes#version, script)
773798
else
774-
let options = ['--database', g:notes_indexfile, '--notes', g:notes_directory]
799+
let options = ['--database', g:notes_indexfile]
775800
if &ignorecase
776801
call add(options, '--ignore-case')
777802
endif
803+
for directory in xolox#notes#find_directories(0)
804+
call extend(options, ['--notes', directory])
805+
endfor
778806
let arguments = map([script] + options + a:000, 'xolox#misc#escape#shell(v:val)')
779807
let command = join([python] + arguments)
780808
call xolox#misc#msg#debug("notes.vim %s: Executing external command %s", g:xolox#notes#version, command)
@@ -812,9 +840,11 @@ function! xolox#notes#get_fnames(include_shadow_notes) " {{{3
812840
" Get list with filenames of all existing notes.
813841
if !s:have_cached_names
814842
let starttime = xolox#misc#timer#start()
815-
let pattern = xolox#misc#path#merge(g:notes_directory, '*')
816-
let listing = glob(xolox#misc#path#absolute(pattern))
817-
call extend(s:cached_fnames, filter(split(listing, '\n'), 'filereadable(v:val)'))
843+
for directory in xolox#notes#find_directories(0)
844+
let pattern = xolox#misc#path#merge(directory, '*')
845+
let listing = glob(xolox#misc#path#absolute(pattern))
846+
call extend(s:cached_fnames, filter(split(listing, '\n'), 'filereadable(v:val)'))
847+
endfor
818848
let s:have_cached_names = 1
819849
call xolox#misc#timer#stop('notes.vim %s: Cached note filenames in %s.', g:xolox#notes#version, starttime)
820850
endif
@@ -891,12 +921,25 @@ function! xolox#notes#title_to_fname(title) " {{{3
891921
" Convert note {title} to absolute filename.
892922
let filename = xolox#misc#path#encode(a:title)
893923
if filename != ''
894-
let pathname = xolox#misc#path#merge(g:notes_directory, filename . g:notes_suffix)
924+
let directory = xolox#notes#select_directory()
925+
let pathname = xolox#misc#path#merge(directory, filename . g:notes_suffix)
895926
return xolox#misc#path#absolute(pathname)
896927
endif
897928
return ''
898929
endfunction
899930

931+
function! xolox#notes#select_directory() " {{{3
932+
" Pick the best suited directory for creating a new note.
933+
let bufdir = expand('%:p:h')
934+
let notes_directories = xolox#notes#find_directories(0)
935+
for directory in notes_directories
936+
if xolox#misc#path#equals(bufdir, directory)
937+
return directory
938+
endif
939+
endfor
940+
return notes_directories[0]
941+
endfunction
942+
900943
function! xolox#notes#cache_add(filename, title) " {{{3
901944
" Add {filename} and {title} of new note to cache.
902945
let filename = xolox#misc#path#absolute(a:filename)

doc/notes.txt

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ Contents ~
77
1. Introduction |notes-introduction|
88
2. Install & usage |notes-install-usage|
99
3. Options |notes-options|
10-
1. The |g:notes_directory| option
10+
1. The |g:notes_directories| option
11+
1. Backwards compatibility |notes-backwards-compatibility|
1112
2. The |g:notes_suffix| option
1213
3. The |g:notes_title_sync| option
1314
4. The |g:notes_smart_quotes| option
@@ -134,17 +135,18 @@ installation you don't need to change any options. They're available for
134135
people who like to customize their directory layout. These options can be
135136
configured in your |vimrc| script by including a line like this:
136137
>
137-
:let g:notes_directory = '~/Documents/Notes'
138+
:let g:notes_directories = ['~/Documents/Notes', '~/Dropbox/Shared Notes']
138139
139140
Note that after changing an option in your |vimrc| script you have to restart
140141
Vim for the changes to take effect.
141142

142143
-------------------------------------------------------------------------------
143-
The *g:notes_directory* option
144+
The *g:notes_directories* option
144145

145-
All your notes are stored together in one directory. This option defines the
146-
path of this directory. The default value depends on circumstances but should
147-
work for most people:
146+
Your notes are stored in one or more directories. This option defines where
147+
you want to store your notes. Its value should be a list (there's an example
148+
above) with one or more pathnames. The default is a single value which depends
149+
on circumstances but should work for most people:
148150

149151
- If the profile directory where the plug-in is installed is writable, the
150152
directory 'misc/notes/user' under the profile directory is used. This is
@@ -155,6 +157,22 @@ work for most people:
155157
'~/vimfiles/misc/notes/user' on Windows and '~/.vim/misc/notes/user' on
156158
other platforms.
157159

160+
-------------------------------------------------------------------------------
161+
*notes-backwards-compatibility*
162+
Backwards compatibility ~
163+
164+
In the past the notes plug-in only supported a single directory and the
165+
corresponding option was called 'g:notes_directory'. When support for multiple
166+
notes directories was introduced the option was renamed to
167+
|g:notes_directories| to reflect that the value is now a list of directory
168+
pathnames.
169+
170+
For backwards compatibility with old configurations (all of them as of this
171+
writing :-) the notes plug-in still uses 'g:notes_directory' when it is
172+
defined (its no longer defined by the plug-in). However when the plug-in warns
173+
you to change your configuration you probably should because this
174+
compatibility will be removed at some point.
175+
158176
-------------------------------------------------------------------------------
159177
The *g:notes_suffix* option
160178

@@ -266,17 +284,18 @@ can recreate it manually by executing |:IndexTaggedNotes| (see below).
266284
*notes-commands*
267285
Commands ~
268286

269-
To edit one of your existing notes you can use Vim commands such as |:edit|,
270-
|:split| and |:tabedit| with a filename that starts with note: followed by (part
271-
of) the title of one of your notes, e.g.:
287+
To edit one of your existing notes (or create a new one) you can use Vim
288+
commands such as |:edit|, |:split| and |:tabedit| with a filename that starts with
289+
note: followed by (part of) the title of one of your notes, e.g.:
272290
>
273291
:edit note:todo
274292
275293
This shortcut also works from the command line:
276294
>
277295
$ gvim note:todo
278296
279-
When you don't follow note: with anything a new note is created.
297+
When you don't follow note: with anything a new note is created like when you
298+
execute |:Note| without any arguments.
280299

281300
-------------------------------------------------------------------------------
282301
The *:Note* command
@@ -290,6 +309,11 @@ new note is started with the given word(s) as title.
290309
This command will fail when changes have been made to the current buffer,
291310
unless you use ':Note!' which discards any changes.
292311

312+
When you are using multiple directories to store your notes and you run
313+
|:Note| while editing an existing note, a new note will inherit the directory
314+
of the note from which you started. Otherwise the note is created in the first
315+
directory in |g:notes_directories|.
316+
293317
This command supports tab completion: If you complete one word, all existing
294318
notes containing the given word somewhere in their title are suggested. If you
295319
type more than one word separated by spaces, the plug-in will complete only
@@ -305,6 +329,10 @@ because it's intended to be executed from a mapping. The default mapping for
305329
this command is '\en' (the backslash is actually the character defined by the
306330
|mapleader| variable).
307331

332+
When you are using multiple directories to store your notes and you run
333+
|:NoteFromSelectedText| while editing an existing note, the new note will
334+
inherit the directory of the note from which it was created.
335+
308336
-------------------------------------------------------------------------------
309337
The *:SplitNoteFromSelectedText* command
310338

0 commit comments

Comments
 (0)