一直想找个用vim来管理todo列表的script, 没发现特别好用的,
自己写了个,用sqlite来保存数据.
将下面代码存为 SzTodo.vim,放到plugin目录里.
用 :SzTodo 启动.
自己写了个,用sqlite来保存数据.
将下面代码存为 SzTodo.vim,放到plugin目录里.
用 :SzTodo 启动.
let g:sztodo_db_path="/root/.vim/todo"
let s:list_type="unfinished"
let s:cur_buf = 0
function! MakeTemplate()
python << EOF
import vim
vim.command("call SwitchToDetailView()")
vim.command("call SetSyntax()")
template = "=" * 50 + "\n" \
+ "tag:" +"\n" \
+ "title:" + "\n" \
+ "=" * 50 + "\n"
for index,line in enumerate(template.split("\n")):
if index ==0 :
vim.current.buffer[0]=line
else :
vim.current.buffer.append(line)
EOF
endfunction
function! SaveTodoItem()
python << EOF
import vim
def loadData(lines):
item=ToDoItem()
content=""
seperates=0
for line in lines:
if line.startswith("====="): seperates=seperates+1
if line.startswith("id:"): item.id=line[3:].strip()
if line.startswith("tag:"): item.tag=line[4:].strip()
if line.startswith("title:"): item.title=line[6:].strip()
if line.startswith("status:"): item.status=line[7:].strip()
if seperates==2 and not line.startswith("===="):
content=content+line+"\n"
item.content=content[:-1]
return item
def addItem(item):
insertSql="insert into SzTodo(tag,title,create_date,status,content) values (?,?,?,?,?)"
con=sqlite.connect(getDbFileName())
cur=con.cursor()
values=(item.tag,item.title,item.create_date,item.status,item.content)
cur.execute(insertSql,values)
con.commit()
con.close()
def updateItem(item):
updateSql="update SzTodo set tag=?,title=?,create_date=?,status=?,content=? where id=?"
con=sqlite.connect(getDbFileName())
cur=con.cursor()
values=(item.tag,item.title,item.create_date,item.status,item.content,item.id)
cur.execute(updateSql,values)
con.commit()
con.close()
data=vim.current.buffer[:]
todoItem=loadData(data)
if not todoItem.title:
print "title can't be empty"
else:
if todoItem.id.strip() == "" :
todoItem.create_date=getCurrentDate()
todoItem.status="unstarted"
addItem(todoItem)
else :
updateItem(todoItem)
print "todo has been saved"
EOF
exec bufwinnr(s:cur_buf) . "wincmd w"
call ListItems()
endfunction
function! ListItems()
python << EOF
import vim
listFinished=vim.eval("s:list_type")
vim.current.buffer[:]=None
vim.command("set nonumber")
if listFinished=="finished":
selectSql="select id,tag,title,create_date,content from SzTodo where status == 'done' "
else:
selectSql="select id,tag,title,create_date,content from SzTodo where status != 'done' "
con=sqlite.connect(getDbFileName())
cur=con.cursor()
items=[]
cur.execute(selectSql)
for index,row in enumerate(cur):
formatedItem=str(row[0])+". "+str(unicode(row[2]).encode("utf-8"))
if index==0:
vim.current.buffer[0]=formatedItem
else :
vim.current.buffer.append(formatedItem)
con.commit()
con.close()
EOF
endfunction
function! SwitchToDetailView()
let s:cur_buf = bufnr("%")
let s:szdb_result_buf=bufnr("SztodoDetail")
if bufwinnr(s:szdb_result_buf) > 0
exec bufwinnr(s:szdb_result_buf) . "wincmd w"
%d
else
exec 'silent! botright split SztodoDetail'
exec "e SztodoDetail"
exec "set nowrap"
map <silent><buffer>s :call SaveTodoItem()<cr>
endif
endfunction
function! ShowItemDetail(preview)
python << EOF
import vim
(row, col) = vim.current.window.cursor
line = vim.current.buffer[row-1]
id=line[0:line.find(".")]
selectSql="select id,tag,title,create_date,content,status from SzTodo where id=?"
con=sqlite.connect(getDbFileName())
cur=con.cursor()
cur.execute(selectSql,(id,))
todoItem=ToDoItem()
for row in cur:
todoItem.id=row[0]
todoItem.tag=unicode(row[1]).encode("utf-8")
todoItem.title=unicode(row[2]).encode("utf-8")
todoItem.create_date=unicode(row[3]).encode("utf-8")
todoItem.content=unicode(row[4]).encode("utf-8")
todoItem.status=unicode(row[5]).encode("utf-8")
vim.command("call SwitchToDetailView()")
vim.command("call SetSyntax()")
for index,line in enumerate(str(todoItem).split("\n")):
if index==0:
vim.current.buffer[0]=line
else:
vim.current.buffer.append(line)
EOF
if a:preview=="true"
exec bufwinnr(s:cur_buf) . "wincmd w"
endif
endfunction
function! UpdateItemStatus(status)
let choice=input('you really want to update the todo item status to '.a:status."?[y/n]")
if choice=="n"
return
endif
python << EOF
import vim
(row, col) = vim.current.window.cursor
line = vim.current.buffer[row-1]
id=line[0:line.find(".")]
updateSql="update SzTodo set status = ? where id=?"
status=vim.eval("a:status")
con=sqlite.connect(getDbFileName())
cur=con.cursor()
cur.execute(updateSql,(status,id))
con.commit()
con.close()
EOF
endfunction
function! InitDb()
python << EOF
import vim
import os
createSql="create table SzTodo (id integer primary key , tag char(20), title varchar(200), \
create_date varchar(10),status char(1),content varchar(5000))"
path=os.path.dirname(getDbFileName())
if not os.path.exists(path):
os.makedirs(path)
con=sqlite.connect(getDbFileName())
cur=con.cursor()
cur.execute(createSql)
con.commit()
con.close()
print "db has been created"
EOF
endfunction
function! s:DefSzTodoGlobal()
python << EOF
import vim
from pysqlite2 import dbapi2 as sqlite
statusDict=dict(done="done",postpone="postpone",doing="doing",unstarted="unstarted")
class ToDoItem(object):
def __init__(self,id="",tag="",title="",content="",create_date="",status=""):
self.id=id
self.tag=tag
self.title=title
self.create_date=create_date
self.status=status
self.content=content
def __str__(self):
return "=" * 50 + "\n" \
+ "id:" + str(self.id) +"\n" \
+ "tag:" + self.tag +"\n" \
+ "title:" + self.title + "\n" \
+ "status:" + self.status + "\n" \
+ "=" * 50 + "\n" \
+ self.content
def getCurrentDate():
from datetime import datetime
t=datetime.now()
return t.strftime("%Y-%m-%d %H:%M")
def getDbFileName():
dbpath=vim.eval("g:sztodo_db_path")
path=os.path.join(dbpath,"todo.dat")
return path
EOF
endfunction
function! StartApp()
python << EOF
import vim
import os
if not os.path.exists(getDbFileName()):
vim.command("call InitDb()")
vim.command("call ListItems()")
vim.command("call SetMapping()")
EOF
endfunction
function! SetMapping()
map <silent><buffer> o :call ShowItemDetail("false")<cr>
map <silent><buffer> s :call ShowItemDetail("true")<cr>
map <silent><buffer> i :call MakeTemplate()<cr>
map <silent><buffer> r :call ListItems()<cr>
map <silent><buffer> p :call UpdateItemStatus("postpone")<cr>
map <silent><buffer> d :call UpdateItemStatus("done")<cr>
command! -nargs=0 FinishedItem :call FinishedItem()
command! -nargs=0 UnfinishedItem :call UnfinishedItem()
endfunction
function! FinishedItem()
let s:list_type="finished"
call ListItems()
endfunction
function! UnfinishedItem()
let s:list_type="unfinished"
call ListItems()
endfunction
function! SetSyntax()
syn keyword sztodoKeyword tag title id status
syn keyword sztodoStatus unstarted done doing postpone
syn match tag "^tag:.*"
syn match title "^title:.*"
syn match id "^id:.*"
syn match status "^status:.*"
hi def link sztodoKeyword Keyword
hi def link sztodoStatus Identifier
hi def link tag String
hi def link id String
hi def link title String
hi def link status String
endfunction
call s:DefSzTodoGlobal()
command! -nargs=0 SzTodo :call StartApp()