On Mon, Jul 13, 2009 at 5:06 PM, Toni Ruottu<[email protected]> wrote:
>
> I'd be perfectly happy in doing :w! and getting the file saved under a
> random named (like the ones you proposed) under ~/.vim/rubbish/. If
> someone then wants to make more advanced user interfaces for exploring
> the rubbish folder, that is fine with me too, but I'd do fine without
> one. I don't mind tidying the files in that folder up every once in a
> while, as long as my work is not interrupted with irritating problems,
> like thinking of file names.

It should be easy enough to create an autocommand that takes the first
line in the text and create a filename for it. I have been using a
small windows note taking utility called Tombo (for historical reasons
originating from Windows Mobile) that actually does this. You just
create a new note and start typing in, and on the first save, it
automatically names the file on the filesystem based on the first line
in the text (this is also how MS Word and quite a few other programs
suggest a name for a new document). I had been thinking of bringing
that convenience to Vim such that I can just stop using Tombo and
switch to Vim for all my note taking. The features that I really need
are:
- Ease of starting a new note
- Automatic naming and saving of new notes under predefined directory
- Tree view of the notes directory for the ease of browsing and opening notes
- Ease of organizing the notes (cut/copy/paste/delete) from tree view
- Sync the name of the file when the note header is updated

After seeing this thread, I got motivated to work on it and have the
attached script so far (CAUTION: It is work in progress). To use it,
configure the first few variables and use :Note command to create a
new note or specify an existing one.

It will be nice if I can find signers for doing early testing and
sending feedback and suggestions.

-- Hari

PS: not sure if attachments are allowed, so copy pasting below, hoping
it won't get truncated.
------------------notes.vim------------------
" TODO:
" - The technique doesn't work with unnamed files, vim refuses to allow :w
"   command.
" - Lots of testing
" - Filename completion for Note
" - Better name generation for automatic names
" - Tree view and note management
" - Plugginization
"
let g:notesRoot = 'c:/tmp/root' " Please, no trailing-slash for now.
let g:notesDefaultName = 'New Note' " Add .txt automatically.
let g:notesMaxNameLenth = 100
let g:notesSyncNameAndTitle = 1

if !isdirectory(g:notesRoot)
    echohl ErrorMsg | echomsg "Notes: Configured root doesn't exist or
is not a directory: " .
                \ g:notesRoot | echohl NONE
endif

command! -nargs=? Note :call OpenNote('<args>')
function! OpenNote(notePath)
    if a:notePath == ''
        let notePath = NewName(g:notesRoot, g:notesDefaultName)
    else
        if (len(filter(['win16', 'win32', 'win65', 'win95', 'dos16',
'dos32'], 'has(v:val)')) > 0 &&
                    \ a:notePath =~ '^\([a-zA-Z]:\|[/\\]\)') || a:notePath =~ 
'^/'
            " This is an absolute path
            if fnamemodify(a:notePath, ':h') != fnamemodify(g:notesRoot)
                echohl ErrorMsg | echohl 'Note not under g:notesRoot' | echohl 
None
                return
            endif
            let notePath = a:notePath
        else
            let notePath = fnamemodify(g:notesRoot.'/'.a:notePath, ':p')
        endif
    endif
    exec 'sp' notePath
    call InstallAutoCmd()
endfunction

function! InstallAutoCmd()
    aug NoteSync
        au BufWriteCmd <buffer> :call feedkeys(":SyncNoteName!\<CR>", 'n')
    aug END
endfunction

function! UninstallAutoCmd()
    aug NoteSync
        au! BufWriteCmd <buffer>
    aug END
endfunction

command! -bang SyncNoteName :call SyncNoteName(expand('<bang>') == '!' ? 1 : 0)
" Look at the first non-empty line and sync the filename to it.
function! SyncNoteName(save) abort
    if &modified
        if !a:save
            echohl ErrorMsg | echo 'Note currently modified, save it first' |
echohl NONE
            return
        endif
        try
            call UninstallAutoCmd()
            write!
        catch
            echohl ErrorMsg | echo 'Error saving the file: '.v:exception | 
echohl NONE
            return
        finally
            call InstallAutoCmd()
        endtry
    endif
    if !g:notesSyncNameAndTitle
        return
    endif

    let goodLine = ''
    for lineNr in range(1, line('$'))
        let line = getline(lineNr)
        if line =~ '\w'
            let goodLine = line
            break
        endif
    endfor
    if goodLine != ''
        let name = substitute(line, '[^[:alnum:]_ ]', '_', 'g')[:
g:notesMaxNameLenth-1]
        let newNotePath = NewName(g:notesRoot, name)
        let prevNotePath = expand('%:p')
        if NoteRootName(newNotePath) == NoteRootName(prevNotePath)
            return
        endif
        if writefile(map(getline(1, '$'), '&ff == "dos" ? v:val."\<CR>" :
v:val'), newNotePath) == 0
            " Success copying the contents, we can now switch to the new
            " note and remove the other note
            try
                exec 'edit' newNotePath
                call InstallAutoCmd()
            catch
                if expand('%:p') == fnamemodify(prevNotePath, ':p')
                    " We are still in the previous note, it is safe to remove
                    " the intermediate file.
                    if delete(newNotePath) != 0
                        echohl ErrorMsg |
                                    \ echomsg 'An unexpected error prevented 
sync and '.
                                    \ 'deleting the intermediate file also 
failed, manual '.
                                    \ 'removal is required for: 
'.newNotePath."\nOriginal error: ".
                                    \ v:exception |
                                    \ echohl NONE
                    endif
                    if expand('#:p') == fnamemodify(newNotePath, ':p')
                        bw #
                    endif
                else
                    echohl ErrorMsg |
                                \ echomsg 'Aborted sync on an unxpected error, 
old path: '.
                                \ prevNotePath. ' new path:'.newNotePath |
                                \ echohl NONE
                endif
            endtry
            if delete(prevNotePath) != 0
                echohl ErrorMsg | echomsg 'Error removing the old path to the 
note:
'.prevNotePath | echohl NONE
            else
                silent! bw #
            endif
        endif
    endif
endfunction

" Creates a new note and returns the path.
" This should really be the job of tempname(), but it doesn't accept the
" directory and prefix (like the Java's utility does)
" LIMITATIONS:
" - Has to start with "1" for the first file for the logic to work, will be
"   nice if number is inserted only from "2" onwards.
function! NewName(dir, prefix)
    let curSuffixMax = max(sort(map(map(
                \ split(glob(a:dir.'/'.a:prefix.'*.txt'), "\<NL>"),
                \   'substitute(v:val, "^.*\\(\\d\\+\\)\\s*\\.txt$", "\\1", 
"")'),
                \ 'v:val + 0'), 'NumCompare'))
    let newNamePath = a:dir . '/' . a:prefix . ' '.(curSuffixMax + 1) . '.txt'
    " Just make sure we will not accidentally overwrite an existing file.
    if exists(newNamePath)
        throw "Notes:Couldn't create a new note, found an existing note with
the same name: " . newNamePath
    endif
    if writefile([], newNamePath) != 0
        throw "Notes:writefile() failed to create new note: " . newNamePath
    endif
    return newNamePath
endfunction

function! NumCompare(i1, i2)
    return a:i1 == a:i2 ? 0 : a:i1 > a:i2 ? 1 : -1
endfunc

function! NoteRootName(noteName)
    let noteName = fnamemodify(a:noteName, ':t:r')
    return substitute(noteName, '\d\+\s*$', '', '')
endfunction
------------------notes.vim------------------

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Attachment: notes.vim
Description: Binary data

Raspunde prin e-mail lui