# -*- 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'' OPTION_SLIENT = u'' 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' % 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 to an abitrary command """ def __init__(self, name, command, mode=MODE_NORMAL): u""" :name: the name of the 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'%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 , ... :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: