Skip to content
This repository has been archived by the owner on Sep 1, 2023. It is now read-only.

Commit

Permalink
first stab on elixir_sense intgration
Browse files Browse the repository at this point in the history
start working on #97
  • Loading branch information
slashmili committed Aug 13, 2017
1 parent 53a0735 commit e43ec51
Show file tree
Hide file tree
Showing 54 changed files with 7,058 additions and 66 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Expand Up @@ -4,4 +4,4 @@
erl_crash.dump
*.ez
*.sw?
*.py*
*.py?
2 changes: 1 addition & 1 deletion .travis.yml
@@ -1,5 +1,5 @@
sudo: false
script:
- python ./alchemist.py
- python ./elixir_sense.py
notifications:
irc: "irc.freenode.org#vim-elixir"
2 changes: 1 addition & 1 deletion after/ftplugin/elixir.vim
Expand Up @@ -17,7 +17,7 @@ if !exists('g:alchemist#omnifunc')
endif

if exists('&omnifunc') && g:alchemist#omnifunc
setl omnifunc=elixircomplete#Complete
setl omnifunc=elixircomplete#auto_complete
endif

runtime! ftplugin/man.vim
Expand Down
21 changes: 11 additions & 10 deletions after/plugin/alchemist.vim
Expand Up @@ -8,18 +8,19 @@ if !exists('g:alchemist#alchemist_client')
let g:alchemist#alchemist_client = expand("<sfile>:p:h:h") . '/../alchemist_client'
endif

function! alchemist#alchemist_client(req)
let req = a:req . "\n"
function! alchemist#alchemist_client(req, lnum, cnum, lines)
echom "alchemist_client"
let req = a:req
let cmd = g:alchemist#alchemist_client
if !alchemist#ansi_enabled()
let cmd = cmd . ' --colors=false '
endif
if exists('g:alchemist#elixir_erlang_src')
let cmd = cmd . ' -s ' . g:alchemist#elixir_erlang_src
endif
"if exists('g:alchemist#elixir_erlang_src')
" let cmd = cmd . ' -s ' . g:alchemist#elixir_erlang_src
"endif
let cmd = cmd . ' -d "' . expand('%:p:h') . '"'

return system(cmd, req)
let cmd = cmd . ' --line=' . a:lnum
let cmd = cmd . ' --column=' . a:cnum
let cmd = cmd . ' --request=' . a:req
echom cmd
return system(cmd, join(a:lines, "\n"))
endfunction

function! alchemist#get_doc(word)
Expand Down
35 changes: 18 additions & 17 deletions alchemist_client
@@ -1,7 +1,7 @@
#!/usr/bin/env python
from __future__ import print_function
import os, sys, getopt
from alchemist import AlchemistClient
from elixir_sense import ElixirSenseClient

debug = False

Expand All @@ -22,51 +22,52 @@ def alchemist_help():
"""

def main(argv):
cmd_type = ""
cmd = ""
request = ""
line = 0
column = 0
cwd = ""
alchemist_script = ""
ansi = True
elixir_erlang_source_dir = ""
source = ""
try:
opts, args = getopt.getopt(argv,"hc:t:d:a:s:",["type=","command-type=", "directory=", "alchemist-server=", "colors=", "source="])
opts, args = getopt.getopt(argv,"hr:l:c:d:",["request=","line=", "column=", "directory=", "alchemist-server=", "colors=", "source_dir="])
except getopt.GetoptError:
print(alchemist_help())
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print(alchemist_help())
sys.exit()
elif opt in ("-c", "--command"):
cmd = arg
elif opt in ("-t", "--command-type"):
cmd_type = arg
elif opt in ("-r", "--request"):
request = arg
elif opt in ("-l", "--line"):
line = arg
elif opt in ("-c", "--column"):
column = arg
elif opt in ("-d", "--directory"):
cwd = arg
elif opt in ("-a", "--alchemist-server"):
alchemist_script = arg
elif opt in ("-s", "--source"):
source = arg
elixir_erlang_source_dir = arg
elif opt in ("--colors"):
if arg == "false":
ansi = False
if os.path.exists(cwd.strip()) == False:
raise Exception("working directory [%s] doesn't exist" % cwd)
cwd = os.path.abspath(cwd)
if cmd == "":
cmd = read_stdin()
source = sys.stdin.read()
if alchemist_script == "":
alchemist_script = "%s/alchemist-server/run.exs" % where_am_i()
if cmd_type == "":
cmd_type = cmd.split(" ")[0]
alchemist_script = "%s/elixir_sense/run.exs" % where_am_i()

if cmd == "" or cmd_type == "" or alchemist_script == "" or cwd == "":
if "" in [request, alchemist_script, request, line, column]:
print("Invalid command, alchemist_script or working directory")
print(alchemist_help())
sys.exit(2)

a = AlchemistClient(debug=debug, cwd=cwd, ansi=ansi, alchemist_script=alchemist_script, source=source)
print(a.process_command(cmd), end="")
s = ElixirSenseClient(debug=debug, cwd=cwd, ansi=ansi, elixir_sense_script=alchemist_script)
print(s.process_command(request, source, line ,column), end="")


def where_am_i():
Expand Down
72 changes: 37 additions & 35 deletions autoload/elixircomplete.vim
@@ -1,18 +1,8 @@
" This code partially is based on helpex.vim project
" Authors:
" * sanmiguel <michael.coles@gmail.com>
" * Milad

if !exists('g:alchemist#alchemist_client')
let g:alchemist#alchemist_client = expand("<sfile>:p:h:h") . '/../alchemist_client'
endif


let s:elixir_namespace= '\<[A-Z][[:alnum:]]\+\(\.[A-Z][[:alnum:].]\+\)*.*$'
let s:erlang_module= ':\<'
let s:elixir_fun_w_arity = '.*/[0-9]$'
let s:elixir_module = '[A-Z][[:alnum:]_]\+\([A_Z][[:alnum:]_]+\)*'

function! elixircomplete#ExDocComplete(ArgLead, CmdLine, CursorPos, ...)
let suggestions = elixircomplete#Complete(0, a:ArgLead)
if type(suggestions) != type([])
Expand All @@ -25,23 +15,27 @@ function! s:strip_dot(input_string)
return substitute(a:input_string, '^\s*\(.\{-}\)\.*$', '\1', '')
endfunction

function! elixircomplete#Complete(findstart, base_or_suggestions)
function! elixircomplete#auto_complete(findstart, base_or_suggestions)
let cnum = col('.')
if a:findstart
return s:FindStart()
else
return s:build_completions(a:base_or_suggestions)
return s:find_start()
end
let suggestions = elixircomplete#get_suggestions(a:base_or_suggestions)
if len(suggestions) == 0
return -1
endif
return suggestions
endfunction

" Omni findstart phase.
function! s:FindStart()
function! s:find_start()
" return int 0 < n <= col('.')
"
" if the column left of us is whitespace, or [(){}[]]
" no word
let col = col('.')
" get the column to the left of us
if strpart(getline(line('.')), col-2, 1) =~ '[{}() ]'
if strpart(getline(line('.')), col-2, 1) =~ '[{}() ]'
return col - 1
endif
" TODO This is a pretty dirty way to go about this
Expand All @@ -55,28 +49,36 @@ function! s:FindStart()
endfunction


function! s:build_completions(base_or_suggestions)
if type(a:base_or_suggestions) == type([])
let suggestions = a:base_or_suggestions
else
let suggestions = elixircomplete#get_suggestions(a:base_or_suggestions)
endif

if len(suggestions) == 0
return -1
endif
return suggestions
endfunction

function! elixircomplete#get_suggestions(hint)
let req = alchemist#alchemist_format("COMPX", a:hint, "Elixir", [], [])
let result = alchemist#alchemist_client(req)
let suggestions = filter(split(result, '\n'), 'v:val != "END-OF-COMPX"')
function! elixircomplete#get_suggestions(base_or_suggestions)
let req = 'suggestions'
let lnum = line('.')
let cnum = col('.') + len(a:base_or_suggestions)
let blines = getline(1, lnum -1)
let cline = getline('.')
let before_c = strpart(getline('.'), 0, col('.'))
let after_c = strpart(getline('.'), col('.'), len(getline('.')))
let cline = before_c . a:base_or_suggestions . after_c
let alines = getline(lnum +1 , '$')
let lines = blines + [cline] + alines
let result = alchemist#alchemist_client(req, lnum, cnum, lines)
let suggestions = split(result, '\n')
let parsed_suggestion = []
for sugg in suggestions
let details = matchlist(sugg, 'kind:\(.*\), word:\(.*\), abbr:\(.*\)$')
let details = matchlist(sugg, 'kind:\(.*\), word:\(.*\), abbr:\(.*\), menu:\(.*\)$')
if len(details) > 0
let a = {'kind': details[1], 'word': details[2], 'abbr': details[3]}
if details[1] == 'f'
let word = details[2]
let sug_parts = split(a:base_or_suggestions, '\.')
if len(sug_parts) == 1 && a:base_or_suggestions[len(a:base_or_suggestions) -1] != '.'
let word_parts = split(word, '\.')
let word_size = len(word_parts) - 1
let word = word_parts[word_size]
endif
let a = {'kind': details[1], 'word': word, 'abbr': details[3], 'menu': details[4], 'dup': 1}
elseif details[1] == 'm' || details[1] == 'p' || details[1] == 'e' || details[1] == 's'
let word = details[2]
let a = {'kind': details[1], 'word': word, 'menu': details[4], 'abbr': details[3]}
endif
call add(parsed_suggestion, a)
endif
endfor
Expand Down

0 comments on commit e43ec51

Please sign in to comment.