예제 #1
0
	def _export(cls, _format):
		""" Export current file in out format

		:flavor:	pdf or html
		:returns:	return code
		"""
		f = _format if _format == 'pdf' else 'html'
		emacs = os.path.expandvars(os.path.expanduser( \
				settings.get(u'org_export_emacs', u'/usr/bin/emacs')))
		if os.path.exists(emacs):
			cmd = [emacs, u'-nw', u'--batch', u'--visit=%s' \
					% (vim.eval(u'expand("%:p")'), ), \
					u'--funcall=org-export-as-%s' % f]

			# source init script as well
			init_script = cls._get_init_script()
			if init_script:
				cmd.extend(['--script', init_script])
			p = subprocess.Popen(cmd, stdout=subprocess.PIPE, \
					stderr=subprocess.PIPE)
			p.wait()
			if p.returncode != 0 or settings.get(u'org_export_verbose') == 1:
				echom('\n'.join(p.communicate()))

			return p.returncode
		else:
			echoe(u'Unable to find emacs binary %s' % emacs)
예제 #2
0
    def create(self):
        from orgmode import ORGMODE, echom

        cmd = self._mode
        if cmd == MODE_ALL:
            cmd = u''
        if not self._remap:
            cmd += u'nore'
        try:
            create_mapping = True
            if isinstance(self._action, Plug):
                # create plug
                self._action.create()
                if int(
                        vim.eval((u'hasmapto("%s")' %
                                  (self._action, )).encode(u'utf-8'))):
                    create_mapping = False
            if isinstance(self._action, Command):
                # create command
                self._action.create()

            if create_mapping:
                vim.command((u':%smap %s %s %s' % (cmd, u' '.join(
                    self._options), self._key, self._action)).encode(u'utf-8'))
        except Exception, e:
            if ORGMODE.debug:
                echom(u'Failed to register key binding %s %s' %
                      (self._key, self._action))
예제 #3
0
    def follow(cls, action='openLink', visual=''):
        """ Follow hyperlink. If called on a regular string UTL determines the
		outcome. Normally a file with that name will be opened.

		:action: "copy" if the link should be copied to clipboard, otherwise the link will be opened
		:visual: "visual" if Universal Text Linking should be triggered in visual mode

		:returns: URI or None
		"""
        if not int(vim.eval('exists(":Utl")')):
            echom(
                'Universal Text Linking plugin not installed, unable to proceed.'
            )
            return

        action = 'copyLink' if action and action.startswith(
            'copy') else 'openLink'
        visual = 'visual' if visual and visual.startswith('visual') else ''

        link = Hyperlinks._get_link()

        if link and link['uri'] != None:
            # call UTL with the URI
            vim.command('Utl %s %s %s' % (action, visual, link['uri']))
            return link['uri']
        else:
            # call UTL and let it decide what to do
            vim.command('Utl %s %s' % (action, visual))
예제 #4
0
	def follow(cls, action=u'openLink', visual=u''):
		u""" Follow hyperlink. If called on a regular string UTL determines the
		outcome. Normally a file with that name will be opened.

		:action: "copy" if the link should be copied to clipboard, otherwise the link will be opened
		:visual: "visual" if Universal Text Linking should be triggered in visual mode

		:returns: URI or None
		"""
		if not int(vim.eval(u'exists(":Utl")')):
			echom(u'Universal Text Linking plugin not installed, unable to proceed.')
			return

		action = u'copyLink' if action and action.startswith(u'copy') else u'openLink'
		visual = u'visual' if visual and visual.startswith(u'visual') else u''

		link = Hyperlinks._get_link()

		if link and link[u'uri'] is not None:
			# call UTL with the URI
			vim.command((u'Utl %s %s %s' % (action, visual, link[u'uri'])).encode(u'utf-8'))
			return link[u'uri']
		else:
			# call UTL and let it decide what to do
			vim.command((u'Utl %s %s' % (action, visual)).encode(u'utf-8'))
예제 #5
0
    def __init__(self):
        u""" Initialize plugin """
        object.__init__(self)
        # menu entries this plugin should create
        self.menu = ORGMODE.orgmenu + Submenu(u'Dates and Scheduling')

        # key bindings for this plugin
        # key bindings are also registered through the menu so only additional
        # bindings should be put in this variable
        self.keybindings = []

        # commands for this plugin
        self.commands = []

        # set speeddating format that is compatible with orgmode
        try:
            if int(vim.eval(u'exists(":SpeedDatingFormat")'.encode(u'utf-8'))):
                vim.command(
                    u':1SpeedDatingFormat %Y-%m-%d %a'.encode(u'utf-8'))
                vim.command(
                    u':1SpeedDatingFormat %Y-%m-%d %a %H:%M'.encode(u'utf-8'))
            else:
                echom(u'Speeddating plugin not installed. Please install it.')
        except:
            echom(u'Speeddating plugin not installed. Please install it.')
예제 #6
0
	def topdf(cls):
		u"""
		Export the current buffer as pdf using emacs orgmode.
		"""
		ret = cls._export(u'pdf')
		if ret != 0:
			echoe(u'PDF export failed.')
		else:
			echom(u'Export successful: %s.%s' % (vim.eval(u'expand("%:r")'), 'pdf'))
예제 #7
0
	def tohtml(cls):
		u"""
		Export the current buffer as html using emacs orgmode.
		"""
		ret = cls._export(u'html')
		if ret != 0:
			echoe(u'HTML export failed.')
		else:
			echom(u'Export successful: %s.%s' % (vim.eval(u'expand("%:r")'), 'html'))
예제 #8
0
파일: Todo.py 프로젝트: imxiaohui/vimrc-1
	def toggle_todo_state(cls, direction=Direction.FORWARD, interactive=False, next_set=False):
		u""" Toggle state of TODO item

		:returns: The changed heading
		"""
		d = ORGMODE.get_document(allow_dirty=True)

		# get heading
		heading = d.find_current_heading()
		if not heading:
			vim.eval(u'feedkeys("^", "n")')
			return

		todo_states = d.get_todo_states(strip_access_key=False)
		# get todo states
		if not todo_states:
			echom(u'No todo keywords configured.')
			return

		current_state = heading.todo

		# get new state interactively
		if interactive:
			# determine position of the interactive prompt
			prompt_pos = settings.get(u'org_todo_prompt_position', u'botright')
			if not prompt_pos in [u'botright', u'topleft']:
				prompt_pos = u'botright'

			# pass todo states to new window
			ORGTODOSTATES[d.bufnr] = todo_states
			settings.set(u'org_current_state_%d' % d.bufnr, \
					current_state if current_state is not None else u'', overwrite=True)
			todo_buffer_exists = bool(int(vim.eval((u'bufexists("org:todo/%d")'
					% (d.bufnr, )).encode(u'utf-8'))))
			if todo_buffer_exists:
				# if the buffer already exists, reuse it
				vim.command((u'%s sbuffer org:todo/%d' %
						(prompt_pos, d.bufnr, )).encode(u'utf-8'))
			else:
				# create a new window
				vim.command((u'keepalt %s %dsplit org:todo/%d' %
						(prompt_pos, len(todo_states), d.bufnr)).encode(u'utf-8'))
		else:
			new_state = Todo._get_next_state(current_state, todo_states,
					direction=direction, interactive=interactive,
					next_set=next_set)
			cls.set_todo_state(new_state)

		# plug
		plug = u'OrgTodoForward'
		if direction == Direction.BACKWARD:
			plug = u'OrgTodoBackward'

		return plug
예제 #9
0
파일: Todo.py 프로젝트: rjp/vim-orgmode
	def toggle_todo_state(cls, direction=DIRECTION_FORWARD, interactive=False, next_set=False):
		u""" Toggle state of TODO item

		:returns: The changed heading
		"""
		d = ORGMODE.get_document(allow_dirty=True)
		lineno, colno = vim.current.window.cursor

		# get heading
		heading = d.find_current_heading()
		if not heading:
			vim.eval(u'feedkeys("^", "n")')
			return

		todo_states = d.get_todo_states(strip_access_key=False)
		# get todo states
		if not todo_states:
			echom(u'No todo keywords configured.')
			return

		# current_state
		current_state = heading.todo

		# get new state
		new_state = Todo._get_next_state(current_state, todo_states, \
				direction=direction, interactive=interactive, next_set=next_set)

		# move cursor along with the inserted state only when current position
		# is in the heading; otherwite do nothing
		if heading.start_vim == lineno:
			if current_state is None and new_state is None:
				offset = 0
			elif current_state is None:
				offset = len(new_state)
			elif new_state is None:
				offset = -len(current_state)
			else:
				offset = len(current_state) - len(new_state)
			vim.current.window.cursor = (lineno, colno + offset)

		# set new headline
		heading.todo = new_state

		# plug
		plug = u'OrgTodoForward'
		if direction == DIRECTION_BACKWARD:
			plug = u'OrgTodoBackward'

		d.write_heading(heading)

		return plug
예제 #10
0
파일: Todo.py 프로젝트: EnTeQuAk/dotfiles
	def toggle_todo_state(cls, direction=DIRECTION_FORWARD):
		""" Toggle state of TODO item

		:returns: The changed heading
		"""
		lineno, colno = vim.current.window.cursor

		# get heading
		heading = Document.current_heading()
		if not heading:
			vim.eval('feedkeys("^", "n")')
			return

		# get todo states
		todo_states, done_states = Todo._get_states()
		all_states = todo_states + done_states
		if len(all_states) < 2:
			echom('No todo keywords configured.')
			return

		# current_state and rest of heading
		current_state, rest = Todo._split_heading(heading.text, all_states)

		# get new state
		new_state = Todo._get_next_state(current_state, all_states, direction)

		# set new headline
		if not new_state:
			new_heading = ' '.join(('*' * heading.level, rest))
		else:
			new_heading = ' '.join(('*' * heading.level, new_state, rest))
		vim.current.buffer[heading.start] = new_heading

		# move cursor along with the inserted state only when current position
		# is in the heading; otherwite do nothing
		if heading.start_vim == lineno:
			if current_state is None:
				offset = len(new_state)
			elif new_state is None:
				offset = -len(current_state)
			else:
				offset = len(current_state) - len(new_state)
			vim.current.window.cursor = (lineno, colno + offset)

		# plug
		plug = 'OrgToggleTodoForward'
		if direction == DIRECTION_BACKWARD:
			plug = 'OrgToggleTodoBackward'
		return plug
예제 #11
0
파일: Todo.py 프로젝트: EnTeQuAk/dotfiles
    def toggle_todo_state(cls, direction=DIRECTION_FORWARD):
        """ Toggle state of TODO item

		:returns: The changed heading
		"""
        lineno, colno = vim.current.window.cursor

        # get heading
        heading = Document.current_heading()
        if not heading:
            vim.eval('feedkeys("^", "n")')
            return

        # get todo states
        todo_states, done_states = Todo._get_states()
        all_states = todo_states + done_states
        if len(all_states) < 2:
            echom('No todo keywords configured.')
            return

        # current_state and rest of heading
        current_state, rest = Todo._split_heading(heading.text, all_states)

        # get new state
        new_state = Todo._get_next_state(current_state, all_states, direction)

        # set new headline
        if not new_state:
            new_heading = ' '.join(('*' * heading.level, rest))
        else:
            new_heading = ' '.join(('*' * heading.level, new_state, rest))
        vim.current.buffer[heading.start] = new_heading

        # move cursor along with the inserted state only when current position
        # is in the heading; otherwite do nothing
        if heading.start_vim == lineno:
            if current_state is None:
                offset = len(new_state)
            elif new_state is None:
                offset = -len(current_state)
            else:
                offset = len(current_state) - len(new_state)
            vim.current.window.cursor = (lineno, colno + offset)

        # plug
        plug = 'OrgToggleTodoForward'
        if direction == DIRECTION_BACKWARD:
            plug = 'OrgToggleTodoBackward'
        return plug
예제 #12
0
	def init_org_todo(cls):
		u""" Initialize org todo selection window.
		"""
		bufnr = int(vim.current.buffer.name.split('/')[-1])
		all_states = ORGTODOSTATES.get(bufnr, None)

		# because timeoutlen can only be set globally it needs to be stored and restored later
		vim.command(u'let g:org_sav_timeoutlen=&timeoutlen'.encode(u'utf-8'))
		vim.command(u'au orgmode BufEnter <buffer> :if ! exists("g:org_sav_timeoutlen")|let g:org_sav_timeoutlen=&timeoutlen|set timeoutlen=1|endif'.encode(u'utf-8'))
		vim.command(u'au orgmode BufLeave <buffer> :if exists("g:org_sav_timeoutlen")|let &timeoutlen=g:org_sav_timeoutlen|unlet g:org_sav_timeoutlen|endif'.encode(u'utf-8'))
		# make window a scratch window and set the statusline differently
		vim.command(u'setlocal tabstop=16 buftype=nofile timeout timeoutlen=1 winfixheight'.encode(u'utf-8'))
		vim.command((u'setlocal statusline=Org\\ todo\\ (%s)' % vim.eval((u'fnameescape(fnamemodify(bufname(%d), ":t"))' % bufnr).encode(u'utf-8'))).encode(u'utf-8'))
		vim.command((u'nnoremap <silent> <buffer> <Esc> :%sbw<CR>' % (vim.eval(u'bufnr("%")'.encode(u'utf-8')), )).encode(u'utf-8'))
		vim.command(u'nnoremap <silent> <buffer> <CR> :let g:org_state = fnameescape(expand("<cword>"))<Bar>bw<Bar>exec "py ORGMODE.plugins[u\'Todo\'].set_todo_state(\'".g:org_state."\')"<Bar>unlet! g:org_state<CR>'.encode(u'utf-8'))

		if all_states is None:
			vim.command(u'bw'.encode(u'utf-8'))
			echom(u'No todo states avaiable for buffer %s' % vim.current.buffer.name)

		for l in xrange(0, len(all_states)):
			res = u''
			did_done = False
			for j in xrange(0, 2):
				if j < len(all_states[l]):
					for i in all_states[l][j]:
						if type(i) != unicode:
							continue
						v, k = split_access_key(i)
						if k:
							res += (u'\t' if res else u'') + u'[%s] %s' % (k, v)
							# map access keys to callback that updates current heading
							# map selection keys
							vim.command((u'nnoremap <silent> <buffer> %s :bw<Bar>py ORGMODE.plugins[u"Todo"].set_todo_state("%s".decode(u"utf-8"))<CR>' % (k, v)).encode(u'utf-8') )
						elif v:
							res += (u'\t' if res else u'') + v
			if res:
				if l == 0:
					vim.current.buffer[0] = res.encode(u'utf-8')
				else:
					vim.current.buffer.append(res.encode(u'utf-8'))

		# finally make buffer non modifiable
		vim.command(u'setfiletype orgtodo'.encode(u'utf-8'))
		vim.command(u'setlocal nomodifiable'.encode(u'utf-8'))

		# remove temporary todo states for the current buffer
		del ORGTODOSTATES[bufnr]
예제 #13
0
	def toggle_todo_state(cls, direction=DIRECTION_FORWARD, interactive=False, next_set=False):
		u""" Toggle state of TODO item

		:returns: The changed heading
		"""
		d = ORGMODE.get_document(allow_dirty=True)

		# get heading
		heading = d.find_current_heading()
		if not heading:
			vim.eval(u'feedkeys("^", "n")')
			return

		todo_states = d.get_todo_states(strip_access_key=False)
		# get todo states
		if not todo_states:
			echom(u'No todo keywords configured.')
			return

		current_state = heading.todo

		# get new state interactively
		if interactive:
			# pass todo states to new window
			ORGTODOSTATES[d.bufnr] = todo_states
			if bool(int(vim.eval(( u'bufexists("org:todo/%d")' % (d.bufnr, ) ).encode(u'utf-8')))):
				# if the buffer already exists, reuse it
				vim.command((u'sbuffer org:todo/%d' % (d.bufnr, )).encode(u'utf-8'))
			else:
				# create a new window
				vim.command((u'keepalt %dsp org:todo/%d' % (len(todo_states), d.bufnr)).encode(u'utf-8'))
		else:
			new_state = Todo._get_next_state(current_state, todo_states, \
					direction=direction, interactive=interactive, next_set=next_set)
			cls.set_todo_state(new_state)

		# plug
		plug = u'OrgTodoForward'
		if direction == DIRECTION_BACKWARD:
			plug = u'OrgTodoBackward'

		return plug
예제 #14
0
파일: Date.py 프로젝트: EnTeQuAk/dotfiles
	def insert_timestamp(cls, active=True):
		"""
		Insert a timestamp (today) at the cursor position.

		TODO: show fancy calendar to pick the date from.
		"""
		today = date.today()
		msg = ''.join(['Insert Date: ', today.strftime('%Y-%m-%d %a'),
				' | Change date'])
		modifier = get_user_input(msg)
		echom(modifier)

		newdate = cls._modify_time(today, modifier)

		# format
		if isinstance(newdate, datetime):
			newdate = newdate.strftime('%Y-%m-%d %a %H:%M')
		else:
			newdate = newdate.strftime('%Y-%m-%d %a')
		timestamp = '<%s>' % newdate if active else '[%s]' % newdate

		insert_at_cursor(timestamp)
예제 #15
0
    def __init__(self):
        u""" Initialize plugin """
        object.__init__(self)
        # menu entries this plugin should create
        self.menu = ORGMODE.orgmenu + Submenu(u"Dates and Scheduling")

        # key bindings for this plugin
        # key bindings are also registered through the menu so only additional
        # bindings should be put in this variable
        self.keybindings = []

        # commands for this plugin
        self.commands = []

        # set speeddating format that is compatible with orgmode
        try:
            if int(vim.eval(u'exists(":SpeedDatingFormat")'.encode(u"utf-8"))) == 2:
                vim.command(u":1SpeedDatingFormat %Y-%m-%d %a".encode(u"utf-8"))
                vim.command(u":1SpeedDatingFormat %Y-%m-%d %a %H:%M".encode(u"utf-8"))
            else:
                echom(u"Speeddating plugin not installed. Please install it.")
        except:
            echom(u"Speeddating plugin not installed. Please install it.")
예제 #16
0
    def insert_timestamp(cls, active=True):
        """
		Insert a timestamp (today) at the cursor position.

		TODO: show fancy calendar to pick the date from.
		"""
        today = date.today()
        msg = ''.join(
            ['Insert Date: ',
             today.strftime('%Y-%m-%d %a'), ' | Change date'])
        modifier = get_user_input(msg)
        echom(modifier)

        newdate = cls._modify_time(today, modifier)

        # format
        if isinstance(newdate, datetime):
            newdate = newdate.strftime('%Y-%m-%d %a %H:%M')
        else:
            newdate = newdate.strftime('%Y-%m-%d %a')
        timestamp = '<%s>' % newdate if active else '[%s]' % newdate

        insert_at_cursor(timestamp)
예제 #17
0
	def create(self):
		from orgmode import ORGMODE, echom

		cmd = self._mode
		if cmd == MODE_ALL:
			cmd = u''
		if not self._remap:
			cmd += u'nore'
		try:
			create_mapping = True
			if isinstance(self._action, Plug):
				# create plug
				self._action.create()
				if int(vim.eval((u'hasmapto("%s")' % (self._action, )).encode(u'utf-8'))):
					create_mapping = False
			if isinstance(self._action, Command):
				# create command
				self._action.create()

			if create_mapping:
				vim.command((u':%smap %s %s %s' % (cmd, u' '.join(self._options), self._key, self._action)).encode(u'utf-8'))
		except Exception, e:
			if ORGMODE.debug:
				echom(u'Failed to register key binding %s %s' % (self._key, self._action))
예제 #18
0
    def toggle_todo_state(cls,
                          direction=Direction.FORWARD,
                          interactive=False,
                          next_set=False):
        u""" Toggle state of TODO item

		:returns: The changed heading
		"""
        d = ORGMODE.get_document(allow_dirty=True)

        # get heading
        heading = d.find_current_heading()
        if not heading:
            vim.eval(u'feedkeys("^", "n")')
            return

        todo_states = d.get_todo_states(strip_access_key=False)
        # get todo states
        if not todo_states:
            echom(u'No todo keywords configured.')
            return

        current_state = heading.todo

        # get new state interactively
        if interactive:
            # determine position of the interactive prompt
            prompt_pos = settings.get(u'org_todo_prompt_position', u'botright')
            if not prompt_pos in [u'botright', u'topleft']:
                prompt_pos = u'botright'

            # pass todo states to new window
            ORGTODOSTATES[d.bufnr] = todo_states
            settings.set(u'org_current_state_%d' % d.bufnr, \
              current_state if current_state is not None else u'', overwrite=True)
            todo_buffer_exists = bool(
                int(
                    vim.eval((u'bufexists("org:todo/%d")' %
                              (d.bufnr, )).encode(u'utf-8'))))
            if todo_buffer_exists:
                # if the buffer already exists, reuse it
                vim.command((u'%s sbuffer org:todo/%d' % (
                    prompt_pos,
                    d.bufnr,
                )).encode(u'utf-8'))
            else:
                # create a new window
                vim.command(
                    (u'keepalt %s %dsplit org:todo/%d' %
                     (prompt_pos, len(todo_states), d.bufnr)).encode(u'utf-8'))
        else:
            new_state = Todo._get_next_state(current_state,
                                             todo_states,
                                             direction=direction,
                                             interactive=interactive,
                                             next_set=next_set)
            cls.set_todo_state(new_state)

        # plug
        plug = u'OrgTodoForward'
        if direction == Direction.BACKWARD:
            plug = u'OrgTodoBackward'

        return plug
