Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement PLANNING line support #314

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions doc/orgguide.txt
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,13 @@ via the 'Org' menu. Most are only usable in command mode.
Dates:~
<localleader>sa - insert date
<localleader>si - insert inactive date
<localleader>ssc - set the SCHEDULED date of the current headline
<localleader>sdl - set the DEADLINE date of the current headline
<localleader>pa - insert date by using calendar selection
<localleader>pi - insert inactive date by using calendar selection
<localleader>psc - set the SCHEDULED date by using calendar selection
<localleader>pdl - set the DEADLINE date by using calendar selection


Agenda:~
<localleader>caa - agenda for the week
Expand Down
35 changes: 35 additions & 0 deletions ftplugin/org.vim
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ for p in vim.eval("&runtimepath").split(','):
break

from orgmode._vim import ORGMODE, insert_at_cursor, get_user_input, date_to_str
from orgmode._vim import ORGMODE, set_scheduled_date, set_deadline_date
ORGMODE.start()

from Date import Date
Expand Down Expand Up @@ -167,3 +168,37 @@ fun CalendarAction(day, month, year, week, dir)
" restore calendar_action
let g:calendar_action = g:org_calendar_action_backup
endf
fun CalendarActionScheduled(day, month, year, week, dir)
let g:org_timestamp = printf("%04d-%02d-%02d Fri", a:year, a:month, a:day)
let datetime_date = printf("datetime.date(%d, %d, %d)", a:year, a:month, a:day)
exe s:py_version . "selected_date = " . datetime_date
" get_user_input
let msg = printf("Inserting %s | Modify date", g:org_timestamp)
exe s:py_version . "modifier = get_user_input('" . msg . "')"
" change date according to user input
exe s:py_version . "newdate = Date._modify_time(selected_date, modifier)"
" close Calendar
exe "q"
" goto previous window
exe "wincmd p"
exe s:py_version . "set_scheduled_date(newdate)"
" restore calendar_action
let g:calendar_action = g:org_calendar_action_backup
endf
fun CalendarActionDeadline(day, month, year, week, dir)
let g:org_timestamp = printf("%04d-%02d-%02d Fri", a:year, a:month, a:day)
let datetime_date = printf("datetime.date(%d, %d, %d)", a:year, a:month, a:day)
exe s:py_version . "selected_date = " . datetime_date
" get_user_input
let msg = printf("Inserting %s | Modify date", g:org_timestamp)
exe s:py_version . "modifier = get_user_input('" . msg . "')"
" change date according to user input
exe s:py_version . "newdate = Date._modify_time(selected_date, modifier)"
" close Calendar
exe "q"
" goto previous window
exe "wincmd p"
exe s:py_version . "set_deadline_date(newdate)"
" restore calendar_action
let g:calendar_action = g:org_calendar_action_backup
endf
52 changes: 37 additions & 15 deletions ftplugin/orgmode/_vim.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from orgmode.exceptions import PluginError
from orgmode.vimbuffer import VimBuffer
from orgmode.liborgmode.agenda import AgendaManager

from orgmode.liborgmode.orgdate import get_orgdate

REPEAT_EXISTS = bool(int(vim.eval('exists("*repeat#set()")')))
TAGSPROPERTIES_EXISTS = False
Expand Down Expand Up @@ -165,6 +165,39 @@ def get_bufname(bufnr):
if b.number == bufnr:
return b.name

def get_heading(allow_dirty=False, line=None):
if not line:
line = int(vim.eval(u_encode(u'v:lnum')))
d = ORGMODE.get_document(allow_dirty=allow_dirty)
heading = None
if allow_dirty:
heading = d.find_current_heading(line - 1)
else:
heading = d.current_heading(line - 1)
return d, heading

def set_scheduled_date(new_date):
u""" Set the SCHEDULED entry in the Planning line of the current heading

"""
allow_dirty = True
line, col = vim.current.window.cursor
doc, heading = get_heading(allow_dirty=allow_dirty, line=line)
new_date = get_orgdate(u"<%s>" % date_to_str(new_date))
heading.scheduled_date = new_date
doc.write_heading(heading)


def set_deadline_date(new_date):
u""" Set de DEADLINE entry in the Planning line of the current heading
"""
allow_dirty = True
line, col = vim.current.window.cursor
doc, heading = get_heading(allow_dirty=allow_dirty, line=line)
new_date = get_orgdate("<%s>" % date_to_str(new_date))
heading.deadline_date = new_date
doc.write_heading(heading)


def indent_orgmode():
u""" Set the indent value for the current line in the variable
Expand All @@ -176,8 +209,7 @@ def indent_orgmode():
:returns: None
"""
line = int(vim.eval(u_encode(u'v:lnum')))
d = ORGMODE.get_document()
heading = d.current_heading(line - 1)
doc, heading = get_heading()
if heading and line != heading.start_vim:
heading.init_checkboxes()
checkbox = heading.current_checkbox()
Expand All @@ -200,12 +232,7 @@ def fold_text(allow_dirty=False):
:returns: None
"""
line = int(vim.eval(u_encode(u'v:foldstart')))
d = ORGMODE.get_document(allow_dirty=allow_dirty)
heading = None
if allow_dirty:
heading = d.find_current_heading(line - 1)
else:
heading = d.current_heading(line - 1)
doc, heading = get_heading(allow_dirty, line)
if heading:
str_heading = unicode(heading)

Expand Down Expand Up @@ -234,12 +261,7 @@ def fold_orgmode(allow_dirty=False):
:returns: None
"""
line = int(vim.eval(u_encode(u'v:lnum')))
d = ORGMODE.get_document(allow_dirty=allow_dirty)
heading = None
if allow_dirty:
heading = d.find_current_heading(line - 1)
else:
heading = d.current_heading(line - 1)
doc, heading = get_heading(allow_dirty)

# if cache_heading != heading:
# heading.init_checkboxes()
Expand Down
76 changes: 73 additions & 3 deletions ftplugin/orgmode/liborgmode/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,17 @@
except:
from UserList import UserList

from orgmode import settings

from orgmode.liborgmode.base import MultiPurposeList, flatten_list, Direction, get_domobj_range
from orgmode.liborgmode.headings import Heading, HeadingList

from orgmode.py3compat.encode_compatibility import *
from orgmode.py3compat.unicode_compatibility import *

import re
REGEX_LOGGING_MODIFIERS = re.compile(r"[!@/]")

class Document(object):
u"""
Representation of a whole org-mode document.
Expand Down Expand Up @@ -51,7 +56,8 @@ def __init__(self):
self._tag_column = 77

# TODO this doesn't differentiate between ACTIVE and FINISHED todo's
self.todo_states = [u'TODO', u'DONE']
self.todo_states_stripped = self.get_settings_todo_states(True)
self.todo_states = self.get_settings_todo_states(False)

def __unicode__(self):
if self.meta_information is None:
Expand All @@ -61,6 +67,65 @@ def __unicode__(self):
def __str__(self):
return u_encode(self.__unicode__())

def get_done_states(self, strip_access_key=True):
all_states = self.get_todo_states(strip_access_key)
done_states = list([ done_state for x in all_states for done_state in x[1]])

return done_states

def parse_todo_settings(self, setting, strip_access_key = True):
def parse_states(s, stop=0):
res = []
if not s:
return res
if type(s[0]) in (unicode, str):
r = []
for i in s:
_i = i
if type(_i) == str:
_i = u_decode(_i)
if type(_i) == unicode and _i:
if strip_access_key and u'(' in _i:
_i = _i[:_i.index(u'(')]
if _i:
r.append(_i)
else:
_i = REGEX_LOGGING_MODIFIERS.sub("", _i)
r.append(_i)
if not u'|' in r:
if not stop:
res.append((r[:-1], [r[-1]]))
else:
res = (r[:-1], [r[-1]])
else:
seperator_pos = r.index(u'|')
if not stop:
res.append((r[0:seperator_pos], r[seperator_pos + 1:]))
else:
res = (r[0:seperator_pos], r[seperator_pos + 1:])
elif type(s) in (list, tuple) and not stop:
for i in s:
r = parse_states(i, stop=1)
if r:
res.append(r)
return res
return parse_states(setting)


def get_settings_todo_states(self, strip_access_key=True):
u""" Returns a list containing a tuple of two lists of allowed todo
states split by todo and done states. Multiple todo-done state
sequences can be defined.

:returns: [([todo states], [done states]), ..]
"""
states = settings.get(u'org_todo_keywords', [])

if type(states) not in (list, tuple):
return []

return self.parse_todo_settings(states, strip_access_key)

def get_all_todo_states(self):
u""" Convenience function that returns all todo and done states and
sequences in one big list.
Expand All @@ -71,7 +136,7 @@ def get_all_todo_states(self):
# TODO This is not necessary remove
return flatten_list(self.get_todo_states())

def get_todo_states(self):
def get_todo_states(self, strip_access_key=True):
u""" Returns a list containing a tuple of two lists of allowed todo
states split by todo and done states. Multiple todo-done state
sequences can be defined.
Expand All @@ -82,7 +147,12 @@ def get_todo_states(self):
# TODO this should be made into property so todo states can be set like
# this too.. or there was also some todo property around... oh well..
# TODO there is the same method in vimbuffer
return self.todo_states

ret = self.todo_states
if strip_access_key:
ret = self.todo_states_stripped

return ret

@property
def tabstop(self):
Expand Down
2 changes: 2 additions & 0 deletions ftplugin/orgmode/liborgmode/dom_obj.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
flags=re.U)
REGEX_TODO = re.compile(r'^[^\s]*$')

REGEX_PLANNING = re.compile(r'(CLOSED|SCHEDULED|DEADLINE)\s*:[^]>]+(\]|>)', flags=re.U)

# checkbox regex:
# - [ ] checkbox item
# - [X] checkbox item
Expand Down
Loading