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

217 lines
5.3 KiB
Python

# -*- coding: utf-8 -*-
import vim
MODE_ALL = u'a'
MODE_NORMAL = u'n'
MODE_VISUAL = u'v'
MODE_INSERT = u'i'
MODE_OPERATOR = u'o'
OPTION_BUFFER_ONLY = u'<buffer>'
OPTION_SLIENT = u'<silent>'
from orgmode.py3compat.encode_compatibility import *
def _register(f, name):
def r(*args, **kwargs):
p = f(*args, **kwargs)
if hasattr(p, name) and isinstance(getattr(p, name), list):
for i in getattr(p, name):
i.create()
return p
return r
def register_keybindings(f):
return _register(f, u'keybindings')
def register_commands(f):
return _register(f, u'commands')
class Command(object):
u""" A vim command """
def __init__(self, name, command, arguments=u'0', complete=None, overwrite_exisiting=False):
u"""
:name: The name of command, first character must be uppercase
:command: The actual command that is executed
:arguments: See :h :command-nargs, only the arguments need to be specified
:complete: See :h :command-completion, only the completion arguments need to be specified
"""
object.__init__(self)
self._name = name
self._command = command
self._arguments = arguments
self._complete = complete
self._overwrite_exisiting = overwrite_exisiting
def __unicode__(self):
return u':%s<CR>' % self.name
def __str__(self):
return u_encode(self.__unicode__())
@property
def name(self):
return self._name
@property
def command(self):
return self._command
@property
def arguments(self):
return self._arguments
@property
def complete(self):
return self._complete
@property
def overwrite_exisiting(self):
return self._overwrite_exisiting
def create(self):
u""" Register/create the command
"""
vim.command(u_encode(':command%(overwrite)s -nargs=%(arguments)s %(complete)s %(name)s %(command)s' %
{u'overwrite': '!' if self.overwrite_exisiting else '',
u'arguments': u_encode(self.arguments),
u'complete': '-complete=%s' % u_encode(self.complete) if self.complete else '',
u'name': self.name,
u'command': self.command}
))
class Plug(object):
u""" Represents a <Plug> to an abitrary command """
def __init__(self, name, command, mode=MODE_NORMAL):
u"""
:name: the name of the <Plug> should be ScriptnameCommandname
:command: the actual command
"""
object.__init__(self)
if mode not in (MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT, MODE_OPERATOR):
raise ValueError(u'Parameter mode not in MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT, MODE_OPERATOR')
self._mode = mode
self.name = name
self.command = command
self.created = False
def __unicode__(self):
return u'<Plug>%s' % self.name
def __str__(self):
return u_encode(self.__unicode__())
def create(self):
if not self.created:
self.created = True
cmd = self._mode
if cmd == MODE_ALL:
cmd = u''
vim.command(u_encode(u':%snoremap %s %s' % (cmd, str(self), self.command)))
@property
def mode(self):
return self._mode
class Keybinding(object):
u""" Representation of a single key binding """
def __init__(self, key, action, mode=None, options=None, remap=True, buffer_only=True, silent=True):
u"""
:key: the key(s) action is bound to
:action: the action triggered by key(s)
:mode: definition in which vim modes the key binding is valid. Should be one of MODE_*
:option: list of other options like <silent>, <buffer> ...
:repmap: allow or disallow nested mapping
:buffer_only: define the key binding only for the current buffer
"""
object.__init__(self)
self._key = key
self._action = action
# grab mode from plug if not set otherwise
if isinstance(self._action, Plug) and not mode:
mode = self._action.mode
if mode not in (MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT, MODE_OPERATOR):
raise ValueError(u'Parameter mode not in MODE_ALL, MODE_NORMAL, MODE_VISUAL, MODE_INSERT, MODE_OPERATOR')
self._mode = mode
self._options = options
if self._options is None:
self._options = []
self._remap = remap
self._buffer_only = buffer_only
self._silent = silent
if self._buffer_only and OPTION_BUFFER_ONLY not in self._options:
self._options.append(OPTION_BUFFER_ONLY)
if self._silent and OPTION_SLIENT not in self._options:
self._options.append(OPTION_SLIENT)
@property
def key(self):
return self._key
@property
def action(self):
return str(self._action)
@property
def mode(self):
return self._mode
@property
def options(self):
return self._options[:]
@property
def remap(self):
return self._remap
@property
def buffer_only(self):
return self._buffer_only
@property
def silent(self):
return self._silent
def create(self):
from orgmode._vim 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_encode(u'hasmapto("%s")' % (self._action, )))):
create_mapping = False
if isinstance(self._action, Command):
# create command
self._action.create()
if create_mapping:
vim.command(u_encode(u':%smap %s %s %s' % (cmd, u' '.join(self._options), self._key, self._action)))
except BaseException as e:
if ORGMODE.debug:
echom(u'Failed to register key binding %s %s' % (self._key, self._action))
# vim: set noexpandtab: