nvim/pack/acp/start/vim-orgmode/ftplugin/orgmode/menu.py

173 lines
4.3 KiB
Python

# -*- coding: utf-8 -*-
import vim
from orgmode.keybinding import Command, Plug, Keybinding
from orgmode.keybinding import MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT
from orgmode.py3compat.encode_compatibility import *
def register_menu(f):
def r(*args, **kwargs):
p = f(*args, **kwargs)
def create(entry):
if isinstance(entry, Submenu) or isinstance(entry, Separator) \
or isinstance(entry, ActionEntry):
entry.create()
if hasattr(p, u'menu'):
if isinstance(p.menu, list) or isinstance(p.menu, tuple):
for e in p.menu:
create(e)
else:
create(p.menu)
return p
return r
def add_cmd_mapping_menu(plugin, name, function, key_mapping, menu_desrc):
u"""A helper function to create a vim command and keybinding and add these
to the menu for a given plugin.
:plugin: the plugin to operate on.
:name: the name of the vim command (and the name of the Plug)
:function: the actual python function which is called when executing the
vim command.
:key_mapping: the keymapping to execute the command.
:menu_desrc: the text which appears in the menu.
"""
cmd = Command(name, function)
keybinding = Keybinding(key_mapping, Plug(name, cmd))
plugin.commands.append(cmd)
plugin.keybindings.append(keybinding)
plugin.menu + ActionEntry(menu_desrc, keybinding)
class Submenu(object):
u""" Submenu entry """
def __init__(self, name, parent=None):
object.__init__(self)
self.name = name
self.parent = parent
self._children = []
def __add__(self, entry):
if entry not in self._children:
self._children.append(entry)
entry.parent = self
return entry
def __sub__(self, entry):
if entry in self._children:
idx = self._children.index(entry)
del self._children[idx]
@property
def children(self):
return self._children[:]
def get_menu(self):
n = self.name.replace(u' ', u'\\ ')
if self.parent:
return u'%s.%s' % (self.parent.get_menu(), n)
return n
def create(self):
for c in self.children:
c.create()
def __str__(self):
res = self.name
for c in self.children:
res += str(c)
return res
class Separator(object):
u""" Menu entry for a Separator """
def __init__(self, parent=None):
object.__init__(self)
self.parent = parent
def __unicode__(self):
return u'-----'
def __str__(self):
return u_encode(self.__unicode__())
def create(self):
if self.parent:
menu = self.parent.get_menu()
vim.command(u_encode(u'menu %s.-%s- :' % (menu, id(self))))
class ActionEntry(object):
u""" ActionEntry entry """
def __init__(self, lname, action, rname=None, mode=MODE_NORMAL, parent=None):
u"""
:lname: menu title on the left hand side of the menu entry
:action: could be a vim command sequence or an actual Keybinding
:rname: menu title that appears on the right hand side of the menu
entry. If action is a Keybinding this value ignored and is
taken from the Keybinding
:mode: defines when the menu entry/action is executable
:parent: the parent instance of this object. The only valid parent is Submenu
"""
object.__init__(self)
self._lname = lname
self._action = action
self._rname = rname
if mode not in (MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT):
raise ValueError(u'Parameter mode not in MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT')
self._mode = mode
self.parent = parent
def __str__(self):
return u'%s\t%s' % (self.lname, self.rname)
@property
def lname(self):
return self._lname.replace(u' ', u'\\ ')
@property
def action(self):
if isinstance(self._action, Keybinding):
return self._action.action
return self._action
@property
def rname(self):
if isinstance(self._action, Keybinding):
return self._action.key.replace(u'<Tab>', u'Tab')
return self._rname
@property
def mode(self):
if isinstance(self._action, Keybinding):
return self._action.mode
return self._mode
def create(self):
menucmd = u':%smenu ' % self.mode
menu = u''
cmd = u''
if self.parent:
menu = self.parent.get_menu()
menu += u'.%s' % self.lname
if self.rname:
cmd = u'%s %s<Tab>%s %s' % (menucmd, menu, self.rname, self.action)
else:
cmd = u'%s %s %s' % (menucmd, menu, self.action)
vim.command(u_encode(cmd))
# keybindings should be stored in the plugin.keybindings property and be registered by the appropriate keybinding registrar
#if isinstance(self._action, Keybinding):
# self._action.create()
# vim: set noexpandtab: