Skip to content

Instantly share code, notes, and snippets.

@Shougo
Last active August 29, 2015 14:22
Show Gist options
  • Save Shougo/3fd5a4591a537f7d1f21 to your computer and use it in GitHub Desktop.
Save Shougo/3fd5a4591a537f7d1f21 to your computer and use it in GitHub Desktop.
Improve sources interface
#=============================================================================
# FILE: buffer.py
# AUTHOR: Shougo Matsushita <Shougo.Matsu at gmail.com>
# License: MIT license {{{
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# }}}
#=============================================================================
import re
class Source(object):
def __init__(self):
self.mark = '[B]'
self.filters = ['matcher_fuzzy']
pass
def get_complete_position(self, vim, context):
m = re.search(context.input, r'[a-zA-Z_][a-zA-Z0-9_]')
if m:
return m.start()
else:
return -1
def gather_candidates(self, vim, context):
candidates = []
p = re.compile('[a-zA-Z_]\w*')
for l in vim.current.buffer:
candidates += p.findall(l)
return [{ 'word': x } for x in candidates]
#=============================================================================
# FILE: deoplete.py
# AUTHOR: Shougo Matsushita <Shougo.Matsu at gmail.com>
# License: MIT license {{{
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# }}}
#=============================================================================
import neovim
import re
import importlib.machinery
import os.path
import deoplete.sources
import deoplete.filters
class Deoplete(object):
def __init__(self, vim):
self.vim = vim
self.filters = {}
self.sources = {}
self.runtimepath = ''
def load_sources(self):
# Load sources from runtimepath
for path in self.vim.eval(
"globpath(&runtimepath, \
'rplugin/python3/deoplete/sources/*.py')").split("\n"):
name = os.path.basename(path)
source = importlib.machinery.SourceFileLoader(
'deoplete.sources.' + name[: -3], path).load_module()
if hasattr(source, 'Source'):
self.sources[name[: -3]] = source.Source()
# self.debug(self.sources)
def load_filters(self):
# Load filters from runtimepath
for path in self.vim.eval(
"globpath(&runtimepath, \
'rplugin/python3/deoplete/filters/*.py')").split("\n"):
name = os.path.basename(path)
filter = importlib.machinery.SourceFileLoader(
'deoplete.filters.' + name[: -3], path).load_module()
if hasattr(filter, 'Filter'):
self.filters[name[: -3]] = filter.Filter()
# self.debug(self.filters)
def debug(self, msg):
self.vim.command('echomsg string("' + str(msg) + '")')
def gather_candidates(self, context):
# Skip completion
if self.vim.eval('&l:completefunc') != '' \
and self.vim.eval('&l:buftype').find('nofile') >= 0:
return []
if self.vim.eval('&runtimepath') != self.runtimepath:
# Recache
self.load_sources()
self.load_filters()
# Encoding conversion
encoding = self.vim.eval('&encoding')
context = { k.decode(encoding) :
(v.decode(encoding) if isinstance(v, bytes) else v)
for k, v in context.items()}
# self.debug(context)
if context['complete_str'] == '':
return []
# Set ignorecase
if context['smartcase'] \
and re.search(r'[A-Z]', context['complete_str']):
context['ignorecase'] = 0
# sources = ['buffer', 'neosnippet']
# sources = ['buffer']
sources = []
candidates = []
for source_name, source in self.sources.items():
if sources and (not source_name in sources):
continue
context['candidates'] = source.gather_candidates(
self.vim, context)
for filter_name in source.filters:
if filter_name in self.filters:
context['candidates'] = self.filters[filter_name].filter(
self.vim, context)
# self.debug(context['candidates'])
# On post filter
if hasattr(source, 'on_post_filter'):
context['candidates'] = source.on_post_filter(
self.vim, context)
# Set default menu
for candidate in context['candidates']:
if not 'menu' in candidate:
candidate['menu'] = source.mark
candidates += context['candidates']
return candidates
#=============================================================================
# FILE: neosnippet.py
# AUTHOR: Shougo Matsushita <Shougo.Matsu at gmail.com>
# License: MIT license {{{
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# }}}
#=============================================================================
import re
class Source(object):
def __init__(self):
self.mark = '[nsnip]'
self.filters = ['matcher_fuzzy']
pass
def get_complete_position(self, vim, context):
m = re.search(context.input, r'[a-zA-Z_][a-zA-Z0-9_]')
if m:
return m.start()
else:
return -1
def gather_candidates(self, vim, context):
return vim.eval("values(neosnippet#helpers#get_snippets())")
def on_post_filter(self, vim, context):
for candidate in context['candidates']:
candidate['dup'] = 1
return context['candidates']
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment