Exemplo n.º 1
0
Arquivo: Misc.py Projeto: guns/haus
	def i_heading(cls, mode=u'visual', selection=u'inner', skip_children=False):
		u"""
		inner heading text object
		"""
		heading = ORGMODE.get_document().current_heading()
		if heading:
			if selection != u'inner':
				heading = heading if not heading.parent else heading.parent

			line_start, col_start = [int(i) for i in vim.eval(u_encode(u'getpos("\'<")'))[1:3]]
			line_end, col_end = [int(i) for i in vim.eval(u_encode(u'getpos("\'>")'))[1:3]]

			if mode != u'visual':
				line_start = vim.current.window.cursor[0]
				line_end = line_start

			start = line_start
			end = line_end
			move_one_character_back = u'' if mode == u'visual' else u'h'

			if heading.start_vim < line_start:
				start = heading.start_vim
			if heading.end_vim > line_end and not skip_children:
				end = heading.end_vim
			elif heading.end_of_last_child_vim > line_end and skip_children:
				end = heading.end_of_last_child_vim

			if mode != u'visual' and not vim.current.buffer[end - 1]:
				end -= 1
				move_one_character_back = u''

			swap_cursor = u'o' if vim.current.window.cursor[0] == line_start else u''

			if selection == u'inner' and vim.current.window.cursor[0] != line_start:
				h = ORGMODE.get_document().current_heading()
				if h:
					heading = h

			visualmode = u_decode(vim.eval(u'visualmode()')) if mode == u'visual' else u'v'

			if line_start == start and line_start != heading.start_vim:
				if col_start in (0, 1):
					vim.command(u_encode(u'normal! %dgg0%s%dgg$%s%s' % (start, visualmode, end, move_one_character_back, swap_cursor)))
				else:
					vim.command(u_encode(u'normal! %dgg0%dl%s%dgg$%s%s' % (start, col_start - 1, visualmode, end, move_one_character_back, swap_cursor)))
			else:
				vim.command(u_encode(u'normal! %dgg0%dl%s%dgg$%s%s' % (start, heading.level + 1, visualmode, end, move_one_character_back, swap_cursor)))

			if selection == u'inner':
				if mode == u'visual':
					return u'OrgInnerHeadingVisual' if not skip_children else u'OrgInnerTreeVisual'
				else:
					return u'OrgInnerHeadingOperator' if not skip_children else u'OrgInnerTreeOperator'
			else:
				if mode == u'visual':
					return u'OrgOuterHeadingVisual' if not skip_children else u'OrgOuterTreeVisual'
				else:
					return u'OrgOuterHeadingOperator' if not skip_children else u'OrgOuterTreeOperator'
		elif mode == u'visual':
			vim.command(u_encode(u'normal! gv'))
Exemplo n.º 2
0
	def i_heading(cls, mode=u'visual', selection=u'inner', skip_children=False):
		u"""
		inner heading text object
		"""
		heading = ORGMODE.get_document().current_heading()
		if heading:
			if selection != u'inner':
				heading = heading if not heading.parent else heading.parent

			line_start, col_start = [int(i) for i in vim.eval(u_encode(u'getpos("\'<")'))[1:3]]
			line_end, col_end = [int(i) for i in vim.eval(u_encode(u'getpos("\'>")'))[1:3]]

			if mode != u'visual':
				line_start = vim.current.window.cursor[0]
				line_end = line_start

			start = line_start
			end = line_end
			move_one_character_back = u'' if mode == u'visual' else u'h'

			if heading.start_vim < line_start:
				start = heading.start_vim
			if heading.end_vim > line_end and not skip_children:
				end = heading.end_vim
			elif heading.end_of_last_child_vim > line_end and skip_children:
				end = heading.end_of_last_child_vim

			if mode != u'visual' and not vim.current.buffer[end - 1]:
				end -= 1
				move_one_character_back = u''

			swap_cursor = u'o' if vim.current.window.cursor[0] == line_start else u''

			if selection == u'inner' and vim.current.window.cursor[0] != line_start:
				h = ORGMODE.get_document().current_heading()
				if h:
					heading = h

			visualmode = u_decode(vim.eval(u'visualmode()')) if mode == u'visual' else u'v'

			if line_start == start and line_start != heading.start_vim:
				if col_start in (0, 1):
					vim.command(u_encode(u'normal! %dgg0%s%dgg$%s%s' % (start, visualmode, end, move_one_character_back, swap_cursor)))
				else:
					vim.command(u_encode(u'normal! %dgg0%dl%s%dgg$%s%s' % (start, col_start - 1, visualmode, end, move_one_character_back, swap_cursor)))
			else:
				vim.command(u_encode(u'normal! %dgg0%dl%s%dgg$%s%s' % (start, heading.level + 1, visualmode, end, move_one_character_back, swap_cursor)))

			if selection == u'inner':
				if mode == u'visual':
					return u'OrgInnerHeadingVisual' if not skip_children else u'OrgInnerTreeVisual'
				else:
					return u'OrgInnerHeadingOperator' if not skip_children else u'OrgInnerTreeOperator'
			else:
				if mode == u'visual':
					return u'OrgOuterHeadingVisual' if not skip_children else u'OrgOuterTreeVisual'
				else:
					return u'OrgOuterHeadingOperator' if not skip_children else u'OrgOuterTreeOperator'
		elif mode == u'visual':
			vim.command(u_encode(u'normal! gv'))
Exemplo n.º 3
0
	def jump_to_first_character(cls):
		heading = ORGMODE.get_document().current_heading()
		if not heading or heading.start_vim != vim.current.window.cursor[0]:
			vim.eval(u_encode(u'feedkeys("^", "n")'))
			return

		vim.current.window.cursor = (vim.current.window.cursor[0], heading.level + 1)
Exemplo n.º 4
0
	def a_heading(cls, selection=u'inner', skip_children=False):
		u"""
		a heading text object
		"""
		heading = ORGMODE.get_document().current_heading()
		if heading:
			if selection != u'inner':
				heading = heading if not heading.parent else heading.parent

			line_start, col_start = [int(i) for i in vim.eval(u_encode(u'getpos("\'<")'))[1:3]]
			line_end, col_end = [int(i) for i in vim.eval(u_encode(u'getpos("\'>")'))[1:3]]

			start = line_start
			end = line_end

			if heading.start_vim < line_start:
				start = heading.start_vim
			if heading.end_vim > line_end and not skip_children:
				end = heading.end_vim
			elif heading.end_of_last_child_vim > line_end and skip_children:
				end = heading.end_of_last_child_vim

			swap_cursor = u'o' if vim.current.window.cursor[0] == line_start else u''

			vim.command(u_encode(u'normal! %dgg%s%dgg$%s' %	(start, vim.eval(u_encode(u'visualmode()')), end, swap_cursor)))
			if selection == u'inner':
				return u'OrgAInnerHeadingVisual' if not skip_children else u'OrgAInnerTreeVisual'
			else:
				return u'OrgAOuterHeadingVisual' if not skip_children else u'OrgAOuterTreeVisual'
		else:
			vim.command(u_encode(u'normal! gv'))
Exemplo n.º 5
0
	def parent_next_sibling(cls, mode):
		u"""
		Focus the parent's next sibling

		:returns: parent's next sibling heading or None
		"""
		heading = ORGMODE.get_document().current_heading()
		if not heading:
			if mode == u'visual':
				vim.command(u'normal! gv'.encode(u'utf-8'))
			else:
				echo(u'No heading found')
			return

		if not heading.parent or not heading.parent.next_sibling:
			if mode == u'visual':
				vim.command(u'normal! gv'.encode(u'utf-8'))
			else:
				echo(u'No parent heading found')
			return

		ns = heading.parent.next_sibling

		if mode == u'visual':
			cls._change_visual_selection(heading, ns, direction=Direction.FORWARD, parent=False)
		elif mode == u'operator':
			vim.current.window.cursor = (ns.start_vim, 0)
		else:
			vim.current.window.cursor = (ns.start_vim, ns.level + 1)
		return ns
Exemplo n.º 6
0
	def parent(cls, mode):
		u"""
		Focus parent heading

		:returns: parent heading or None
		"""
		heading = ORGMODE.get_document().current_heading()
		if not heading:
			if mode == u'visual':
				vim.command(u'normal! gv'.encode(u'utf-8'))
			else:
				echo(u'No heading found')
			return

		if not heading.parent:
			if mode == u'visual':
				vim.command(u'normal! gv'.encode(u'utf-8'))
			else:
				echo(u'No parent heading found')
			return

		p = heading.parent

		if mode == u'visual':
			cls._change_visual_selection(heading, p, direction=Direction.BACKWARD, parent=True)
		else:
			vim.current.window.cursor = (p.start_vim, p.level + 1)
		return p
Exemplo n.º 7
0
	def _get_agendadocuments(self):
		u"""
		Return the org documents of the agenda files; return None if no
		agenda documents are defined.

		TODO: maybe turn this into an decorator?
		"""
		# load org files of agenda
		agenda_files = settings.get(u'org_agenda_files', u',')
		if not agenda_files or agenda_files == ',':
			echoe((u"No org_agenda_files defined. Use :let "
				   u"g:org_agenda_files=['~/org/index.org'] to add "
				   u"files to the agenda view."))
			return

		# glob for files in agenda_files
		resolved_files = []
		for f in agenda_files:
			f = glob.glob(os.path.join(os.path.expanduser(os.path.dirname(f)),
				          os.path.basename(f)))
			resolved_files.extend(f)

		agenda_files = [os.path.realpath(f) for f in resolved_files]

		# load the agenda files into buffers
		for agenda_file in agenda_files:
			vim.command((u'badd %s' % agenda_file.replace(" ", "\ ")).encode(u'utf-8'))

		# determine the buffer nr of the agenda files
		agenda_nums = [get_bufnumber(fn) for fn in agenda_files]

		# collect all documents of the agenda files and create the agenda
		return [ORGMODE.get_document(i) for i in agenda_nums if i is not None]
    def test_realign_tags(self):
        vim.current.window.cursor = (2, 0)
        vim.EVALRESULTS[u'input("Tags: ", "", "customlist,Org_complete_tags")'.
                        encode(u'utf-8')] = u':hello:world:'.encode('utf-8')
        self.tagsproperties.set_tags()
        self.assertEqual(
            vim.current.buffer[1],
            u'* Überschrift 1\t\t\t\t\t\t\t\t    :hello:world:'.encode(
                'utf-8'))

        d = ORGMODE.get_document()
        heading = d.find_current_heading()
        self.assertEqual(
            str(heading),
            u'* Überschrift 1\t\t\t\t\t\t\t\t    :hello:world:'.encode(
                'utf-8'))
        self.tagsproperties.realign_tags()
        heading = d.find_current_heading()
        self.assertEqual(
            str(heading),
            u'* Überschrift 1\t\t\t\t\t\t\t\t    :hello:world:'.encode(
                'utf-8'))
        self.assertEqual(
            vim.current.buffer[1],
            u'* Überschrift 1\t\t\t\t\t\t\t\t    :hello:world:'.encode(
                'utf-8'))
Exemplo n.º 9
0
	def new_checkbox(cls, below=None):
		d = ORGMODE.get_document()
		h = d.current_heading()
		if h is None:
			return
		# init checkboxes for current heading
		h.init_checkboxes()
		c = h.current_checkbox()

		# default checkbox level
		level = h.level
		# if no checkbox is found, insert at current line with indent level=1
		if c is None:
			start = h.start
			if h.checkboxes:
				level = h.first_checkbox.level
		else:
			level = c.level
			if below:
				start = c.end_of_last_child
			else:
				start = c.start

		vim.current.window.cursor = (start + 1, 0)

		if below:
			vim.command("normal o")
		else:
			vim.command("normal O")

		new_checkbox = Checkbox(level=level)
		insert_at_cursor(str(new_checkbox))
		vim.command("call feedkeys('a')")
Exemplo n.º 10
0
    def get_timestamp_header(self):
        """ info, body
			- info is the dict of time headers
			- body is the list of strings """
        # will do all the checks and stuff
        d = ORGMODE.get_document(allow_dirty=True)

        info, body = {}, d.find_current_heading().body
        try:
            firstline = body[0]
            if not firstline.startswith(' '):
                parts = [
                    f.split(': ')
                    for f in firstline.strip().replace(']', '>').split('>')
                    if f
                ]

                for k, v in parts:
                    k = k.strip()
                    if k != k.upper():
                        raise

                    if v[0] == '<':
                        v += '>'
                    elif v[0] == '[':
                        v += ']'
                    else:
                        raise
                    info[k] = v
                body.pop(0)
        except:
            info = {}

        return info, body
Exemplo n.º 11
0
    def a_heading(cls, selection=u"inner", skip_children=False):
        u"""
		a heading text object
		"""
        heading = ORGMODE.get_document().current_heading()
        if heading:
            if selection != u"inner":
                heading = heading if not heading.parent else heading.parent

            line_start, col_start = [int(i) for i in vim.eval(u'getpos("\'<")'.encode(u"utf-8"))[1:3]]
            line_end, col_end = [int(i) for i in vim.eval(u'getpos("\'>")'.encode(u"utf-8"))[1:3]]

            start = line_start
            end = line_end

            if heading.start_vim < line_start:
                start = heading.start_vim
            if heading.end_vim > line_end and not skip_children:
                end = heading.end_vim
            elif heading.end_of_last_child_vim > line_end and skip_children:
                end = heading.end_of_last_child_vim

            swap_cursor = u"o" if vim.current.window.cursor[0] == line_start else u""

            vim.command(
                (
                    u"normal! %dgg%s%dgg$%s" % (start, vim.eval(u"visualmode()".encode(u"utf-8")), end, swap_cursor)
                ).encode(u"utf-8")
            )
            if selection == u"inner":
                return u"OrgAInnerHeadingVisual" if not skip_children else u"OrgAInnerTreeVisual"
            else:
                return u"OrgAOuterHeadingVisual" if not skip_children else u"OrgAOuterTreeVisual"
        else:
            vim.command(u"normal! gv".encode(u"utf-8"))
Exemplo n.º 12
0
	def set_tags(cls):
		u""" Set tags for current heading
		"""
		d = ORGMODE.get_document()
		heading = d.current_heading()
		if not heading:
			return

		# retrieve tags
		res = None
		if heading.tags:
			res = vim.eval(u'input("Tags: ", ":%s:", "customlist,Org_complete_tags")' % u':'.join(heading.tags))
		else:
			res = vim.eval(u'input("Tags: ", "", "customlist,Org_complete_tags")')

		if res is None:
			# user pressed <Esc> abort any further processing
			return

		# remove empty tags
		heading.tags = filter(lambda x: x.strip() != u'', res.decode(u'utf-8').strip().strip(u':').split(u':'))

		d.write()

		return u'OrgSetTags'
Exemplo n.º 13
0
    def new_checkbox(cls, below=None):
        d = ORGMODE.get_document()
        h = d.current_heading()
        if h is None:
            return
        # init checkboxes for current heading
        h.init_checkboxes()
        c = h.current_checkbox()

        # default checkbox level
        level = h.level
        # if no checkbox is found, insert at current line with indent level=1
        if c is None:
            start = h.start
            if h.checkboxes:
                level = h.first_checkbox.level
        else:
            level = c.level
            if below:
                start = c.end_of_last_child
            else:
                start = c.start

        vim.current.window.cursor = (start + 1, 0)

        if below:
            vim.command("normal o")
        else:
            vim.command("normal O")

        new_checkbox = Checkbox(level=level)
        insert_at_cursor(str(new_checkbox))
        vim.command("call feedkeys('a')")
Exemplo n.º 14
0
	def global_toggle_folding(cls, reverse=False):
		""" Toggle folding globally

		:reverse:	If False open folding by one level otherwise close it by one.
		"""
		d = ORGMODE.get_document()
		if reverse:
			foldlevel = int(vim.eval(u_encode(u'&foldlevel')))
			if foldlevel == 0:
				# open all folds because the user tries to close folds beyound 0
				vim.eval(u_encode(u'feedkeys("zR", "n")'))
			else:
				# vim can reduce the foldlevel on its own
				vim.eval(u_encode(u'feedkeys("zm", "n")'))
		else:
			found = False
			for h in d.headings:
				res = cls._fold_depth(h)
				if res:
					found = res[1]
				if found:
					break
			if not found:
				# no fold found and the user tries to advance the fold level
				# beyond maximum so close everything
				vim.eval(u_encode(u'feedkeys("zM", "n")'))
			else:
				# fold found, vim can increase the foldlevel on its own
				vim.eval(u_encode(u'feedkeys("zr", "n")'))

		return d
Exemplo n.º 15
0
    def jump_to_first_character(cls):
        heading = ORGMODE.get_document().current_heading()
        if not heading or heading.start_vim != vim.current.window.cursor[0]:
            vim.eval(u'feedkeys("^", "n")'.encode(u"utf-8"))
            return

        vim.current.window.cursor = (vim.current.window.cursor[0], heading.level + 1)
Exemplo n.º 16
0
	def update_checkboxes_status(cls):
		d = ORGMODE.get_document()
		h = d.current_heading()
		# init checkboxes for current heading
		h.init_checkboxes()

		cls._update_checkboxes_status(h.first_checkbox)
		cls._update_subtasks()
Exemplo n.º 17
0
	def edit_at_first_character(cls):
		heading = ORGMODE.get_document().current_heading()
		if not heading or heading.start_vim != vim.current.window.cursor[0]:
			vim.eval(u_encode(u'feedkeys("I", "n")'))
			return

		vim.current.window.cursor = (vim.current.window.cursor[0], heading.level + 1)
		vim.command(u_encode(u'startinsert'))
Exemplo n.º 18
0
    def update_checkboxes_status(cls):
        d = ORGMODE.get_document()
        h = d.current_heading()
        # init checkboxes for current heading
        h.init_checkboxes()

        cls._update_checkboxes_status(h.first_checkbox)
        cls._update_subtasks()
Exemplo n.º 19
0
    def edit_at_first_character(cls):
        heading = ORGMODE.get_document().current_heading()
        if not heading or heading.start_vim != vim.current.window.cursor[0]:
            vim.eval(u'feedkeys("I", "n")'.encode(u"utf-8"))
            return

        vim.current.window.cursor = (vim.current.window.cursor[0], heading.level + 1)
        vim.command(u"startinsert".encode(u"utf-8"))
Exemplo n.º 20
0
	def realign_all_tags(cls):
		u"""
		Updates tags when user finishes editing a heading
		"""
		d = ORGMODE.get_document()
		for heading in d.all_headings():
			heading.set_dirty_heading()

		d.write()
Exemplo n.º 21
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 prompt_pos not 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_encode(
				u'bufexists("org:todo/%d")' % (d.bufnr, )))))
			if todo_buffer_exists:
				# if the buffer already exists, reuse it
				vim.command(u_encode(
					u'%s sbuffer org:todo/%d' % (prompt_pos, d.bufnr, )))
			else:
				# create a new window
				vim.command(u_encode(
					u'keepalt %s %dsplit org:todo/%d' % (prompt_pos, len(todo_states), d.bufnr)))
		else:
			new_state = Todo._get_next_state(
				current_state, todo_states, direction=direction,
				next_set=next_set)

			cls.set_todo_state(new_state)

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

		return plug
Exemplo n.º 22
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 prompt_pos not 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
Exemplo n.º 23
0
	def _update_checkboxes_status(cls, checkbox=None):
		u""" helper function for update checkboxes status
			:checkbox: The first checkbox of this indent level
			:return: The status of the parent checkbox
		"""
		if checkbox is None:
			return

		status_off, status_on, status_int, total = 0, 0, 0, 0
		# update all top level checkboxes' status
		for c in checkbox.all_siblings():
			current_status = c.status
			# if this checkbox is not leaf, its status should determine by all its children
			if c.all_children_status()[0] > 0:
				current_status = cls._update_checkboxes_status(c.first_child)

			# don't update status if the checkbox has no status
			if c.status is None:
				current_status = None
			# the checkbox needs to have status
			else:
				total += 1

			# count number of status in this checkbox level
			if current_status == Checkbox.STATUS_OFF:
				status_off += 1
			elif current_status == Checkbox.STATUS_ON:
				status_on += 1
			elif current_status == Checkbox.STATUS_INT:
				status_int += 1

			# write status if any update
			if current_status is not None and c.status != current_status:
				c.status = current_status
				d = ORGMODE.get_document()
				d.write_checkbox(c)

		parent_status = Checkbox.STATUS_INT
		# all silbing checkboxes are off status
		if total == 0:
			pass
		elif status_off == total:
			parent_status = Checkbox.STATUS_OFF
		# all silbing checkboxes are on status
		elif status_on == total:
			parent_status = Checkbox.STATUS_ON
		# one silbing checkbox is on or int status
		elif status_on != 0 or status_int != 0:
			parent_status = Checkbox.STATUS_INT
		# other cases
		else:
			parent_status = None

		return parent_status
Exemplo n.º 24
0
	def test_demote_last_heading(self):
		vim.current.buffer[:] = [ u_encode(i) for i in u"""
* Überschrift 2
* Überschrift 3""".split('\n')]
		vim.current.window.cursor = (3, 0)
		h = ORGMODE.get_document().current_heading()
		self.assertNotEqual(self.editstructure.demote_heading(), None)
		self.assertEqual(h.end, 2)
		# self.assertFalse(vim.CMDHISTORY)
		self.assertEqual(vim.current.buffer[2], u_encode(u'** Überschrift 3'))
		self.assertEqual(vim.current.window.cursor, [3, 1])
Exemplo n.º 25
0
	def test_subtasks(self):
		bufnr = 3
		set_vim_buffer(buf=self.c1, bufnr=bufnr)
		h = ORGMODE.get_document(bufnr=bufnr).current_heading()
		h.init_checkboxes()
		c = h.current_checkbox(position=3)
		c.toggle()
		c = h.current_checkbox(position=2)
		(total, on) = c.all_siblings_status()
		c.update_subtasks(total=total, on=on)
		self.assertEqual(str(c), "  - [-] checkbox1 [50%]")
Exemplo n.º 26
0
	def realign_tags(cls):
		u"""
		Updates tags when user finished editing a heading
		"""
		d = ORGMODE.get_document(allow_dirty=True)
		heading = d.find_current_heading()
		if not heading:
			return

		if vim.current.window.cursor[0] == heading.start_vim:
			heading.set_dirty_heading()
			d.write_heading(heading, including_children=False)
	def test_realign_tags(self):
		vim.current.window.cursor = (2, 0)
		vim.EVALRESULTS[u'input("Tags: ", "", "customlist,Org_complete_tags")'.encode(u'utf-8')] = u':hello:world:'.encode('utf-8')
		self.tagsproperties.set_tags()
		self.assertEqual(vim.current.buffer[1], u'* Überschrift 1\t\t\t\t\t\t\t\t    :hello:world:'.encode('utf-8'))

		d = ORGMODE.get_document()
		heading = d.find_current_heading()
		self.assertEqual(str(heading), u'* Überschrift 1\t\t\t\t\t\t\t\t    :hello:world:'.encode('utf-8'))
		self.tagsproperties.realign_tags()
		heading = d.find_current_heading()
		self.assertEqual(str(heading), u'* Überschrift 1\t\t\t\t\t\t\t\t    :hello:world:'.encode('utf-8'))
		self.assertEqual(vim.current.buffer[1], u'* Überschrift 1\t\t\t\t\t\t\t\t    :hello:world:'.encode('utf-8'))
Exemplo n.º 28
0
	def _update_subtasks(cls):
		d = ORGMODE.get_document()
		h = d.current_heading()
		# init checkboxes for current heading
		h.init_checkboxes()
		# update heading subtask info
		c = h.first_checkbox
		if c is None:
			return
		total, on = c.all_siblings_status()
		h.update_subtasks(total, on)
		# update all checkboxes under current heading
		cls._update_checkboxes_subtasks(c)
Exemplo n.º 29
0
	def _move_heading(cls, direction=Direction.FORWARD, including_children=True):
		u""" Move heading up or down

		:returns: heading or None
		"""
		d = ORGMODE.get_document()
		current_heading = d.current_heading()
		if not current_heading or \
			(direction == Direction.FORWARD and not current_heading.next_sibling) or \
			(direction == Direction.BACKWARD and not current_heading.previous_sibling):
			return None

		cursor_offset = vim.current.window.cursor[0] - (current_heading._orig_start + 1)
		l = current_heading.get_parent_list()
		if l is None:
			raise HeadingDomError(u'Current heading is not properly linked in DOM')

		if not including_children:
			if current_heading.previous_sibling:
				npl = current_heading.previous_sibling.children
				for child in current_heading.children:
					npl.append(child, taint=False)
			elif current_heading.parent:
				# if the current heading doesn't have a previous sibling it
				# must be the first heading
				np = current_heading.parent
				for child in current_heading.children:
					cls._append_heading(child, np)
			else:
				# if the current heading doesn't have a parent, its children
				# must be added as top level headings to the document
				npl = l
				for child in current_heading.children[::-1]:
					npl.insert(0, child, taint=False)
			current_heading.children.remove_slice(0, len(current_heading.children), taint=False)

		idx = current_heading.get_index_in_parent_list()
		if idx is None:
			raise HeadingDomError(u'Current heading is not properly linked in DOM')

		offset = 1 if direction == Direction.FORWARD else -1
		del l[idx]
		l.insert(idx + offset, current_heading)

		d.write()

		vim.current.window.cursor = (
			current_heading.start_vim + cursor_offset,
			vim.current.window.cursor[1])

		return True
Exemplo n.º 30
0
def contains_active_todo(heading):
	u"""

	Returns:
		bool: True if heading contains an active TODO.
	"""
	# TODO make this more efficient by checking some val and not calling the
	# function
	# TODO why is this import failing at top level? circular dependecy...
	from orgmode._vim import ORGMODE
	active = []
	for act in ORGMODE.get_document().get_todo_states():
		active.extend(act[0])
	return heading.todo in active
Exemplo n.º 31
0
    def set_todo_state(cls, state):
        u""" Set todo state for buffer.

		:bufnr:		Number of buffer the todo state should be updated for
		:state:		The new todo state
		"""
        lineno, colno = vim.current.window.cursor
        d = ORGMODE.get_document(allow_dirty=True)
        heading = d.find_current_heading()

        if not heading:
            return

        # toggle to scheduled dates
        if ORGMODE.plugins.get("Date"):
            isdone, next_state = False, ''
            todos = d.get_todo_states()
            for t in todos:
                if not isdone and state in t[1]:
                    isdone = True
                    next_state = t[0][0]
            if ORGMODE.plugins["Date"].update_todo_timestamp(isdone):
                state = next_state

        current_state = heading.todo

        # set new headline
        heading.todo = state
        d.write_heading(heading)

        # move cursor along with the inserted state only when current position
        # is in the heading; otherwite do nothing
        if heading.start_vim == lineno and colno > heading.level:
            if current_state is not None and \
             colno <= heading.level + len(current_state):
                # the cursor is actually on the todo keyword
                # move it back to the beginning of the keyword in that case
                vim.current.window.cursor = (lineno, heading.level + 1)
            else:
                # the cursor is somewhere in the text, move it along
                if current_state is None and state is None:
                    offset = 0
                elif current_state is None and state is not None:
                    offset = len(state) + 1
                elif current_state is not None and state is None:
                    offset = -len(current_state) - 1
                else:
                    offset = len(state) - len(current_state)
                vim.current.window.cursor = (lineno, colno + offset)
Exemplo n.º 32
0
	def test_toggle(self):
		bufnr = 2
		# test init_checkboxes
		set_vim_buffer(buf=self.c1, bufnr=bufnr)
		h = ORGMODE.get_document(bufnr=bufnr).current_heading()
		h.init_checkboxes()

		# toggle checkbox
		c = h.current_checkbox(position=4)
		c.toggle()
		self.assertEqual(str(c), "        - [X] checkbox3")
		c.toggle()
		self.assertEqual(str(c), "        - [ ] checkbox3")

		(total, on) = c.all_siblings_status()
		self.assertEqual((total, on), (2, 1))
Exemplo n.º 33
0
    def complete_tags(cls):
        u""" build a list of tags and store it in variable b:org_tag_completion
		"""
        d = ORGMODE.get_document()
        heading = d.current_heading()
        if not heading:
            return

        leading_portion = vim.eval(u'a:ArgLead').decode(u'utf-8')
        cursor = int(vim.eval(u'a:CursorPos'))

        # extract currently completed tag
        idx_orig = leading_portion.rfind(u':', 0, cursor)
        if idx_orig == -1:
            idx = 0
        else:
            idx = idx_orig

        current_tag = leading_portion[idx:cursor].lstrip(u':')
        head = leading_portion[:idx + 1]
        if idx_orig == -1:
            head = u''
        tail = leading_portion[cursor:]

        # extract all tags of the current file
        all_tags = set()
        for h in d.all_headings():
            for t in h.tags:
                all_tags.add(t)

        ignorecase = bool(
            int(
                settings.get(u'org_tag_completion_ignorecase',
                             int(vim.eval(u'&ignorecase')))))
        possible_tags = []
        current_tags = heading.tags
        for t in all_tags:
            if ignorecase:
                if t.lower().startswith(current_tag.lower()):
                    possible_tags.append(t)
            elif t.startswith(current_tag):
                possible_tags.append(t)

        vim.command((
            u'let b:org_complete_tags = [%s]' %
            u', '.join([u'"%s%s:%s"' % (head, i, tail)
                        for i in possible_tags])).encode(u'utf-8'))
Exemplo n.º 34
0
	def complete_tags(cls):
		u""" build a list of tags and store it in variable b:org_tag_completion
		"""
		d = ORGMODE.get_document()
		heading = d.current_heading()
		if not heading:
			return

		leading_portion = u_decode(vim.eval(u'a:ArgLead'))
		cursor = int(vim.eval(u'a:CursorPos'))

		# extract currently completed tag
		idx_orig = leading_portion.rfind(u':', 0, cursor)
		if idx_orig == -1:
			idx = 0
		else:
			idx = idx_orig

		current_tag = leading_portion[idx: cursor].lstrip(u':')
		head = leading_portion[:idx + 1]
		if idx_orig == -1:
			head = u''
		tail = leading_portion[cursor:]

		# extract all tags of the current file
		all_tags = set()
		for h in d.all_headings():
			for t in h.tags:
				all_tags.add(t)

		ignorecase = bool(int(settings.get(u'org_tag_completion_ignorecase', int(vim.eval(u'&ignorecase')))))
		possible_tags = []
		# TODO current tags never used...
		current_tags = heading.tags
		for t in all_tags:
			if ignorecase:
				if t.lower().startswith(current_tag.lower()):
					possible_tags.append(t)
			elif t.startswith(current_tag):
				possible_tags.append(t)

		vim.command(u_encode(u'let b:org_complete_tags = [%s]' % u', '.join([u'"%s%s:%s"' % (head, i, tail) for i in possible_tags])))
