summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2020-09-17 19:49:33 +1000
committerMaxime Coste <mawww@kakoune.org>2020-09-17 19:49:33 +1000
commitdbd7e4da79ff59a63be03c580d3f396657199596 (patch)
tree0c6dea51a1cc3c5d2069c774ffeca0b67ae336f8
parentfd658f699596077c22e63793c7ab02c1c05a32f4 (diff)
parent9fe1a2a9a4894ab3bca418c4458c7c2fa323bb8d (diff)
Merge remote-tracking branch 'voroskoi/gopls' into master
-rw-r--r--rc/tools/go/go-tools.kak191
-rw-r--r--rc/tools/go/gopls.kak98
2 files changed, 98 insertions, 191 deletions
diff --git a/rc/tools/go/go-tools.kak b/rc/tools/go/go-tools.kak
deleted file mode 100644
index af1cacbb..00000000
--- a/rc/tools/go/go-tools.kak
+++ /dev/null
@@ -1,191 +0,0 @@
-# Provides integration of the following tools:
-# - gocode for code completion (github.com/nsf/gocode)
-# - goimports for code formatting on save
-# - gogetdoc for documentation display and source jump (needs jq) (github.com/zmb3/gogetdoc)
-# Needs the following tools in the path:
-# - jq for json deserializaton
-
-hook -once global BufSetOption filetype=go %{
- require-module go-tools
-}
-
-provide-module go-tools %{
-
-evaluate-commands %sh{
- for dep in gocode goimports gogetdoc jq; do
- if ! command -v $dep > /dev/null 2>&1; then
- echo "echo -debug %{Dependency unmet: $dep, please install it to use go-tools}"
- fi
- done
-}
-
-# Auto-completion
-# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
-
-declare-option -hidden str go_complete_tmp_dir
-declare-option -hidden completions gocode_completions
-
-define-command go-complete -docstring "Complete the current selection with gocode" %{
- evaluate-commands %sh{
- dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-go.XXXXXXXX)
- printf %s\\n "set-option buffer go_complete_tmp_dir ${dir}"
- printf %s\\n "evaluate-commands -no-hooks write ${dir}/buf"
- }
- nop %sh{
- dir=${kak_opt_go_complete_tmp_dir}
- (
- gocode_data=$(gocode -f=godit --in=${dir}/buf autocomplete ${kak_cursor_byte_offset})
- rm -r ${dir}
- column_offset=$(printf %s "${gocode_data}" | head -n1 | cut -d, -f1)
-
- header="${kak_cursor_line}.$((${kak_cursor_column} - $column_offset))@${kak_timestamp}"
- compl=$(echo "${gocode_data}" | sed 1d | awk -F ",," '{
- gsub(/~/, "~~", $1)
- gsub(/~/, "~~", $2)
- print "%~" $2 "||" $1 "~"
- }' | paste -s -)
- printf %s\\n "evaluate-commands -client '${kak_client}' %{
- set-option 'buffer=${kak_bufname}' gocode_completions ${header} ${compl}
- }" | kak -p ${kak_session}
- ) > /dev/null 2>&1 < /dev/null &
- }
-}
-
-define-command go-enable-autocomplete -docstring "Add gocode completion candidates to the completer" %{
- set-option window completers "option=gocode_completions" %opt{completers}
- hook window -group go-autocomplete InsertIdle .* %{ try %{
- execute-keys -draft <a-h><a-k>[\w\.].\z<ret>
- go-complete
- } }
- alias window complete go-complete
-}
-
-define-command go-disable-autocomplete -docstring "Disable gocode completion" %{
- set-option window completers %sh{ printf %s\\n "${kak_opt_completers}" | sed "s/'option=gocode_completions'//g" }
- remove-hooks window go-autocomplete
- unalias window complete go-complete
-}
-
-# Auto-format
-# ‾‾‾‾‾‾‾‾‾‾‾
-
-declare-option -hidden str go_format_tmp_dir
-
-define-command -params ..1 go-format \
- -docstring "go-format [-use-goimports]: custom formatter for go files" %{
- evaluate-commands %sh{
- dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-go.XXXXXXXX)
- printf %s\\n "set-option buffer go_format_tmp_dir ${dir}"
- printf %s\\n "evaluate-commands -no-hooks write ${dir}/buf"
- }
- evaluate-commands %sh{
- dir=${kak_opt_go_format_tmp_dir}
- if [ "$1" = "-use-goimports" ]; then
- fmt_cmd="goimports -srcdir '${kak_buffile}'"
- else
- fmt_cmd="gofmt -s"
- fi
- eval "${fmt_cmd} -e -w ${dir}/buf 2> ${dir}/stderr"
- if [ $? ]; then
- cp ${dir}/buf "${kak_buffile}"
- else
- # we should report error if linting isn't active
- printf %s\\n "echo -debug '$(cat ${dir}/stderr)'"
- fi
- rm -r ${dir}
- }
- edit!
-}
-
-# Documentation
-# ‾‾‾‾‾‾‾‾‾‾‾‾‾
-
-declare-option -hidden str go_doc_tmp_dir
-
-# FIXME text escaping
-define-command -hidden -params 1..2 gogetdoc-cmd %{
- evaluate-commands %sh{
- dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-go.XXXXXXXX)
- printf %s\\n "set-option buffer go_doc_tmp_dir ${dir}"
- printf %s\\n "evaluate-commands -no-hooks write ${dir}/buf"
- }
- evaluate-commands %sh{
- dir=${kak_opt_go_doc_tmp_dir}
- (
- printf %s\\n "${kak_buffile}" > ${dir}/modified
- cat ${dir}/buf | wc -c >> ${dir}/modified
- cat ${dir}/buf >> ${dir}/modified
-
- args=""
- if [ "$2" = "1" ]; then
- args="-json"
- fi
- output=$(cat ${dir}/modified \
- | gogetdoc $args -pos "${kak_buffile}:#${kak_cursor_byte_offset}" -modified \
- | sed 's/%/%%/g')
- rm -r ${dir}
- printf %s "${output}" | grep -v -q "^gogetdoc: "
- status=$?
-
- case "$1" in
- "info")
- if [ ${status} -eq 0 ]; then
- printf %s\\n "evaluate-commands -client '${kak_client}' %{
- info -anchor ${kak_cursor_line}.${kak_cursor_column} %@${output}@
- }" | kak -p ${kak_session}
- else
- msg=$(printf %s "${output}" | cut -d' ' -f2-)
- printf %s\\n "evaluate-commands -client '${kak_client}' %{
- echo '${msg}'
- }" | kak -p ${kak_session}
- fi
- ;;
- "echo")
- if [ ${status} -eq 0 ]; then
- signature=$(printf %s "${output}" | sed -n 3p)
- printf %s\\n "evaluate-commands -client '${kak_client}' %{
- echo '${signature}'
- }" | kak -p ${kak_session}
- fi
- ;;
- "jump")
- if [ ${status} -eq 0 ]; then
- pos=$(printf %s "${output}" | jq -r .pos)
- file=$(printf %s "${pos}" | cut -d: -f1)
- line=$(printf %s "${pos}" | cut -d: -f2)
- col=$(printf %s "${pos}" | cut -d: -f3)
- printf %s\\n "evaluate-commands -client '${kak_client}' %{
- evaluate-commands -try-client '${kak_opt_jumpclient}' edit -existing ${file} ${line} ${col}
- try %{ focus '${kak_opt_jumpclient}' }
- }" | kak -p ${kak_session}
- fi
- ;;
- *)
- printf %s\\n "evaluate-commands -client '${kak_client}' %{
- echo -error %{unkown command '$1'}
- }" | kak -p ${kak_session}
- ;;
-
- esac
- ) > /dev/null 2>&1 < /dev/null &
- }
-}
-
-define-command go-doc-info -docstring "Show the documention of the symbol under the cursor" %{
- gogetdoc-cmd "info"
-}
-
-define-command go-print-signature -docstring "Print the signature of the symbol under the cursor" %{
- gogetdoc-cmd "echo"
-}
-
-define-command go-jump -docstring "Jump to the symbol definition" %{
- gogetdoc-cmd "jump" 1
-}
-
-define-command go-share-selection -docstring "Share the selection using the Go Playground" %{ evaluate-commands %sh{
- snippet_id=$(printf %s\\n "${kak_selection}" | curl -s https://play.golang.org/share --data-binary @-)
- printf "echo https://play.golang.org/p/%s" ${snippet_id}
-} }
-
-}
diff --git a/rc/tools/go/gopls.kak b/rc/tools/go/gopls.kak
new file mode 100644
index 00000000..6ae19e12
--- /dev/null
+++ b/rc/tools/go/gopls.kak
@@ -0,0 +1,98 @@
+# gopls.kak: gopls bindings for kakoune
+
+define-command -params 1 -docstring %{
+gopls <command>: gopls command wrapper
+
+All commands are forwarded to gopls utility
+Available commands are:
+ format
+ imports
+ definition
+ references
+} -shell-script-candidates %{
+ printf "format\nimports\ndefinition\nreferences\n"
+} \
+gopls %{
+ require-module gopls
+ evaluate-commands %sh{
+ case "$1" in
+ format|imports)
+ printf %s\\n "gopls-cmd $1"
+ ;;
+ definition)
+ printf %s\\n "gopls-def"
+ ;;
+ references)
+ printf %s\\n "gopls-ref"
+ ;;
+ *)
+ printf "fail Unknown gopls command '%s'\n" "$1"
+ exit
+ ;;
+ esac
+ }
+}
+
+provide-module gopls %§
+
+evaluate-commands %sh{
+ if ! command -v gopls > /dev/null 2>&1; then
+ echo "fail Please install gopls or add to PATH!"
+ fi
+}
+
+# Temp dir preparation
+declare-option -hidden str gopls_tmp_dir
+define-command -hidden -params 0 gopls-prepare %{
+ evaluate-commands %sh{
+ dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-gopls.XXXXXXXX)
+ printf %s\\n "set-option buffer gopls_tmp_dir ${dir}"
+ }
+}
+
+# gopls format/imports
+define-command -hidden -params 1 gopls-cmd %{
+ gopls-prepare
+ evaluate-commands %sh{
+ dir=${kak_opt_gopls_tmp_dir}
+ gopls $1 -w ${kak_buffile} 2> "${dir}/stderr"
+ if [ $? -ne 0 ]; then
+ # show error messages in *debug* buffer
+ printf %s\\n "echo -debug %file{ '${dir}/stderr' }"
+ fi
+ rm -r "${dir}"
+ }
+ edit!
+}
+
+# gopls definition
+define-command -hidden -params 0 gopls-def %{
+ evaluate-commands %sh{
+ jump=$( gopls definition ${kak_buffile}:${kak_cursor_line}:${kak_cursor_column} \
+ |sed -e 's/-.*//; s/:/ /g; q' 2> /dev/null )
+ if [ "cat ${jump}" != "" ]; then
+ printf %s\\n "evaluate-commands -try-client '${kak_opt_jumpclient}' %{
+ edit ${jump}
+ }"
+ fi
+ }
+}
+
+# gopls references
+define-command -hidden -params 0 gopls-ref %{
+ gopls-prepare
+ evaluate-commands %sh{
+ dir=${kak_opt_gopls_tmp_dir}
+ mkfifo "${dir}/fifo"
+ ( gopls references ${kak_buffile}:${kak_cursor_line}:${kak_cursor_column} \
+ > "${dir}/fifo" 2> /dev/null & ) > /dev/null 2>&1 < /dev/null
+ # using filetype=grep for nice hilight and <ret> mapping
+ printf %s\\n "evaluate-commands -try-client '${kak_opt_toolsclient}' %{
+ edit! -fifo '${dir}/fifo' *gopls-refs*
+ set-option buffer filetype grep
+ hook -always -once buffer BufCloseFifo .* %{ nop %sh{ rm -r '${dir}' } }
+ }"
+ }
+}
+