예제 #19
0
class Date(object):
    """
	Handles all date and timestamp related tasks.

	TODO: extend functionality (calendar, repetitions, ranges). See
			http://orgmode.org/guide/Dates-and-Times.html#Dates-and-Times
	"""

    date_regex = r"\d\d\d\d-\d\d-\d\d"
    datetime_regex = r"[A-Z]\w\w \d\d\d\d-\d\d-\d\d \d\d:\d\d>"

    month_mapping = {
        'jan': 1,
        'feb': 2,
        'mar': 3,
        'apr': 4,
        'mai': 5,
        'jun': 6,
        'jul': 7,
        'aug': 8,
        'sep': 9,
        'oct': 10,
        'nov': 11,
        'dec': 12
    }

    # set speeddating format that is compatible with orgmode
    try:
        if int(vim.eval('exists(":SpeedDatingFormat")')):
            vim.command(':1SpeedDatingFormat %Y-%m-%d %a')
            vim.command(':1SpeedDatingFormat %Y-%m-%d %a %H:%M')
        else:
            echom('Speeddating plugin not installed. Please install it.')
    except:
        echom('Speeddating plugin not installed. Please install it.')

    def __init__(self):
        """ Initialize plugin """
        object.__init__(self)
        # menu entries this plugin should create
        self.menu = ORGMODE.orgmenu + Submenu('Dates and Scheduling')

        # key bindings for this plugin
        # key bindings are also registered through the menu so only additional
        # bindings should be put in this variable
        self.keybindings = []

        # commands for this plugin
        self.commands = []

    @classmethod
    def _modify_time(cls, startdate, modifier):
        """Modify the given startdate according to modifier. Return the new time.

		See http://orgmode.org/manual/The-date_002ftime-prompt.html#The-date_002ftime-prompt
		"""
        if modifier is None:
            return startdate

        # check real date
        date_regex = r"(\d\d\d\d)-(\d\d)-(\d\d)"
        match = re.search(date_regex, modifier)
        if match:
            year, month, day = match.groups()
            t = date(int(year), int(month), int(day))
            return t

        # check abbreviated date, seperated with '-'
        date_regex = "(\d{1,2})-(\d+)-(\d+)"
        match = re.search(date_regex, modifier)
        if match:
            year, month, day = match.groups()
            t = date(2000 + int(year), int(month), int(day))
            return t

        # check abbreviated date, seperated with '/'
        # month/day/year
        date_regex = "(\d{1,2})/(\d+)/(\d+)"
        match = re.search(date_regex, modifier)
        if match:
            month, day, year = match.groups()
            t = date(2000 + int(year), int(month), int(day))
            return t

        # check abbreviated date, seperated with '/'
        # month/day
        date_regex = "(\d{1,2})/(\d{1,2})"
        match = re.search(date_regex, modifier)
        if match:
            month, day = match.groups()
            newdate = date(startdate.year, int(month), int(day))
            # date should be always in the future
            if newdate < startdate:
                newdate = date(startdate.year + 1, int(month), int(day))
            return newdate

        # check full date, seperated with 'space'
        # month day year
        # 'sep 12 9' --> 2009 9 12
        date_regex = "(\w\w\w) (\d{1,2}) (\d{1,2})"
        match = re.search(date_regex, modifier)
        if match:
            gr = match.groups()
            day = int(gr[1])
            month = int(cls.month_mapping[gr[0]])
            year = 2000 + int(gr[2])
            return date(year, int(month), int(day))

        # check days as integers
        date_regex = "^(\d{1,2})$"
        match = re.search(date_regex, modifier)
        if match:
            newday, = match.groups()
            newday = int(newday)
            if newday > startdate.day:
                newdate = date(startdate.year, startdate.month, newday)
            else:
                # TODO: DIRTY, fix this
                #       this does NOT cover all edge cases
                newdate = startdate + timedelta(days=28)
                newdate = date(newdate.year, newdate.month, newday)
            return newdate

        # check for full days: Mon, Tue, Wed, Thu, Fri, Sat, Sun
        modifier_lc = modifier.lower()
        match = re.search('mon|tue|wed|thu|fri|sat|sun', modifier_lc)
        if match:
            weekday_mapping = {
                'mon': 0,
                'tue': 1,
                'wed': 2,
                'thu': 3,
                'fri': 4,
                'sat': 5,
                'sun': 6
            }
            diff = (weekday_mapping[modifier_lc] - startdate.weekday()) % 7
            # use next weeks weekday if current weekday is the same as modifier
            if diff == 0:
                diff = 7

            return startdate + timedelta(days=diff)

        # check for month day
        modifier_lc = modifier.lower()
        match = re.search(
            '(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec) (\d{1,2})',
            modifier_lc)
        if match:
            month = cls.month_mapping[match.groups()[0]]
            day = int(match.groups()[1])

            newdate = date(startdate.year, int(month), int(day))
            # date should be always in the future
            if newdate < startdate:
                newdate = date(startdate.year + 1, int(month), int(day))
            return newdate

        # check for time: HH:MM
        # '12:45' --> datetime(2006,06,13, 12,45))
        match = re.search('(\d{1,2}):(\d\d)', modifier)
        if match:
            return datetime(startdate.year, startdate.month, startdate.day,
                            int(match.groups()[0]), int(match.groups()[1]))

        # check for days modifier
        match = re.search('\+(\d*)d', modifier)
        if match:
            days = int(match.groups()[0])
            return startdate + timedelta(days=days)

        # check for week modifier
        match = re.search('\+(\d+)w', modifier)
        if match:
            weeks = int(match.groups()[0])
            return startdate + timedelta(weeks=weeks)

        # check for week modifier
        match = re.search('\+(\d+)m', modifier)
        if match:
            months = int(match.groups()[0])
            return date(startdate.year, startdate.month + months,
                        startdate.day)

        # check for year modifier
        match = re.search('\+(\d*)y', modifier)
        if match:
            years = int(match.groups()[0])
            return date(startdate.year + years, startdate.month, startdate.day)

        return startdate

    @classmethod
    def insert_timestamp(cls, active=True):
        """
		Insert a timestamp (today) at the cursor position.

		TODO: show fancy calendar to pick the date from.
		"""
        today = date.today()
        msg = ''.join(
            ['Insert Date: ',
             today.strftime('%Y-%m-%d %a'), ' | Change date'])
        modifier = get_user_input(msg)
        echom(modifier)

        newdate = cls._modify_time(today, modifier)

        # format
        if isinstance(newdate, datetime):
            newdate = newdate.strftime('%Y-%m-%d %a %H:%M')
        else:
            newdate = newdate.strftime('%Y-%m-%d %a')
        timestamp = '<%s>' % newdate if active else '[%s]' % newdate

        insert_at_cursor(timestamp)

    def register(self):
        """
		Registration of the plugin.

		Key bindings and other initialization should be done here.
		"""
        settings.set('org_leader', ',')
        leader = settings.get('org_leader', ',')

        self.keybindings.append(
            Keybinding(
                '%stn' % leader,
                Plug('OrgDateInsertTimestampActive',
                     ':py ORGMODE.plugins["Date"].insert_timestamp()<CR>')))
        self.menu + ActionEntry('Timestamp', self.keybindings[-1])

        self.keybindings.append(
            Keybinding(
                '%sti' % leader,
                Plug(
                    'OrgDateInsertTimestampInactive',
                    ':py ORGMODE.plugins["Date"].insert_timestamp(False)<CR>'))
        )
        self.menu + ActionEntry('Timestamp (inactive)', self.keybindings[-1])