Exemplo n.º 35
0
	def _load_agendafiles(self, agenda_files):
		# glob for files in agenda_files
		resolved_files = []
		for f in agenda_files:
			f = glob.glob(os.path.join(
				os.path.expanduser(os.path.dirname(f)),
				os.path.basename(f)))
			resolved_files.extend(f)

		agenda_files = [os.path.realpath(f) for f in resolved_files]

		# load the agenda files into buffers
		for agenda_file in agenda_files:
			vim.command((u'badd %s' % agenda_file.replace(" ", "\ ")).encode(u'utf-8'))

		# determine the buffer nr of the agenda files
		agenda_nums = [get_bufnumber(fn) for fn in agenda_files]

		# collect all documents of the agenda files and create the agenda
		return [ORGMODE.get_document(i) for i in agenda_nums if i is not None]
Exemplo n.º 36
0
	def toggle(cls, checkbox=None):
		u"""
		Toggle the checkbox given in the parameter.
		If the checkbox is not given, it will toggle the current checkbox.
		"""
		d = ORGMODE.get_document()
		current_heading = d.current_heading()
		# init checkboxes for current heading
		if current_heading is None:
			return
		current_heading = current_heading.init_checkboxes()

		if checkbox is None:
			# get current_checkbox
			c = current_heading.current_checkbox()
			# no checkbox found
			if c is None:
				cls.update_checkboxes_status()
				return
		else:
			c = checkbox

		if c.status == Checkbox.STATUS_OFF or c.status is None:
			# set checkbox status on if all children are on
			if not c.children or c.are_children_all(Checkbox.STATUS_ON):
				c.toggle()
				d.write_checkbox(c)
			elif c.status is None:
				c.status = Checkbox.STATUS_OFF
				d.write_checkbox(c)

		elif c.status == Checkbox.STATUS_ON:
			if not c.children or c.is_child_one(Checkbox.STATUS_OFF):
				c.toggle()
				d.write_checkbox(c)

		elif c.status == Checkbox.STATUS_INT:
			# can't toggle intermediate state directly according to emacs orgmode
			pass
		# update checkboxes status
		cls.update_checkboxes_status()
Exemplo n.º 37
0
	def test_basic(self):
		bufnr = 1
		set_vim_buffer(buf=self.c1, bufnr=bufnr)
		h = ORGMODE.get_document(bufnr=bufnr).current_heading()
		h.init_checkboxes()

		c = h.current_checkbox(position=2)
		self.assertEqual(str(c), self.c1[2])
		self.assertFalse(c.are_children_all(Checkbox.STATUS_ON))
		self.assertTrue(c.is_child_one(Checkbox.STATUS_OFF))
		self.assertFalse(c.are_siblings_all(Checkbox.STATUS_ON))

		for child in c.all_children():
			pass
		for sibling in c.all_siblings():
			pass
		c = h.current_checkbox(position=3)
		new_checkbox = c.copy()
		self.assertEqual(str(c), self.c1[3])
		c.get_parent_list()
		c.get_index_in_parent_list()
Exemplo n.º 38
0
	def set_todo_state(cls, state):
		u""" Set todo state for buffer.

		:bufnr:		Number of buffer the todo state should be updated for
		:state:		The new todo state
		"""
		lineno, colno = vim.current.window.cursor
		d = ORGMODE.get_document(allow_dirty=True)
		heading = d.find_current_heading()

		if not heading:
			return

		current_state = heading.todo

		# set new headline
		heading.todo = state
		d.write_heading(heading)

		# move cursor along with the inserted state only when current position
		# is in the heading; otherwite do nothing
		if heading.start_vim == lineno and colno > heading.level:
			if current_state is not None and \
				colno <= heading.level + len(current_state):
				# the cursor is actually on the todo keyword
				# move it back to the beginning of the keyword in that case
				vim.current.window.cursor = (lineno, heading.level + 1)
			else:
				# the cursor is somewhere in the text, move it along
				if current_state is None and state is None:
					offset = 0
				elif current_state is None and state is not None:
					offset = len(state) + 1
				elif current_state is not None and state is None:
					offset = -len(current_state) - 1
				else:
					offset = len(state) - len(current_state)
				vim.current.window.cursor = (lineno, colno + offset)
Exemplo n.º 39
0
	def list_timeline(cls):
		"""
		List a timeline of the current buffer to get an overview of the
		current file.
		"""
		raw_agenda = ORGMODE.agenda_manager.get_timestamped_items(
				[ORGMODE.get_document()])

		# create buffer at bottom
		cmd = [u'setlocal filetype=orgagenda']
		cls._switch_to(u'AGENDA', cmd)

		cls.line2doc = {}
		# format text of agenda
		final_agenda = []
		for i, h in enumerate(raw_agenda):
			tmp = u"%s %s" % (h.todo, h.title)
			final_agenda.append(tmp)
			cls.line2doc[len(final_agenda)] = (get_bufname(h.document.bufnr), h.document.bufnr, h.start)

		# show agenda
		vim.current.buffer[:] = [ i.encode(u'utf-8') for i in final_agenda ]
		vim.command(u'setlocal nomodifiable conceallevel=2 concealcursor=nc'.encode(u'utf-8'))
