From 568020d67bd745cc203dd8fbf2957bb39e435b1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=96R=C3=96SK=C5=90I=20Andr=C3=A1s?= Date: Wed, 2 Sep 2020 23:21:49 +0200 Subject: [PATCH 2/4] rc gopls.kak: initial import Add support for the following gopls commands: - format - imports - definition - references Thanks krobelus@ and lenormf@ for their review and suggestions. --- rc/tools/go/gopls.kak | 116 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 rc/tools/go/gopls.kak diff --git a/rc/tools/go/gopls.kak b/rc/tools/go/gopls.kak new file mode 100644 index 00000000..1280a64f --- /dev/null +++ b/rc/tools/go/gopls.kak @@ -0,0 +1,116 @@ +# gopls.kak: gopls bindings for kakoune + +define-command -params 1 -docstring %{ +gopls : gopls command wrapper for kakoune + +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 prepatation +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} + eval "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 %{ + gopls-prepare + evaluate-commands %sh{ + dir=${kak_opt_gopls_tmp_dir} + eval "gopls definition ${kak_buffile}:${kak_cursor_line}:${kak_cursor_column} \ + |sed -e 's/-.*//' -e 's/:/ /g' > '${dir}/jump'" + if [ -s "${dir}/jump" ]; then + printf %s\\n "evaluate-commands -try-client '${kak_opt_jumpclient}' %{ + edit $(cat "${dir}/jump" ) + }" + fi + rm -r "${dir}" + } +} + +# 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 + printf %s\\n "evaluate-commands -try-client '${kak_opt_toolsclient}' %{ + edit! -fifo '${dir}/fifo' *gopls-refs* + set-option buffer filetype gopls + hook -always -once buffer BufCloseFifo .* %{ nop %sh{ rm -r '${dir}' } } + }" + } +} + +hook global WinSetOption filetype=gopls %{ + hook buffer -group gopls-hooks NormalKey refs-jump + hook -once -always window WinSetOption filetype=.* %{ + remove-hooks buffer gopls-hooks + } +} + +define-command -hidden -params 0 refs-jump %{ + try %{ + execute-keys 's^((?:\w:)?[^:]+):(\d+):(\d+)?' + evaluate-commands -try-client %opt{jumpclient} -verbatim -- \ + edit -existing %reg{1} %reg{2} %reg{3} + try %{ focus %opt{jumpclient} } + } +} + +§ From 2b18b1d08829cec267a34dfbf5f1e66564e4a3fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=96R=C3=96SK=C5=90I=20Andr=C3=A1s?= Date: Tue, 15 Sep 2020 01:02:19 +0200 Subject: [PATCH 3/4] rc/go-tools.kak: remove Working functions replaced by gopls Use kak-lsp if you need in place documentation and autocompletion --- rc/tools/go/go-tools.kak | 191 --------------------------------------- 1 file changed, 191 deletions(-) delete mode 100644 rc/tools/go/go-tools.kak 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 [\w\.].\z - 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} -} } - -} From 9fe1a2a9a4894ab3bca418c4458c7c2fa323bb8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=96R=C3=96SK=C5=90I=20Andr=C3=A1s?= Date: Wed, 16 Sep 2020 21:58:22 +0200 Subject: [PATCH 4/4] gopls: fixes based on krobelus@ review --- rc/tools/go/gopls.kak | 36 +++++++++--------------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/rc/tools/go/gopls.kak b/rc/tools/go/gopls.kak index 1280a64f..6ae19e12 100644 --- a/rc/tools/go/gopls.kak +++ b/rc/tools/go/gopls.kak @@ -1,7 +1,7 @@ # gopls.kak: gopls bindings for kakoune define-command -params 1 -docstring %{ -gopls : gopls command wrapper for kakoune +gopls : gopls command wrapper All commands are forwarded to gopls utility Available commands are: @@ -41,7 +41,7 @@ evaluate-commands %sh{ fi } -# Temp dir prepatation +# Temp dir preparation declare-option -hidden str gopls_tmp_dir define-command -hidden -params 0 gopls-prepare %{ evaluate-commands %sh{ @@ -55,7 +55,7 @@ define-command -hidden -params 1 gopls-cmd %{ gopls-prepare evaluate-commands %sh{ dir=${kak_opt_gopls_tmp_dir} - eval "gopls $1 -w ${kak_buffile} 2> '${dir}/stderr'" + 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' }" @@ -67,17 +67,14 @@ define-command -hidden -params 1 gopls-cmd %{ # gopls definition define-command -hidden -params 0 gopls-def %{ - gopls-prepare evaluate-commands %sh{ - dir=${kak_opt_gopls_tmp_dir} - eval "gopls definition ${kak_buffile}:${kak_cursor_line}:${kak_cursor_column} \ - |sed -e 's/-.*//' -e 's/:/ /g' > '${dir}/jump'" - if [ -s "${dir}/jump" ]; then + 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 $(cat "${dir}/jump" ) + edit ${jump} }" fi - rm -r "${dir}" } } @@ -89,28 +86,13 @@ define-command -hidden -params 0 gopls-ref %{ 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 mapping printf %s\\n "evaluate-commands -try-client '${kak_opt_toolsclient}' %{ edit! -fifo '${dir}/fifo' *gopls-refs* - set-option buffer filetype gopls + set-option buffer filetype grep hook -always -once buffer BufCloseFifo .* %{ nop %sh{ rm -r '${dir}' } } }" } } -hook global WinSetOption filetype=gopls %{ - hook buffer -group gopls-hooks NormalKey refs-jump - hook -once -always window WinSetOption filetype=.* %{ - remove-hooks buffer gopls-hooks - } -} - -define-command -hidden -params 0 refs-jump %{ - try %{ - execute-keys 's^((?:\w:)?[^:]+):(\d+):(\d+)?' - evaluate-commands -try-client %opt{jumpclient} -verbatim -- \ - edit -existing %reg{1} %reg{2} %reg{3} - try %{ focus %opt{jumpclient} } - } -} - §