阿里狼 发表于 2017-5-5 11:25:20

python写vim script 之 山寨版 GTD

一直想找个用vim来管理todo列表的script, 没发现特别好用的,
自己写了个,用sqlite来保存数据.
将下面代码存为 SzTodo.vim,放到plugin目录里.
用 :SzTodo启动.


letg:sztodo_db_path="/root/.vim/todo"
lets:list_type="unfinished"
lets: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=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.strip()
if line.startswith("tag:"): item.tag=line.strip()
if line.startswith("title:"): item.title=line.strip()
if line.startswith("status:"): item.status=line.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)+". "+str(unicode(row).encode("utf-8"))
if index==0:
vim.current.buffer=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
id=line
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
todoItem.tag=unicode(row).encode("utf-8")
todoItem.title=unicode(row).encode("utf-8")
todoItem.create_date=unicode(row).encode("utf-8")
todoItem.content=unicode(row).encode("utf-8")
todoItem.status=unicode(row).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=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."?")
if choice=="n"
return
endif
python << EOF
import vim
(row, col) = vim.current.window.cursor
line = vim.current.buffer
id=line
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()
页: [1]
查看完整版本: python写vim script 之 山寨版 GTD