phi_st
phi_st

Reputation: 55

Using Vim in a GTD way

I'd like to change my habit in the way I take notes.

I want add files named YYYYmmddHHiiss.txt in a directory and start them this way:

=Call somebody (title of my note)
@work (context of my note)
!todo (type of the note, I'll use !inbox, !todo, !waiting, !someday and !reference, each one his habit)
#project_name
#call
#Name of the person
#other tags if needed...

Details...

What I'd like is:

Model

:GtdGrep !todo @work
:GtdGrep !inbox
:GtdGrep @waiting @home
:GtdGrep !todo @work #this_project
:GtdGrep #name_of_a_co-worker #this_project

Now that I introduced you my need, I can start describing my problem ^^ I want to create the function behind the :GtdGrep command but there is a lot of things I don't manage to gather... Here is my draft.

let gtd_dir=expand($HOME)."/Desktop/notes"

function! GtdGrep(...)
    execute "silent! vimgrep /\%<10l".join(a:000, "\\_.*")."/j ".gtd_dir."/**"
    execute "copen"
endfunction
command! -nargs=* GtdGrep call GtdGrep(<f-args>)
  1. How to restrain the search before the first empty line? I managed to look for my tags in the first 9 lines with the regexp \%<10l but that's it.
  2. How to look for my tags regardless of their positions in the file? I just succeeded to do the grep on several lines with the \_.* regexp which is for the line returns.
  3. The icing on the cake will be that the display on the quickfix window focus on the title part of my note (after /^=). I think it is possible with a ^=\zs.*\ze but it is too much for me in a single vimgrep!

EDIT

I solve my "AND" vimgrep issue by doing successive vimgrep on the previous results. Is it a good solution?

let gtd_dir=expand($HOME)."/Desktop/notes"

function! GtdGrep(...)
    let dest = g:gtd_dir."/**"
    for arg in a:000
        execute "silent! vimgrep /^".arg."$/j ".dest
        let dest = []
        let results = getqflist()
        if empty(results)
            break
        else
            for res in results
                 call add(dest, bufname(res.bufnr))
            endfor
            let dest = join(dest, ' ')
        endif
    endfor

    " Last vimgrep to focus on titles before displaying results
    let results = getqflist()
    if !empty(results)
        echom dest
        execute "silent! vimgrep /\\%<10l^=.*/j ".dest
        execute "copen"
    else
        echom "No results"
    endif
endfunction
command! -nargs=* GtdGrep call GtdGrep(<f-args>)

I'd like to restrain my vimgrep on the lines before the first blank line but I didn't succeed to do this. Any idea?

Upvotes: -1

Views: 1068

Answers (1)

Kent
Kent

Reputation: 195029

First of all, you should know the risk if you use dynamic string as pattern. E.g. your project_name contains [].*()...

What you can try is, building this command:

vimgrep '/\%<10l\(foo\|bar\|blah\|whatever\)' path/*

Upvotes: 0

Related Questions