예제 #20
0
파일: Todo.py 프로젝트: imxiaohui/vimrc-1
	def _get_next_state(cls, current_state, all_states,
			direction=Direction.FORWARD, interactive=False, next_set=False):
		u"""
		:current_state:		the current todo state
		:all_states:		a list containing all todo states within sublists.
							The todo states may contain access keys
		:direction:			direction of state or keyword set change (forward/backward)
		:interactive:		if interactive and more than one todo sequence is
							specified, open a selection window
		:next_set:			advance to the next keyword set in defined direction

		:return:			return the next state as string, or NONE if the
							next state is no state.
		"""
		if not all_states:
			return

		def find_current_todo_state(c, a, stop=0):
			u"""
			:c:		current todo state
			:a:		list of todo states
			:stop:	internal parameter for parsing only two levels of lists

			:return:	first position of todo state in list in the form
						(IDX_TOPLEVEL, IDX_SECOND_LEVEL (0|1), IDX_OF_ITEM)
			"""
			for i in xrange(0, len(a)):
				if type(a[i]) in (tuple, list) and stop < 2:
					r = find_current_todo_state(c, a[i], stop=stop + 1)
					if r:
						r.insert(0, i)
						return r
				# ensure that only on the second level of sublists todo states
				# are found
				if type(a[i]) == unicode and stop == 2:
					_i = split_access_key(a[i])[0]
					if c == _i:
						return [i]

		ci = find_current_todo_state(current_state, all_states)

		if not ci:
			if next_set and direction == Direction.BACKWARD:
				echom(u'Already at the first keyword set')
				return current_state

			return split_access_key(all_states[0][0][0] if all_states[0][0] else all_states[0][1][0])[0] \
					if direction == Direction.FORWARD else \
					split_access_key(all_states[0][1][-1] if all_states[0][1] else all_states[0][0][-1])[0]
		elif next_set:
			if direction == Direction.FORWARD and ci[0] + 1 < len(all_states[ci[0]]):
				echom(u'Keyword set: %s | %s' % (u', '.join(all_states[ci[0] + 1][0]), u', '.join(all_states[ci[0] + 1][1])))
				return split_access_key(all_states[ci[0] + 1][0][0] \
						if all_states[ci[0] + 1][0] else all_states[ci[0] + 1][1][0])[0]
			elif current_state is not None and direction == Direction.BACKWARD and ci[0] - 1 >= 0:
				echom(u'Keyword set: %s | %s' % (u', '.join(all_states[ci[0] - 1][0]), u', '.join(all_states[ci[0] - 1][1])))
				return split_access_key(all_states[ci[0] - 1][0][0] \
						if all_states[ci[0] - 1][0] else all_states[ci[0] - 1][1][0])[0]
			else:
				echom(u'Already at the %s keyword set' % (u'first' if direction == Direction.BACKWARD else u'last'))
				return current_state
		else:
			next_pos = ci[2] + 1 if direction == Direction.FORWARD else ci[2] - 1
			if direction == Direction.FORWARD:
				if next_pos < len(all_states[ci[0]][ci[1]]):
					# select next state within done or todo states
					return split_access_key(all_states[ci[0]][ci[1]][next_pos])[0]

				elif not ci[1] and next_pos - len(all_states[ci[0]][ci[1]]) < len(all_states[ci[0]][ci[1] + 1]):
					# finished todo states, jump to done states
					return split_access_key(all_states[ci[0]][ci[1] + 1][next_pos - len(all_states[ci[0]][ci[1]])])[0]
			else:
				if next_pos >= 0:
					# select previous state within done or todo states
					return split_access_key(all_states[ci[0]][ci[1]][next_pos])[0]

				elif ci[1] and len(all_states[ci[0]][ci[1] - 1]) + next_pos < len(all_states[ci[0]][ci[1] - 1]):
					# finished done states, jump to todo states
					return split_access_key(all_states[ci[0]][ci[1] - 1][len(all_states[ci[0]][ci[1] - 1]) + next_pos])[0]
