parent
6fa3f737e2
commit
231ff0946e
12 changed files with 209 additions and 1 deletions
@ -0,0 +1,4 @@ |
|||||||
|
[flake8] |
||||||
|
exclude = .git,__pycache__,autoload,doc |
||||||
|
max-complexity = 10 |
||||||
|
max-line-length = 100 |
@ -0,0 +1,21 @@ |
|||||||
|
MIT License |
||||||
|
|
||||||
|
Copyright (c) 2017 Filip Szymański |
||||||
|
|
||||||
|
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. |
@ -0,0 +1,19 @@ |
|||||||
|
# deoplete-abook |
||||||
|
|
||||||
|
`Deoplete-abook` offers asynchronous completion of email addresses in [Mutt](http://www.mutt.org/) using [abook](http://abook.sourceforge.net/) contacts stored in a plain text database. |
||||||
|
Inspired by [Greg Hurrell's](https://github.com/wincent) Vim screencast [#58](https://www.youtube.com/watch?v=BNnSjJOpXDk). |
||||||
|
|
||||||
|
## Installation |
||||||
|
|
||||||
|
To install `deoplete-abook`, use your favorite [Neovim](https://neovim.io/) plugin manager. |
||||||
|
|
||||||
|
#### Using [vim-plug](https://github.com/junegunn/vim-plug) |
||||||
|
|
||||||
|
```vim |
||||||
|
Plug 'Shougo/deoplete.nvim', {'do': ':UpdateRemotePlugins'} |
||||||
|
Plug 'fszymanski/deoplete-abook' |
||||||
|
``` |
||||||
|
|
||||||
|
## Documentation |
||||||
|
|
||||||
|
For more information, see `:help deoplete_abook.txt`. |
@ -0,0 +1,35 @@ |
|||||||
|
scriptencoding utf-8 |
||||||
|
|
||||||
|
" Copyright (c) 2017 Filip Szymański. All rights reserved. |
||||||
|
" Use of this source code is governed by an MIT license that can be |
||||||
|
" found in the LICENSE file. |
||||||
|
|
||||||
|
function! s:check_deoplete() abort |
||||||
|
if !empty(globpath(&runtimepath, 'plugin/deoplete.vim')) |
||||||
|
call health#report_ok('Deoplete plugin is installed') |
||||||
|
else |
||||||
|
call health#report_error('Deoplete plugin is not installed', [ |
||||||
|
\ 'The deoplete plugin can be found here: ' . |
||||||
|
\ 'https://github.com/Shougo/deoplete.nvim' |
||||||
|
\ ]) |
||||||
|
endif |
||||||
|
endfunction |
||||||
|
|
||||||
|
function! s:check_addressbook() abort |
||||||
|
let datafile = get(g:, 'deoplete#sources#abook#datafile', |
||||||
|
\ expand('~/.abook/addressbook')) |
||||||
|
if filereadable(datafile) |
||||||
|
call health#report_ok('Addressbook file was found: ' . datafile) |
||||||
|
else |
||||||
|
call health#report_error('Addressbook file was not found', |
||||||
|
\ ['help: deoplete_abook.txt']) |
||||||
|
endif |
||||||
|
endfunction |
||||||
|
|
||||||
|
function! health#deoplete_abook#check() abort |
||||||
|
call health#report_start('Dependencies') |
||||||
|
call s:check_deoplete() |
||||||
|
call s:check_addressbook() |
||||||
|
endfunction |
||||||
|
|
||||||
|
" vim: ts=2 et sw=2 |
@ -0,0 +1,61 @@ |
|||||||
|
*deoplete_abook.txt* Deoplete source for abook contacts |
||||||
|
|
||||||
|
Author: Filip Szymański <filip.szymanski@zoho.eu> |
||||||
|
|
||||||
|
============================================================================== |
||||||
|
CONTENTS *deoplete-abook-contents* |
||||||
|
|
||||||
|
1. Introduction |deoplete-abook-introduction| |
||||||
|
2. Configuration |deoplete-abook-configuration| |
||||||
|
3. License |deoplete-abook-license| |
||||||
|
4. Bugs |deoplete-abook-bugs| |
||||||
|
5. Contributing |deoplete-abook-contributing| |
||||||
|
|
||||||
|
============================================================================== |
||||||
|
INTRODUCTION *deoplete-abook-introduction* |
||||||
|
|
||||||
|
This deoplete[1] source offers asynchronous completion of email addresses |
||||||
|
in Mutt[2] using abook[3] contacts stored in a plain text database. |
||||||
|
|
||||||
|
Note: Inspired by Greg Hurrell's[4] Vim screencast #58[5]. |
||||||
|
|
||||||
|
============================================================================== |
||||||
|
CONFIGURATION *deoplete-abook-configuration* |
||||||
|
|
||||||
|
*g:deoplete#sources#abook#datafile* |
||||||
|
Set this option to use an alternative addressbook file. |
||||||
|
> |
||||||
|
let g:deoplete#sources#abook#datafile = expand('~/path/to/addressbook') |
||||||
|
< |
||||||
|
Default: '~/.abook/addressbook' |
||||||
|
Type: string |
||||||
|
|
||||||
|
============================================================================== |
||||||
|
LICENSE *deoplete-abook-license* |
||||||
|
|
||||||
|
MIT |
||||||
|
|
||||||
|
============================================================================== |
||||||
|
BUGS *deoplete-abook-bugs* |
||||||
|
|
||||||
|
If you find a bug please create an issue on GitHub. |
||||||
|
|
||||||
|
https://github.com/fszymanski/deoplete-abook/issues |
||||||
|
|
||||||
|
============================================================================== |
||||||
|
CONTRIBUTING *deoplete-abook-contributing* |
||||||
|
|
||||||
|
Think you can make this plugin better? Awesome. Fork it on GitHub and create |
||||||
|
a pull request. |
||||||
|
|
||||||
|
https://github.com/fszymanski/deoplete-abook |
||||||
|
|
||||||
|
============================================================================== |
||||||
|
|
||||||
|
[1] https://github.com/Shougo/deoplete.nvim |
||||||
|
[2] http://www.mutt.org/ |
||||||
|
[3] http://abook.sourceforge.net/ |
||||||
|
[4] https://github.com/wincent |
||||||
|
[5] https://www.youtube.com/watch?v=BNnSjJOpXDk |
||||||
|
|
||||||
|
vim: tw=78 ts=8 ft=help norl |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,64 @@ |
|||||||
|
# Copyright (c) 2017 Filip Szymański. All rights reserved. |
||||||
|
# Use of this source code is governed by an MIT license that can be |
||||||
|
# found in the LICENSE file. |
||||||
|
|
||||||
|
import configparser |
||||||
|
import os.path |
||||||
|
import re |
||||||
|
|
||||||
|
from .base import Base # pylint: disable=E0401 |
||||||
|
|
||||||
|
|
||||||
|
# pylint: disable=W0201,W0613 |
||||||
|
class Source(Base): |
||||||
|
COLON_PATTERN = re.compile(r':\s?') |
||||||
|
COMMA_PATTERN = re.compile(r'.+,\s?') |
||||||
|
HEADER_PATTERN = re.compile(r'^(Bcc|Cc|From|Reply-To|To):(\s?|.+,\s?)') |
||||||
|
|
||||||
|
def __init__(self, vim): |
||||||
|
super().__init__(vim) |
||||||
|
|
||||||
|
self.__cache = [] |
||||||
|
|
||||||
|
self.filetypes = ['mail'] |
||||||
|
self.mark = '[abook]' |
||||||
|
self.matchers = ['matcher_length', 'matcher_full_fuzzy'] |
||||||
|
self.min_pattern_length = 0 |
||||||
|
self.name = 'abook' |
||||||
|
|
||||||
|
def on_init(self, context): |
||||||
|
self.__datafile = context['vars'].get('deoplete#sources#abook#datafile', |
||||||
|
os.path.expanduser('~/.abook/addressbook')) |
||||||
|
if not os.path.isfile(self.__datafile): |
||||||
|
self.vim.err_write('[deoplete-abook] No such file: {0}\n'.format(self.__datafile)) |
||||||
|
|
||||||
|
def on_event(self, context): |
||||||
|
self.__make_cache() |
||||||
|
|
||||||
|
def gather_candidates(self, context): |
||||||
|
if self.HEADER_PATTERN.search(context['input']) is not None: |
||||||
|
if not self.__cache: |
||||||
|
self.__make_cache() |
||||||
|
|
||||||
|
return self.__cache |
||||||
|
|
||||||
|
def get_complete_position(self, context): |
||||||
|
colon = self.COLON_PATTERN.search(context['input']) |
||||||
|
comma = self.COMMA_PATTERN.search(context['input']) |
||||||
|
return max(colon.end() if colon is not None else -1, |
||||||
|
comma.end() if comma is not None else -1) |
||||||
|
|
||||||
|
def __make_cache(self): |
||||||
|
addressbook = configparser.ConfigParser() |
||||||
|
addressbook.read(self.__datafile) |
||||||
|
for section in addressbook.sections(): |
||||||
|
emails = addressbook.get(section, 'email', fallback=None) |
||||||
|
if emails is not None: |
||||||
|
name = addressbook.get(section, 'name', fallback=None) |
||||||
|
for email in emails.split(','): |
||||||
|
if name is not None: |
||||||
|
email = '"{0}" <{1}>'.format(name, email) |
||||||
|
|
||||||
|
self.__cache.append({'word': email}) |
||||||
|
|
||||||
|
# vim: ts=4 et sw=4 |
@ -1 +1 @@ |
|||||||
Subproject commit 9fff379c17729d4643c9ed3b2e0494e2a7bbafe8 |
Subproject commit dd4e62324ab1607aefdbeddc776489cf9826ee6e |
@ -0,0 +1 @@ |
|||||||
|
Subproject commit 11ed125209e2277d439cf6d0340c6fca263cb09b |
Loading…
Reference in new issue