Exemplo n.º 40
0
    def i_heading(cls, mode=u"visual", selection=u"inner", skip_children=False):
        u"""
		inner heading text object
		"""
        heading = ORGMODE.get_document().current_heading()
        if heading:
            if selection != u"inner":
                heading = heading if not heading.parent else heading.parent

            line_start, col_start = [int(i) for i in vim.eval(u'getpos("\'<")'.encode(u"utf-8"))[1:3]]
            line_end, col_end = [int(i) for i in vim.eval(u'getpos("\'>")'.encode(u"utf-8"))[1:3]]

            if mode != u"visual":
                line_start = vim.current.window.cursor[0]
                line_end = line_start

            start = line_start
            end = line_end
            move_one_character_back = u"" if mode == u"visual" else u"h"

            if heading.start_vim < line_start:
                start = heading.start_vim
            if heading.end_vim > line_end and not skip_children:
                end = heading.end_vim
            elif heading.end_of_last_child_vim > line_end and skip_children:
                end = heading.end_of_last_child_vim

            if mode != u"visual" and not vim.current.buffer[end - 1]:
                end -= 1
                move_one_character_back = u""

            swap_cursor = u"o" if vim.current.window.cursor[0] == line_start else u""

            if selection == u"inner" and vim.current.window.cursor[0] != line_start:
                h = ORGMODE.get_document().current_heading()
                if h:
                    heading = h

            visualmode = vim.eval(u"visualmode()").decode(u"utf-8") if mode == u"visual" else u"v"

            if line_start == start and line_start != heading.start_vim:
                if col_start in (0, 1):
                    vim.command(
                        (
                            u"normal! %dgg0%s%dgg$%s%s" % (start, visualmode, end, move_one_character_back, swap_cursor)
                        ).encode(u"utf-8")
                    )
                else:
                    vim.command(
                        (
                            u"normal! %dgg0%dl%s%dgg$%s%s"
                            % (start, col_start - 1, visualmode, end, move_one_character_back, swap_cursor)
                        ).encode(u"utf-8")
                    )
            else:
                vim.command(
                    (
                        u"normal! %dgg0%dl%s%dgg$%s%s"
                        % (start, heading.level + 1, visualmode, end, move_one_character_back, swap_cursor)
                    ).encode(u"utf-8")
                )

            if selection == u"inner":
                if mode == u"visual":
                    return u"OrgInnerHeadingVisual" if not skip_children else u"OrgInnerTreeVisual"
                else:
                    return u"OrgInnerHeadingOperator" if not skip_children else u"OrgInnerTreeOperator"
            else:
                if mode == u"visual":
                    return u"OrgOuterHeadingVisual" if not skip_children else u"OrgOuterTreeVisual"
                else:
                    return u"OrgOuterHeadingOperator" if not skip_children else u"OrgOuterTreeOperator"
        elif mode == u"visual":
            vim.command(u"normal! gv".encode(u"utf-8"))
Exemplo n.º 41
0
	def new_checkbox(cls, below=None):
		d = ORGMODE.get_document()
		h = d.current_heading()
		if h is None:
			return
		# init checkboxes for current heading
		h.init_checkboxes()
		c = h.current_checkbox()

		nc = Checkbox()
		nc._heading = h

		# default checkbox level
		level = h.level + 1
		start = vim.current.window.cursor[0] - 1
		# if no checkbox is found, insert at current line with indent level=1
		if c is None:
			h.checkboxes.append(nc)
		else:
			l = c.get_parent_list()
			idx = c.get_index_in_parent_list()
			if l is not None and idx is not None:
				l.insert(idx + (1 if below else 0), nc)
				# workaround for broken associations, Issue #165
				nc._parent = c.parent
				if below:
					if c.next_sibling:
						c.next_sibling._previous_sibling = nc
					nc._next_sibling = c.next_sibling
					c._next_sibling = nc
					nc._previous_sibling = c
				else:
					if c.previous_sibling:
						c.previous_sibling._next_sibling = nc
					nc._next_sibling = c
					nc._previous_sibling = c.previous_sibling
					c._previous_sibling = nc

			t = c.type
			# increase key for ordered lists
			if t[-1] in OrderListType:
				try:
					num = int(t[:-1]) + (1 if below else -1)
					if num < 0:
						# don't decrease to numbers below zero
						echom(u"Can't decrement further than '0'")
						return
					t = '%d%s' % (num, t[-1])
				except ValueError:
					try:
						char = ord(t[:-1]) + (1 if below else -1)
						if below:
							if char == 91:
								# stop incrementing at Z (90)
								echom(u"Can't increment further than 'Z'")
								return
							elif char == 123:
								# increment from z (122) to A
								char = 65
						else:
							if char == 96:
								# stop decrementing at a (97)
								echom(u"Can't decrement further than 'a'")
								return
							elif char == 64:
								# decrement from A (65) to z
								char = 122
						t = u'%s%s' % (chr(char), t[-1])
					except ValueError:
						pass
			nc.type = t
			if not c.status:
				nc.status = None
			level = c.level

			if below:
				start = c.end_of_last_child
			else:
				start = c.start
		nc.level = level

		if below:
			start += 1
		# vim's buffer behave just opposite to Python's list when inserting a
		# new item.  The new entry is appended in vim put prepended in Python!
		vim.current.buffer[start:start] = [unicode(nc)]

		# update checkboxes status
		cls.update_checkboxes_status()

		vim.command((u'exe "normal %dgg"|startinsert!' % (start + 1, )).encode(u'utf-8'))