Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Support for multiple directories with notes (related to issue #18)
Issue #18 on GitHub:
  #18
  • Loading branch information
xolox committed May 12, 2013
1 parent cbf4f3b commit a523c28
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 55 deletions.
20 changes: 15 additions & 5 deletions README.md
Expand Up @@ -31,18 +31,24 @@ Unzip the most recent [ZIP archive] [download] file inside your Vim profile dire

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:

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

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

### The `g:notes_directory` option
### The `g:notes_directories` option

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:
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:

* 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.

* 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.

#### Backwards compatibility

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.

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.

### The `g:notes_suffix` option

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.:
Expand Down Expand Up @@ -103,28 +109,32 @@ This option defines the pathname of the text file that stores the list of known

## Commands

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.:
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.:

:edit note:todo

This shortcut also works from the command line:

$ gvim note:todo

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

### The `:Note` command

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.

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

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`.

*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.

### The `:NoteFromSelectedText` command

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).

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.

### The `:SplitNoteFromSelectedText` command

Same as `:NoteFromSelectedText` but opens the new note in a vertical split window. The default mapping for this command is `\sn`.
Expand Down
83 changes: 63 additions & 20 deletions autoload/xolox/notes.vim
@@ -1,12 +1,12 @@
" Vim auto-load script
" Author: Peter Odding <peter@peterodding.com>
" Last Change: May 6, 2013
" Last Change: May 12, 2013
" URL: http://peterodding.com/code/vim/notes/

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

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

call xolox#misc#compat#check('notes', 2)
Expand All @@ -26,11 +26,17 @@ function! xolox#notes#init() " {{{1
else
let localdir = xolox#misc#path#absolute('~/.vim/misc/notes')
endif
" Backwards compatibility with old configurations.
if exists('g:notes_directory')
call xolox#misc#msg#warn("notes.vim %s: Please upgrade your configuration, see :help notes-backwards-compatibility", g:xolox#notes#version)
let g:notes_directories = [g:notes_directory]
unlet g:notes_directory
endif
" Define the default location where the user's notes are saved?
if !exists('g:notes_directory')
let g:notes_directory = xolox#misc#path#merge(localdir, 'user')
if !exists('g:notes_directories')
let g:notes_directories = [xolox#misc#path#merge(localdir, 'user')]
endif
call s:create_notes_directory()
call s:create_notes_directories()
" Define the default location of the shadow directory with predefined notes?
if !exists('g:notes_shadowdir')
let g:notes_shadowdir = xolox#misc#path#merge(systemdir, 'shadow')
Expand Down Expand Up @@ -82,15 +88,16 @@ function! xolox#notes#init() " {{{1
endif
endfunction

function! s:create_notes_directory()
let notes_directory = expand(g:notes_directory)
if !isdirectory(notes_directory)
call xolox#misc#msg#info("notes.vim %s: Creating notes directory (first run?) ..", g:xolox#notes#version)
call mkdir(notes_directory, 'p')
endif
if filewritable(notes_directory) != 2
call xolox#misc#msg#warn("notes.vim %s: The notes directory (%s) is not writable!", g:xolox#notes#version, notes_directory)
endif
function! s:create_notes_directories()
for directory in xolox#notes#find_directories(0)
if !isdirectory(directory)
call xolox#misc#msg#info("notes.vim %s: Creating notes directory %s (first run?) ..", g:xolox#notes#version, directory)
call mkdir(directory, 'p')
endif
if filewritable(directory) != 2
call xolox#misc#msg#warn("notes.vim %s: The notes directory %s is not writable!", g:xolox#notes#version, directory)
endif
endfor
endfunction

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

" Miscellaneous functions. {{{1

function! xolox#notes#find_directories(include_shadow_directory) " {{{2
" Generate a list of absolute pathnames of all notes directories.
let directories = copy(g:notes_directories)
" Add the shadow directory?
if a:include_shadow_directory
call add(directories, g:notes_shadowdir)
endif
" Return the expanded directory pathnames.
return map(directories, 'expand(v:val)')
endfunction

function! xolox#notes#set_filetype() " {{{2
" Load the notes file type if not already loaded.
if &filetype != 'notes'
Expand Down Expand Up @@ -646,7 +664,14 @@ endfunction

function! xolox#notes#buffer_is_note() " {{{2
" Check whether the current buffer is a note (with the correct file type and path).
return xolox#notes#filetype_is_note(&ft) && xolox#misc#path#equals(expand('%:p:h'), g:notes_directory)
let bufpath = expand('%:p:h')
if xolox#notes#filetype_is_note(&ft)
for directory in xolox#notes#find_directories(1)
if xolox#misc#path#equals(bufpath, directory)
return 1
endif
endfor
endif
endfunction

function! xolox#notes#current_title() " {{{2
Expand Down Expand Up @@ -771,10 +796,13 @@ function! s:python_command(...) " {{{2
if !(executable(python) && filereadable(script))
call xolox#misc#msg#debug("notes.vim %s: We can't execute the %s script!", g:xolox#notes#version, script)
else
let options = ['--database', g:notes_indexfile, '--notes', g:notes_directory]
let options = ['--database', g:notes_indexfile]
if &ignorecase
call add(options, '--ignore-case')
endif
for directory in xolox#notes#find_directories(0)
call extend(options, ['--notes', directory])
endfor
let arguments = map([script] + options + a:000, 'xolox#misc#escape#shell(v:val)')
let command = join([python] + arguments)
call xolox#misc#msg#debug("notes.vim %s: Executing external command %s", g:xolox#notes#version, command)
Expand Down Expand Up @@ -812,9 +840,11 @@ function! xolox#notes#get_fnames(include_shadow_notes) " {{{3
" Get list with filenames of all existing notes.
if !s:have_cached_names
let starttime = xolox#misc#timer#start()
let pattern = xolox#misc#path#merge(g:notes_directory, '*')
let listing = glob(xolox#misc#path#absolute(pattern))
call extend(s:cached_fnames, filter(split(listing, '\n'), 'filereadable(v:val)'))
for directory in xolox#notes#find_directories(0)
let pattern = xolox#misc#path#merge(directory, '*')
let listing = glob(xolox#misc#path#absolute(pattern))
call extend(s:cached_fnames, filter(split(listing, '\n'), 'filereadable(v:val)'))
endfor
let s:have_cached_names = 1
call xolox#misc#timer#stop('notes.vim %s: Cached note filenames in %s.', g:xolox#notes#version, starttime)
endif
Expand Down Expand Up @@ -891,12 +921,25 @@ function! xolox#notes#title_to_fname(title) " {{{3
" Convert note {title} to absolute filename.
let filename = xolox#misc#path#encode(a:title)
if filename != ''
let pathname = xolox#misc#path#merge(g:notes_directory, filename . g:notes_suffix)
let directory = xolox#notes#select_directory()
let pathname = xolox#misc#path#merge(directory, filename . g:notes_suffix)
return xolox#misc#path#absolute(pathname)
endif
return ''
endfunction

function! xolox#notes#select_directory() " {{{3
" Pick the best suited directory for creating a new note.
let bufdir = expand('%:p:h')
let notes_directories = xolox#notes#find_directories(0)
for directory in notes_directories
if xolox#misc#path#equals(bufdir, directory)
return directory
endif
endfor
return notes_directories[0]
endfunction

function! xolox#notes#cache_add(filename, title) " {{{3
" Add {filename} and {title} of new note to cache.
let filename = xolox#misc#path#absolute(a:filename)
Expand Down
48 changes: 38 additions & 10 deletions doc/notes.txt
Expand Up @@ -7,7 +7,8 @@ Contents ~
1. Introduction |notes-introduction|
2. Install & usage |notes-install-usage|
3. Options |notes-options|
1. The |g:notes_directory| option
1. The |g:notes_directories| option
1. Backwards compatibility |notes-backwards-compatibility|
2. The |g:notes_suffix| option
3. The |g:notes_title_sync| option
4. The |g:notes_smart_quotes| option
Expand Down Expand Up @@ -134,17 +135,18 @@ 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 by including a line like this:
>
:let g:notes_directory = '~/Documents/Notes'
:let g:notes_directories = ['~/Documents/Notes', '~/Dropbox/Shared Notes']
Note that after changing an option in your |vimrc| script you have to restart
Vim for the changes to take effect.

-------------------------------------------------------------------------------
The *g:notes_directory* option
The *g:notes_directories* option

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:
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:

- 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
Expand All @@ -155,6 +157,22 @@ work for most people:
'~/vimfiles/misc/notes/user' on Windows and '~/.vim/misc/notes/user' on
other platforms.

-------------------------------------------------------------------------------
*notes-backwards-compatibility*
Backwards compatibility ~

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.

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.

-------------------------------------------------------------------------------
The *g:notes_suffix* option

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

To edit one of your existing notes you can use Vim commands such as |:edit|,
|:split| and |:tabedit| with a filename that starts with note: followed by (part
of) the title of one of your notes, e.g.:
To edit one of your existing notes (or create a new one) you can use Vim
commands such as |:edit|, |:split| and |:tabedit| with a filename that starts with
note: followed by (part of) the title of one of your notes, e.g.:
>
:edit note:todo
This shortcut also works from the command line:
>
$ gvim note:todo
When you don't follow note: with anything a new note is created.
When you don't follow note: with anything a new note is created like when you
execute |:Note| without any arguments.

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

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|.

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
Expand All @@ -305,6 +329,10 @@ 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| variable).

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.

-------------------------------------------------------------------------------
The *:SplitNoteFromSelectedText* command

Expand Down

0 comments on commit a523c28

Please sign in to comment.