Skip to content

Commit

Permalink
json_cache: Support parses library name & Change json cache dir name
Browse files Browse the repository at this point in the history
- Add parses library name
  -  e.g. 'go/ast' is 'go'
  - If imported 'github.com/pkg/errors', ignore cache for 'errors'

- Change json cache files
  - 'go/ast' is '/path/to/go/ast.json'
  - 'errors' is '/path/to/errors/errors.json'

Signed-off-by: Koichi Shiraishi <k@zchee.io>
  • Loading branch information
zchee committed May 26, 2016
1 parent 03d4dc2 commit eef6f7b
Show file tree
Hide file tree
Showing 5 changed files with 226 additions and 53 deletions.
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Plug 'zchee/deoplete-go', { 'do': 'make'}
| `g:deoplete#sources#go#package_dot` | `0` | No |
| `g:deoplete#sources#go#sort_class` | `[]` | Recommend |
| `g:deoplete#sources#go#use_cache` | `0` | Recommend |
| `g:deoplete#sources#go#data_directory` | `$HOME.'/.config/gocode/json'` | Recommend |
| `g:deoplete#sources#go#json_directory` | `$HOME.'/.config/gocode/json'` | Recommend |

### `g:deoplete#sources#go#align_class`
#### Class Aligning
Expand Down Expand Up @@ -173,7 +173,7 @@ let g:deoplete#sources#go#sort_class = ['package', 'func', 'type', 'var', 'const

Try test it with the `os` package :)

### `g:deoplete#sources#go#use_cache` `g:deoplete#sources#go#data_directory`
### `g:deoplete#sources#go#use_cache` `g:deoplete#sources#go#json_directory`
#### Static json caching

`g:deoplete#sources#go#use_cache`
Expand All @@ -184,9 +184,9 @@ Try test it with the `os` package :)
| **Type** | int |
| **Example** | `1` |

`g:deoplete#sources#go#data_directory`
`g:deoplete#sources#go#json_directory`

| **Default** | `~/.cache/gocode/json` |
| **Default** | `~/.cache/deoplete/go/$GOOS_$GOARCH` |
|--------------|------------------------|
| **Required** | **Recommend** |
| **Type** | string |
Expand All @@ -202,14 +202,14 @@ Terms:
- You typed package name have not `import` current buffer
- Match the typed package name and json file name

`deoplete-go` will parse `g:deoplete#sources#go#data_directory` directory. You can define of json data directory.
Default is `~/.cache/gocode/json`.
`deoplete-go` will parse `g:deoplete#sources#go#json_directory` directory. You can define of json data directory.
Default is `~/.cache/deoplete/go/$GOOS_$GOARCH`.

Also, See [How to use static json caching](#how-to-use-static-json-caching)

```vim
let g:deoplete#sources#go#use_cache = 1
let g:deoplete#sources#go#data_directory = '/path/to/data_dir'
let g:deoplete#sources#go#json_directory = '/path/to/data_dir'
```

===
Expand All @@ -223,7 +223,7 @@ let g:deoplete#sources#go#data_directory = '/path/to/data_dir'

Pre-generate json data is [data/json](./data/json).
If you use it, `cp -r data/json/VERSION/$GOOS_$GOARCH /path/to/data_dir`.
`/path/to/data_dir` is `g:deoplete#sources#go#data_directory`.
`/path/to/data_dir` is `g:deoplete#sources#go#json_directory`.

And, You can generate your Go environment. such as version is `devel`, GOARCH is `arm`.
If you want to it, run `make gen_json`.
Expand Down Expand Up @@ -259,7 +259,7 @@ let g:deoplete#enable_at_startup = 1
let g:deoplete#sources#go#gocode_binary = $GOPATH.'/bin/gocode'
let g:deoplete#sources#go#sort_class = ['package', 'func', 'type', 'var', 'const']
let g:deoplete#sources#go#use_cache = 1
let g:deoplete#sources#go#data_directory = '/path/to/data_dir'
let g:deoplete#sources#go#json_directory = '/path/to/data_dir'
```

===
Expand Down
9 changes: 7 additions & 2 deletions data/gen_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ def main():

func = None
if re.search(r'/', pkg):
library = str(pkg).split(r'/')[:-1]
func = str(pkg).split(r'/')[-1]
else:
library = pkg
func = pkg
source = str(fs).replace('IMPORT', pkg).replace('FUNC', func).encode()

Expand All @@ -52,8 +54,11 @@ def main():
if not os.path.exists(out_dir):
os.makedirs(out_dir)

pkg_dir = os.path.join(out_dir, ''.join(library))
if not os.path.exists(pkg_dir):
os.makedirs(pkg_dir)
out_path = \
os.path.join(out_dir, func + '.json')
os.path.join(pkg_dir, func + '.json')
out = open(out_path, 'w')
out.write(json.dumps(result, sort_keys=True))
out.close()
Expand All @@ -75,6 +80,6 @@ def is_exec(fpath):
binary = os.path.join(path, cmd)
if is_exec(binary):
return binary
return error(self.vim, 'gocode binary not found')
return print('gocode binary not found')

main()
139 changes: 139 additions & 0 deletions data/stdlib-devel_darwin_amd64.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
archive/tar
archive/zip
bufio
bytes
compress/bzip2
compress/flate
compress/gzip
compress/lzw
compress/zlib
container/heap
container/list
container/ring
context
crypto
crypto/aes
crypto/cipher
crypto/des
crypto/dsa
crypto/ecdsa
crypto/elliptic
crypto/hmac
crypto/md5
crypto/rand
crypto/rc4
crypto/rsa
crypto/sha1
crypto/sha256
crypto/sha512
crypto/subtle
crypto/tls
crypto/x509
crypto/x509/pkix
database/sql
database/sql/driver
debug/dwarf
debug/elf
debug/gosym
debug/macho
debug/pe
debug/plan9obj
encoding
encoding/ascii85
encoding/asn1
encoding/base32
encoding/base64
encoding/binary
encoding/csv
encoding/gob
encoding/hex
encoding/json
encoding/pem
encoding/xml
errors
expvar
flag
fmt
go/ast
go/build
go/constant
go/doc
go/format
go/importer
go/parser
go/printer
go/scanner
go/token
go/types
hash
hash/adler32
hash/crc32
hash/crc64
hash/fnv
html
html/template
image
image/color
image/color/palette
image/draw
image/gif
image/jpeg
image/png
index/suffixarray
io
io/ioutil
log
log/syslog
math
math/big
math/cmplx
math/rand
mime
mime/multipart
mime/quotedprintable
net
net/http
net/http/cgi
net/http/cookiejar
net/http/fcgi
net/http/httptest
net/http/httptrace
net/http/httputil
net/http/pprof
net/mail
net/rpc
net/rpc/jsonrpc
net/smtp
net/textproto
net/url
os
os/exec
os/signal
os/user
path
path/filepath
reflect
regexp
regexp/syntax
runtime
runtime/debug
runtime/pprof
runtime/trace
sort
strconv
strings
sync
sync/atomic
syscall
testing
testing/iotest
testing/quick
text/scanner
text/tabwriter
text/template
text/template/parse
time
unicode
unicode/utf16
unicode/utf8
unsafe
4 changes: 2 additions & 2 deletions plugin/deoplete-go.vim
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ let g:deoplete#sources#go#sort_class =
let g:deoplete#sources#go#use_cache =
\ get( g:, 'deoplete#sources#go#use_cache', 0 )

let g:deoplete#sources#go#data_directory =
\ get( g:, 'deoplete#sources#go#data_directory', $XDG_DATA_HOME.'/gocode/json/' )
let g:deoplete#sources#go#json_directory =
\ get( g:, 'deoplete#sources#go#json_directory', '' )
109 changes: 69 additions & 40 deletions rplugin/python3/deoplete/sources/deoplete_go.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ def __init__(self, vim):
self.vim.vars['deoplete#sources#go#sort_class']
self.use_cache = \
self.vim.vars['deoplete#sources#go#use_cache']
self.data_directory = \
self.vim.vars['deoplete#sources#go#data_directory']
self.json_directory = \
self.vim.vars['deoplete#sources#go#json_directory']
self.debug_enabled = \
self.vim.vars.get('deoplete#sources#go#debug', 0)

Expand All @@ -46,44 +46,32 @@ def get_complete_position(self, context):
return m.start() if m else -1

def gather_candidates(self, context):
buf = self.vim.current.buffer
pkgs = ''
parent = ''
pkg_data = ''
buffer = self.vim.current.buffer

if self.use_cache:
pkgs = self.GetCurrentImportPackages(buf)
m = re.search(r'[\w]*.$', context['input'])
parent = str(m.group(0))

pkg_data = os.path.join(self.data_directory, parent + 'json')
import_packages = self.get_import_package(buffer)
import_package = [x['package'] for x in import_packages]

if parent not in pkgs and '.' \
in parent and os.path.isfile(pkg_data):
with open(pkg_data) as json_pkg_data:
result = loads(json_pkg_data.read())
m = re.search(r'[\w]*.$', context['input'])
package = str(m.group(0))
library = [x['library'][0] for x in import_packages if str(
package).strip('.') == x['package']]
if len(library) == 0:
library = [str(package).strip('.')]
package_json = os.path.join(
self.json_directory,
library[0],
package + 'json')

if package not in import_package and \
'.' in package and os.path.isfile(package_json):
with open(package_json) as j:
result = loads(j.read())
else:
result = self.get_complete_result(buffer, context)

else:
line = self.vim.current.window.cursor[0]
column = context['complete_position']

offset = self.vim.call('line2byte', line) + \
charpos2bytepos(self.vim, context['input'][: column],
column) - 1
source = '\n'.join(buf).encode()

process = subprocess.Popen([self.GoCodeBinary(),
'-f=json',
'autocomplete',
buf.name,
str(offset)],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
start_new_session=True)
process.stdin.write(source)
stdout_data, stderr_data = process.communicate()
result = loads(stdout_data.decode())
result = self.get_complete_result(buffer, context)

try:
if result[1][0]['class'] == 'PANIC':
Expand Down Expand Up @@ -137,17 +125,58 @@ def gather_candidates(self, context):
except Exception:
return []

def GetCurrentImportPackages(self, buf):
pkgs = []
def get_complete_result(self, buffer, context):
line = self.vim.current.window.cursor[0]
column = context['complete_position']

offset = self.vim.call('line2byte', line) + \
charpos2bytepos(self.vim, context['input'][: column],
column) - 1
source = '\n'.join(buffer).encode()

process = subprocess.Popen([self.GoCodeBinary(),
'-f=json',
'autocomplete',
buffer.name,
str(offset)],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
start_new_session=True)
process.stdin.write(source)
stdout_data, stderr_data = process.communicate()
return loads(stdout_data.decode())

def get_import_package(self, buffer):
start = 0
for line, b in enumerate(buf):
packages = []

for line, b in enumerate(buffer):

if re.match(r'^\s*import \w*|^\s*import \(', b):
start = line
continue
elif re.match(r'\)', b):
break
elif line > start:
pkgs.append(re.sub(r'\t|"', '', b))
return pkgs
package_name = re.sub(r'\t|"', '', b)
if str(package_name).find(r'/', 0) > 0:
full_package_name = str(package_name).split('/', -1)
package_name = full_package_name[
len(full_package_name) - 1]
library = '/'.join(
full_package_name[:len(full_package_name) - 1]),

packages.append(dict(
library=library,
package=package_name
))
else:
packages.append(dict(
library='none',
package=package_name
))
return packages

def GoCodeBinary(self):
try:
Expand Down

0 comments on commit eef6f7b

Please sign in to comment.