예제 #21
0
	def _get_next_state(cls, current_state, all_states,
			direction=DIRECTION_FORWARD, interactive=False, next_set=False):
		u"""
		:current_state:		the current todo state
		:all_states:		a list containing all todo states within sublists.
							The todo states may contain access keys
		:direction:			direction of state or keyword set change (forward/backward)
		:interactive:		if interactive and more than one todo sequence is
							specified, open a selection window
		:next_set:			advance to the next keyword set in defined direction

		:return:			return the next state as string, or NONE if the
							next state is no state.
		"""
		if not all_states:
			return

		def find_current_todo_state(c, a, stop=0):
			u"""
			:c:		current todo state
			:a:		list of todo states
			:stop:	internal parameter for parsing only two levels of lists

			:return:	first position of todo state in list in the form
						(IDX_TOPLEVEL, IDX_SECOND_LEVEL (0|1), IDX_OF_ITEM)
			"""
			for i in xrange(0, len(a)):
				if type(a[i]) in (tuple, list) and stop < 2:
					r = find_current_todo_state(c, a[i], stop=stop + 1)
					if r:
						r.insert(0, i)
						return r
				# ensure that only on the second level of sublists todo states
				# are found
				if type(a[i]) == unicode and stop == 2:
					_i = split_access_key(a[i])[0]
					if c == _i:
						return [i]

		ci = find_current_todo_state(current_state, all_states)

		if not ci:
			if next_set and direction == DIRECTION_BACKWARD:
				echom(u'Already at the first keyword set')
				return current_state

			return split_access_key(all_states[0][0][0] if all_states[0][0] else all_states[0][1][0])[0] \
					if direction == DIRECTION_FORWARD else \
					split_access_key(all_states[0][1][-1] if all_states[0][1] else all_states[0][0][-1])[0]
		elif next_set:
			if direction == DIRECTION_FORWARD and ci[0] + 1 < len(all_states[ci[0]]):
				echom(u'Keyword set: %s | %s' % (u', '.join(all_states[ci[0] + 1][0]), u', '.join(all_states[ci[0] + 1][1])))
				return split_access_key(all_states[ci[0] + 1][0][0] \
						if all_states[ci[0] + 1][0] else all_states[ci[0] + 1][1][0])[0]
			elif current_state is not None and direction == DIRECTION_BACKWARD and ci[0] - 1 >= 0:
				echom(u'Keyword set: %s | %s' % (u', '.join(all_states[ci[0] - 1][0]), u', '.join(all_states[ci[0] - 1][1])))
				return split_access_key(all_states[ci[0] - 1][0][0] \
						if all_states[ci[0] - 1][0] else all_states[ci[0] - 1][1][0])[0]
			else:
				echom(u'Already at the %s keyword set' % (u'first' if direction == DIRECTION_BACKWARD else u'last'))
				return current_state
		else:
			next_pos = ci[2] + 1 if direction == DIRECTION_FORWARD else ci[2] - 1
			if direction == DIRECTION_FORWARD:
				if next_pos < len(all_states[ci[0]][ci[1]]):
					# select next state within done or todo states
					return split_access_key(all_states[ci[0]][ci[1]][next_pos])[0]

				elif not ci[1] and next_pos - len(all_states[ci[0]][ci[1]]) < len(all_states[ci[0]][ci[1] + 1]):
					# finished todo states, jump to done states
					return split_access_key(all_states[ci[0]][ci[1] + 1][next_pos - len(all_states[ci[0]][ci[1]])])[0]
			else:
				if next_pos >= 0:
					# select previous state within done or todo states
					return split_access_key(all_states[ci[0]][ci[1]][next_pos])[0]

				elif ci[1] and len(all_states[ci[0]][ci[1] - 1]) + next_pos < len(all_states[ci[0]][ci[1] - 1]):
					# finished done states, jump to todo states
					return split_access_key(all_states[ci[0]][ci[1] - 1][len(all_states[ci[0]][ci[1] - 1]) + next_pos])[0]