Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for hhp for newer GHC versions #86

Merged
merged 1 commit into from
Jun 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
*.py[cod]
doc/tags
**/tags
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ It shows your environment information possibly related to neco-ghc.

- Current filetype
- neco-ghc only works in the buffer with filetype haskell or lhaskell.
- ghc-mod executable (required)
- neco-ghc requires [ghc-mod](https://github.com/kazu-yamamoto/ghc-mod) and it must be placed in your `$PATH`.
- ghc-mod OR hhpc executable (required)
- neco-ghc requires [ghc-mod](https://github.com/kazu-yamamoto/ghc-mod) or [hhp](https://github.com/kazu-yamamoto/hhp) and they must be placed in your `$PATH`.
- 'omnifunc'
- To use Vim builtin completion, `'omnifunc'` must be set to `necoghc#omnifunc` by `setlocal omnifunc=necoghc#omnifunc`.
- Completion plugin installation (optional)
Expand Down
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# neco-ghc: ghc-mod completion for neocomplcache/neocomplete/deoplete
# neco-ghc: ghc-mod/hhpc completion for neocomplcache/neocomplete/deoplete

A completion plugin for Haskell, using ghc-mod
A completion plugin for Haskell, using ghc-mod or hhpc

## What is neco-ghc

Expand All @@ -22,7 +22,8 @@ ujihisa added some new features.

## Install

* Install ghc-mod package by `stack install ghc-mod` or `cabal install ghc-mod`
* Install the ghc-mod package by `stack install ghc-mod` or `cabal install ghc-mod`
OR install the hhpc package by `stack install hhpc` or `cabal install hhpc`
* Unarchive neco-ghc and put it into a dir of your &rtp.

Note: If you use ghc-mod 5.4, you should use ghc-mod 5.5+.
Expand Down Expand Up @@ -72,25 +73,25 @@ This feature was introduced in ghc-mod 1.11.5.
### `g:necoghc_debug`
Default: 0

Show error message if ghc-mod command fails.
Show error message if ghc-mod/hhpc command fails.
Usually it will be noisy if `ghc-mod browse Your.Project.Module` always
fails.
Use this flag only if you have some trouble.

### `g:necoghc_use_stack`
Default: 0

Allow using stack's own ghc-mod.
It will change direct `ghc-mod` mod calls to `stack exec --no-stack-exe ghc-mod
--` instead.
Use this flag if your globally installed ghc-mod doesn't work properly with your
Allow using stack's own ghc-mod/hhpc.
If you are using ghc-mod, it will change direct `ghc-mod` mod calls to `stack
exec --no-stack-exe ghc-mod --` instead. The same goes for hhpc.
Use this flag if your globally installed ghc-mod/hhpc doesn't work properly with your
stack projects.

## Troubleshoot

### Q: neco-ghc does not work

Check the $PATH variable in vim contains the path to your ghc-mod command.
Check the $PATH variable in vim contains the path to your ghc-mod/hhpc command.
Or you can execute `:NecoGhcDiagnostics` command for debug.

### Q: Completion isn't working for local functions or modules
Expand Down
36 changes: 24 additions & 12 deletions autoload/necoghc.vim
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,29 @@ let s:is_async = has('nvim')
let s:job_info = {}
let s:max_processes = 5

let s:ghc_mod_path = ['ghc-mod']
if executable('ghc-mod')
let g:necoghc#executable = 'ghc-mod'
elseif executable('hhpc')
let g:necoghc#executable = 'hhpc'
else
let g:necoghc#executable = ''
endif

let s:exe_path = [g:necoghc#executable]

function! necoghc#boot() abort "{{{
if exists('s:browse_cache')
return
endif

if get(g:, 'necoghc_use_stack', 0)
let s:ghc_mod_path = ['stack', 'exec', '--no-stack-exe', 'ghc-mod', '--']
let s:exe_path = ['stack', 'exec', '--no-stack-exe', g:necoghc#executable, '--']
endif

let l:opts = get(g:, 'ghcmod_ghc_options', [])

for l:opt in l:opts
call extend(s:ghc_mod_path, ['-g', l:opt])
call extend(s:exe_path, ['-g', l:opt])
endfor

let s:browse_cache = {}
Expand Down Expand Up @@ -284,7 +292,7 @@ function! s:ghc_mod_caching_browse(mod) abort "{{{
endif

if has('nvim')
let l:id = jobstart(s:ghc_mod_path + l:cmd, {
let l:id = jobstart(s:exe_path + l:cmd, {
\ 'on_stdout': function('s:job_handler'),
\ 'on_stderr': function('s:job_handler'),
\ 'on_exit': function('s:job_handler'),
Expand All @@ -303,7 +311,7 @@ function! s:ghc_mod_caching_browse(mod) abort "{{{
let shellslash = &shellslash
set noshellslash
endif
let l:job = job_start(s:ghc_mod_path + l:cmd, {
let l:job = job_start(s:exe_path + l:cmd, {
\ 'callback': function('s:job_handler_vim'),
\ 'close_cb': function('s:job_close_callback_vim'),
\ })
Expand Down Expand Up @@ -400,7 +408,7 @@ function! necoghc#get_modules() abort "{{{
endfunction "}}}

function! s:ghc_mod(cmd) abort "{{{
let l:cmd = s:ghc_mod_path + a:cmd
let l:cmd = s:exe_path + a:cmd
let l:lines = split(s:system(l:cmd), '\r\n\|[\r\n]')

let l:warnings = filter(copy(l:lines), "v:val =~# '^Warning:'")
Expand All @@ -409,14 +417,14 @@ function! s:ghc_mod(cmd) abort "{{{

if empty(l:lines) && get(g:, 'necoghc_debug', 0)
echohl ErrorMsg
echomsg printf('neco-ghc: ghc-mod returned nothing: %s', join(l:cmd, ' '))
echomsg printf('neco-ghc: ' . g:necoghc#executable . ' returned nothing: %s', join(l:cmd, ' '))
echohl None
endif

if !empty(l:errors)
if get(g:, 'necoghc_debug', 0)
echohl ErrorMsg
echomsg printf('neco-ghc: ghc-mod returned error messages: %s', join(l:cmd, ' '))
echomsg printf('neco-ghc: ' . g:necoghc#executable . ' returned error messages: %s', join(l:cmd, ' '))
for l:line in l:errors
echomsg l:line
endfor
Expand All @@ -428,7 +436,7 @@ function! s:ghc_mod(cmd) abort "{{{
if !empty(l:warnings)
if get(g:, 'necoghc_debug', 0)
echohl ErrorMsg
echomsg printf('neco-ghc: ghc-mod returned warning messages: %s', join(l:cmd, ' '))
echomsg printf('neco-ghc: ' . g:necoghc#executable . ' returned warning messages: %s', join(l:cmd, ' '))
for l:line in l:warnings
echomsg l:line
endfor
Expand Down Expand Up @@ -516,8 +524,12 @@ function! s:dangling_import(n) abort "{{{
endfunction "}}}

function! necoghc#ghc_mod_version() abort "{{{
let l:ret = s:system(s:ghc_mod_path + ['version'])
return matchstr(l:ret, '\cghc-mod\%(.exe\)\?\s\+version\s\+\zs\%(\d\+\.\)*\d\+')
let l:ret = s:system(s:exe_path + ['version'])
if g:necoghc#executable ==# 'ghc-mod'
return matchstr(l:ret, '\cghc-mod\%(.exe\)\?\s\+version\s\+\zs\%(\d\+\.\)*\d\+')
elseif g:necoghc#executable ==# 'hhpc'
return matchstr(l:ret, '\chhpc\%(.exe\)\?\s\+version\s\+\zs\%(\d\+\.\)*\d\+')
endif
endfunction "}}}

function! s:synname(...) abort "{{{
Expand Down Expand Up @@ -563,7 +575,7 @@ function! s:get_ghcmod_root() abort "{{{
try
lcd `=fnamemodify(bufname('%'), ':p:h')`
let b:ghcmod_root =
\ substitute(s:system(s:ghc_mod_path + ['root']), '\n*$', '', '')
\ substitute(s:system(s:exe_path + ['root']), '\n*$', '', '')
finally
lcd `=l:dir`
endtry
Expand Down
7 changes: 5 additions & 2 deletions autoload/necoghc/diagnostics.vim
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ function! necoghc#diagnostics#report() abort

echomsg 'Current filetype:' &l:filetype

let l:executable = executable('ghc-mod')
echomsg 'ghc-mod is executable:' l:executable
let l:ghc_mod_executable = executable('ghc-mod')
let l:hhpc_executable = executable('hhpc')
let l:executable = l:ghc_mod_executable || l:hhpc_executable
echomsg 'ghc-mod is executable:' l:ghc_mod_executable
echomsg 'hhpc-mod is executable:' l:hhpc_executable
if !l:executable
echomsg ' Your $PATH:' $PATH
endif
Expand Down
2 changes: 1 addition & 1 deletion autoload/neocomplcache/sources/ghc.vim
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function! s:source.get_complete_words(cur_keyword_pos, cur_keyword_str) abort
endfunction

function! neocomplcache#sources#ghc#define() abort
if !executable('ghc-mod')
if g:necoghc#executable ==# ''
return {}
endif
return s:source
Expand Down
2 changes: 1 addition & 1 deletion autoload/neocomplete/sources/ghc.vim
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function! s:source.gather_candidates(context) abort
endfunction

function! neocomplete#sources#ghc#define() abort
if !executable('ghc-mod')
if g:necoghc#executable ==# ''
return {}
endif

Expand Down
9 changes: 8 additions & 1 deletion rplugin/python3/deoplete/sources/ghc.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from .base import Base
import deoplete.util
import distutils.spawn
import re

class Source(Base):
Expand All @@ -20,7 +21,13 @@ def __init__(self, vim):
# force auto-completion on importing functions
self.input_pattern = r'import\s+\w*|[^. \t0-9]\.\w*'

self.__executable_ghc = self.vim.funcs.executable('ghc-mod')
if distutils.spawn.find_executable('ghc-mod') is not None:
self.__executable_ghc = self.vim.funcs.executable('ghc-mod')
elif distutils.spawn.find_executable('hhpc') is not None:
self.__executable_ghc = self.vim.funcs.executable('hhpc')
else:
self.__executable_ghc = self.vim.funcs.executable('')

self.__is_booted = False

def __boot(self):
Expand Down