Add support with Go language.
This commit is contained in:
parent
71e3f2fa49
commit
de80db5969
205 changed files with 29172 additions and 0 deletions
13
sources_non_forked/vim-go/.codecov.yml
Normal file
13
sources_non_forked/vim-go/.codecov.yml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
coverage:
|
||||||
|
status:
|
||||||
|
project:
|
||||||
|
default:
|
||||||
|
target: auto
|
||||||
|
threshold: 1
|
||||||
|
base: auto
|
||||||
|
patch: off
|
||||||
|
comment: false
|
||||||
|
ignore:
|
||||||
|
- "!autoload/go/*.vim$"
|
||||||
|
- "autoload/go/*_test.vim$"
|
3
sources_non_forked/vim-go/.coveragerc
Normal file
3
sources_non_forked/vim-go/.coveragerc
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[run]
|
||||||
|
plugins = covimerage
|
||||||
|
data_file = .coverage_covimerage
|
8
sources_non_forked/vim-go/.dockerignore
Normal file
8
sources_non_forked/vim-go/.dockerignore
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
.local/
|
||||||
|
.config/
|
||||||
|
.cache/
|
||||||
|
.dlv/
|
||||||
|
.git/
|
||||||
|
.viminfo
|
||||||
|
issues/
|
||||||
|
autoload/go/**/pkg/
|
17
sources_non_forked/vim-go/.editorconfig
Normal file
17
sources_non_forked/vim-go/.editorconfig
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# http://EditorConfig.org
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.go]
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
[Makefile]
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 8
|
12
sources_non_forked/vim-go/.github/CONTRIBUTING.md
vendored
Normal file
12
sources_non_forked/vim-go/.github/CONTRIBUTING.md
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
Thanks for improving vim-go! Before you dive in please read the following:
|
||||||
|
|
||||||
|
1. Please read our
|
||||||
|
[Documentation](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt),
|
||||||
|
it might have a solution to your problem.
|
||||||
|
2. If you add a new feature then please don't forget to update the documentation:
|
||||||
|
[doc/vim-go.txt](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt).
|
||||||
|
3. If it's a breaking change or exceeds 100 lines of code then please open an
|
||||||
|
issue first and describe the changes you want to make.
|
||||||
|
4. See `:help go-development` for instructions on how to run and write tests. If
|
||||||
|
you add a new feature be sure you also include a test if feasible.
|
||||||
|
|
1
sources_non_forked/vim-go/.github/FUNDING.yml
vendored
Normal file
1
sources_non_forked/vim-go/.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
patreon: bhcleek
|
50
sources_non_forked/vim-go/.github/ISSUE_TEMPLATE.md
vendored
Normal file
50
sources_non_forked/vim-go/.github/ISSUE_TEMPLATE.md
vendored
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
<!--
|
||||||
|
Before filing an issue, please check if vim-go's help addresses your problem (see `:help go-troubleshooting`).
|
||||||
|
|
||||||
|
Consider executing `:GoReportGitHubIssue` to populate much of this information automatically.
|
||||||
|
-->
|
||||||
|
### What did you do? (required: The issue will be **closed** when not provided)
|
||||||
|
|
||||||
|
<!--
|
||||||
|
If possible, please provide clear steps for reproducing the problem.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### What did you expect to happen?
|
||||||
|
|
||||||
|
### What happened instead?
|
||||||
|
|
||||||
|
### Configuration (**MUST** fill this out):
|
||||||
|
|
||||||
|
#### vim-go version:
|
||||||
|
|
||||||
|
#### `vimrc` you used to reproduce:
|
||||||
|
<!--
|
||||||
|
Use a *minimal* vimrc with other plugins disabled; do not link to a 2,000 line vimrc.
|
||||||
|
|
||||||
|
If this is not provided or is obviously incomplete, the issue may be unceremoniously closed.
|
||||||
|
-->
|
||||||
|
<!-- vimrc -->
|
||||||
|
<details><summary>vimrc</summary>
|
||||||
|
|
||||||
|
```vim
|
||||||
|
|
||||||
|
```
|
||||||
|
</details>
|
||||||
|
|
||||||
|
#### Vim version (first three lines from `:version`):
|
||||||
|
<!-- :version -->
|
||||||
|
|
||||||
|
#### Go version (`go version`):
|
||||||
|
<!-- go version -->
|
||||||
|
|
||||||
|
#### Go environment
|
||||||
|
<details><summary><code>go env</code> Output:</summary><br><pre>
|
||||||
|
<!-- go env -->
|
||||||
|
|
||||||
|
</pre></details>
|
||||||
|
|
||||||
|
#### gopls version
|
||||||
|
<details><summary><code>gopls version</code> Output:</summary><br><pre>
|
||||||
|
<!-- gopls version -->
|
||||||
|
|
||||||
|
</pre></details>
|
11
sources_non_forked/vim-go/.github/workflows/git.yml
vendored
Normal file
11
sources_non_forked/vim-go/.github/workflows/git.yml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
name: git checks
|
||||||
|
on: [pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
autosquash-commits-integrated:
|
||||||
|
runs-on: ubuntu-18.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2.0.0
|
||||||
|
- name: Block Fixup Commit Merge
|
||||||
|
uses: 13rac1/block-fixup-merge-action@v2.0.0
|
60
sources_non_forked/vim-go/.github/workflows/test.yml
vendored
Normal file
60
sources_non_forked/vim-go/.github/workflows/test.yml
vendored
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
name: test
|
||||||
|
on: [push, pull_request]
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
name: lint
|
||||||
|
runs-on: ubuntu-18.04
|
||||||
|
steps:
|
||||||
|
- name: set up python
|
||||||
|
uses: actions/setup-python@v2.1.4
|
||||||
|
with:
|
||||||
|
python-version: 3.6
|
||||||
|
- name: install vim-vint
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install vim-vint pathlib
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v2.1.0
|
||||||
|
- name: install vim
|
||||||
|
run: $GITHUB_WORKSPACE/scripts/install-vim vim-8.2
|
||||||
|
- name: install tools
|
||||||
|
run: $GITHUB_WORKSPACE/scripts/install-tools vim-8.2
|
||||||
|
- name: lint
|
||||||
|
run: $GITHUB_WORKSPACE/scripts/lint vim-8.2
|
||||||
|
test:
|
||||||
|
name: test
|
||||||
|
runs-on: ubuntu-18.04
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
go: ['1.17','1.18']
|
||||||
|
vim: ['vim-8.0', 'vim-8.2', 'nvim']
|
||||||
|
steps:
|
||||||
|
- name: setup Go
|
||||||
|
uses: actions/setup-go@v2.1.3
|
||||||
|
with:
|
||||||
|
go-version: ${{ matrix.go }}
|
||||||
|
- name: set up python
|
||||||
|
uses: actions/setup-python@v2.1.4
|
||||||
|
with:
|
||||||
|
python-version: 3.6
|
||||||
|
- name: install covimerage
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install click==7.1.2 covimerage==0.2.1 codecov pathlib
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v2.1.0
|
||||||
|
- name: install vim
|
||||||
|
run: $GITHUB_WORKSPACE/scripts/install-vim ${{ matrix.vim }}
|
||||||
|
- name: install tools
|
||||||
|
run: $GITHUB_WORKSPACE/scripts/install-tools ${{ matrix.vim }}
|
||||||
|
- name: test
|
||||||
|
run: $GITHUB_WORKSPACE/scripts/test -c ${{ matrix.vim }}
|
||||||
|
- uses: codecov/codecov-action@v1
|
||||||
|
with:
|
||||||
|
# token is not required for public repos
|
||||||
|
#token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
|
file: $GITHUB_WORKSPACE/coverage.xml
|
||||||
|
flags: unittests
|
||||||
|
name: vim-go
|
||||||
|
fail_ci_if_error: false
|
11
sources_non_forked/vim-go/.gitignore
vendored
Normal file
11
sources_non_forked/vim-go/.gitignore
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
*.pyc
|
||||||
|
.DS_Store
|
||||||
|
/.bash_history
|
||||||
|
/.cache
|
||||||
|
/.config
|
||||||
|
/.coverage.covimerage
|
||||||
|
/.local
|
||||||
|
/.viminfo
|
||||||
|
/coverage.xml
|
||||||
|
/doc/tags
|
||||||
|
/issues
|
7
sources_non_forked/vim-go/.vintrc.yaml
Normal file
7
sources_non_forked/vim-go/.vintrc.yaml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
policies:
|
||||||
|
ProhibitUnnecessaryDoubleQuote:
|
||||||
|
enabled: false
|
||||||
|
ProhibitEqualTildeOperator:
|
||||||
|
enabled: false
|
||||||
|
ProhibitNoAbortFunction:
|
||||||
|
enabled: false
|
2243
sources_non_forked/vim-go/CHANGELOG.md
Normal file
2243
sources_non_forked/vim-go/CHANGELOG.md
Normal file
File diff suppressed because it is too large
Load diff
27
sources_non_forked/vim-go/Dockerfile
Normal file
27
sources_non_forked/vim-go/Dockerfile
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
FROM golang:1.18.1
|
||||||
|
|
||||||
|
RUN apt-get update -y --allow-insecure-repositories && \
|
||||||
|
apt-get install -y build-essential curl git libncurses5-dev python3-pip && \
|
||||||
|
apt-get clean && \
|
||||||
|
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||||
|
|
||||||
|
RUN pip3 install vim-vint
|
||||||
|
|
||||||
|
RUN useradd -ms /bin/bash -d /vim-go vim-go
|
||||||
|
USER vim-go
|
||||||
|
|
||||||
|
COPY scripts/install-vim /vim-go/scripts/install-vim
|
||||||
|
WORKDIR /vim-go
|
||||||
|
|
||||||
|
RUN scripts/install-vim vim-8.0
|
||||||
|
RUN scripts/install-vim vim-8.2
|
||||||
|
RUN scripts/install-vim nvim
|
||||||
|
|
||||||
|
COPY . /vim-go/
|
||||||
|
WORKDIR /vim-go
|
||||||
|
|
||||||
|
RUN scripts/install-tools vim-8.0
|
||||||
|
RUN scripts/install-tools vim-8.2
|
||||||
|
RUN scripts/install-tools nvim
|
||||||
|
|
||||||
|
ENTRYPOINT ["make"]
|
60
sources_non_forked/vim-go/LICENSE
Normal file
60
sources_non_forked/vim-go/LICENSE
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
Copyright (c) 2015, Fatih Arslan
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of vim-go nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
This software includes some portions from Go. Go is used under the terms of the
|
||||||
|
BSD like license.
|
||||||
|
|
||||||
|
Copyright (c) 2012 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
The Go gopher was designed by Renee French. http://reneefrench.blogspot.com/ The design is licensed under the Creative Commons 3.0 Attributions license. Read this article for more details: https://blog.golang.org/gopher
|
31
sources_non_forked/vim-go/Makefile
Normal file
31
sources_non_forked/vim-go/Makefile
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
VIMS ?= vim-8.0 vim-8.2 nvim
|
||||||
|
TEST_FLAGS ?=
|
||||||
|
|
||||||
|
all: install lint test
|
||||||
|
|
||||||
|
install:
|
||||||
|
@echo "==> Installing Vims: $(VIMS)"
|
||||||
|
@for vim in $(VIMS); do \
|
||||||
|
./scripts/install-vim $$vim; \
|
||||||
|
./scripts/install-tools $$vim; \
|
||||||
|
done
|
||||||
|
|
||||||
|
test:
|
||||||
|
@echo "==> Running tests for $(VIMS)"
|
||||||
|
@for vim in $(VIMS); do \
|
||||||
|
./scripts/test $(TEST_FLAGS) $$vim; \
|
||||||
|
done
|
||||||
|
|
||||||
|
lint:
|
||||||
|
@echo "==> Running linting tools"
|
||||||
|
@./scripts/lint vim-8.2
|
||||||
|
|
||||||
|
docker:
|
||||||
|
@echo "==> Building/starting Docker container"
|
||||||
|
@./scripts/docker-test
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@echo "==> Cleaning /tmp/vim-go-test"
|
||||||
|
@rm -rf /tmp/vim-go-test
|
||||||
|
|
||||||
|
.PHONY: all test install clean lint docker
|
104
sources_non_forked/vim-go/README.md
Normal file
104
sources_non_forked/vim-go/README.md
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
# vim-go [![GitHub Actions Status](https://github.com/fatih/vim-go/workflows/test/badge.svg)](https://github.com/fatih/vim-go/actions)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img style="float: right;" src="assets/vim-go.png" alt="Vim-go logo"/>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
This plugin adds Go language support for Vim, with the following main features:
|
||||||
|
|
||||||
|
* Compile your package with `:GoBuild`, install it with `:GoInstall` or test it
|
||||||
|
with `:GoTest`. Run a single test with `:GoTestFunc`).
|
||||||
|
* Quickly execute your current file(s) with `:GoRun`.
|
||||||
|
* Improved syntax highlighting and folding.
|
||||||
|
* Debug programs with integrated [`delve`](https://github.com/go-delve/delve) support with `:GoDebugStart`.
|
||||||
|
* Completion and many other features support via `gopls`.
|
||||||
|
* formatting on save keeps the cursor position and undo history.
|
||||||
|
* Go to symbol/declaration with `:GoDef`.
|
||||||
|
* Look up documentation with `:GoDoc` or `:GoDocBrowser`.
|
||||||
|
* Easily import packages via `:GoImport`, remove them via `:GoDrop`.
|
||||||
|
* Precise type-safe renaming of identifiers with `:GoRename`.
|
||||||
|
* See which code is covered by tests with `:GoCoverage`.
|
||||||
|
* Add or remove tags on struct fields with `:GoAddTags` and `:GoRemoveTags`.
|
||||||
|
* Call [`staticcheck`](https://staticcheck.io/) with `:GoMetaLinter` to invoke all possible linters
|
||||||
|
(e.g. `golint`, `vet`, `errcheck`, `deadcode`, etc.) and put the result in the
|
||||||
|
quickfix or location list.
|
||||||
|
* Lint your code with `:GoLint`, run your code through `:GoVet` to catch static
|
||||||
|
errors, or make sure errors are checked with `:GoErrCheck`.
|
||||||
|
* Advanced source analysis tools utilizing `guru`, such as `:GoImplements`,
|
||||||
|
`:GoCallees`, and `:GoReferrers`.
|
||||||
|
* ... and many more! Please see [doc/vim-go.txt](doc/vim-go.txt) for more
|
||||||
|
information.
|
||||||
|
* Integration with [`gopls`](https://github.com/golang/tools/blob/master/gopls/README.md).
|
||||||
|
* The `gopls` instance can be shared with other Vim plugins.
|
||||||
|
* Vim-go's use of `gopls` can be disabled and alternative tools can be used when desired.
|
||||||
|
* Integration with [`Tagbar`](https://github.com/preservim/tagbar) via [`gotags`](https://github.com/jstemmer/gotags).
|
||||||
|
* Integration with [`Ultisnips`](https://github.com/SirVer/ultisnips) and other snippet engines.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
vim-go requires at least Vim 8.0.1453 or Neovim 0.4.0.
|
||||||
|
|
||||||
|
The [**latest stable release**](https://github.com/fatih/vim-go/releases/latest) is the
|
||||||
|
recommended version to use. If you choose to use the master branch instead,
|
||||||
|
please do so with caution; it is a _development_ branch.
|
||||||
|
|
||||||
|
|
||||||
|
vim-go follows the standard runtime path structure. Below are some helper lines
|
||||||
|
for popular package managers:
|
||||||
|
|
||||||
|
* [Vim 8 packages](http://vimhelp.appspot.com/repeat.txt.html#packages)
|
||||||
|
* `git clone https://github.com/fatih/vim-go.git ~/.vim/pack/plugins/start/vim-go`
|
||||||
|
* [Neovim packages](https://neovim.io/doc/user/repeat.html#packages)
|
||||||
|
* `git clone https://github.com/fatih/vim-go.git ~/.local/share/nvim/site/pack/plugins/start/vim-go`
|
||||||
|
* [Pathogen](https://github.com/tpope/vim-pathogen)
|
||||||
|
* `git clone https://github.com/fatih/vim-go.git ~/.vim/bundle/vim-go`
|
||||||
|
* [vim-plug](https://github.com/junegunn/vim-plug)
|
||||||
|
* `Plug 'fatih/vim-go', { 'do': ':GoUpdateBinaries' }`
|
||||||
|
* [Vundle](https://github.com/VundleVim/Vundle.vim)
|
||||||
|
* `Plugin 'fatih/vim-go'`
|
||||||
|
|
||||||
|
You will also need to install all the necessary binaries. vim-go makes it easy
|
||||||
|
to install all of them by providing a command, `:GoInstallBinaries`, which will
|
||||||
|
`go install` all the required binaries.
|
||||||
|
|
||||||
|
Check out the Install section in [the documentation](doc/vim-go.txt) for more
|
||||||
|
detailed instructions (`:help go-install`).
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
The full documentation can be found at [doc/vim-go.txt](doc/vim-go.txt). You can
|
||||||
|
display it from within Vim with `:help vim-go`.
|
||||||
|
|
||||||
|
Depending on your installation method, you may have to generate the plugin's
|
||||||
|
[`help tags`](http://vimhelp.appspot.com/helphelp.txt.html#%3Ahelptags)
|
||||||
|
manually (e.g. `:helptags ALL`).
|
||||||
|
|
||||||
|
We also have a [tutorial](https://github.com/fatih/vim-go/wiki/Tutorial) in the [official vim-go wiki](https://github.com/fatih/vim-go/wiki).
|
||||||
|
|
||||||
|
## FAQ and troubleshooting
|
||||||
|
|
||||||
|
The FAQ and troubleshooting tips are in the documentation and can be quickly
|
||||||
|
accessed using `:help go-troubleshooting`. If you believe you've found a bug or
|
||||||
|
shortcoming in vim-go that is neither addressed by help nor in [existing
|
||||||
|
issues](https://github.com/fatih/vim-go/issues), please open an issue with
|
||||||
|
clear reproduction steps. `:GoReportGitHubIssue` can be used pre-populate a lot
|
||||||
|
of the information needed when creating a new issue.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
All PRs are welcome. If you are planning to contribute a large patch or to
|
||||||
|
integrate a new tool, please create an issue first to get any upfront questions
|
||||||
|
or design decisions out of the way first.
|
||||||
|
|
||||||
|
You can run the tests locally by running `make`. It will lint the VimL for you,
|
||||||
|
lint the documentation, and run the tests against the minimum required version
|
||||||
|
of Vim, other versions of Vim that may be critical to support, and Neovim.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
The BSD 3-Clause License - see [`LICENSE`](LICENSE) for more details
|
||||||
|
|
6
sources_non_forked/vim-go/addon-info.json
Normal file
6
sources_non_forked/vim-go/addon-info.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"name": "vim-go",
|
||||||
|
"description": "Full featured Go (golang) support for Vim.",
|
||||||
|
"author": "Fatih Arslan <fatih@arslan.io>",
|
||||||
|
"repository" : {"type": "git", "url": "https://github.com/fatih/vim-go.git"}
|
||||||
|
}
|
BIN
sources_non_forked/vim-go/assets/vim-go.png
Normal file
BIN
sources_non_forked/vim-go/assets/vim-go.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
821
sources_non_forked/vim-go/assets/vim-go.svg
Normal file
821
sources_non_forked/vim-go/assets/vim-go.svg
Normal file
|
@ -0,0 +1,821 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="173.53481mm"
|
||||||
|
height="147.26407mm"
|
||||||
|
viewBox="0 0 614.88711 521.80181"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.91 r13725"
|
||||||
|
sodipodi:docname="vim-go.svg"
|
||||||
|
style="enable-background:new"
|
||||||
|
inkscape:export-filename="F:\Go\src\github.com\egonelbre\vim-go\assets\vim-go.png"
|
||||||
|
inkscape:export-xdpi="46.84"
|
||||||
|
inkscape:export-ydpi="46.84">
|
||||||
|
<defs
|
||||||
|
id="defs4">
|
||||||
|
<linearGradient
|
||||||
|
id="gopher-iris"
|
||||||
|
osb:paint="solid"
|
||||||
|
gradientTransform="translate(-9.2596241,38.869516)">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#394455;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4317" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="docker-iris"
|
||||||
|
osb:paint="solid">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#394d54;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4311" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="docker-jaw"
|
||||||
|
osb:paint="solid">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#d4edf1;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4305" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="docker-eye"
|
||||||
|
osb:paint="solid">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4299" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="docker-line"
|
||||||
|
osb:paint="solid">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#394d54;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4293" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="docker-body"
|
||||||
|
osb:paint="solid">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#24b8eb;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4287" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="gopher-limbs"
|
||||||
|
osb:paint="solid">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#e1d6b9;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4269" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="gopher-nose"
|
||||||
|
osb:paint="solid">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#e1d0cb;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4263" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="gopher-body"
|
||||||
|
osb:paint="solid"
|
||||||
|
gradientTransform="matrix(-0.18574987,-0.98259706,0.98259706,-0.18574987,-1213.2665,1828.8814)">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#96d6ff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4334" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4253">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#bce8ff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4194" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4182">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#2e3436;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4184" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="gopher-eye"
|
||||||
|
osb:paint="solid"
|
||||||
|
gradientTransform="translate(381.30424,802.02286)">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4178" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="gopher-lines"
|
||||||
|
osb:paint="solid"
|
||||||
|
gradientTransform="matrix(2.0620253,3.9293227,1.3839016,-0.24027903,2506.9621,8572.3972)">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#394655;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4166" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#gopher-lines"
|
||||||
|
id="linearGradient4168"
|
||||||
|
x1="776.14288"
|
||||||
|
y1="39.505058"
|
||||||
|
x2="822.42859"
|
||||||
|
y2="39.505058"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.92105265,0,0,0.92105265,79.548449,262.52483)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#gopher-eye"
|
||||||
|
id="linearGradient4180"
|
||||||
|
x1="776.14288"
|
||||||
|
y1="90.770309"
|
||||||
|
x2="822.42859"
|
||||||
|
y2="90.770309"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.92105266,0,0,0.92105266,124.54841,215.30684)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#gopher-body"
|
||||||
|
id="linearGradient4336"
|
||||||
|
x1="-628.69226"
|
||||||
|
y1="371.77307"
|
||||||
|
x2="-151.41731"
|
||||||
|
y2="371.77307"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(-1,0,0,1,-681.83098,347.55492)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#gopher-nose"
|
||||||
|
id="linearGradient4265"
|
||||||
|
x1="198.05417"
|
||||||
|
y1="374.50043"
|
||||||
|
x2="263.28683"
|
||||||
|
y2="374.50043"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.65610141,0,0,0.65610141,185.97779,480.81383)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#gopher-limbs"
|
||||||
|
id="linearGradient4271"
|
||||||
|
x1="730.36273"
|
||||||
|
y1="373.60995"
|
||||||
|
x2="831.0592"
|
||||||
|
y2="373.60995"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.90381797,-0.29515654,-0.62039307,-0.90381797,-597.71307,820.3894)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#gopher-limbs"
|
||||||
|
id="linearGradient4273"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(-0.54351115,-0.65417141,-1.0770811,0.54351115,655.01412,667.6722)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#gopher-limbs"
|
||||||
|
id="linearGradient4275"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(-0.94401471,-0.3302474,-0.32955964,0.94401471,1151.0861,721.50542)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#gopher-limbs"
|
||||||
|
id="linearGradient4279"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.89463991,0.4064691,0.49110603,-0.89463991,-749.6705,579.40921)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#gopher-limbs"
|
||||||
|
id="linearGradient4281"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.49170605,0.377674,2.0076181,-0.49170605,229.12024,357.65841)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#gopher-iris"
|
||||||
|
id="linearGradient4319"
|
||||||
|
x1="427.26477"
|
||||||
|
y1="316.13431"
|
||||||
|
x2="488.88409"
|
||||||
|
y2="316.13431"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(-1,0,0,1,744.54563,401.01143)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#gopher-iris"
|
||||||
|
id="linearGradient4321"
|
||||||
|
gradientTransform="matrix(5.6994379,2.2315229,-1.9072375,4.8711945,4487.6828,1182.8772)"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="0.76274166"
|
||||||
|
inkscape:cx="499.78979"
|
||||||
|
inkscape:cy="92.336365"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer11"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1018"
|
||||||
|
inkscape:window-x="1912"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:snap-bbox="true"
|
||||||
|
inkscape:bbox-nodes="true"
|
||||||
|
inkscape:snap-global="false"
|
||||||
|
showguides="true"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid4305"
|
||||||
|
originx="-15.732723"
|
||||||
|
originy="-274.01154" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer11"
|
||||||
|
inkscape:label="background"
|
||||||
|
style="display:none"
|
||||||
|
transform="translate(-15.732722,-256.54886)">
|
||||||
|
<rect
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d3e5de;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
id="rect4347"
|
||||||
|
width="614.88708"
|
||||||
|
height="521.80182"
|
||||||
|
x="15.732722"
|
||||||
|
y="256.54886"
|
||||||
|
inkscape:export-filename="vim-go.png"
|
||||||
|
inkscape:export-xdpi="46.84"
|
||||||
|
inkscape:export-ydpi="46.84" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer6"
|
||||||
|
inkscape:label="shadow"
|
||||||
|
transform="translate(-15.732722,-256.54886)">
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#2e4233;fill-opacity:0.10714285;fill-rule:nonzero;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m 287.3893,695.44531 c -50.0612,-2.78118 -62.1134,11.12305 -91.7793,11.12305 -29.6659,0 -47.28069,-6.48881 -76.01953,-1.85352 -28.738834,4.6353 -40.790093,3.70867 -55.623042,16.6875 -14.832949,12.97883 -21.926707,11.85327 -18.541016,20.39454 1.318705,3.32677 3.956373,1.53579 10.703125,0.83984 115.165183,-11.87969 237.050993,16.53486 337.406243,16.77539 83.20192,0.19942 110.33047,-21.09623 105.22253,-34.76541 -16.86616,-45.13499 -81.24683,-23.67849 -211.36901,-29.20139 z"
|
||||||
|
id="path4349"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="csssssssc" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="cape-back"
|
||||||
|
style="display:inline"
|
||||||
|
sodipodi:insensitive="true"
|
||||||
|
transform="translate(-15.732722,-256.54886)">
|
||||||
|
<path
|
||||||
|
style="fill:#0c7a31;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 260.24444,535.87695 c -20.68496,5.13447 -3.94094,36.63825 -23.78246,45.53288 -18.22356,8.16932 -29.87743,27.29784 -48.21487,37.53094 -24.3143,13.56845 -47.25416,17.93122 -70.94376,35.71927 -11.54022,8.66532 -48.036929,3.46906 -49.132109,17.96915 56.226929,-8.73065 86.269619,15.95087 120.882979,20.57024 30.54605,4.07656 53.64011,2.39756 79.48357,-7.50413 89.71977,-34.37532 52.16171,-111.74704 51.81195,-135.28471 -17.69563,-3.28964 -42.98659,-18.78289 -60.1053,-14.53364 z"
|
||||||
|
id="path4321"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="sssscsscs" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer5"
|
||||||
|
inkscape:label="gopher-body"
|
||||||
|
style="display:inline;opacity:1"
|
||||||
|
sodipodi:insensitive="true"
|
||||||
|
transform="translate(-15.732722,-256.54886)">
|
||||||
|
<g
|
||||||
|
style="display:inline;opacity:1"
|
||||||
|
transform="matrix(-0.34823803,-0.28093567,-0.33018747,0.52325377,856.33627,409.62314)"
|
||||||
|
id="g4537">
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient4275);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m 419.84023,584.57289 c -1.11092,4.23495 -3.11543,7.14238 -5.84936,9.02308 -2.73394,1.8807 -6.19236,2.76095 -10.13743,3.23943 -3.94504,0.47846 -8.37351,0.59759 -13.05363,0.66122 -4.6801,0.0636 -9.60653,0.0259 -14.5852,-0.15006 -4.97865,-0.17599 -9.67742,-0.66266 -13.94891,-1.44453 -4.27148,-0.78187 -8.12262,-1.83504 -11.28827,-3.15781 -3.16564,-1.32277 -5.63542,-2.92368 -7.07427,-4.89074 -1.43884,-1.96709 -1.83785,-4.30021 -0.94134,-7.07932 0.89648,-2.77911 2.64686,-4.65171 5.05838,-5.71202 2.41152,-1.06032 5.47772,-1.29847 8.97039,-1.04717 3.49268,0.25132 7.40119,0.98198 11.60615,1.60695 4.20496,0.62498 8.71575,1.10136 13.55734,0.95747 4.84159,-0.14387 9.82241,-1.20624 14.59946,-2.18657 4.77703,-0.9803 9.35663,-1.80521 13.2055,-1.76209 3.8489,0.0431 6.93814,0.92314 8.72484,2.84805 1.78673,1.92488 0.0493,13.32997 1.15633,9.09414 z"
|
||||||
|
id="path4539"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cssssssssssssssssc" />
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#gopher-lines);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m 411.66722,570.50504 c -3.64483,-0.3204 -7.91192,0.0353 -12.44327,0.67313 -5.17866,0.72899 -10.69026,1.78243 -16.25596,1.96339 -5.56571,0.181 -10.75654,-0.27799 -15.6406,-0.87383 -4.8841,-0.59575 -9.46828,-1.26261 -13.59381,-1.35067 -4.12552,-0.0881 -7.77812,0.41271 -10.6665,1.77043 -2.88834,1.35772 -5.00621,3.55109 -6.11385,6.60546 -1.10762,3.05438 -0.68341,5.7953 0.96623,8.19507 1.64966,2.39979 4.51594,4.46252 8.19691,6.21125 3.681,1.74874 8.16283,3.1933 13.12136,4.28264 4.95854,1.08935 10.4013,1.79657 16.15733,2.05756 5.756,0.26106 11.2421,0.29972 16.33832,0.21929 5.09618,-0.0804 9.79866,-0.25121 13.94009,-0.87517 1.57579,-0.23741 3.06793,-0.55279 4.47088,-0.96129 2.8331,-0.82603 3.60613,-5.66983 1.06694,-4.35369 -2.35253,1.21937 -5.13009,1.88834 -8.23473,2.27934 -3.78352,0.47652 -8.03435,0.60519 -12.52976,0.67623 -4.49538,0.071 -9.22983,0.0403 -14.01368,-0.12137 -4.78387,-0.16172 -9.29761,-0.62006 -13.39935,-1.36274 -4.10176,-0.74271 -7.79879,-1.74643 -10.8363,-3.01023 -3.03748,-1.2638 -5.40588,-2.79646 -6.78423,-4.6796 -1.37835,-1.88316 -1.75885,-4.11616 -0.89417,-6.78092 0.86467,-2.66475 2.54876,-4.4645 4.86314,-5.48862 2.31437,-1.0241 5.2526,-1.265 8.60072,-1.03925 3.34811,0.22576 7.09649,0.90864 11.13305,1.49473 4.03653,0.5862 8.37113,1.03632 13.02879,0.89877 4.65766,-0.13756 9.45383,-1.14909 14.04535,-2.09377 4.59152,-0.94468 8.9823,-1.75345 12.66755,-1.73592 0.46066,0.002 0.91144,0.0161 1.3482,0.0436 1.1223,0.0708 2.1698,0.20509 3.10067,0.47739 1.0735,0.314 2.95461,-2.6047 -0.11758,-2.94357 -0.49859,-0.055 -1.54942,0.19872 -1.52174,-0.17766 z"
|
||||||
|
id="path4541"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="csscsscssssssssssssssssssssccsssc" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
transform="matrix(-0.20408679,0.36109427,0.8060854,0.48598006,286.09208,226.24278)"
|
||||||
|
id="g4640"
|
||||||
|
style="display:inline;opacity:1">
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#gopher-lines);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m 767.29926,387.32674 c 11.1235,7.96555 31.77795,11.29978 44.73159,15.54502 12.95363,4.24526 18.14889,9.35948 22.12936,13.37285 3.98046,4.01338 5.94428,7.14463 4.71807,9.52723 -1.2262,2.38259 -5.54351,3.99405 -14.00119,4.81166 -8.45765,0.81761 -15.90978,0.12055 -23.02358,-1.72572 -7.11381,-1.84628 -13.80694,-4.86649 -21.70559,-8.603 -7.89866,-3.73649 -17.3272,-8.0507 -25.81115,-14.18439 -8.48395,-6.13369 -17.62324,-13.90003 -23.14238,-24.13356 -5.51915,-10.23352 -5.78201,-21.34406 -5.37146,-30.88264 0.41055,-9.53859 1.51092,-17.55377 2.71572,-23.74931 1.20482,-6.19553 2.71509,-10.67437 4.77102,-13.66952 2.05591,-2.99513 4.65165,-4.52673 7.71923,-4.52673 3.06759,0 5.70357,1.83092 7.62535,5.49926 1.9218,3.66832 3.04778,9.24444 3.28639,16.76004 0.23861,7.51561 -0.67126,17.08072 0.34029,27.19831 1.01155,10.1176 3.89485,20.79494 15.01833,28.7605 z"
|
||||||
|
id="path4642"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="sssssssssssssssss" />
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient4281);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m 760.81735,387.61463 c 8.35351,7.22933 23.40419,11.34465 36.92829,14.85447 13.52408,3.50986 21.76315,7.50998 26.41399,11.29491 4.65086,3.78492 7.04347,6.96136 6.89289,9.28045 -0.15059,2.31908 -3.07202,3.85186 -9.99413,4.53735 -6.92209,0.68549 -13.12478,-0.17957 -19.18856,-2.15841 -6.06375,-1.97886 -12.01277,-5.06603 -19.62326,-8.64782 -7.61047,-3.5818 -16.94465,-7.61787 -24.98938,-13.21535 -8.04472,-5.59749 -15.82286,-12.65396 -20.9022,-21.24583 -5.07935,-8.59186 -6.01346,-17.801 -5.99188,-25.91871 0.0216,-8.1177 0.93462,-15.14861 1.86635,-20.66954 0.93173,-5.52092 2.01706,-9.59713 3.38259,-12.30465 1.36554,-2.70753 3.03466,-4.06947 5.01979,-4.01398 1.98511,0.0555 3.57672,1.84704 4.61437,5.2751 1.03765,3.42807 1.44745,8.54444 1.4737,15.15288 0.0262,6.60845 -0.43638,14.76057 0.91317,23.27473 1.34954,8.51418 4.83074,17.27506 13.18427,24.5044 z"
|
||||||
|
id="path4644"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="sssssssssssssssss" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
style="display:inline;opacity:1"
|
||||||
|
id="g4594"
|
||||||
|
transform="matrix(-0.13664232,-0.29657059,-0.88136995,0.09664282,727.56031,790.52022)">
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="sssssssssssssssss"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4588"
|
||||||
|
d="m 767.29926,387.32674 c 11.1235,7.96555 31.77795,11.29978 44.73159,15.54502 12.95363,4.24526 18.14889,9.35948 22.12936,13.37285 3.98046,4.01338 5.94428,7.14463 4.71807,9.52723 -1.2262,2.38259 -5.54351,3.99405 -14.00119,4.81166 -8.45765,0.81761 -15.90978,0.12055 -23.02358,-1.72572 -7.11381,-1.84628 -13.80694,-4.86649 -21.70559,-8.603 -7.89866,-3.73649 -17.3272,-8.0507 -25.81115,-14.18439 -8.48395,-6.13369 -17.62324,-13.90003 -23.14238,-24.13356 -5.51915,-10.23352 -5.78201,-21.34406 -5.37146,-30.88264 0.41055,-9.53859 1.51092,-17.55377 2.71572,-23.74931 1.20482,-6.19553 2.71509,-10.67437 4.77102,-13.66952 2.05591,-2.99513 4.65165,-4.52673 7.71923,-4.52673 3.06759,0 5.70357,1.83092 7.62535,5.49926 1.9218,3.66832 3.04778,9.24444 3.28639,16.76004 0.23861,7.51561 -0.67126,17.08072 0.34029,27.19831 1.01155,10.1176 3.89485,20.79494 15.01833,28.7605 z"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#gopher-lines);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="sssssssssssssssss"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="ellipse4590"
|
||||||
|
d="m 760.81735,387.61463 c 8.35351,7.22933 23.40419,11.34465 36.92829,14.85447 13.52408,3.50986 21.76315,7.50998 26.41399,11.29491 4.65086,3.78492 7.04347,6.96136 6.89289,9.28045 -0.15059,2.31908 -3.07202,3.85186 -9.99413,4.53735 -6.92209,0.68549 -13.12478,-0.17957 -19.18856,-2.15841 -6.06375,-1.97886 -12.01277,-5.06603 -19.62326,-8.64782 -7.61047,-3.5818 -16.94465,-7.61787 -24.98938,-13.21535 -8.04472,-5.59749 -15.82286,-12.65396 -20.9022,-21.24583 -5.07935,-8.59186 -6.01346,-17.801 -5.99188,-25.91871 0.0216,-8.1177 0.93462,-15.14861 1.86635,-20.66954 0.93173,-5.52092 2.01706,-9.59713 3.38259,-12.30465 1.36554,-2.70753 3.03466,-4.06947 5.01979,-4.01398 1.98511,0.0555 3.57672,1.84704 4.61437,5.2751 1.03765,3.42807 1.44745,8.54444 1.4737,15.15288 0.0262,6.60845 -0.43638,14.76057 0.91317,23.27473 1.34954,8.51418 4.83074,17.27506 13.18427,24.5044 z"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient4271);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
style="display:inline"
|
||||||
|
id="g4533-2"
|
||||||
|
transform="matrix(-0.60102903,0.32221978,0.53870829,0.77401445,526.12645,47.501077)" />
|
||||||
|
<g
|
||||||
|
style="opacity:1"
|
||||||
|
transform="matrix(-0.32879267,0.17361606,0.20143296,0.28338802,143.13323,319.59452)"
|
||||||
|
id="g4404">
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="sssssssssssssssss"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4406"
|
||||||
|
d="m -626.54672,402.3529 c 2.22767,10.86299 0.34493,21.82632 -3.86747,31.42527 -4.21252,9.59894 -10.55173,17.86115 -17.72096,24.29983 -7.1694,6.43883 -15.25476,11.10591 -24.5716,13.61353 -9.31698,2.50761 -20.94966,4.46936 -31.63903,1.98398 -10.68939,-2.48537 -18.0688,-9.22838 -24.09401,-15.89285 -6.02508,-6.66442 -12.35923,-14.47524 -22.96531,-22.06805 -10.60584,-7.59266 -20.8648,-15.59839 -25.16123,-23.3775 -4.29632,-7.77931 -7.008,-15.66934 -7.81517,-23.39095 -0.80717,-7.7215 0.35908,-14.55922 3.12288,-20.54462 2.76393,-5.98548 7.12557,-11.1208 12.7854,-15.40902 5.65998,-4.28811 12.61751,-7.73606 20.64204,-10.24271 8.02465,-2.50651 17.11262,-4.07552 27.13941,-4.41504 10.0268,-0.3395 20.06604,0.59388 29.76158,2.87504 9.69543,2.2813 19.05511,5.92037 27.47739,11.02309 8.42215,5.10286 15.89307,11.69212 21.60465,19.6287 5.71147,7.93674 13.0738,19.62846 15.30143,30.4913 z"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#gopher-body);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="csssccscsccscscccsccscsssscscscc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4408"
|
||||||
|
d="m -784.21409,457.33922 c -0.56136,0.0656 -1.08141,0.1809 -1.55606,0.33615 -0.63289,0.20699 -1.18396,0.48516 -1.6349,0.82686 -0.45093,0.3417 -0.80184,0.74659 -1.02778,1.21891 -0.22595,0.47234 -0.32669,1.01119 -0.27449,1.62035 0.0522,0.60917 0.25282,1.23371 0.57968,1.84938 0.32687,0.61567 0.98957,1.25218 1.83531,1.84156 0.84574,0.58937 1.35671,1.20529 1.82543,1.72857 0.46713,0.52147 1.13451,0.85371 2.02424,0.92674 0.10253,0.008 0.12328,-0.30471 0.0344,-0.32876 -0.78083,-0.20262 -1.25826,-0.72023 -1.71877,-1.11076 -0.4254,-0.46645 -0.87231,-1.01406 -1.62104,-1.54604 -0.74871,-0.53197 -1.47289,-1.09304 -1.77689,-1.63886 -0.30398,-0.54584 -0.49685,-1.10009 -0.55469,-1.64239 -0.0579,-0.54231 0.0245,-1.0222 0.21918,-1.44322 0.19469,-0.42103 0.50198,-0.78371 0.90168,-1.08623 0.39973,-0.30252 0.89062,-0.54587 1.4577,-0.7237 0.28355,-0.0889 0.5872,-0.16119 0.90722,-0.21465 0.32002,-0.0535 0.6576,-0.0885 1.01178,-0.10163 0.70839,-0.0255 1.4163,0.0392 2.10043,0.1987 0.68412,0.15947 1.34499,0.41522 1.93838,0.77329 0.59338,0.35806 1.11885,0.81986 1.52108,1.37653 0.40222,0.55667 0.92117,1.37523 1.07925,2.13677 0.12981,0.62539 0.0734,1.25844 -0.13288,1.83379 -0.0385,0.10712 0.4977,0.29416 0.62787,-0.0111 0.24265,-0.5698 0.23445,-1.24057 0.1026,-1.8741 -0.17834,-0.85666 -0.69031,-1.76937 -1.13671,-2.40019 -0.4464,-0.6308 -1.03123,-1.15292 -1.68895,-1.55276 -0.65772,-0.39984 -1.38674,-0.68003 -2.14271,-0.85021 -0.75599,-0.17016 -1.54036,-0.23166 -2.32498,-0.19142 -0.19617,0.0101 -0.38815,0.0268 -0.57528,0.0484 z"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#gopher-lines);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
transform="matrix(13.851095,0,0,13.851095,10133.213,-6001.611)" />
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#gopher-lines);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m -753.77185,413.0219 c -0.13663,-2.61847 2.18018,-4.94804 7.2193,-6.20054 7.65443,-1.90257 20.03831,1.84566 27.93811,5.67152 4.33357,2.09883 8.88981,3.89076 12.66635,7.19411 1.28185,1.12133 2.51799,2.28349 3.36855,4.40869 -1.65849,0.577 -4.10492,-0.92134 -5.87278,-2.13046 -6.96771,-4.76531 -14.69502,-8.08983 -22.67695,-9.12646 -6.71591,-0.87187 -8.86923,-3.11022 -14.75541,-2.56175 -3.72583,0.34716 -4.90626,2.13878 -7.88716,2.74489 z"
|
||||||
|
id="path4365-1-2"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cssscsssc" />
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#gopher-lines);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m -720.16989,411.68353 c 0.28532,-2.32502 0.86962,3.90377 -0.31886,5.45995 -4.46007,5.84 -8.20289,12.32072 -12.42083,18.36519 -1.37385,1.96787 -3.29463,0.0414 -2.42738,-2.09874 0.88118,-2.1739 2.06053,-3.99898 3.34915,-5.8153 1.20809,-1.70147 2.81353,-3.0576 3.88834,-4.85958 2.06619,-3.46267 2.39577,-6.62873 4.25443,-10.2393 0.63712,-1.23818 3.5225,0.42546 3.67386,-0.80905 z"
|
||||||
|
id="path4367-9-2"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="sssssssss" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
style="display:inline;opacity:1"
|
||||||
|
id="g4198"
|
||||||
|
transform="matrix(0.69027452,0,0,0.73815345,642.18876,259.65104)">
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#gopher-lines);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m -140.71724,398.66408 c -9.31409,71.69689 -25.7611,141.32 -83.87724,188.8641 -73.31672,59.97949 -208.09131,67.90599 -303.42706,10.99618 -27.57065,-16.45805 -49.52457,-62.17665 -53.04177,-91.74122 -7.35191,-61.79791 19.82699,-103.64945 13.47928,-160.67805 -5.05249,-45.39216 -29.63784,-82.95495 -27.30836,-137.00138 1.56315,-36.26681 11.06536,-78.46439 40.50727,-100.88356 38.57103,-29.370718 83.60539,-46.188952 134.68095,-45.031125 72.73731,1.648875 151.17838,6.326503 212.18714,49.939365 43.544,31.12796 68.50323,82.53699 72.90385,135.3004 4.52019,54.19698 -0.16075,104.48555 -6.10406,150.23529 z"
|
||||||
|
id="path4188"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="sssssssssss" />
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient4336);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m -158.93683,464.92976 c -15.56115,65.9367 -58.42288,127.39267 -134.42207,151.72082 -70.61462,22.6045 -163.49236,17.29949 -232.18476,-25.54762 -26.14623,-16.30879 -46.09162,-61.46233 -48.95901,-89.47579 -6.03547,-58.9646 19.04741,-102.17429 13.30293,-156.59502 -4.7951,-45.42661 -28.02123,-78.34585 -27.29597,-132.22289 0.47399,-35.21112 8.99044,-76.95773 37.82112,-98.79995 36.52466,-27.671205 78.3526,-45.238515 126.45621,-45.012482 76.22124,0.358155 162.16208,5.533182 222.84373,56.658952 55.47879,46.74224 63.38318,129.04796 60.81019,193.3049 -2.12217,52.99813 -7.67242,100.63054 -18.37237,145.96908 z"
|
||||||
|
id="ellipse4190"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="sssssssssss" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g4376"
|
||||||
|
transform="matrix(0.40138799,-0.13710458,0.13710458,0.40138799,470.81791,82.723801)"
|
||||||
|
style="opacity:1">
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#gopher-body);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m -626.57295,401.69566 c 2.24713,11.35067 0.36741,22.38948 -3.843,32.03835 -4.21053,9.64886 -10.54997,17.90531 -17.7192,24.34399 -7.1694,6.43883 -15.25457,11.1106 -24.57171,13.61082 -9.31727,2.5002 -20.94956,4.47176 -31.64526,1.82793 -10.69571,-2.64383 -18.09209,-9.81214 -24.14818,-17.25062 -6.05597,-7.43843 -12.44269,-16.56671 -23.09665,-25.35944 -10.65372,-8.79255 -20.95218,-17.78817 -25.30072,-26.87318 -4.34843,-9.08528 -7.1154,-18.36084 -7.98,-27.52156 -0.86459,-9.1606 0.24716,-17.36404 2.9617,-24.58398 2.71467,-7.22004 7.03243,-13.45488 12.66059,-18.5369 5.6283,-5.08191 12.56665,-9.01064 20.59229,-11.48936 8.02576,-2.47858 17.13537,-3.50537 27.20916,-2.66707 10.0738,0.83832 20.1809,3.47234 29.95223,7.6529 9.77122,4.18068 19.21426,9.9086 27.71179,16.89733 8.49741,6.98886 16.03465,15.24007 21.79567,24.41557 5.7609,9.17565 13.1742,22.14471 15.42129,33.49522 z"
|
||||||
|
id="path4398"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="sssssssssssssssss" />
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#gopher-lines);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m -784.27135,455.90422 c -0.56339,0.0147 -1.08437,0.10666 -1.55902,0.26191 -0.63289,0.20699 -1.18231,0.52669 -1.63059,0.93484 -0.44828,0.40815 -0.79558,0.90361 -1.01756,1.4752 -0.22199,0.5716 -0.31844,1.21792 -0.26185,1.93717 0.0566,0.71926 0.26134,1.4471 0.59196,2.157 0.33063,0.7099 0.99621,1.41858 1.84494,2.08284 0.84872,0.66425 1.36325,1.36931 1.83382,1.93901 0.46898,0.56774 1.13678,0.9105 2.02675,0.98962 0.10256,0.009 0.12294,-0.31321 0.034,-0.33899 -0.78143,-0.21746 -1.26048,-0.77583 -1.72293,-1.21489 -0.42768,-0.5236 -0.87838,-1.16625 -1.63058,-1.78505 -0.75217,-0.61879 -1.47924,-1.25213 -1.78697,-1.89162 -0.30772,-0.63951 -0.50455,-1.29287 -0.56648,-1.9378 -0.062,-0.64492 0.0165,-1.22191 0.20772,-1.73042 0.1912,-0.50852 0.49539,-0.94884 0.89287,-1.30706 0.3975,-0.35822 0.88707,-0.63484 1.45426,-0.80994 0.2836,-0.0875 0.58767,-0.1494 0.90851,-0.1822 0.32084,-0.0328 0.65966,-0.0369 1.01552,-0.008 0.71174,0.0585 1.42446,0.24383 2.11396,0.53794 0.6895,0.29412 1.35628,0.69807 1.95502,1.19025 0.59873,0.49218 1.12894,1.07271 1.53474,1.71893 0.4058,0.64623 0.9285,1.5589 1.08808,2.35795 0.13104,0.65619 0.075,1.29927 -0.13103,1.88026 -0.0384,0.10817 0.49808,0.30362 0.62824,-0.002 0.24262,-0.57052 0.23429,-1.24452 0.10166,-1.89748 -0.17938,-0.88293 -0.69436,-1.871 -1.14416,-2.58711 -0.44981,-0.71609 -1.03943,-1.35821 -1.70275,-1.89855 -0.66333,-0.54034 -1.3987,-0.97968 -2.16052,-1.29649 -0.76184,-0.31679 -1.55154,-0.51173 -2.33984,-0.56369 -0.19709,-0.013 -0.38986,-0.0163 -0.57767,-0.0116 z"
|
||||||
|
id="path4369"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="csssccscsccscscccsccscsssscscscc"
|
||||||
|
transform="matrix(13.851095,0,0,13.851095,10133.213,-6001.611)" />
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#gopher-lines);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m -730.27274,382.91266 c 1.8068,-2.76405 6.31309,-3.63001 13.24575,-1.6171 10.53068,3.05761 22.43414,14.97755 28.94834,24.04709 3.57338,4.97534 7.6424,9.78266 9.64772,15.62449 0.68055,1.98294 1.27611,3.97774 0.68898,6.70435 -2.4056,-0.49416 -4.1871,-3.62313 -5.37952,-6.01329 -4.69962,-9.4202 -11.38574,-17.86492 -20.09536,-24.13889 -7.3284,-5.27852 -8.20487,-8.9719 -15.61502,-12.25742 -4.69053,-2.07967 -7.44128,-1.02076 -11.44089,-2.34923 z"
|
||||||
|
id="path4365-1"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cssscsssc" />
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#gopher-lines);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m -689.31909,403.49962 c 2.08771,-2.1886 -1.9021,4.5559 -4.48533,5.36905 -9.69439,3.05157 -19.01784,7.22624 -28.57811,10.64488 -3.11327,1.11257 -3.94795,-2.11026 -1.30738,-3.72982 2.68251,-1.64492 5.45711,-2.73872 8.35507,-3.75217 2.71578,-0.94874 5.64428,-1.2851 8.27731,-2.4236 5.06052,-2.18718 7.83343,-5.20599 12.75841,-7.67984 1.68866,-0.84854 3.86766,2.73608 4.97603,1.5739 z"
|
||||||
|
id="path4367-9"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="sssssssss" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g4634"
|
||||||
|
transform="matrix(0.13058783,-0.42795023,-0.60869797,-0.11092817,632.15501,956.21909)"
|
||||||
|
style="display:inline;opacity:1">
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="sssssssssssssssss"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4636"
|
||||||
|
d="m 423.50332,581.83521 c -0.004,4.40048 -1.19837,7.58856 -3.37524,9.82844 -2.17687,2.23987 -5.33154,3.55156 -9.14619,4.44292 -3.81465,0.89135 -8.28246,1.39523 -13.05675,1.83828 -4.77428,0.44304 -9.85163,0.79076 -14.95001,1.09928 -5.09838,0.30851 -9.94541,0.34741 -14.40217,0.0862 -4.45676,-0.26122 -8.52354,-0.79908 -11.99271,-1.71189 -3.46915,-0.91282 -6.33736,-2.21356 -8.3562,-4.09288 -2.01885,-1.87935 -3.18709,-4.34475 -3.25466,-7.51083 -0.0676,-3.16607 0.9983,-5.4859 2.92534,-7.0838 1.92703,-1.5979 4.71248,-2.46394 8.09977,-2.84688 3.38729,-0.38293 7.37282,-0.28336 11.77044,-0.16051 4.39762,0.12284 9.21051,0.23456 14.33166,-0.12202 5.12115,-0.35659 10.27171,-1.47349 15.16022,-2.54099 4.88852,-1.06749 9.50395,-2.05149 13.43823,-2.27114 3.9343,-0.21967 7.17754,0.32322 9.39823,2.04598 2.22069,1.72276 3.41425,4.59936 3.41004,8.99986 z"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient4279);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="csscsscssssssssssssssssssssccsssc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4638"
|
||||||
|
d="m 411.91406,568.54883 c -3.75011,-0.0271 -8.08701,0.53975 -12.76172,1.28711 -5.34251,0.85413 -11.10706,1.92059 -17.00976,2.32617 -5.9027,0.40562 -11.41103,0.38326 -16.44727,0.41406 -5.03624,0.0309 -9.6045,0.1607 -13.50781,0.85938 -3.9033,0.69867 -7.13503,1.96743 -9.4082,3.96875 -2.27316,2.00131 -3.58535,4.71676 -3.65235,8.17578 -0.067,3.45901 1.21821,6.3073 3.54297,8.58008 2.32476,2.27278 5.68789,3.9795 9.76172,5.25 4.07385,1.27051 8.85237,2.11894 14.05664,2.59765 5.20427,0.47871 10.83381,0.56134 16.70313,0.22266 5.86931,-0.33868 11.47146,-0.78653 16.60547,-1.34961 5.13399,-0.56309 9.79334,-1.22365 13.70703,-2.34375 1.48913,-0.4262 2.86677,-0.9287 4.12695,-1.51953 2.54507,-1.19325 2.05015,-6.17249 -0.0996,-4.54102 -1.99172,1.51153 -4.14364,1.68162 -7.15735,2.35061 -3.67269,0.81527 -8.18136,0.99111 -12.55008,1.3428 -4.3687,0.35167 -8.7789,1.78431 -13.31332,2.07736 -4.53444,0.29304 -8.86787,0.32801 -12.93181,0.0702 -4.06396,-0.25785 -7.85651,-0.78075 -11.12475,-1.64296 -3.26823,-0.86221 -5.99695,-2.08037 -7.8846,-3.81399 -1.88765,-1.73365 -2.92537,-3.9871 -2.97865,-6.80086 -0.0533,-2.81374 0.90176,-4.8192 2.66881,-6.10562 1.76704,-1.28641 5.61732,-0.58475 8.69196,-0.71399 3.07463,-0.12925 6.90624,-0.54484 10.78772,-0.41733 3.88147,0.12754 6.54592,-0.48119 11.04844,-1.2139 4.50252,-0.73264 9.15212,-2.3434 13.88736,-3.72101 4.73523,-1.37761 9.22461,-2.34259 13.00861,-2.55385 0.473,-0.0264 0.93707,-0.0422 1.38868,-0.0449 1.16046,-0.007 2.25007,0.0442 3.25,0.23633 1.15313,0.22156 2.31543,-2.86146 -0.83789,-2.92773 -0.51177,-0.0108 -1.03459,-0.045 -1.57032,-0.0488 z"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#gopher-lines);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer9"
|
||||||
|
inkscape:label="gopher-shadow"
|
||||||
|
style="display:inline;opacity:0.06000001"
|
||||||
|
sodipodi:insensitive="true"
|
||||||
|
transform="translate(-15.732722,-256.54886)">
|
||||||
|
<ellipse
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
id="path4544"
|
||||||
|
cx="-467.52527"
|
||||||
|
cy="482.66467"
|
||||||
|
rx="22.450642"
|
||||||
|
ry="20.682871"
|
||||||
|
transform="scale(-1,1)" />
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m 234.60547,309.98047 c -6.62163,-0.0703 -10.7426,0.83465 -15.61133,3.26758 -5.0378,2.51742 -10.044,7.91661 -11.55273,12.45898 -2.26972,6.83348 -0.42196,14.92592 5.01757,21.97656 3.19606,4.1427 6.84938,6.56071 14.60938,9.66993 3.20846,1.28553 7.68985,3.50108 9.95898,4.92382 5.6211,3.52442 9.83526,5.31873 13.54102,5.76563 2.42194,0.29208 3.11523,0.63719 3.11523,1.55469 0,0.89182 -0.7061,1.28567 -2.89062,1.61328 -1.58919,0.23867 -3.77121,0.24076 -4.84961,0.004 -1.95019,-0.42833 -1.9703,-0.40483 -3.65625,4.68555 -3.87667,11.7048 -5.82609,25.85658 -5.80859,42.15625 0.0196,18.31899 1.82597,28.89111 9.58007,56.04688 5.56137,19.47655 7.15656,26.40249 8.58008,37.26171 2.05331,15.66359 1.31467,26.60445 -3.90625,57.79102 -4.8641,29.05517 -5.15869,31.69637 -5.18359,46.54297 -0.0239,14.28001 0.63486,19.84952 3.52539,29.8125 5.44577,18.77032 13.72789,34.11825 23.9082,44.30078 8.00321,8.00498 22.62783,16.26261 41.23438,23.2832 5.47456,2.06566 5.83617,2.12101 6.46679,0.99414 1.72277,-3.07839 3.2087,-3.7772 9.33203,-3.79882 -38.68101,-33.75954 -34.48259,-82.29367 -25.52281,-108.9339 7.33431,-21.80723 31.77025,-53.23407 31.77025,-53.23407 l -22.41052,-1.98245 c 0,0 -7.25969,-42.63753 -13.15682,-59.9065 -22.58603,-66.14023 -29.82384,-120.35922 4.37069,-158.19894 5.84309,-6.46598 12.5988,-11.21335 19.60937,-14.69727 -9.02679,1.89877 -18.30173,4.80561 -26.41601,8.32813 -6.65247,2.88791 -19.01394,9.90994 -18.99415,10.78906 0.009,0.39075 0.30731,1.97487 0.66407,3.52148 0.79845,3.46141 -0.0807,5.55969 -2.20117,5.25782 -1.1871,-0.16901 -1.49742,-0.76108 -1.83008,-3.48633 -0.63121,-5.17109 -3.20076,-9.39815 -9.06836,-14.91797 -9.25402,-8.70552 -17.29671,-12.21829 -29.22461,-12.76172 -1.05756,-0.0482 -2.05405,-0.0778 -3,-0.0879 z m 1.38086,24.10156 c 1.88404,0.0642 3.99413,0.41696 5.88476,1.04492 3.99187,1.32589 12.35644,6.69047 14.31446,9.17969 3.00519,3.82048 1.04901,4.01008 -3.4043,0.33008 -1.74522,-1.44216 -3.36983,-2.6211 -3.60937,-2.6211 -0.23954,0 -2.78812,1.91597 -5.66407,4.25782 -2.87594,2.34185 -5.59815,4.25776 -6.04883,4.25976 -1.88842,0.007 -0.56519,-2.08264 3.10938,-4.91015 4.64288,-3.57262 5.88952,-5.38766 4.12891,-6.00977 -0.64649,-0.22845 -2.92374,-1.13445 -5.06055,-2.01367 -3.0123,-1.23949 -4.52138,-1.50334 -6.71875,-1.17383 -3.06661,0.45987 -3.82178,-0.39095 -1.46485,-1.65234 0.9899,-0.52978 2.64916,-0.75563 4.53321,-0.69141 z m 103.78515,383.73633 c -0.005,0.0152 -0.007,0.0256 -0.0117,0.041 l -0.70118,2.28906 5.65625,1.01562 c 0.0901,0.0162 0.20551,0.0326 0.29688,0.0488 -1.81728,-1.11236 -3.56263,-2.24473 -5.24024,-3.39453 z"
|
||||||
|
id="path4271"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="sssssssscssssssssssscsccsscscssssssscsssscscsssscccccccc" />
|
||||||
|
<path
|
||||||
|
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 328.4205,548.25967 -4.47623,14.88037 c 2.60939,0.0254 9.84161,-6.41982 16.75619,-6.818 76.94638,-4.43102 125.04829,-0.40565 187.26295,-5.40532 1.45456,-0.11689 3.76527,-0.10936 5.20677,0.2079 5.21485,1.14773 8.09003,14.3736 9.3628,13.60525 0.6055,-14.12878 -2.32372,-19.14168 -5.81784,-22.69773 z"
|
||||||
|
id="path4275"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ccsssccc" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer2"
|
||||||
|
inkscape:label="gopher-face"
|
||||||
|
style="display:inline"
|
||||||
|
sodipodi:insensitive="true"
|
||||||
|
transform="translate(-15.732722,-256.54886)">
|
||||||
|
<g
|
||||||
|
id="g4818"
|
||||||
|
transform="matrix(-0.65610141,0,0,0.65610141,655.70091,210.42145)">
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="sssssssssssssssss"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4812"
|
||||||
|
d="m 547.42756,318.16456 c -0.44046,14.77191 -4.12869,29.02667 -10.38967,42.25266 -6.26099,13.22599 -15.09198,25.42687 -25.80466,35.99686 -10.71268,10.57 -23.30432,19.50822 -37.11826,26.08983 -13.81394,6.58161 -28.85103,10.80263 -44.50193,11.8618 -15.65091,1.05917 -30.4406,-1.15844 -43.81781,-6.16756 -13.37721,-5.00911 -25.3405,-12.8075 -35.30087,-22.80416 -9.96037,-9.99666 -17.91599,-22.19037 -23.26581,-35.90798 -5.34983,-13.71761 -8.0915,-28.95913 -7.64195,-44.98105 0.44955,-16.02192 4.04447,-31.2937 10.1422,-45.07896 6.09773,-13.78526 14.69591,-26.08175 25.16951,-36.25747 10.4736,-10.17571 22.82245,-18.23043 36.46168,-23.66123 13.63924,-5.4308 28.57214,-8.24285 44.22923,-8.02541 15.6571,0.21745 30.56095,3.42714 44.11009,8.94154 13.54914,5.5144 25.7404,13.33722 35.92568,22.91495 10.18529,9.57774 18.36233,20.91345 23.87736,33.53282 5.51504,12.61936 8.36566,26.52144 7.92521,41.29336 z"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#gopher-lines);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="sssssssssssssssss"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="ellipse4814"
|
||||||
|
d="m 539.72249,314.79002 c 10e-4,13.89984 -3.01572,27.53808 -8.51346,40.35257 -5.49774,12.81449 -13.48047,24.80543 -23.37659,35.2527 -9.89612,10.44726 -21.70519,19.34133 -34.78531,25.87862 -13.08011,6.53727 -27.4256,10.71236 -42.3773,11.7667 -14.9517,1.05435 -29.09103,-1.11258 -41.85904,-5.93108 -12.76803,-4.81852 -24.16883,-12.28715 -33.66552,-21.79076 -9.49671,-9.50362 -17.08979,-21.04298 -22.23241,-33.95465 -5.14261,-12.91166 -7.83328,-27.19561 -7.52333,-42.13595 0.30995,-14.94034 3.58995,-29.10832 9.22975,-41.85842 5.63981,-12.7501 13.63743,-24.08168 23.39638,-33.47108 9.75897,-9.38941 21.27795,-16.83842 34.00359,-21.94183 12.72563,-5.10342 26.66067,-7.86812 41.28534,-7.94317 14.62467,-0.0751 28.55938,2.53224 41.26083,7.24431 12.70145,4.71207 24.16709,11.5339 33.81555,20.03646 9.64847,8.50257 17.47884,18.68937 22.90117,30.21241 5.42232,11.52304 8.43889,24.38332 8.44035,38.28317 z"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#gopher-eye);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||||
|
<circle
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient4319);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
id="path4828"
|
||||||
|
cx="458.07443"
|
||||||
|
cy="316.13431"
|
||||||
|
r="30.809652" />
|
||||||
|
<circle
|
||||||
|
r="15.152287"
|
||||||
|
cy="301.99216"
|
||||||
|
cx="444.43738"
|
||||||
|
id="circle4830"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#gopher-eye);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
transform="matrix(-0.49821858,-0.255998,-0.255998,0.49821858,841.05915,359.59091)"
|
||||||
|
id="g4822">
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#gopher-lines);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m 544.2609,323.96628 c -5.95391,12.33766 -15.20034,24.2228 -25.89846,35.91934 -10.69814,11.69654 -22.74349,23.28172 -34.52447,34.21851 -11.78099,10.93679 -23.27607,21.15489 -34.23709,29.30247 -10.96102,8.14759 -21.47285,14.18083 -32.04267,16.95199 -10.56982,2.77117 -20.29711,2.02561 -29.30402,-1.67713 -9.00692,-3.70274 -20.58076,-7.76561 -27.66538,-16.71749 -7.08461,-8.95188 -12.84054,-20.18257 -16.5035,-33.03389 -3.66297,-12.85133 -5.229,-27.32914 -3.92417,-42.72858 1.30484,-15.39944 5.36688,-30.24976 11.81788,-43.75488 6.45101,-13.5051 15.29008,-25.65823 26.00811,-35.78271 10.71803,-10.12447 28.44246,-20.29305 42.24879,-25.86698 13.80633,-5.57394 28.83304,-8.62768 44.20973,-8.80364 15.3767,-0.17594 29.62737,2.52591 41.94358,7.37479 12.31622,4.84887 22.69735,11.85058 30.35956,20.34718 7.66222,8.49661 12.60139,18.48263 14.06496,29.34879 1.4636,10.86615 -0.59894,22.56457 -6.55285,34.90223 z"
|
||||||
|
id="path4824"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="sssssssssssssssss" />
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m 538.18032,322.65868 c -5.17728,11.63182 -13.27733,23.10077 -22.96883,34.40428 -9.69151,11.30351 -20.93897,22.46482 -32.34413,32.7753 -11.40514,10.31051 -22.90789,19.71873 -33.85893,27.13351 -10.95103,7.41476 -21.39599,12.82014 -31.59528,15.28718 -10.19931,2.46703 -19.30202,1.76338 -27.56839,-1.62958 -8.26637,-3.39295 -19.13397,-6.9512 -25.3913,-15.16185 -6.25732,-8.21068 -11.24381,-18.53447 -14.30417,-30.37519 -3.06035,-11.84072 -4.18965,-25.20221 -2.68634,-39.42576 1.5033,-14.22354 5.50837,-27.94818 11.67956,-40.43838 6.17119,-12.4902 14.50792,-23.74111 24.54768,-33.13895 10.03978,-9.39782 26.99021,-19.0621 39.83566,-24.2929 12.84546,-5.2308 26.78412,-8.15811 41.0009,-8.45853 14.21678,-0.30038 27.34319,2.03758 38.64284,6.33106 11.29965,4.29349 20.7704,10.54463 27.74089,18.16875 6.97048,7.62413 11.43794,16.6127 12.81335,26.51165 1.37541,9.89894 -0.36624,20.67759 -5.54351,32.30941 z"
|
||||||
|
id="path4826"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="sssssssssssssssss" />
|
||||||
|
<circle
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient4321);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
id="path4828-0"
|
||||||
|
cx="438.70038"
|
||||||
|
cy="219.30804"
|
||||||
|
r="27.721321"
|
||||||
|
transform="matrix(0.98640333,0.16434257,-0.16434257,0.98640333,0,0)" />
|
||||||
|
<circle
|
||||||
|
r="13.633434"
|
||||||
|
cy="205.95601"
|
||||||
|
cx="431.24106"
|
||||||
|
id="circle4830-3"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
transform="matrix(0.98640333,0.16434257,-0.16434257,0.98640333,0,0)" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer7"
|
||||||
|
inkscape:label="gopher-mouth"
|
||||||
|
style="display:inline"
|
||||||
|
sodipodi:insensitive="true"
|
||||||
|
transform="translate(-15.732722,-256.54886)">
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#2e3436;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m 477.59321,477.72343 -6.36763,0.0828 -3.71113,-0.0821 c -1.18372,-0.0262 -2.23819,0.53559 -3.00662,1.36379 -0.76845,0.82822 -1.14658,1.97521 -1.32551,3.22687 l -1.01303,7.08562 -1.40711,7.111 c -0.25342,1.28069 0.0841,2.40965 0.70518,3.23132 0.6211,0.82165 1.57363,1.28978 2.69674,1.31649 l 3.7446,0.0891 7.40657,-0.17258 c 1.42055,-0.0331 2.74014,-0.58514 3.70785,-1.43299 0.96771,-0.84787 1.54004,-2.00084 1.65553,-3.2592 l 0.6476,-7.05621 0.52522,-7.04505 c 0.0935,-1.25398 -0.46676,-2.37726 -1.25366,-3.18163 -0.78689,-0.80437 -1.85738,-1.2842 -3.00457,-1.27716 z"
|
||||||
|
id="rect4659"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="scssscssscssscsss" />
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m 476.43064,479.86835 -5.19684,0.0698 -2.47497,-0.10149 c -0.94018,-0.0386 -1.80825,0.43586 -2.46124,1.11384 -0.65298,0.67797 -1.03424,1.61771 -1.21175,2.64338 l -1.0026,5.79325 -1.25494,5.80832 c -0.22406,1.03701 0.002,1.97056 0.48938,2.64162 0.48783,0.67105 1.26653,1.03411 2.19892,1.07115 l 2.54193,0.101 5.88547,-0.12754 c 1.11447,-0.0242 2.17518,-0.47212 2.97321,-1.1643 0.79803,-0.69218 1.30904,-1.6349 1.43939,-2.66511 l 0.73009,-5.77006 0.63032,-5.76301 c 0.11259,-1.02637 -0.28558,-1.94744 -0.89178,-2.6062 -0.60618,-0.65877 -1.45658,-1.05733 -2.39458,-1.04471 z"
|
||||||
|
id="rect4661"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="scssscssscssscsss" />
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#gopher-lines);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m 447.45177,471.71537 c 0.17729,2.27145 1.57656,4.32647 3.56538,6.17684 1.98881,1.85037 4.73553,3.49055 7.9169,4.83408 3.18137,1.34353 6.76993,2.37673 10.40491,2.92876 3.63499,0.55204 7.31771,0.61337 10.93742,0.17695 3.61969,-0.43645 6.8614,-1.30517 9.67542,-2.37849 2.81402,-1.07332 5.17844,-2.3467 7.04073,-3.75925 1.86231,-1.41254 3.23922,-2.97722 4.10853,-4.72358 0.86932,-1.74636 1.22997,-3.67959 0.91461,-5.76285 -0.31535,-2.08326 -1.29186,-4.11481 -2.79935,-5.98131 -1.5075,-1.86649 -3.53491,-3.56576 -5.91642,-4.97983 -2.3815,-1.41407 -5.11304,-2.54212 -8.12844,-3.28158 -3.0154,-0.73946 -6.31783,-1.09096 -9.93094,-0.97174 -3.6131,0.11924 -7.2186,0.69446 -10.6419,1.64517 -3.4233,0.95069 -6.6496,2.2832 -9.33875,3.91065 -2.68913,1.62746 -4.89892,3.50256 -6.18894,5.61926 -1.32139,2.16817 -1.77021,4.61153 -1.61916,6.54692 z"
|
||||||
|
id="ellipse4650"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="sssssssssssssssss" />
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient4265);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m 455.1011,471.20532 c 0.31019,1.80429 1.36577,3.48937 2.98663,4.99917 1.62086,1.5098 3.80505,2.84719 6.28703,3.91437 2.48197,1.06719 5.24944,1.8562 8.07117,2.27071 2.82174,0.4145 5.70079,0.45265 8.53169,0.10713 2.83089,-0.34553 5.35911,-1.02976 7.553,-1.90451 2.19389,-0.87475 4.04484,-1.93848 5.497,-3.12538 1.45217,-1.1869 2.50911,-2.50179 3.13219,-3.93394 0.62308,-1.43214 0.81446,-2.98543 0.48985,-4.63056 -0.32461,-1.64514 -1.13916,-3.22548 -2.3414,-4.6674 -1.20224,-1.44192 -2.78948,-2.74346 -4.65903,-3.82078 -1.86955,-1.07733 -4.01937,-1.92982 -6.38974,-2.4811 -2.37037,-0.55129 -4.96168,-0.80162 -7.76722,-0.68542 -2.80553,0.11621 -5.57317,0.58631 -8.1874,1.34158 -2.61424,0.75528 -5.07126,1.79757 -7.14628,3.06167 -2.07504,1.26412 -3.75959,2.75051 -4.8326,4.37276 -1.07302,1.62225 -1.53509,3.37741 -1.22489,5.1817 z"
|
||||||
|
id="ellipse4652"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="sssssssssssssssss" />
|
||||||
|
<path
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#gopher-lines);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="m 465.13937,460.19393 c 0.45232,1.29294 1.43586,2.44115 2.79664,3.4102 1.36078,0.96906 3.0934,1.76079 4.97332,2.36791 1.87992,0.60712 3.89927,1.0315 5.87533,1.25741 1.97606,0.2259 3.90879,0.25223 5.71982,0.052 1.81102,-0.20028 3.33955,-0.60742 4.63321,-1.17435 1.29367,-0.56695 2.35232,-1.29343 3.18646,-2.14861 0.83413,-0.85519 1.44471,-1.8405 1.79916,-2.93195 0.35445,-1.09146 0.45213,-2.29028 0.21175,-3.55738 -0.24038,-1.2671 -0.80099,-2.48156 -1.64917,-3.57911 -0.84818,-1.09755 -1.9831,-2.07741 -3.35494,-2.8723 -1.37184,-0.7949 -2.98056,-1.40441 -4.76729,-1.7664 -1.78672,-0.36199 -3.75169,-0.47615 -5.82322,-0.29097 -2.07153,0.18518 -4.05358,0.65136 -5.84566,1.3298 -1.79207,0.67844 -3.39432,1.56902 -4.69144,2.60198 -1.29713,1.03296 -2.28898,2.20893 -2.84443,3.45293 -0.55546,1.24399 -0.67186,2.55593 -0.21954,3.84888 z"
|
||||||
|
id="path4648"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="sssssssssssssssss" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer12"
|
||||||
|
inkscape:label="gopher-hands"
|
||||||
|
style="display:inline"
|
||||||
|
sodipodi:insensitive="true"
|
||||||
|
transform="translate(-15.732722,-256.54886)">
|
||||||
|
<g
|
||||||
|
id="g4533"
|
||||||
|
transform="matrix(-0.28489616,-0.34500545,-0.42832103,0.44649678,715.99765,474.46827)">
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="sssssssssssssssss"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="ellipse4523"
|
||||||
|
d="m 423.50332,581.83521 c -0.004,4.40048 -1.19837,7.58856 -3.37524,9.82844 -2.17687,2.23987 -5.33154,3.55156 -9.14619,4.44292 -3.81465,0.89135 -8.28246,1.39523 -13.05675,1.83828 -4.77428,0.44304 -9.85163,0.79076 -14.95001,1.09928 -5.09838,0.30851 -9.94541,0.34741 -14.40217,0.0862 -4.45676,-0.26122 -8.52354,-0.79908 -11.99271,-1.71189 -3.46915,-0.91282 -6.33736,-2.21356 -8.3562,-4.09288 -2.01885,-1.87935 -3.18709,-4.34475 -3.25466,-7.51083 -0.0676,-3.16607 0.9983,-5.4859 2.92534,-7.0838 1.92703,-1.5979 4.71248,-2.46394 8.09977,-2.84688 3.38729,-0.38293 7.37282,-0.28336 11.77044,-0.16051 4.39762,0.12284 9.21051,0.23456 14.33166,-0.12202 5.12115,-0.35659 10.27171,-1.47349 15.16022,-2.54099 4.88852,-1.06749 9.50395,-2.05149 13.43823,-2.27114 3.9343,-0.21967 7.17754,0.32322 9.39823,2.04598 2.22069,1.72276 3.41425,4.59936 3.41004,8.99986 z"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient4273);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="ssscsscssssssssssssssssssssccsss"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4521"
|
||||||
|
d="m 411.91406,568.54883 c -3.75011,-0.0271 -8.08701,0.53975 -12.76172,1.28711 -5.34251,0.85413 -11.10706,1.92059 -17.00976,2.32617 -5.9027,0.40562 -11.41103,0.38326 -16.44727,0.41406 -5.03624,0.0309 -9.6045,0.1607 -13.50781,0.85938 -3.9033,0.69867 -7.13503,1.96743 -9.4082,3.96875 -2.27316,2.00131 -3.58535,4.71676 -3.65235,8.17578 -0.067,3.45901 1.21821,6.3073 3.54297,8.58008 2.32476,2.27278 5.68789,3.9795 9.76172,5.25 4.07385,1.27051 8.85237,2.11894 14.05664,2.59765 5.20427,0.47871 10.83381,0.56134 16.70313,0.22266 5.86931,-0.33868 11.47146,-0.78653 16.60547,-1.34961 5.13399,-0.56309 9.79334,-1.22365 13.70703,-2.34375 1.48913,-0.4262 2.86677,-0.9287 4.12695,-1.51953 2.54507,-1.19325 2.05015,-6.17249 -0.0996,-4.54102 -1.99172,1.51153 -4.55969,2.50355 -7.57031,3.20703 -3.66893,0.85731 -7.96668,1.34146 -12.5586,1.76758 -4.59191,0.42612 -9.47527,0.75991 -14.3789,1.05664 -4.90363,0.29673 -9.56506,0.33523 -13.85156,0.084 -4.28652,-0.25124 -8.19851,-0.76855 -11.53516,-1.64649 -3.33664,-0.87795 -6.09539,-2.12996 -8.03711,-3.9375 -1.94173,-1.80756 -3.06587,-4.17751 -3.13086,-7.22265 -0.065,-3.04513 0.96102,-5.2776 2.81445,-6.81446 1.85342,-1.53686 4.53117,-2.36997 7.78907,-2.73828 3.2579,-0.36831 7.09262,-0.27244 11.32226,-0.1543 4.22963,0.11816 8.85767,0.22578 13.7832,-0.11718 4.92553,-0.34297 9.88026,-1.41664 14.58204,-2.44336 4.70178,-1.02671 9.13982,-1.97234 12.92382,-2.1836 0.473,-0.0264 0.93707,-0.0422 1.38868,-0.0449 1.16046,-0.007 2.25007,0.0442 3.25,0.23633 1.15313,0.22156 2.31543,-2.86146 -0.83789,-2.92773 -0.51177,-0.0108 -1.03459,-0.045 -1.57032,-0.0488 z"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#gopher-lines);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer3"
|
||||||
|
inkscape:label="cape-front"
|
||||||
|
style="display:inline"
|
||||||
|
transform="translate(-15.732722,-256.54886)">
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cssscscc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4248"
|
||||||
|
d="m 250.62773,531.91504 c -9.09672,21.35801 -15.29674,29.07226 -30.27188,44.83759 -11.50237,12.10933 -28.85117,24.46609 -43.81134,39.61682 -13.55246,13.72509 -26.12338,21.00434 -64.22257,32.01103 -11.97434,3.45934 -44.031036,6.55017 -51.472472,37.30246 C 107.21772,654.7909 183.17617,662.32228 228.40418,636.09787 266.34279,614.10005 317.82474,552.6315 355.9453,547.7268 284.49621,547.05928 263.34291,542.49874 250.62773,531.91504 Z"
|
||||||
|
style="display:inline;fill:#019833;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||||
|
<path
|
||||||
|
style="fill:#019833;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 473.29262,543.99873 73.7751,-5.10117 c 0,0 2.29258,1.0455 2.68673,2.11494 7.36409,19.98076 -12.72148,60.84328 -12.72148,60.84328 0,-2.97132 13.53121,-43.94425 -5.91529,-53.46522 -16.4456,-8.05173 -38.16124,-2.06803 -57.82506,-4.39183 z"
|
||||||
|
id="path4265"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ccscsc" />
|
||||||
|
<path
|
||||||
|
style="display:inline;fill:#019432;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 249.90625,533.57227 c -8.70868,20.08478 -14.97837,27.83833 -29.55078,43.17968 -11.50237,12.10933 -28.85038,24.46646 -43.81055,39.61719 -13.55246,13.72509 -26.12346,21.00503 -64.22265,32.01172 -10.63128,3.07133 -37.077893,5.86957 -48.087895,27.97656 2.731585,-3.48747 7.206694,-4.8761 9.881319,-8.70029 4.506995,-6.44411 60.824806,-11.61546 75.673426,-21.06752 9.77176,-6.22033 32.61216,-17.69963 44.08393,-25.40211 11.47178,-7.70248 50.16856,-39.82139 59.98047,-41.62695 30.99143,-5.70295 56.04882,-31.95703 56.04882,-31.95703 0,0 -5.76873,-1.34099 -7.30468,-1.69727 -26.4653,-1.9743 -39.57284,-5.58234 -48.29883,-11.28125 -1.77957,-0.42346 -3.78649,-0.89828 -4.39258,-1.05273 z"
|
||||||
|
id="path4280"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cssscsssscccc" />
|
||||||
|
<path
|
||||||
|
style="fill:#01a939;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 250.88543,527.29897 c 4.9284,1.23444 7.57648,5.23948 12.39942,6.83706 14.83134,4.91283 28.22069,8.13985 43.80356,9.2706 19.18619,1.39223 40.09821,1.50171 59.33179,1.15882 36.63136,-0.65304 73.4946,-1.92414 110.08831,-3.70824 19.9513,-0.97271 40.58394,-2.2893 60.49061,-3.94 3.86874,-0.3208 7.97563,-6.05622 11.58825,-4.6353 2.39418,0.94168 2.01049,3.29975 2.64058,5.79412 2.44082,4.93143 0.14511,6.64447 -5.65353,7.64824 -19.43937,3.05253 -39.20884,3.55847 -58.86827,4.40354 -48.01128,2.06378 -96.10464,2.11621 -144.15772,1.62235 -17.00379,-0.17475 -34.11943,0.52285 -50.98827,-1.62235 -13.27515,-1.68819 -26.90453,-3.45163 -39.16825,-8.80707 -4.12399,-1.80091 -7.99437,-2.72852 -8.97266,-7.12095 -0.30759,-1.38101 1.19417,-2.17728 1.88173,-3.29956 0.57446,-0.93767 0.21317,-2.26036 1.23886,-2.84803 1.34064,-0.76812 2.84679,-1.12864 4.34559,-0.75323 z"
|
||||||
|
id="path4267"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="sssssssccssssssss" />
|
||||||
|
<path
|
||||||
|
style="fill:#019d35;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 245.9043,528.82812 c -0.24767,0.63868 -0.21658,1.44068 -0.60352,2.07227 -0.68756,1.12228 -2.18845,1.91782 -1.88086,3.29883 0.97829,4.39243 4.84867,5.32018 8.97266,7.12109 12.26372,5.35544 25.89282,7.11845 39.16797,8.80664 16.86884,2.1452 33.98449,1.4483 50.98828,1.62305 48.05308,0.49386 96.14692,0.44073 144.1582,-1.62305 19.65943,-0.84507 39.42782,-1.34981 58.86719,-4.40234 5.79864,-1.00377 8.09512,-2.71701 5.6543,-7.64844 -0.0557,-0.22031 -0.0962,-0.43699 -0.13868,-0.65429 0.48647,4.64963 -6.66572,4.9037 -11.87478,5.92187 -33.64204,6.57569 -68.48165,3.5437 -102.75586,4.0957 -42.87828,0.69057 -93.34812,6.52037 -135.57053,-0.98242 -17.79033,-3.16129 -43.90403,-10.17243 -54.98437,-17.62891 z"
|
||||||
|
id="path4340"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="csssssscccsssc" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer8"
|
||||||
|
inkscape:label="vim"
|
||||||
|
transform="translate(-15.732722,-256.54886)">
|
||||||
|
<g
|
||||||
|
id="g4330">
|
||||||
|
<rect
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#005d04;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
id="rect4293"
|
||||||
|
width="194.71968"
|
||||||
|
height="194.71968"
|
||||||
|
x="-29.381023"
|
||||||
|
y="744.44128"
|
||||||
|
transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,0,0)" />
|
||||||
|
<rect
|
||||||
|
transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,0,0)"
|
||||||
|
y="753.35699"
|
||||||
|
x="-20.465342"
|
||||||
|
height="176.88821"
|
||||||
|
width="176.88821"
|
||||||
|
id="rect4283"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#019833;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||||
|
<g
|
||||||
|
id="text4285"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:203.27047729px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;display:inline;fill:#fefefe;fill-opacity:1;stroke:#005d04;stroke-width:4;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
transform="matrix(1.0880646,0,-0.29154603,1.0880646,-528.83975,-369.0604)">
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cccccccccccccccsc"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4324"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:800;font-stretch:normal;font-family:Eczar;-inkscape-font-specification:'Eczar Ultra-Bold';fill:#fefefe;fill-opacity:1;stroke:#005d04;stroke-width:5.01092911;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 202.34975,1029.0537 -56.02157,-157.11507 -17.82505,-3.05571 0.25466,-14.0054 89.88914,0 1.52787,8.1486 c -2.7162,2.2069 -5.77193,4.32893 -9.16717,6.36609 -3.22549,2.03714 -6.70561,3.98941 -10.44038,5.85679 l 26.38345,87.17129 39.56921,-89.71773 -21.89934,-3.81964 0.25464,-14.0054 72.06411,0 -68.4991,168.82868 0.25465,0.2547 c -6.28122,1.0184 -13.49612,1.9522 -21.6447,2.8011 -8.14859,0.8487 -16.38207,1.6126 -24.70042,2.2917 z" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<use
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#g4330"
|
||||||
|
id="use4338"
|
||||||
|
transform="matrix(0.4546439,-0.10745401,-0.02175104,0.44922994,711.99298,282.73776)"
|
||||||
|
width="100%"
|
||||||
|
height="100%" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer4"
|
||||||
|
inkscape:label="palette"
|
||||||
|
style="display:inline"
|
||||||
|
sodipodi:insensitive="true"
|
||||||
|
transform="translate(-15.732722,-256.54886)">
|
||||||
|
<rect
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient4168);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21052647;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
id="rect4162"
|
||||||
|
width="40.789474"
|
||||||
|
height="40.789474"
|
||||||
|
x="779.60529"
|
||||||
|
y="21.967466" />
|
||||||
|
<rect
|
||||||
|
y="21.967466"
|
||||||
|
x="824.60529"
|
||||||
|
height="40.789474"
|
||||||
|
width="40.789474"
|
||||||
|
id="rect4170"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient4180);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21052742;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||||
|
<rect
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#bce8ff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21052647;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
id="rect4208"
|
||||||
|
width="40.789474"
|
||||||
|
height="40.789474"
|
||||||
|
x="779.60529"
|
||||||
|
y="86.967468" />
|
||||||
|
<rect
|
||||||
|
y="-127.75694"
|
||||||
|
x="824.60529"
|
||||||
|
height="40.789474"
|
||||||
|
width="40.789474"
|
||||||
|
id="rect4223"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#abccd9;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21052647;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
transform="scale(1,-1)" />
|
||||||
|
<rect
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c3b0cb;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21052647;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
id="rect4227"
|
||||||
|
width="40.789474"
|
||||||
|
height="40.789474"
|
||||||
|
x="779.60529"
|
||||||
|
y="131.96747" />
|
||||||
|
<rect
|
||||||
|
y="131.96747"
|
||||||
|
x="824.60529"
|
||||||
|
height="40.789474"
|
||||||
|
width="40.789474"
|
||||||
|
id="rect4231"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#e1d0cb;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21052647;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||||
|
<rect
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#f5c3d2;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21052647;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
id="rect4233"
|
||||||
|
width="40.789474"
|
||||||
|
height="40.789474"
|
||||||
|
x="869.60529"
|
||||||
|
y="131.96747" />
|
||||||
|
<rect
|
||||||
|
y="176.96747"
|
||||||
|
x="779.60529"
|
||||||
|
height="40.789474"
|
||||||
|
width="40.789474"
|
||||||
|
id="rect4248"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#cec4ad;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21052647;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||||
|
<rect
|
||||||
|
transform="scale(1,-1)"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#96d6ff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21052647;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
id="rect4263"
|
||||||
|
width="40.789474"
|
||||||
|
height="40.789474"
|
||||||
|
x="869.60529"
|
||||||
|
y="-127.75694" />
|
||||||
|
<rect
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#f2f2ce;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21052647;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
id="rect4267"
|
||||||
|
width="40.789474"
|
||||||
|
height="40.789474"
|
||||||
|
x="824.60529"
|
||||||
|
y="176.96747" />
|
||||||
|
<rect
|
||||||
|
y="-327.75693"
|
||||||
|
x="779.60529"
|
||||||
|
height="40.789474"
|
||||||
|
width="40.789474"
|
||||||
|
id="rect4280"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#24b8eb;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21052647;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
transform="scale(1,-1)" />
|
||||||
|
<rect
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#8aa9ff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21052647;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
id="rect4284"
|
||||||
|
width="40.789474"
|
||||||
|
height="40.789474"
|
||||||
|
x="824.60529"
|
||||||
|
y="286.96747" />
|
||||||
|
<rect
|
||||||
|
y="331.96747"
|
||||||
|
x="779.60529"
|
||||||
|
height="40.789474"
|
||||||
|
width="40.789474"
|
||||||
|
id="rect4297"
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d4edf1;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21052647;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||||
|
<rect
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#394d54;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21052647;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
id="rect4301"
|
||||||
|
width="40.789474"
|
||||||
|
height="40.789474"
|
||||||
|
x="779.60529"
|
||||||
|
y="241.96747" />
|
||||||
|
<rect
|
||||||
|
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d6e2ff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:9.21052647;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
id="rect4303"
|
||||||
|
width="40.789474"
|
||||||
|
height="40.789474"
|
||||||
|
x="824.60529"
|
||||||
|
y="331.96747" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 84 KiB |
152
sources_non_forked/vim-go/autoload/ctrlp/decls.vim
Normal file
152
sources_non_forked/vim-go/autoload/ctrlp/decls.vim
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
let s:go_decls_var = {
|
||||||
|
\ 'init': 'ctrlp#decls#init()',
|
||||||
|
\ 'exit': 'ctrlp#decls#exit()',
|
||||||
|
\ 'enter': 'ctrlp#decls#enter()',
|
||||||
|
\ 'accept': 'ctrlp#decls#accept',
|
||||||
|
\ 'lname': 'declarations',
|
||||||
|
\ 'sname': 'decls',
|
||||||
|
\ 'type': 'tabs',
|
||||||
|
\}
|
||||||
|
|
||||||
|
if exists('g:ctrlp_ext_vars') && !empty(g:ctrlp_ext_vars)
|
||||||
|
let g:ctrlp_ext_vars = add(g:ctrlp_ext_vars, s:go_decls_var)
|
||||||
|
else
|
||||||
|
let g:ctrlp_ext_vars = [s:go_decls_var]
|
||||||
|
endif
|
||||||
|
|
||||||
|
function! ctrlp#decls#init() abort
|
||||||
|
cal s:enable_syntax()
|
||||||
|
return s:decls
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ctrlp#decls#exit() abort
|
||||||
|
unlet! s:decls s:target
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" The action to perform on the selected string
|
||||||
|
" Arguments:
|
||||||
|
" a:mode the mode that has been chosen by pressing <cr> <c-v> <c-t> or <c-x>
|
||||||
|
" the values are 'e', 'v', 't' and 'h', respectively
|
||||||
|
" a:str the selected string
|
||||||
|
function! ctrlp#decls#accept(mode, str) abort
|
||||||
|
try
|
||||||
|
let vals = matchlist(a:str, '|\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)|')
|
||||||
|
|
||||||
|
" i.e: main.go
|
||||||
|
let filename = vals[1]
|
||||||
|
let line = vals[2]
|
||||||
|
let col = vals[3]
|
||||||
|
|
||||||
|
" i.e: /Users/fatih/vim-go/main.go
|
||||||
|
let filepath = fnamemodify(filename, ":p")
|
||||||
|
|
||||||
|
" acceptile is a very versatile method,
|
||||||
|
call ctrlp#acceptfile(a:mode, filepath)
|
||||||
|
call cursor(line, col)
|
||||||
|
silent! norm! zvzz
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ctrlp#decls#enter() abort
|
||||||
|
let s:decls = []
|
||||||
|
|
||||||
|
let l:cmd = ['motion',
|
||||||
|
\ '-format', 'vim',
|
||||||
|
\ '-mode', 'decls',
|
||||||
|
\ '-include', go#config#DeclsIncludes(),
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
call go#cmd#autowrite()
|
||||||
|
|
||||||
|
if s:mode == 0
|
||||||
|
" current file mode
|
||||||
|
let l:fname = expand("%:p")
|
||||||
|
if exists('s:target')
|
||||||
|
let l:fname = s:target
|
||||||
|
endif
|
||||||
|
|
||||||
|
let cmd += ['-file', l:fname]
|
||||||
|
else
|
||||||
|
" all functions mode
|
||||||
|
let l:dir = expand("%:p:h")
|
||||||
|
if exists('s:target')
|
||||||
|
let l:dir = s:target
|
||||||
|
endif
|
||||||
|
|
||||||
|
let cmd += ['-dir', l:dir]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let [l:out, l:err] = go#util#Exec(l:cmd)
|
||||||
|
if l:err
|
||||||
|
call go#util#EchoError(l:out)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let result = eval(out)
|
||||||
|
if type(result) != 4 || !has_key(result, 'decls')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let decls = result.decls
|
||||||
|
|
||||||
|
" find the maximum function name
|
||||||
|
let max_len = 0
|
||||||
|
for decl in decls
|
||||||
|
if len(decl.ident)> max_len
|
||||||
|
let max_len = len(decl.ident)
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
for decl in decls
|
||||||
|
" paddings
|
||||||
|
let space = " "
|
||||||
|
for i in range(max_len - len(decl.ident))
|
||||||
|
let space .= " "
|
||||||
|
endfor
|
||||||
|
|
||||||
|
call add(s:decls, printf("%s\t%s |%s:%s:%s|\t%s",
|
||||||
|
\ decl.ident . space,
|
||||||
|
\ decl.keyword,
|
||||||
|
\ fnamemodify(decl.filename, ":p"),
|
||||||
|
\ decl.line,
|
||||||
|
\ decl.col,
|
||||||
|
\ decl.full,
|
||||||
|
\))
|
||||||
|
endfor
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
function! s:enable_syntax() abort
|
||||||
|
if !(has('syntax') && exists('g:syntax_on'))
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
syntax match CtrlPIdent '\zs\h\+\ze\s'
|
||||||
|
syntax match CtrlPKeyword '\zs[^\t|]\+\ze|[^|]\+:\d\+:\d\+|'
|
||||||
|
syntax match CtrlPFilename '|\zs[^|]\+:\d\+:\d\+\ze|'
|
||||||
|
syntax match CtrlPSignature '\zs\t.*\ze$' contains=CtrlPKeyWord,CtrlPFilename
|
||||||
|
|
||||||
|
highlight link CtrlPIdent Function
|
||||||
|
highlight link CtrlPKeyword Keyword
|
||||||
|
highlight link CtrlPFilename SpecialComment
|
||||||
|
highlight link CtrlPSignature Comment
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
let s:id = g:ctrlp_builtins + len(g:ctrlp_ext_vars)
|
||||||
|
|
||||||
|
function! ctrlp#decls#cmd(mode, ...) abort
|
||||||
|
let s:mode = a:mode
|
||||||
|
if a:0 && !empty(a:1)
|
||||||
|
let s:target = a:1
|
||||||
|
endif
|
||||||
|
return s:id
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
155
sources_non_forked/vim-go/autoload/fzf/decls.vim
Normal file
155
sources_non_forked/vim-go/autoload/fzf/decls.vim
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
function! s:code(group, attr) abort
|
||||||
|
let code = synIDattr(synIDtrans(hlID(a:group)), a:attr, "cterm")
|
||||||
|
if code =~ '^[0-9]\+$'
|
||||||
|
return code
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:color(str, group) abort
|
||||||
|
let fg = s:code(a:group, "fg")
|
||||||
|
let bg = s:code(a:group, "bg")
|
||||||
|
let bold = s:code(a:group, "bold")
|
||||||
|
let italic = s:code(a:group, "italic")
|
||||||
|
let reverse = s:code(a:group, "reverse")
|
||||||
|
let underline = s:code(a:group, "underline")
|
||||||
|
let color = (empty(fg) ? "" : ("38;5;".fg)) .
|
||||||
|
\ (empty(bg) ? "" : (";48;5;".bg)) .
|
||||||
|
\ (empty(bold) ? "" : ";1") .
|
||||||
|
\ (empty(italic) ? "" : ";3") .
|
||||||
|
\ (empty(reverse) ? "" : ";7") .
|
||||||
|
\ (empty(underline) ? "" : ";4")
|
||||||
|
return printf("\x1b[%sm%s\x1b[m", color, a:str)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:sink(str) abort
|
||||||
|
if len(a:str) < 2
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
try
|
||||||
|
" we jump to the file directory so we can get the fullpath via fnamemodify
|
||||||
|
" below
|
||||||
|
let l:dir = go#util#Chdir(s:current_dir)
|
||||||
|
|
||||||
|
let vals = matchlist(a:str[1], '|\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)|')
|
||||||
|
|
||||||
|
" i.e: main.go
|
||||||
|
let filename = vals[1]
|
||||||
|
let line = vals[2]
|
||||||
|
let col = vals[3]
|
||||||
|
|
||||||
|
" i.e: /Users/fatih/vim-go/main.go
|
||||||
|
let filepath = fnamemodify(filename, ":p")
|
||||||
|
|
||||||
|
let cmd = get({'ctrl-x': 'split',
|
||||||
|
\ 'ctrl-v': 'vertical split',
|
||||||
|
\ 'ctrl-t': 'tabe'}, a:str[0], 'e')
|
||||||
|
execute cmd fnameescape(filepath)
|
||||||
|
call cursor(line, col)
|
||||||
|
silent! norm! zvzz
|
||||||
|
finally
|
||||||
|
"jump back to old dir
|
||||||
|
call go#util#Chdir(l:dir)
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:source(mode,...) abort
|
||||||
|
let s:current_dir = expand('%:p:h')
|
||||||
|
let ret_decls = []
|
||||||
|
|
||||||
|
let l:cmd = ['motion',
|
||||||
|
\ '-format', 'vim',
|
||||||
|
\ '-mode', 'decls',
|
||||||
|
\ '-include', go#config#DeclsIncludes(),
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
call go#cmd#autowrite()
|
||||||
|
|
||||||
|
if a:mode == 0
|
||||||
|
" current file mode
|
||||||
|
let l:fname = expand("%:p")
|
||||||
|
if a:0 && !empty(a:1)
|
||||||
|
let l:fname = a:1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let cmd += ['-file', l:fname]
|
||||||
|
else
|
||||||
|
" all functions mode
|
||||||
|
if a:0 && !empty(a:1)
|
||||||
|
let s:current_dir = a:1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:cmd += ['-dir', s:current_dir]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let [l:out, l:err] = go#util#Exec(l:cmd)
|
||||||
|
if l:err
|
||||||
|
call go#util#EchoError(l:out)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let result = eval(out)
|
||||||
|
if type(result) != 4 || !has_key(result, 'decls')
|
||||||
|
return ret_decls
|
||||||
|
endif
|
||||||
|
|
||||||
|
let decls = result.decls
|
||||||
|
|
||||||
|
" find the maximum function name
|
||||||
|
let max_len = 0
|
||||||
|
for decl in decls
|
||||||
|
if len(decl.ident)> max_len
|
||||||
|
let max_len = len(decl.ident)
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
for decl in decls
|
||||||
|
" paddings
|
||||||
|
let space = " "
|
||||||
|
for i in range(max_len - len(decl.ident))
|
||||||
|
let space .= " "
|
||||||
|
endfor
|
||||||
|
|
||||||
|
let pos = printf("|%s:%s:%s|",
|
||||||
|
\ fnamemodify(decl.filename, ":t"),
|
||||||
|
\ decl.line,
|
||||||
|
\ decl.col
|
||||||
|
\)
|
||||||
|
call add(ret_decls, printf("%s\t%s\t%s\t%s",
|
||||||
|
\ s:color(decl.ident . space, "goDeclsFzfFunction"),
|
||||||
|
\ s:color(decl.keyword, "goDeclsFzfKeyword"),
|
||||||
|
\ s:color(decl.full, "goDeclsFzfComment"),
|
||||||
|
\ s:color(pos, "goDeclsFzfSpecialComment"),
|
||||||
|
\))
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return sort(ret_decls)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
function! fzf#decls#cmd(...) abort
|
||||||
|
let normal_fg = s:code("Normal", "fg")
|
||||||
|
let normal_bg = s:code("Normal", "bg")
|
||||||
|
let cursor_fg = s:code("CursorLine", "fg")
|
||||||
|
let cursor_bg = s:code("CursorLine", "bg")
|
||||||
|
let colors = printf(" --color %s%s%s%s%s",
|
||||||
|
\ &background,
|
||||||
|
\ empty(normal_fg) ? "" : (",fg:".normal_fg),
|
||||||
|
\ empty(normal_bg) ? "" : (",bg:".normal_bg),
|
||||||
|
\ empty(cursor_fg) ? "" : (",fg+:".cursor_fg),
|
||||||
|
\ empty(cursor_bg) ? "" : (",bg+:".cursor_bg),
|
||||||
|
\)
|
||||||
|
call fzf#run(fzf#wrap('GoDecls', {
|
||||||
|
\ 'source': call('<sid>source', a:000),
|
||||||
|
\ 'options': printf('-n 1 --with-nth 1,2 --delimiter=$''\t'' --preview "echo {3}" --preview-window "wrap" --ansi --prompt "GoDecls> " --expect=ctrl-t,ctrl-v,ctrl-x%s', colors),
|
||||||
|
\ 'sink*': function('s:sink')
|
||||||
|
\ }))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
35
sources_non_forked/vim-go/autoload/go/alternate.vim
Normal file
35
sources_non_forked/vim-go/autoload/go/alternate.vim
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
" Test alternates between the implementation of code and the test code.
|
||||||
|
function! go#alternate#Switch(bang, cmd) abort
|
||||||
|
let file = expand('%')
|
||||||
|
if empty(file)
|
||||||
|
call go#util#EchoError("no buffer name")
|
||||||
|
return
|
||||||
|
elseif file =~# '^\f\+_test\.go$'
|
||||||
|
let l:root = split(file, '_test.go$')[0]
|
||||||
|
let l:alt_file = l:root . ".go"
|
||||||
|
elseif file =~# '^\f\+\.go$'
|
||||||
|
let l:root = split(file, ".go$")[0]
|
||||||
|
let l:alt_file = l:root . '_test.go'
|
||||||
|
else
|
||||||
|
call go#util#EchoError("not a go file")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
if !filereadable(alt_file) && !bufexists(alt_file) && !a:bang
|
||||||
|
call go#util#EchoError("couldn't find ".alt_file)
|
||||||
|
return
|
||||||
|
elseif empty(a:cmd)
|
||||||
|
execute ":" . go#config#AlternateMode() . " " . alt_file
|
||||||
|
else
|
||||||
|
execute ":" . a:cmd . " " . alt_file
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
76
sources_non_forked/vim-go/autoload/go/asmfmt.vim
Normal file
76
sources_non_forked/vim-go/autoload/go/asmfmt.vim
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
" asmfmt.vim: Vim command to format Go asm files with asmfmt
|
||||||
|
" (github.com/klauspost/asmfmt).
|
||||||
|
"
|
||||||
|
" This filetype plugin adds new commands for asm buffers:
|
||||||
|
"
|
||||||
|
" :Fmt
|
||||||
|
"
|
||||||
|
" Filter the current asm buffer through asmfmt.
|
||||||
|
" It tries to preserve cursor position and avoids
|
||||||
|
" replacing the buffer with stderr output.
|
||||||
|
"
|
||||||
|
" Options:
|
||||||
|
"
|
||||||
|
" g:go_asmfmt_autosave [default=0]
|
||||||
|
"
|
||||||
|
" Flag to automatically call :Fmt when file is saved.
|
||||||
|
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
let s:got_fmt_error = 0
|
||||||
|
|
||||||
|
" This is a trimmed-down version of the logic in fmt.vim.
|
||||||
|
|
||||||
|
function! go#asmfmt#Format() abort
|
||||||
|
" Save state.
|
||||||
|
let l:curw = winsaveview()
|
||||||
|
|
||||||
|
" Write the current buffer to a tempfile.
|
||||||
|
let l:tmpname = tempname()
|
||||||
|
call writefile(go#util#GetLines(), l:tmpname)
|
||||||
|
|
||||||
|
" Run asmfmt.
|
||||||
|
let [l:out, l:err] = go#util#Exec(['asmfmt', '-w', l:tmpname])
|
||||||
|
if l:err
|
||||||
|
call go#util#EchoError(l:out)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Remove undo point caused by BufWritePre.
|
||||||
|
try | silent undojoin | catch | endtry
|
||||||
|
|
||||||
|
" Replace the current file with the temp file; then reload the buffer.
|
||||||
|
let old_fileformat = &fileformat
|
||||||
|
|
||||||
|
" save old file permissions
|
||||||
|
let original_fperm = getfperm(expand('%'))
|
||||||
|
call rename(l:tmpname, expand('%'))
|
||||||
|
|
||||||
|
" restore old file permissions
|
||||||
|
call setfperm(expand('%'), original_fperm)
|
||||||
|
silent edit!
|
||||||
|
let &fileformat = old_fileformat
|
||||||
|
let &syntax = &syntax
|
||||||
|
|
||||||
|
" Restore the cursor/window positions.
|
||||||
|
call winrestview(l:curw)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#asmfmt#ToggleAsmFmtAutoSave() abort
|
||||||
|
if go#config#AsmfmtAutosave()
|
||||||
|
call go#config#SetAsmfmtAutosave(1)
|
||||||
|
call go#util#EchoProgress("auto asmfmt enabled")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
call go#config#SetAsmfmtAutosave(0)
|
||||||
|
call go#util#EchoProgress("auto asmfmt disabled")
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
203
sources_non_forked/vim-go/autoload/go/auto.vim
Normal file
203
sources_non_forked/vim-go/autoload/go/auto.vim
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
function! go#auto#template_autocreate()
|
||||||
|
if !go#config#TemplateAutocreate() || !&modifiable
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" create new template from scratch
|
||||||
|
call go#template#create()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#auto#complete_done()
|
||||||
|
if &omnifunc isnot 'go#complete#Complete'
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
call s:echo_go_info()
|
||||||
|
call s:ExpandSnippet()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:ExpandSnippet() abort
|
||||||
|
if !exists('v:completed_item') || empty(v:completed_item) || !go#config#GoplsUsePlaceholders()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
let l:engine = go#config#SnippetEngine()
|
||||||
|
|
||||||
|
if l:engine is 'ultisnips'
|
||||||
|
if !get(g:, 'did_plugin_ultisnips', 0)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
" the snippet may have a '{\}' in it. For UltiSnips, that should be spelled
|
||||||
|
" \{}. fmt.Printf is such a snippet that can be used to demonstrate.
|
||||||
|
let l:snippet = substitute(v:completed_item.word, '{\\}', '\{}', 'g')
|
||||||
|
call UltiSnips#Anon(l:snippet, v:completed_item.word, '', 'i')
|
||||||
|
" elseif l:engine is 'neosnippet'
|
||||||
|
" " TODO(bc): make the anonymous expansion for neosnippet work
|
||||||
|
"
|
||||||
|
" if !get(g:, 'loaded_neosnippet') is 1
|
||||||
|
" return
|
||||||
|
" endif
|
||||||
|
"
|
||||||
|
" " neosnippet#anonymous doesn't need a trigger, so replace the
|
||||||
|
" " completed_item.word with an empty string before calling neosnippet#anonymous
|
||||||
|
" let l:snippet = substitute(v:completed_item.word, '{\\}', '\{\}', 'g')
|
||||||
|
" call setline('.', substitute(getline('.'), substitute(v:completed_item.word, '\', '\\', 'g'), '', ''))
|
||||||
|
" call neosnippet#anonymous(l:snippet)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:echo_go_info()
|
||||||
|
if !go#config#EchoGoInfo()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !exists('v:completed_item') || empty(v:completed_item)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let item = v:completed_item
|
||||||
|
|
||||||
|
if !has_key(item, "user_data")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if empty(item.user_data)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
redraws! | echo "vim-go: " | echohl Function | echon item.user_data | echohl None
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
let s:timer_id = 0
|
||||||
|
|
||||||
|
" go#auto#update_autocmd() will be called on BufEnter,CursorHold. This
|
||||||
|
" configures the augroup according to conditions below.
|
||||||
|
"
|
||||||
|
" | # | has_timer | should_enable | do |
|
||||||
|
" |---|-----------|---------------|------------------------------------|
|
||||||
|
" | 1 | false | false | return early |
|
||||||
|
" | 2 | true | true | return early |
|
||||||
|
" | 3 | true | false | clear the group and stop the timer |
|
||||||
|
" | 4 | false | true | configure the group |
|
||||||
|
function! go#auto#update_autocmd()
|
||||||
|
let has_timer = get(b:, 'has_timer')
|
||||||
|
let should_enable = go#config#AutoTypeInfo() || go#config#AutoSameids()
|
||||||
|
if (!has_timer && !should_enable) || (has_timer && should_enable)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_timer
|
||||||
|
augroup vim-go-buffer-auto
|
||||||
|
autocmd! * <buffer>
|
||||||
|
augroup END
|
||||||
|
let b:has_timer = 0
|
||||||
|
call s:timer_stop()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
augroup vim-go-buffer-auto
|
||||||
|
autocmd! * <buffer>
|
||||||
|
autocmd CursorMoved <buffer> call s:timer_restart()
|
||||||
|
autocmd BufLeave <buffer> call s:timer_stop()
|
||||||
|
augroup END
|
||||||
|
let b:has_timer = 1
|
||||||
|
call s:timer_start()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:timer_restart()
|
||||||
|
if isdirectory(expand('%:p:h'))
|
||||||
|
call s:timer_stop()
|
||||||
|
call s:timer_start()
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:timer_stop()
|
||||||
|
if s:timer_id
|
||||||
|
call timer_stop(s:timer_id)
|
||||||
|
let s:timer_id = 0
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:timer_start()
|
||||||
|
let s:timer_id = timer_start(go#config#Updatetime(), function('s:handler'))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:handler(timer_id)
|
||||||
|
if go#config#AutoTypeInfo()
|
||||||
|
call go#tool#Info(0)
|
||||||
|
endif
|
||||||
|
if go#config#AutoSameids()
|
||||||
|
call go#guru#SameIds(0)
|
||||||
|
endif
|
||||||
|
let s:timer_id = 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#auto#fmt_autosave()
|
||||||
|
if !(isdirectory(expand('%:p:h')) && resolve(expand('<afile>:p')) == expand('%:p'))
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !(go#config#FmtAutosave() || go#config#ImportsAutosave())
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Order matters when formatting and adjusting imports, because of gopls'
|
||||||
|
" support for gofumpt. Gofumpt formatting will group all imports that look
|
||||||
|
" like a stdlib package (e.g. there's no '.' in the package path) together.
|
||||||
|
" When the local setting is provided, the only way to get the local imports
|
||||||
|
" grouped separately when gofumpt is used to format is to format first and
|
||||||
|
" then organize imports.
|
||||||
|
|
||||||
|
if go#config#FmtAutosave() && !(go#config#ImportsAutosave() && go#config#ImportsMode() == 'goimports')
|
||||||
|
call go#fmt#Format(0)
|
||||||
|
|
||||||
|
" return early when the imports mode is goimports, because there's no need
|
||||||
|
" to format again when goimports was run
|
||||||
|
if go#config#FmtCommand() == 'goimports'
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !go#config#ImportsAutosave()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#fmt#Format(1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#auto#metalinter_autosave()
|
||||||
|
if !go#config#MetalinterAutosave() || !isdirectory(expand('%:p:h'))
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" run gometalinter on save
|
||||||
|
call go#lint#Gometa(!g:go_jump_to_error, 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#auto#modfmt_autosave()
|
||||||
|
if !(go#config#ModFmtAutosave() && isdirectory(expand('%:p:h')) && resolve(expand('<afile>:p')) == expand('%:p'))
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" go.mod code formatting on save
|
||||||
|
call go#mod#Format()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#auto#asmfmt_autosave()
|
||||||
|
if !(go#config#AsmfmtAutosave() && isdirectory(expand('%:p:h')) && resolve(expand('<afile>:p')) == expand('%:p'))
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Go asm formatting on save
|
||||||
|
call go#asmfmt#Format()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
32
sources_non_forked/vim-go/autoload/go/calls.vim
Normal file
32
sources_non_forked/vim-go/autoload/go/calls.vim
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
function! go#calls#Callers() abort
|
||||||
|
if !go#config#GoplsEnabled()
|
||||||
|
call go#util#EchoError("gopls is disabled")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let [l:line, l:col] = getpos('.')[1:2]
|
||||||
|
let [l:line, l:col] = go#lsp#lsp#Position(l:line, l:col)
|
||||||
|
let l:fname = expand('%:p')
|
||||||
|
call go#lsp#Callers(l:fname, l:line, l:col, funcref('s:parse_output', ['callers']))
|
||||||
|
return
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" This uses Vim's errorformat to parse the output and put it into a quickfix
|
||||||
|
" or locationlist.
|
||||||
|
function! s:parse_output(mode, output) abort
|
||||||
|
let errformat = ",%f:%l:%c:\ %m"
|
||||||
|
let l:listtype = go#list#Type("GoCallers")
|
||||||
|
call go#list#ParseFormat(l:listtype, errformat, a:output, a:mode, 0)
|
||||||
|
|
||||||
|
let errors = go#list#Get(l:listtype)
|
||||||
|
call go#list#Window(l:listtype, len(errors))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
48
sources_non_forked/vim-go/autoload/go/calls_test.vim
Normal file
48
sources_non_forked/vim-go/autoload/go/calls_test.vim
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
scriptencoding utf-8
|
||||||
|
|
||||||
|
func! Test_Callers() abort
|
||||||
|
try
|
||||||
|
let l:tmp = gotest#write_file('calls/caller.go', [
|
||||||
|
\ 'package main',
|
||||||
|
\ '',
|
||||||
|
\ 'import "fmt"',
|
||||||
|
\ '',
|
||||||
|
\ 'func Quux() {}',
|
||||||
|
\ '',
|
||||||
|
\ 'func main() {',
|
||||||
|
\ "\tQ\x1fuux()",
|
||||||
|
\ "\tQuux()",
|
||||||
|
\ '',
|
||||||
|
\ "\tfmt.Println(\"vim-go\")",
|
||||||
|
\ '}',
|
||||||
|
\ ])
|
||||||
|
|
||||||
|
let l:expected = [
|
||||||
|
\ {'lnum': 8, 'bufnr': bufnr(''), 'col': 2, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': 'main'},
|
||||||
|
\ {'lnum': 9, 'bufnr': bufnr(''), 'col': 2, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': 'main'},
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
call go#calls#Callers()
|
||||||
|
|
||||||
|
let l:actual = getloclist(0)
|
||||||
|
let l:start = reltime()
|
||||||
|
while len(l:actual) != len(l:expected) && reltimefloat(reltime(l:start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
let l:actual = getloclist(0)
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call gotest#assert_quickfix(l:actual, l:expected)
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
375
sources_non_forked/vim-go/autoload/go/cmd.vim
Normal file
375
sources_non_forked/vim-go/autoload/go/cmd.vim
Normal file
|
@ -0,0 +1,375 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
function! go#cmd#autowrite() abort
|
||||||
|
if &autowrite == 1 || &autowriteall == 1
|
||||||
|
silent! wall
|
||||||
|
else
|
||||||
|
for l:nr in range(0, bufnr('$'))
|
||||||
|
if buflisted(l:nr) && getbufvar(l:nr, '&modified')
|
||||||
|
" Sleep one second to make sure people see the message. Otherwise it is
|
||||||
|
" often immediately overwritten by the async messages (which also
|
||||||
|
" doesn't invoke the "hit ENTER" prompt).
|
||||||
|
call go#util#EchoWarning('[No write since last change]')
|
||||||
|
sleep 1
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Build builds the source code without producing any output binary. We live in
|
||||||
|
" an editor so the best is to build it to catch errors and fix them. By
|
||||||
|
" default it tries to call simply 'go build', but it first tries to get all
|
||||||
|
" dependent files for the current folder and passes it to go build.
|
||||||
|
function! go#cmd#Build(bang, ...) abort
|
||||||
|
" Create our command arguments. go build discards any results when it
|
||||||
|
" compiles multiple packages. So we pass the `errors` package just as an
|
||||||
|
" placeholder with the current folder (indicated with '.').
|
||||||
|
let l:args =
|
||||||
|
\ ['build', '-tags', go#config#BuildTags()] +
|
||||||
|
\ map(copy(a:000), "expand(v:val)") +
|
||||||
|
\ [".", "errors"]
|
||||||
|
|
||||||
|
" Vim and Neovim async
|
||||||
|
if go#util#has_job()
|
||||||
|
call s:cmd_job({
|
||||||
|
\ 'cmd': ['go'] + args,
|
||||||
|
\ 'bang': a:bang,
|
||||||
|
\ 'for': 'GoBuild',
|
||||||
|
\ 'statustype': 'build'
|
||||||
|
\})
|
||||||
|
|
||||||
|
" Vim without async
|
||||||
|
else
|
||||||
|
let l:status = {
|
||||||
|
\ 'desc': 'current status',
|
||||||
|
\ 'type': 'build',
|
||||||
|
\ 'state': "started",
|
||||||
|
\ }
|
||||||
|
call go#statusline#Update(expand('%:p:h'), l:status)
|
||||||
|
|
||||||
|
let default_makeprg = &makeprg
|
||||||
|
let &makeprg = "go " . join(go#util#Shelllist(args), ' ')
|
||||||
|
|
||||||
|
let l:listtype = go#list#Type("GoBuild")
|
||||||
|
" execute make inside the source folder so we can parse the errors
|
||||||
|
" correctly
|
||||||
|
try
|
||||||
|
let l:dir = go#util#Chdir(expand("%:p:h"))
|
||||||
|
if l:listtype == "locationlist"
|
||||||
|
silent! exe 'lmake!'
|
||||||
|
else
|
||||||
|
silent! exe 'make!'
|
||||||
|
endif
|
||||||
|
redraw!
|
||||||
|
finally
|
||||||
|
call go#util#Chdir(l:dir)
|
||||||
|
let &makeprg = default_makeprg
|
||||||
|
endtry
|
||||||
|
|
||||||
|
let errors = go#list#Get(l:listtype)
|
||||||
|
call go#list#Window(l:listtype, len(errors))
|
||||||
|
if !empty(errors) && !a:bang
|
||||||
|
call go#list#JumpToFirst(l:listtype)
|
||||||
|
let l:status.state = 'failed'
|
||||||
|
else
|
||||||
|
let l:status.state = 'success'
|
||||||
|
if go#config#EchoCommandInfo()
|
||||||
|
call go#util#EchoSuccess("[build] SUCCESS")
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
call go#statusline#Update(expand('%:p:h'), l:status)
|
||||||
|
endif
|
||||||
|
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
" BuildTags sets or shows the current build tags used for tools
|
||||||
|
function! go#cmd#BuildTags(bang, ...) abort
|
||||||
|
if a:0
|
||||||
|
let v = a:1
|
||||||
|
if v == '""' || v == "''"
|
||||||
|
let v = ""
|
||||||
|
endif
|
||||||
|
call go#config#SetBuildTags(v)
|
||||||
|
let tags = go#config#BuildTags()
|
||||||
|
if empty(tags)
|
||||||
|
call go#util#EchoSuccess("build tags are cleared")
|
||||||
|
else
|
||||||
|
call go#util#EchoSuccess("build tags are changed to: " . tags)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let tags = go#config#BuildTags()
|
||||||
|
if empty(tags)
|
||||||
|
call go#util#EchoSuccess("build tags are not set")
|
||||||
|
else
|
||||||
|
call go#util#EchoSuccess("current build tags: " . tags)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
" Run runs the current file (and their dependencies if any) in a new terminal.
|
||||||
|
function! go#cmd#RunTerm(bang, mode, files) abort
|
||||||
|
let cmd = ["go", "run"]
|
||||||
|
if len(go#config#BuildTags()) > 0
|
||||||
|
call extend(cmd, ["-tags", go#config#BuildTags()])
|
||||||
|
endif
|
||||||
|
|
||||||
|
if empty(a:files)
|
||||||
|
call extend(cmd, go#tool#Files())
|
||||||
|
else
|
||||||
|
call extend(cmd, map(copy(a:files), funcref('s:expandRunArgs')))
|
||||||
|
endif
|
||||||
|
call go#term#newmode(a:bang, cmd, s:runerrorformat(), a:mode)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Run runs the current file (and their dependencies if any) and outputs it.
|
||||||
|
" This is intended to test small programs and play with them. It's not
|
||||||
|
" suitable for long running apps, because vim is blocking by default and
|
||||||
|
" calling long running apps will block the whole UI.
|
||||||
|
function! go#cmd#Run(bang, ...) abort
|
||||||
|
if go#config#TermEnabled()
|
||||||
|
call go#cmd#RunTerm(a:bang, '', a:000)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if go#util#has_job()
|
||||||
|
" NOTE(arslan): 'term': 'open' case is not implement for +jobs. This means
|
||||||
|
" executions waiting for stdin will not work. That's why we don't do
|
||||||
|
" anything. Once this is implemented we're going to make :GoRun async
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:status = {
|
||||||
|
\ 'desc': 'current status',
|
||||||
|
\ 'type': 'run',
|
||||||
|
\ 'state': "started",
|
||||||
|
\ }
|
||||||
|
|
||||||
|
call go#statusline#Update(expand('%:p:h'), l:status)
|
||||||
|
|
||||||
|
let l:cmd = ['go', 'run']
|
||||||
|
let l:tags = go#config#BuildTags()
|
||||||
|
if len(l:tags) > 0
|
||||||
|
let l:cmd = l:cmd + ['-tags', l:tags]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:0 == 0
|
||||||
|
let l:files = go#tool#Files()
|
||||||
|
else
|
||||||
|
let l:files = map(copy(a:000), funcref('s:expandRunArgs'))
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:cmd = l:cmd + l:files
|
||||||
|
|
||||||
|
if go#util#IsWin()
|
||||||
|
if go#util#HasDebug('shell-commands')
|
||||||
|
call go#util#EchoInfo(printf('shell command: %s', string(l:cmd)))
|
||||||
|
endif
|
||||||
|
try
|
||||||
|
let l:dir = go#util#Chdir(expand("%:p:h"))
|
||||||
|
exec printf('!%s', go#util#Shelljoin(l:cmd, 1))
|
||||||
|
finally
|
||||||
|
call go#util#Chdir(l:dir)
|
||||||
|
endtry
|
||||||
|
|
||||||
|
let l:status.state = 'success'
|
||||||
|
if v:shell_error
|
||||||
|
let l:status.state = 'failed'
|
||||||
|
if go#config#EchoCommandInfo()
|
||||||
|
redraws!
|
||||||
|
call go#util#EchoError('[run] FAILED')
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
if go#config#EchoCommandInfo()
|
||||||
|
redraws!
|
||||||
|
call go#util#EchoSuccess('[run] SUCCESS')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#statusline#Update(expand('%:p:h'), l:status)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" :make expands '%' and '#' wildcards, so they must also be escaped
|
||||||
|
let l:default_makeprg = &makeprg
|
||||||
|
let &makeprg = go#util#Shelljoin(l:cmd, 1)
|
||||||
|
|
||||||
|
let l:listtype = go#list#Type("GoRun")
|
||||||
|
|
||||||
|
let l:status.state = 'success'
|
||||||
|
|
||||||
|
let l:dir = go#util#Chdir(expand("%:p:h"))
|
||||||
|
try
|
||||||
|
" backup user's errorformat, will be restored once we are finished
|
||||||
|
let l:old_errorformat = &errorformat
|
||||||
|
let &errorformat = s:runerrorformat()
|
||||||
|
|
||||||
|
if go#util#HasDebug('shell-commands')
|
||||||
|
call go#util#EchoInfo(printf('shell command: %s', string(l:cmd)))
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:listtype == "locationlist"
|
||||||
|
exe 'lmake!'
|
||||||
|
else
|
||||||
|
exe 'make!'
|
||||||
|
endif
|
||||||
|
finally
|
||||||
|
call go#util#Chdir(l:dir)
|
||||||
|
let &errorformat = l:old_errorformat
|
||||||
|
let &makeprg = l:default_makeprg
|
||||||
|
endtry
|
||||||
|
|
||||||
|
let l:errors = go#list#Get(l:listtype)
|
||||||
|
|
||||||
|
call go#list#Window(l:listtype, len(l:errors))
|
||||||
|
if !empty(l:errors)
|
||||||
|
let l:status.state = 'failed'
|
||||||
|
if !a:bang
|
||||||
|
call go#list#JumpToFirst(l:listtype)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
call go#statusline#Update(expand('%:p:h'), l:status)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Install installs the package by simple calling 'go install'. If any argument
|
||||||
|
" is given(which are passed directly to 'go install') it tries to install
|
||||||
|
" those packages. Errors are populated in the location window.
|
||||||
|
function! go#cmd#Install(bang, ...) abort
|
||||||
|
" use vim's job functionality to call it asynchronously
|
||||||
|
if go#util#has_job()
|
||||||
|
" expand all wildcards(i.e: '%' to the current file name)
|
||||||
|
let goargs = map(copy(a:000), "expand(v:val)")
|
||||||
|
|
||||||
|
call s:cmd_job({
|
||||||
|
\ 'cmd': ['go', 'install', '-tags', go#config#BuildTags()] + goargs,
|
||||||
|
\ 'bang': a:bang,
|
||||||
|
\ 'for': 'GoInstall',
|
||||||
|
\ 'statustype': 'install'
|
||||||
|
\})
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let default_makeprg = &makeprg
|
||||||
|
|
||||||
|
" :make expands '%' and '#' wildcards, so they must also be escaped
|
||||||
|
let goargs = go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1)
|
||||||
|
let &makeprg = "go install " . goargs
|
||||||
|
|
||||||
|
let l:listtype = go#list#Type("GoInstall")
|
||||||
|
" execute make inside the source folder so we can parse the errors
|
||||||
|
" correctly
|
||||||
|
try
|
||||||
|
let l:dir = go#util#Chdir(expand("%:p:h"))
|
||||||
|
if l:listtype == "locationlist"
|
||||||
|
silent! exe 'lmake!'
|
||||||
|
else
|
||||||
|
silent! exe 'make!'
|
||||||
|
endif
|
||||||
|
redraw!
|
||||||
|
finally
|
||||||
|
call go#util#Chdir(l:dir)
|
||||||
|
let &makeprg = default_makeprg
|
||||||
|
endtry
|
||||||
|
|
||||||
|
let errors = go#list#Get(l:listtype)
|
||||||
|
call go#list#Window(l:listtype, len(errors))
|
||||||
|
if !empty(errors) && !a:bang
|
||||||
|
call go#list#JumpToFirst(l:listtype)
|
||||||
|
else
|
||||||
|
call go#util#EchoSuccess("installed to ". go#path#Default())
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Generate runs 'go generate' in similar fashion to go#cmd#Build()
|
||||||
|
function! go#cmd#Generate(bang, ...) abort
|
||||||
|
let default_makeprg = &makeprg
|
||||||
|
|
||||||
|
" :make expands '%' and '#' wildcards, so they must also be escaped
|
||||||
|
let goargs = go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1)
|
||||||
|
if go#util#ShellError() != 0
|
||||||
|
let &makeprg = "go generate " . goargs
|
||||||
|
else
|
||||||
|
let gofiles = go#util#Shelljoin(go#tool#Files(), 1)
|
||||||
|
let &makeprg = "go generate " . goargs . ' ' . gofiles
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:status = {
|
||||||
|
\ 'desc': 'current status',
|
||||||
|
\ 'type': 'generate',
|
||||||
|
\ 'state': "started",
|
||||||
|
\ }
|
||||||
|
call go#statusline#Update(expand('%:p:h'), l:status)
|
||||||
|
|
||||||
|
if go#config#EchoCommandInfo()
|
||||||
|
call go#util#EchoProgress('generating ...')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:listtype = go#list#Type("GoGenerate")
|
||||||
|
|
||||||
|
try
|
||||||
|
if l:listtype == "locationlist"
|
||||||
|
silent! exe 'lmake!'
|
||||||
|
else
|
||||||
|
silent! exe 'make!'
|
||||||
|
endif
|
||||||
|
finally
|
||||||
|
redraw!
|
||||||
|
let &makeprg = default_makeprg
|
||||||
|
endtry
|
||||||
|
|
||||||
|
let errors = go#list#Get(l:listtype)
|
||||||
|
call go#list#Window(l:listtype, len(errors))
|
||||||
|
if !empty(errors)
|
||||||
|
let l:status.status = 'failed'
|
||||||
|
if !a:bang
|
||||||
|
call go#list#JumpToFirst(l:listtype)
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
let l:status.status = 'success'
|
||||||
|
if go#config#EchoCommandInfo()
|
||||||
|
redraws!
|
||||||
|
call go#util#EchoSuccess('[generate] SUCCESS')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
call go#statusline#Update(expand(':%:p:h'), l:status)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:runerrorformat()
|
||||||
|
let l:panicaddress = "%\\t%#%f:%l +0x%[0-9A-Fa-f]%\\+"
|
||||||
|
let l:errorformat = '%A' . l:panicaddress . "," . &errorformat
|
||||||
|
return l:errorformat
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" s:expandRunArgs expands arguments for go#cmd#Run according to the
|
||||||
|
" documentation of :GoRun. When val is a readable file, it is expanded to the
|
||||||
|
" full path so that go run can be executed in the current buffer's directory.
|
||||||
|
" val is return unaltered otherwise to support non-file arguments to go run.
|
||||||
|
function! s:expandRunArgs(idx, val) abort
|
||||||
|
let l:val = expand(a:val)
|
||||||
|
if !filereadable(l:val)
|
||||||
|
return l:val
|
||||||
|
endif
|
||||||
|
|
||||||
|
return fnamemodify(l:val, ':p')")
|
||||||
|
endfunction
|
||||||
|
" ---------------------
|
||||||
|
" | Vim job callbacks |
|
||||||
|
" ---------------------
|
||||||
|
|
||||||
|
function! s:cmd_job(args) abort
|
||||||
|
" autowrite is not enabled for jobs
|
||||||
|
call go#cmd#autowrite()
|
||||||
|
|
||||||
|
call go#job#Spawn(a:args.cmd, a:args)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
37
sources_non_forked/vim-go/autoload/go/cmd_test.vim
Normal file
37
sources_non_forked/vim-go/autoload/go/cmd_test.vim
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
func! Test_GoBuildErrors()
|
||||||
|
try
|
||||||
|
let l:filename = 'cmd/bad.go'
|
||||||
|
let l:tmp = gotest#load_fixture(l:filename)
|
||||||
|
|
||||||
|
" set the compiler type so that the errorformat option will be set
|
||||||
|
" correctly.
|
||||||
|
compiler go
|
||||||
|
|
||||||
|
let expected = [{'lnum': 4, 'bufnr': bufnr('%'), 'col': 2, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'undefined: notafunc'}]
|
||||||
|
" clear the quickfix lists
|
||||||
|
call setqflist([], 'r')
|
||||||
|
|
||||||
|
call go#cmd#Build(1)
|
||||||
|
|
||||||
|
let actual = getqflist()
|
||||||
|
let start = reltime()
|
||||||
|
while len(actual) == 0 && reltimefloat(reltime(start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
let actual = getqflist()
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call gotest#assert_quickfix(actual, l:expected)
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
67
sources_non_forked/vim-go/autoload/go/complete.vim
Normal file
67
sources_non_forked/vim-go/autoload/go/complete.vim
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
" go#complete#GoInfo returns the description of the identifier under the
|
||||||
|
" cursor.
|
||||||
|
function! go#complete#GetInfo() abort
|
||||||
|
return go#lsp#GetInfo()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#complete#Complete(findstart, base) abort
|
||||||
|
if !go#config#GoplsEnabled()
|
||||||
|
return -3
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:state = {'done': 0, 'matches': [], 'start': -1}
|
||||||
|
|
||||||
|
function! s:handler(state, start, matches) abort dict
|
||||||
|
let a:state.start = a:start
|
||||||
|
let a:state.matches = a:matches
|
||||||
|
let a:state.done = 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
"findstart = 1 when we need to get the start of the match
|
||||||
|
if a:findstart == 1
|
||||||
|
let [l:line, l:col] = getpos('.')[1:2]
|
||||||
|
let [l:line, l:col] = go#lsp#lsp#Position(l:line, l:col)
|
||||||
|
let l:completion = go#lsp#Completion(expand('%:p'), l:line, l:col, funcref('s:handler', [l:state]))
|
||||||
|
if l:completion
|
||||||
|
return -3
|
||||||
|
endif
|
||||||
|
|
||||||
|
while !l:state.done
|
||||||
|
sleep 10m
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
if len(l:state.matches) == 0
|
||||||
|
" no matches. cancel and leave completion mode.
|
||||||
|
call go#util#EchoInfo("no matches")
|
||||||
|
return -3
|
||||||
|
endif
|
||||||
|
|
||||||
|
let s:completions = l:state.matches
|
||||||
|
|
||||||
|
return go#lsp#lsp#PositionOf(getline(l:line+1), l:state.start-1)
|
||||||
|
|
||||||
|
else "findstart = 0 when we need to return the list of completions
|
||||||
|
return s:completions
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#complete#ToggleAutoTypeInfo() abort
|
||||||
|
if go#config#AutoTypeInfo()
|
||||||
|
call go#config#SetAutoTypeInfo(0)
|
||||||
|
call go#util#EchoProgress("auto type info disabled")
|
||||||
|
else
|
||||||
|
call go#config#SetAutoTypeInfo(1)
|
||||||
|
call go#util#EchoProgress("auto type info enabled")
|
||||||
|
endif
|
||||||
|
call go#auto#update_autocmd()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
29
sources_non_forked/vim-go/autoload/go/complete_test.vim
Normal file
29
sources_non_forked/vim-go/autoload/go/complete_test.vim
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
func! Test_GetInfo_gopls()
|
||||||
|
let g:go_info_mode = 'gopls'
|
||||||
|
call s:getinfo()
|
||||||
|
unlet g:go_info_mode
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
func! s:getinfo()
|
||||||
|
let l:filename = 'complete/complete.go'
|
||||||
|
let l:tmp = gotest#load_fixture(l:filename)
|
||||||
|
try
|
||||||
|
call cursor(8, 3)
|
||||||
|
|
||||||
|
let expected = 'func Example(s string)'
|
||||||
|
let actual = go#complete#GetInfo()
|
||||||
|
call assert_equal(expected, actual)
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
632
sources_non_forked/vim-go/autoload/go/config.vim
Normal file
632
sources_non_forked/vim-go/autoload/go/config.vim
Normal file
|
@ -0,0 +1,632 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
function! go#config#ListTypeCommands() abort
|
||||||
|
return get(g:, 'go_list_type_commands', {})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#VersionWarning() abort
|
||||||
|
return get(g:, 'go_version_warning', 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#BuildTags() abort
|
||||||
|
return get(g:, 'go_build_tags', '')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#SetBuildTags(value) abort
|
||||||
|
if a:value is ''
|
||||||
|
silent! unlet g:go_build_tags
|
||||||
|
call go#lsp#ResetWorkspaceDirectories()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let g:go_build_tags = a:value
|
||||||
|
call go#lsp#ResetWorkspaceDirectories()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#TestTimeout() abort
|
||||||
|
return get(g:, 'go_test_timeout', '10s')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#TestShowName() abort
|
||||||
|
return get(g:, 'go_test_show_name', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#TermHeight() abort
|
||||||
|
return get(g:, 'go_term_height', winheight(0))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#TermWidth() abort
|
||||||
|
return get(g:, 'go_term_width', winwidth(0))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#TermMode() abort
|
||||||
|
return get(g:, 'go_term_mode', 'vsplit')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#TermCloseOnExit() abort
|
||||||
|
return get(g:, 'go_term_close_on_exit', 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#TermReuse() abort
|
||||||
|
return get(g:, 'go_term_reuse', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#SetTermCloseOnExit(value) abort
|
||||||
|
let g:go_term_close_on_exit = a:value
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#TermEnabled() abort
|
||||||
|
" nvim always support
|
||||||
|
" vim will support if terminal feature exists
|
||||||
|
let l:support = has('nvim') || has('terminal')
|
||||||
|
return support && get(g:, 'go_term_enabled', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#SetTermEnabled(value) abort
|
||||||
|
let g:go_term_enabled = a:value
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#TemplateUsePkg() abort
|
||||||
|
return get(g:, 'go_template_use_pkg', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#TemplateTestFile() abort
|
||||||
|
return get(g:, 'go_template_test_file', "hello_world_test.go")
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#TemplateFile() abort
|
||||||
|
return get(g:, 'go_template_file', "hello_world.go")
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#StatuslineDuration() abort
|
||||||
|
return get(g:, 'go_statusline_duration', 60000)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#SnippetEngine() abort
|
||||||
|
let l:engine = get(g:, 'go_snippet_engine', 'automatic')
|
||||||
|
if l:engine is? "automatic"
|
||||||
|
if get(g:, 'did_plugin_ultisnips') is 1
|
||||||
|
let l:engine = 'ultisnips'
|
||||||
|
elseif get(g:, 'loaded_neosnippet') is 1
|
||||||
|
let l:engine = 'neosnippet'
|
||||||
|
elseif get(g:, 'loaded_minisnip') is 1
|
||||||
|
let l:engine = 'minisnip'
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:engine
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#PlayBrowserCommand() abort
|
||||||
|
if go#util#IsWin()
|
||||||
|
let go_play_browser_command = '!start rundll32 url.dll,FileProtocolHandler %URL%'
|
||||||
|
elseif go#util#IsMac()
|
||||||
|
let go_play_browser_command = 'open %URL%'
|
||||||
|
elseif executable('xdg-open')
|
||||||
|
let go_play_browser_command = 'xdg-open %URL%'
|
||||||
|
elseif executable('firefox')
|
||||||
|
let go_play_browser_command = 'firefox %URL% &'
|
||||||
|
elseif executable('chromium')
|
||||||
|
let go_play_browser_command = 'chromium %URL% &'
|
||||||
|
else
|
||||||
|
let go_play_browser_command = ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
return get(g:, 'go_play_browser_command', go_play_browser_command)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#MetalinterDeadline() abort
|
||||||
|
" gometalinter has a default deadline of 5 seconds only when asynchronous
|
||||||
|
" jobs are not supported.
|
||||||
|
|
||||||
|
let deadline = '5s'
|
||||||
|
if go#util#has_job() && has('lambda')
|
||||||
|
let deadline = ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
return get(g:, 'go_metalinter_deadline', deadline)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#ListType() abort
|
||||||
|
return get(g:, 'go_list_type', '')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#ListAutoclose() abort
|
||||||
|
return get(g:, 'go_list_autoclose', 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#InfoMode() abort
|
||||||
|
return get(g:, 'go_info_mode', 'gopls')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#GuruScope() abort
|
||||||
|
let scope = get(g:, 'go_guru_scope', [])
|
||||||
|
|
||||||
|
if !empty(scope)
|
||||||
|
" strip trailing slashes for each path in scope. bug:
|
||||||
|
" https://github.com/golang/go/issues/14584
|
||||||
|
let scopes = go#util#StripTrailingSlash(scope)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return scope
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#SetGuruScope(scope) abort
|
||||||
|
if empty(a:scope)
|
||||||
|
if exists('g:go_guru_scope')
|
||||||
|
unlet g:go_guru_scope
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
let g:go_guru_scope = a:scope
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#EchoCommandInfo() abort
|
||||||
|
return get(g:, 'go_echo_command_info', 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#DocUrl() abort
|
||||||
|
let godoc_url = get(g:, 'go_doc_url', 'https://pkg.go.dev')
|
||||||
|
if godoc_url isnot 'https://pkg.go.dev'
|
||||||
|
" strip last '/' character if available
|
||||||
|
let last_char = strlen(godoc_url) - 1
|
||||||
|
if godoc_url[last_char] == '/'
|
||||||
|
let godoc_url = strpart(godoc_url, 0, last_char)
|
||||||
|
endif
|
||||||
|
" custom godoc installations expect /pkg before package names
|
||||||
|
let godoc_url .= "/pkg"
|
||||||
|
endif
|
||||||
|
return godoc_url
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#DocPopupWindow() abort
|
||||||
|
return get(g:, 'go_doc_popup_window', 0)
|
||||||
|
endfunction
|
||||||
|
function! go#config#DefReuseBuffer() abort
|
||||||
|
return get(g:, 'go_def_reuse_buffer', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#DefMode() abort
|
||||||
|
return get(g:, 'go_def_mode', 'gopls')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#DeclsIncludes() abort
|
||||||
|
return get(g:, 'go_decls_includes', 'func,type')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#Debug() abort
|
||||||
|
return get(g:, 'go_debug', [])
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#DebugWindows() abort
|
||||||
|
return get(g:, 'go_debug_windows', {
|
||||||
|
\ 'vars': 'leftabove 30vnew',
|
||||||
|
\ 'stack': 'leftabove 20new',
|
||||||
|
\ 'goroutines': 'botright 10new',
|
||||||
|
\ 'out': 'botright 5new',
|
||||||
|
\ }
|
||||||
|
\ )
|
||||||
|
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#DebugSubstitutePaths() abort
|
||||||
|
return get(g:, 'go_debug_substitute_paths', [])
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#DebugPreserveLayout() abort
|
||||||
|
return get(g:, 'go_debug_preserve_layout', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#DebugAddress() abort
|
||||||
|
return get(g:, 'go_debug_address', '127.0.0.1:8181')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#DebugCommands() abort
|
||||||
|
" make sure g:go_debug_commands is set so that it can be added to easily.
|
||||||
|
let g:go_debug_commands = get(g:, 'go_debug_commands', [])
|
||||||
|
return g:go_debug_commands
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#DebugLogOutput() abort
|
||||||
|
return get(g:, 'go_debug_log_output', 'debugger,rpc')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#LspLog() abort
|
||||||
|
" make sure g:go_lsp_log is set so that it can be added to easily.
|
||||||
|
let g:go_lsp_log = get(g:, 'go_lsp_log', [])
|
||||||
|
return g:go_lsp_log
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#SetDebugDiag(value) abort
|
||||||
|
let g:go_debug_diag = a:value
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#AutoSameids() abort
|
||||||
|
return get(g:, 'go_auto_sameids', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#SetAutoSameids(value) abort
|
||||||
|
let g:go_auto_sameids = a:value
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#AddtagsTransform() abort
|
||||||
|
return get(g:, 'go_addtags_transform', "snakecase")
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#AddtagsSkipUnexported() abort
|
||||||
|
return get(g:, 'go_addtags_skip_unexported', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#TemplateAutocreate() abort
|
||||||
|
return get(g:, "go_template_autocreate", 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#SetTemplateAutocreate(value) abort
|
||||||
|
let g:go_template_autocreate = a:value
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
let s:default_metalinter = 'staticcheck'
|
||||||
|
function! go#config#MetalinterCommand() abort
|
||||||
|
return get(g:, 'go_metalinter_command', s:default_metalinter)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#MetalinterAutosaveEnabled() abort
|
||||||
|
let l:default = []
|
||||||
|
if get(g:, 'go_metalinter_command', s:default_metalinter) == 'golangci-lint'
|
||||||
|
let l:default = ['govet', 'revive']
|
||||||
|
endif
|
||||||
|
|
||||||
|
return get(g:, 'go_metalinter_autosave_enabled', l:default)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#MetalinterEnabled() abort
|
||||||
|
let l:default = []
|
||||||
|
if get(g:, 'go_metalinter_command', s:default_metalinter) == 'golangci-lint'
|
||||||
|
let l:default = ['vet', 'revive', 'errcheck']
|
||||||
|
endif
|
||||||
|
|
||||||
|
return get(g:, 'go_metalinter_enabled', l:default)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#GolintBin() abort
|
||||||
|
return get(g:, "go_golint_bin", "revive")
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#ErrcheckBin() abort
|
||||||
|
return get(g:, "go_errcheck_bin", "errcheck")
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#MetalinterAutosave() abort
|
||||||
|
return get(g:, "go_metalinter_autosave", 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#SetMetalinterAutosave(value) abort
|
||||||
|
let g:go_metalinter_autosave = a:value
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#ListHeight() abort
|
||||||
|
return get(g:, "go_list_height", 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#FmtAutosave() abort
|
||||||
|
return get(g:, "go_fmt_autosave", 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#ImportsAutosave() abort
|
||||||
|
return get(g:, 'go_imports_autosave', 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#SetFmtAutosave(value) abort
|
||||||
|
let g:go_fmt_autosave = a:value
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#AsmfmtAutosave() abort
|
||||||
|
return get(g:, "go_asmfmt_autosave", 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#SetAsmfmtAutosave(value) abort
|
||||||
|
let g:go_asmfmt_autosave = a:value
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#ModFmtAutosave() abort
|
||||||
|
return get(g:, "go_mod_fmt_autosave", 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#SetModFmtAutosave(value) abort
|
||||||
|
let g:go_mod_fmt_autosave = a:value
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#DocMaxHeight() abort
|
||||||
|
return get(g:, "go_doc_max_height", 20)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#AutoTypeInfo() abort
|
||||||
|
return get(g:, "go_auto_type_info", 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#SetAutoTypeInfo(value) abort
|
||||||
|
let g:go_auto_type_info = a:value
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#AlternateMode() abort
|
||||||
|
return get(g:, "go_alternate_mode", "edit")
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#DeclsMode() abort
|
||||||
|
return get(g:, "go_decls_mode", "")
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#FmtCommand() abort
|
||||||
|
return get(g:, "go_fmt_command", go#config#GoplsEnabled() ? 'gopls' : 'gofmt')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#ImportsMode() abort
|
||||||
|
return get(g:, "go_imports_mode", go#config#GoplsEnabled() ? 'gopls' : 'goimports')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#FmtOptions() abort
|
||||||
|
return get(b:, "go_fmt_options", get(g:, "go_fmt_options", {}))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#FmtFailSilently() abort
|
||||||
|
return get(g:, "go_fmt_fail_silently", 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#FmtExperimental() abort
|
||||||
|
return get(g:, "go_fmt_experimental", 0 )
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#PlayOpenBrowser() abort
|
||||||
|
return get(g:, "go_play_open_browser", 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#RenameCommand() abort
|
||||||
|
" delegate to go#config#GorenameBin for backwards compatability.
|
||||||
|
return get(g:, "go_rename_command", go#config#GorenameBin())
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#GorenameBin() abort
|
||||||
|
return get(g:, "go_gorename_bin", 'gopls')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#GorenamePrefill() abort
|
||||||
|
return get(g:, "go_gorename_prefill", 'expand("<cword>") =~# "^[A-Z]"' .
|
||||||
|
\ '? go#util#pascalcase(expand("<cword>"))' .
|
||||||
|
\ ': go#util#camelcase(expand("<cword>"))')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#TextobjIncludeFunctionDoc() abort
|
||||||
|
return get(g:, "go_textobj_include_function_doc", 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#TextobjIncludeVariable() abort
|
||||||
|
return get(g:, "go_textobj_include_variable", 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#BinPath() abort
|
||||||
|
return get(g:, "go_bin_path", "")
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#SearchBinPathFirst() abort
|
||||||
|
return get(g:, 'go_search_bin_path_first', 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#HighlightArrayWhitespaceError() abort
|
||||||
|
return get(g:, 'go_highlight_array_whitespace_error', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#HighlightChanWhitespaceError() abort
|
||||||
|
return get(g:, 'go_highlight_chan_whitespace_error', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#HighlightExtraTypes() abort
|
||||||
|
return get(g:, 'go_highlight_extra_types', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#HighlightSpaceTabError() abort
|
||||||
|
return get(g:, 'go_highlight_space_tab_error', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#HighlightTrailingWhitespaceError() abort
|
||||||
|
return get(g:, 'go_highlight_trailing_whitespace_error', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#HighlightOperators() abort
|
||||||
|
return get(g:, 'go_highlight_operators', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#HighlightFunctions() abort
|
||||||
|
return get(g:, 'go_highlight_functions', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#HighlightFunctionParameters() abort
|
||||||
|
" fallback to highlight_function_arguments for backwards compatibility
|
||||||
|
return get(g:, 'go_highlight_function_parameters', get(g:, 'go_highlight_function_arguments', 0))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#HighlightFunctionCalls() abort
|
||||||
|
return get(g:, 'go_highlight_function_calls', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#HighlightFields() abort
|
||||||
|
return get(g:, 'go_highlight_fields', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#HighlightTypes() abort
|
||||||
|
return get(g:, 'go_highlight_types', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#HighlightBuildConstraints() abort
|
||||||
|
return get(g:, 'go_highlight_build_constraints', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#HighlightStringSpellcheck() abort
|
||||||
|
return get(g:, 'go_highlight_string_spellcheck', 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#HighlightFormatStrings() abort
|
||||||
|
return get(g:, 'go_highlight_format_strings', 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#HighlightGenerateTags() abort
|
||||||
|
return get(g:, 'go_highlight_generate_tags', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#HighlightVariableAssignments() abort
|
||||||
|
return get(g:, 'go_highlight_variable_assignments', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#HighlightVariableDeclarations() abort
|
||||||
|
return get(g:, 'go_highlight_variable_declarations', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#HighlightDiagnosticErrors() abort
|
||||||
|
return get(g:, 'go_highlight_diagnostic_errors', 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#HighlightDiagnosticWarnings() abort
|
||||||
|
return get(g:, 'go_highlight_diagnostic_warnings', 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#HighlightDebug() abort
|
||||||
|
return get(g:, 'go_highlight_debug', 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#DebugBreakpointSignText() abort
|
||||||
|
return get(g:, 'go_debug_breakpoint_sign_text', '>')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#FoldEnable(...) abort
|
||||||
|
if a:0 > 0
|
||||||
|
return index(go#config#FoldEnable(), a:1) > -1
|
||||||
|
endif
|
||||||
|
return get(g:, 'go_fold_enable', ['block', 'import', 'varconst', 'package_comment'])
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#EchoGoInfo() abort
|
||||||
|
return get(g:, "go_echo_go_info", 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#CodeCompletionEnabled() abort
|
||||||
|
return get(g:, "go_code_completion_enabled", 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#CodeCompletionIcase() abort
|
||||||
|
return get(g:, "go_code_completion_icase", 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#Updatetime() abort
|
||||||
|
let go_updatetime = get(g:, 'go_updatetime', 800)
|
||||||
|
return go_updatetime == 0 ? &updatetime : go_updatetime
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#ReferrersMode() abort
|
||||||
|
return get(g:, 'go_referrers_mode', 'gopls')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#ImplementsMode() abort
|
||||||
|
return get(g:, 'go_implements_mode', 'gopls')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#GoplsCompleteUnimported() abort
|
||||||
|
return get(g:, 'go_gopls_complete_unimported', v:null)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#GoplsDeepCompletion() abort
|
||||||
|
return get(g:, 'go_gopls_deep_completion', v:null)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#GoplsMatcher() abort
|
||||||
|
if !exists('g:go_gopls_matcher') && get(g:, 'g:go_gopls_fuzzy_matching', v:null) is 1
|
||||||
|
return 'fuzzy'
|
||||||
|
endif
|
||||||
|
return get(g:, 'go_gopls_matcher', v:null)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#GoplsStaticCheck() abort
|
||||||
|
return get(g:, 'go_gopls_staticcheck', v:null)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#GoplsUsePlaceholders() abort
|
||||||
|
return get(g:, 'go_gopls_use_placeholders', v:null)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#GoplsTempModfile() abort
|
||||||
|
return get(g:, 'go_gopls_temp_modfile', v:null)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#GoplsAnalyses() abort
|
||||||
|
return get(g:, 'go_gopls_analyses', v:null)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#GoplsLocal() abort
|
||||||
|
return get(g:, 'go_gopls_local', v:null)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#GoplsGofumpt() abort
|
||||||
|
return get(g:, 'go_gopls_gofumpt', v:null)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#GoplsSettings() abort
|
||||||
|
return get(g:, 'go_gopls_settings', v:null)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#GoplsEnabled() abort
|
||||||
|
return get(g:, 'go_gopls_enabled', 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" TODO(bc): remove support for g:go_diagnostics_enabled;
|
||||||
|
" g:go_diagnostics_level is the replacement.
|
||||||
|
function! go#config#DiagnosticsEnabled() abort
|
||||||
|
return get(g:, 'go_diagnostics_enabled', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#DiagnosticsLevel() abort
|
||||||
|
let l:default = 0
|
||||||
|
if has_key(g:, 'go_diagnostics_enabled') && g:go_diagnostics_enabled
|
||||||
|
let l:default = 2
|
||||||
|
endif
|
||||||
|
|
||||||
|
return get(g:, 'go_diagnostics_level', l:default)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#GoplsOptions() abort
|
||||||
|
return get(g:, 'go_gopls_options', ['-remote=auto'])
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#FillStructMode() abort
|
||||||
|
return get(g:, 'go_fillstruct_mode', 'fillstruct')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#DebugMappings() abort
|
||||||
|
let l:default = {
|
||||||
|
\ '(go-debug-continue)': {'key': '<F5>'},
|
||||||
|
\ '(go-debug-print)': {'key': '<F6>'},
|
||||||
|
\ '(go-debug-breakpoint)': {'key': '<F9>'},
|
||||||
|
\ '(go-debug-next)': {'key': '<F10>'},
|
||||||
|
\ '(go-debug-step)': {'key': '<F11>'},
|
||||||
|
\ '(go-debug-halt)': {'key': '<F8>'},
|
||||||
|
\ }
|
||||||
|
|
||||||
|
let l:user = deepcopy(get(g:, 'go_debug_mappings', {}))
|
||||||
|
|
||||||
|
return extend(l:user, l:default, 'keep')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#config#DocBalloon() abort
|
||||||
|
return get(g:, 'go_doc_balloon', 0)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Set the default value. A value of "1" is a shortcut for this, for
|
||||||
|
" compatibility reasons.
|
||||||
|
if exists("g:go_gorename_prefill") && g:go_gorename_prefill == 1
|
||||||
|
unlet g:go_gorename_prefill
|
||||||
|
endif
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
107
sources_non_forked/vim-go/autoload/go/config_test.vim
Normal file
107
sources_non_forked/vim-go/autoload/go/config_test.vim
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
scriptencoding utf-8
|
||||||
|
|
||||||
|
func! Test_SetBuildTags() abort
|
||||||
|
if !go#util#has_job()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
let g:go_def_mode = 'gopls'
|
||||||
|
let l:dir = 'test-fixtures/config/buildtags'
|
||||||
|
let l:jumpstart = [0, 4, 2, 0]
|
||||||
|
|
||||||
|
execute 'e ' . printf('%s/buildtags.go', l:dir)
|
||||||
|
let l:jumpstartbuf = bufnr('')
|
||||||
|
|
||||||
|
call setpos('.', [l:jumpstartbuf, l:jumpstart[1], l:jumpstart[2], 0])
|
||||||
|
|
||||||
|
let l:expectedfilename = printf('%s/foo.go', l:dir)
|
||||||
|
|
||||||
|
let l:expected = [0, 5, 1, 0]
|
||||||
|
call assert_notequal(l:expected, l:jumpstart)
|
||||||
|
|
||||||
|
call go#def#Jump('', 0)
|
||||||
|
|
||||||
|
let l:start = reltime()
|
||||||
|
while getpos('.') != l:expected && reltimefloat(reltime(l:start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call assert_equal(l:expectedfilename, bufname("%"))
|
||||||
|
call assert_equal(l:expected, getpos('.'))
|
||||||
|
|
||||||
|
execute 'e ' . printf('%s/buildtags.go', l:dir)
|
||||||
|
|
||||||
|
" prepare to wait for the workspace/configuration request
|
||||||
|
let g:go_debug=['lsp']
|
||||||
|
|
||||||
|
" set the build constraint
|
||||||
|
call go#config#SetBuildTags('constrained')
|
||||||
|
|
||||||
|
" wait for the workspace/configuration request
|
||||||
|
let l:lsplog = getbufline('__GOLSP_LOG__', 1, '$')
|
||||||
|
let l:start = reltime()
|
||||||
|
while match(l:lsplog, 'workspace/configuration') == -1 && reltimefloat(reltime(l:start)) < 10
|
||||||
|
sleep 50m
|
||||||
|
let l:lsplog = getbufline('__GOLSP_LOG__', 1, '$')
|
||||||
|
endwhile
|
||||||
|
unlet g:go_debug
|
||||||
|
" close the __GOLSP_LOG__ window
|
||||||
|
only
|
||||||
|
|
||||||
|
" verify the cursor position within buildtags.go
|
||||||
|
call setpos('.', [l:jumpstartbuf, l:jumpstart[1], l:jumpstart[2], 0])
|
||||||
|
call assert_equal(l:jumpstart, getpos('.'))
|
||||||
|
|
||||||
|
let l:expectedfilename = printf('%s/constrainedfoo.go', l:dir)
|
||||||
|
let l:expected = [0, 6, 1, 0]
|
||||||
|
call assert_notequal(l:expected, l:jumpstart)
|
||||||
|
|
||||||
|
call go#def#Jump('', 0)
|
||||||
|
|
||||||
|
let l:start = reltime()
|
||||||
|
while getpos('.') != l:expected && reltimefloat(reltime(l:start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call assert_equal(l:expectedfilename, bufname("%"))
|
||||||
|
call assert_equal(l:expected, getpos('.'))
|
||||||
|
|
||||||
|
let l:lsplog = getbufline('__GOLSP_LOG__', 1, '$')
|
||||||
|
|
||||||
|
finally
|
||||||
|
call go#config#SetBuildTags('')
|
||||||
|
unlet g:go_def_mode
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_GoplsEnabled_Clear() abort
|
||||||
|
if !go#util#has_job()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
let g:go_gopls_enabled = 0
|
||||||
|
|
||||||
|
let l:tmp = gotest#write_file('gopls_disabled.go', [
|
||||||
|
\ 'package example',
|
||||||
|
\ '',
|
||||||
|
\ 'func Example() {',
|
||||||
|
\ "\tprintln(" . '"hello, world!")',
|
||||||
|
\ '}',
|
||||||
|
\ ] )
|
||||||
|
|
||||||
|
finally
|
||||||
|
unlet g:go_gopls_enabled
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
295
sources_non_forked/vim-go/autoload/go/coverage.vim
Normal file
295
sources_non_forked/vim-go/autoload/go/coverage.vim
Normal file
|
@ -0,0 +1,295 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
let s:toggle = 0
|
||||||
|
|
||||||
|
" Buffer creates a new cover profile with 'go test -coverprofile' and changes
|
||||||
|
" the current buffers highlighting to show covered and uncovered sections of
|
||||||
|
" the code. If run again it clears the annotation.
|
||||||
|
function! go#coverage#BufferToggle(bang, ...) abort
|
||||||
|
if s:toggle
|
||||||
|
call go#coverage#Clear()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:0 == 0
|
||||||
|
return call(function('go#coverage#Buffer'), [a:bang])
|
||||||
|
endif
|
||||||
|
|
||||||
|
return call(function('go#coverage#Buffer'), [a:bang] + a:000)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Buffer creates a new cover profile with 'go test -coverprofile' and changes
|
||||||
|
" the current buffers highlighting to show covered and uncovered sections of
|
||||||
|
" the code. Calling it again reruns the tests and shows the last updated
|
||||||
|
" coverage.
|
||||||
|
function! go#coverage#Buffer(bang, ...) abort
|
||||||
|
|
||||||
|
" check if the version of Vim being tested supports matchaddpos()
|
||||||
|
if !exists("*matchaddpos")
|
||||||
|
call go#util#EchoError("GoCoverage is not supported by your version of Vim.")
|
||||||
|
return -1
|
||||||
|
endif
|
||||||
|
|
||||||
|
" check if there is any test file, if not we just return
|
||||||
|
try
|
||||||
|
let l:dir = go#util#Chdir(expand("%:p:h"))
|
||||||
|
if empty(glob("*_test.go"))
|
||||||
|
call go#util#EchoError("no test files available")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
finally
|
||||||
|
call go#util#Chdir(l:dir)
|
||||||
|
endtry
|
||||||
|
|
||||||
|
let s:toggle = 1
|
||||||
|
let l:tmpname = tempname()
|
||||||
|
|
||||||
|
if go#util#has_job()
|
||||||
|
call s:coverage_job({
|
||||||
|
\ 'cmd': ['go', 'test', '-tags', go#config#BuildTags(), '-coverprofile', l:tmpname] + a:000,
|
||||||
|
\ 'complete': function('s:coverage_callback', [l:tmpname]),
|
||||||
|
\ 'bang': a:bang,
|
||||||
|
\ 'for': 'GoTest',
|
||||||
|
\ 'statustype': 'coverage',
|
||||||
|
\ })
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if go#config#EchoCommandInfo()
|
||||||
|
call go#util#EchoProgress("testing...")
|
||||||
|
endif
|
||||||
|
|
||||||
|
let args = [a:bang, 0, "-coverprofile", l:tmpname]
|
||||||
|
if a:0
|
||||||
|
call extend(args, a:000)
|
||||||
|
endif
|
||||||
|
|
||||||
|
let id = call('go#test#Test', args)
|
||||||
|
|
||||||
|
if go#util#ShellError() == 0
|
||||||
|
call go#coverage#overlay(l:tmpname)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call delete(l:tmpname)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Clear clears and resets the buffer annotation matches
|
||||||
|
function! go#coverage#Clear() abort
|
||||||
|
call clearmatches()
|
||||||
|
|
||||||
|
if exists("s:toggle") | let s:toggle = 0 | endif
|
||||||
|
|
||||||
|
" remove the autocmd we defined
|
||||||
|
augroup vim-go-coverage
|
||||||
|
autocmd! * <buffer>
|
||||||
|
augroup end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Browser creates a new cover profile with 'go test -coverprofile' and opens
|
||||||
|
" a new HTML coverage page from that profile in a new browser
|
||||||
|
function! go#coverage#Browser(bang, ...) abort
|
||||||
|
let l:tmpname = tempname()
|
||||||
|
if go#util#has_job()
|
||||||
|
call s:coverage_job({
|
||||||
|
\ 'cmd': ['go', 'test', '-tags', go#config#BuildTags(), '-coverprofile', l:tmpname] + a:000,
|
||||||
|
\ 'complete': function('s:coverage_browser_callback', [l:tmpname]),
|
||||||
|
\ 'bang': a:bang,
|
||||||
|
\ 'for': 'GoTest',
|
||||||
|
\ 'statustype': 'coverage',
|
||||||
|
\ })
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let args = [a:bang, 0, "-coverprofile", l:tmpname]
|
||||||
|
if a:0
|
||||||
|
call extend(args, a:000)
|
||||||
|
endif
|
||||||
|
|
||||||
|
let id = call('go#test#Test', args)
|
||||||
|
|
||||||
|
if go#util#ShellError() == 0
|
||||||
|
call go#util#ExecInDir(['go', 'tool', 'cover', '-html=' . l:tmpname])
|
||||||
|
endif
|
||||||
|
|
||||||
|
call delete(l:tmpname)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Parses a single line from the cover file generated via go test -coverprofile
|
||||||
|
" and returns a single coverage profile block.
|
||||||
|
function! go#coverage#parsegocoverline(line) abort
|
||||||
|
" file:startline.col,endline.col numstmt count
|
||||||
|
let mx = '\([^:]\+\):\(\d\+\)\.\(\d\+\),\(\d\+\)\.\(\d\+\)\s\(\d\+\)\s\(\d\+\)'
|
||||||
|
let tokens = matchlist(a:line, mx)
|
||||||
|
let ret = {}
|
||||||
|
let ret.file = tokens[1]
|
||||||
|
let ret.startline = str2nr(tokens[2])
|
||||||
|
let ret.startcol = str2nr(tokens[3])
|
||||||
|
let ret.endline = str2nr(tokens[4])
|
||||||
|
let ret.endcol = str2nr(tokens[5])
|
||||||
|
let ret.numstmt = tokens[6]
|
||||||
|
let ret.cnt = tokens[7]
|
||||||
|
return ret
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Generates matches to be added to matchaddpos for the given coverage profile
|
||||||
|
" block
|
||||||
|
function! go#coverage#genmatch(cov) abort
|
||||||
|
let color = 'goCoverageCovered'
|
||||||
|
if a:cov.cnt == 0
|
||||||
|
let color = 'goCoverageUncover'
|
||||||
|
endif
|
||||||
|
|
||||||
|
let matches = []
|
||||||
|
|
||||||
|
" if start and end are the same, also specify the byte length
|
||||||
|
" example: foo.go:92.2,92.65 1 0
|
||||||
|
if a:cov.startline == a:cov.endline
|
||||||
|
call add(matches, {
|
||||||
|
\ 'group': color,
|
||||||
|
\ 'pos': [[a:cov.startline, a:cov.startcol, a:cov.endcol - a:cov.startcol]],
|
||||||
|
\ 'priority': 2,
|
||||||
|
\ })
|
||||||
|
return matches
|
||||||
|
endif
|
||||||
|
|
||||||
|
" add start columns. Because we don't know the length of the of
|
||||||
|
" the line, we assume it is at maximum 200 bytes. I know this is hacky,
|
||||||
|
" but that's only way of fixing the issue
|
||||||
|
call add(matches, {
|
||||||
|
\ 'group': color,
|
||||||
|
\ 'pos': [[a:cov.startline, a:cov.startcol, 200]],
|
||||||
|
\ 'priority': 2,
|
||||||
|
\ })
|
||||||
|
|
||||||
|
" and then the remaining lines
|
||||||
|
let start_line = a:cov.startline
|
||||||
|
while start_line < a:cov.endline
|
||||||
|
let start_line += 1
|
||||||
|
call add(matches, {
|
||||||
|
\ 'group': color,
|
||||||
|
\ 'pos': [[start_line]],
|
||||||
|
\ 'priority': 2,
|
||||||
|
\ })
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
" finally end columns
|
||||||
|
call add(matches, {
|
||||||
|
\ 'group': color,
|
||||||
|
\ 'pos': [[a:cov.endline, a:cov.endcol-1]],
|
||||||
|
\ 'priority': 2,
|
||||||
|
\ })
|
||||||
|
|
||||||
|
return matches
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Reads the given coverprofile file and annotates the current buffer
|
||||||
|
function! go#coverage#overlay(file) abort
|
||||||
|
if !filereadable(a:file)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let lines = readfile(a:file)
|
||||||
|
|
||||||
|
" cover mode, by default it's 'set'. Just here for debugging purposes
|
||||||
|
let mode = lines[0]
|
||||||
|
|
||||||
|
" contains matches for matchaddpos()
|
||||||
|
let matches = []
|
||||||
|
|
||||||
|
" first mark all lines as goCoverageNormalText. We use a custom group to not
|
||||||
|
" interfere with other buffers highlightings. Because the priority is
|
||||||
|
" lower than the cover and uncover matches, it'll be overridden.
|
||||||
|
let cnt = 1
|
||||||
|
while cnt <= line('$')
|
||||||
|
call add(matches, {'group': 'goCoverageNormalText', 'pos': [cnt], 'priority': 1})
|
||||||
|
let cnt += 1
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
let fname = expand('%')
|
||||||
|
|
||||||
|
" when called for a _test.go file, run the coverage for the actuall file
|
||||||
|
" file
|
||||||
|
if fname =~# '^\f\+_test\.go$'
|
||||||
|
let l:root = split(fname, '_test.go$')[0]
|
||||||
|
let fname = l:root . ".go"
|
||||||
|
|
||||||
|
if !filereadable(fname)
|
||||||
|
call go#util#EchoError("couldn't find ".fname)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" open the alternate file to show the coverage
|
||||||
|
exe ":edit ". fnamemodify(fname, ":p")
|
||||||
|
endif
|
||||||
|
|
||||||
|
" cov.file includes only the filename itself, without full path
|
||||||
|
let fname = fnamemodify(fname, ":t")
|
||||||
|
|
||||||
|
for line in lines[1:]
|
||||||
|
let cov = go#coverage#parsegocoverline(line)
|
||||||
|
|
||||||
|
" TODO(arslan): for now only include the coverage for the current
|
||||||
|
" buffer
|
||||||
|
if fname != fnamemodify(cov.file, ':t')
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
call extend(matches, go#coverage#genmatch(cov))
|
||||||
|
endfor
|
||||||
|
|
||||||
|
" clear the matches if we leave the buffer
|
||||||
|
augroup vim-go-coverage
|
||||||
|
autocmd! * <buffer>
|
||||||
|
autocmd BufWinLeave <buffer> call go#coverage#Clear()
|
||||||
|
augroup end
|
||||||
|
|
||||||
|
for m in matches
|
||||||
|
call matchaddpos(m.group, m.pos)
|
||||||
|
endfor
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
" ---------------------
|
||||||
|
" | Vim job callbacks |
|
||||||
|
" ---------------------
|
||||||
|
"
|
||||||
|
function s:coverage_job(args)
|
||||||
|
" autowrite is not enabled for jobs
|
||||||
|
call go#cmd#autowrite()
|
||||||
|
|
||||||
|
let disabled_term = 0
|
||||||
|
if go#config#TermEnabled()
|
||||||
|
let disabled_term = 1
|
||||||
|
call go#config#SetTermEnabled(0)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#job#Spawn(a:args.cmd, a:args)
|
||||||
|
|
||||||
|
if disabled_term
|
||||||
|
call go#config#SetTermEnabled(1)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" coverage_callback is called when the coverage execution is finished
|
||||||
|
function! s:coverage_callback(coverfile, job, exit_status, data)
|
||||||
|
if a:exit_status == 0
|
||||||
|
call go#coverage#overlay(a:coverfile)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call delete(a:coverfile)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:coverage_browser_callback(coverfile, job, exit_status, data)
|
||||||
|
if a:exit_status == 0
|
||||||
|
call go#util#ExecInDir(['go', 'tool', 'cover', '-html=' . a:coverfile])
|
||||||
|
endif
|
||||||
|
|
||||||
|
call delete(a:coverfile)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
1771
sources_non_forked/vim-go/autoload/go/debug.vim
Normal file
1771
sources_non_forked/vim-go/autoload/go/debug.vim
Normal file
File diff suppressed because it is too large
Load diff
177
sources_non_forked/vim-go/autoload/go/debug_test.vim
Normal file
177
sources_non_forked/vim-go/autoload/go/debug_test.vim
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
function! Test_GoDebugStart_Empty() abort
|
||||||
|
call s:debug()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Test_GoDebugStart_RelativePackage() abort
|
||||||
|
call s:debug('./debug/debugmain')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Test_GoDebugStart_RelativePackage_NullModule() abort
|
||||||
|
call s:debug('./debug/debugmain', 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Test_GoDebugStart_Package() abort
|
||||||
|
call s:debug('vim-go.test/debug/debugmain')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Test_GoDebugStart_Errors() abort
|
||||||
|
if !go#util#has_job()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:tmp = gotest#load_fixture('debug/compilerror/main.go')
|
||||||
|
|
||||||
|
let l:expected = [
|
||||||
|
\ {'lnum': 0, 'bufnr': 0, 'col': 0, 'valid': 0, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': '# vim-go.test/debug/compilerror'},
|
||||||
|
\ {'lnum': 6, 'bufnr': bufnr('%'), 'col': 22, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': ' syntax error: unexpected newline, expecting comma or )'},
|
||||||
|
\ {'lnum': 0, 'bufnr': 0, 'col': 0, 'valid': 0, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'exit status 2'}
|
||||||
|
\]
|
||||||
|
call setqflist([], 'r')
|
||||||
|
|
||||||
|
call assert_false(exists(':GoDebugStop'))
|
||||||
|
|
||||||
|
call go#util#Chdir('debug/compilerror')
|
||||||
|
|
||||||
|
call go#debug#Start('debug')
|
||||||
|
|
||||||
|
let l:actual = getqflist()
|
||||||
|
let l:start = reltime()
|
||||||
|
while len(l:actual) == 0 && reltimefloat(reltime(l:start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
let l:actual = getqflist()
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call gotest#assert_quickfix(l:actual, l:expected)
|
||||||
|
call assert_false(exists(':GoDebugStop'))
|
||||||
|
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
" clear the quickfix lists
|
||||||
|
call setqflist([], 'r')
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Test_GoDebugModeRemapsAndRestoresKeys() abort
|
||||||
|
if !go#util#has_job()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
let g:go_debug_mappings = {'(go-debug-continue)': {'key': 'q', 'arguments': '<nowait>'}}
|
||||||
|
let l:tmp = gotest#load_fixture('debug/debugmain/debugmain.go')
|
||||||
|
|
||||||
|
call assert_false(exists(':GoDebugStop'))
|
||||||
|
|
||||||
|
call go#util#Chdir('debug/debugmain')
|
||||||
|
|
||||||
|
call go#debug#Start('debug')
|
||||||
|
|
||||||
|
let l:start = reltime()
|
||||||
|
while maparg('q') == '' && reltimefloat(reltime(l:start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call assert_false(exists(':GoDebugStart'))
|
||||||
|
call assert_equal('<Plug>(go-debug-continue)', maparg('q', 'n', 0))
|
||||||
|
|
||||||
|
call go#debug#Stop()
|
||||||
|
while exists(':GoDebugStop') && reltimefloat(reltime(l:start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
endwhile
|
||||||
|
call assert_equal('', maparg('q'))
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Test_GoDebugStopRemovesPlugMappings() abort
|
||||||
|
if !go#util#has_job()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:tmp = gotest#load_fixture('debug/debugmain/debugmain.go')
|
||||||
|
|
||||||
|
call assert_false(exists(':GoDebugStop'))
|
||||||
|
|
||||||
|
call go#util#Chdir('debug/debugmain')
|
||||||
|
|
||||||
|
call go#debug#Start('debug')
|
||||||
|
|
||||||
|
let l:start = reltime()
|
||||||
|
while maparg('<Plug>(go-debug-stop)') == '' && reltimefloat(reltime(l:start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call assert_false(exists(':GoDebugStart'))
|
||||||
|
call assert_equal(':<C-U>call go#debug#Stop()<CR>', maparg('<Plug>(go-debug-stop)', 'n', 0))
|
||||||
|
|
||||||
|
call go#debug#Stop()
|
||||||
|
while exists(':GoDebugStop') && reltimefloat(reltime(l:start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
endwhile
|
||||||
|
call assert_equal('', maparg('<Plug>(go-debug-stop'))
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" s:debug takes 2 optional arguments. The first is a package to debug. The
|
||||||
|
" second is a flag to indicate whether to reset GOPATH after
|
||||||
|
" gotest#load_fixture is called in order to test behavior outside of GOPATH.
|
||||||
|
function! s:debug(...) abort
|
||||||
|
if !go#util#has_job()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
let $oldgopath = $GOPATH
|
||||||
|
let l:tmp = gotest#load_fixture('debug/debugmain/debugmain.go')
|
||||||
|
|
||||||
|
if a:0 > 1 && a:2 == 1
|
||||||
|
let $GOPATH = $oldgopath
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#debug#Breakpoint(6)
|
||||||
|
|
||||||
|
call assert_false(exists(':GoDebugStop'))
|
||||||
|
|
||||||
|
if a:0 == 0
|
||||||
|
call go#util#Chdir(printf('%s/src/debug/debugmain', l:tmp))
|
||||||
|
let l:job = go#debug#Start('debug')
|
||||||
|
else
|
||||||
|
let l:job = go#debug#Start('debug', a:1)
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:start = reltime()
|
||||||
|
while !exists(':GoDebugStop') && reltimefloat(reltime(l:start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call assert_true(exists(':GoDebugStop'))
|
||||||
|
call gotest#assert_quickfix(getqflist(), [])
|
||||||
|
|
||||||
|
call go#debug#Stop()
|
||||||
|
|
||||||
|
if !has('nvim')
|
||||||
|
call assert_equal(job_status(l:job), 'dead')
|
||||||
|
endif
|
||||||
|
|
||||||
|
call assert_false(exists(':GoDebugStop'))
|
||||||
|
|
||||||
|
finally
|
||||||
|
call go#debug#Breakpoint(6)
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
26
sources_non_forked/vim-go/autoload/go/decls.vim
Normal file
26
sources_non_forked/vim-go/autoload/go/decls.vim
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
function! go#decls#Decls(mode, ...) abort
|
||||||
|
let decls_mode = go#config#DeclsMode()
|
||||||
|
if decls_mode == 'ctrlp'
|
||||||
|
call ctrlp#init(call("ctrlp#decls#cmd", [a:mode] + a:000))
|
||||||
|
elseif decls_mode == 'fzf'
|
||||||
|
call call("fzf#decls#cmd", [a:mode] + a:000)
|
||||||
|
else
|
||||||
|
if globpath(&rtp, 'plugin/ctrlp.vim') != ""
|
||||||
|
call ctrlp#init(call("ctrlp#decls#cmd", [a:mode] + a:000))
|
||||||
|
elseif globpath(&rtp, 'plugin/fzf.vim') != ""
|
||||||
|
call call("fzf#decls#cmd", [a:mode] + a:000)
|
||||||
|
else
|
||||||
|
call go#util#EchoError("neither ctrlp.vim nor fzf.vim are installed. Please install either one")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
366
sources_non_forked/vim-go/autoload/go/def.vim
Normal file
366
sources_non_forked/vim-go/autoload/go/def.vim
Normal file
|
@ -0,0 +1,366 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
let s:go_stack = []
|
||||||
|
let s:go_stack_level = 0
|
||||||
|
|
||||||
|
function! go#def#Jump(mode, type) abort
|
||||||
|
let l:fname = fnamemodify(expand("%"), ':p:gs?\\?/?')
|
||||||
|
|
||||||
|
" so guru right now is slow for some people. previously we were using
|
||||||
|
" godef which also has it's own quirks. But this issue come up so many
|
||||||
|
" times I've decided to support both. By default we still use guru as it
|
||||||
|
" covers all edge cases, but now anyone can switch to godef if they wish
|
||||||
|
let bin_name = go#config#DefMode()
|
||||||
|
if bin_name == 'godef'
|
||||||
|
let l:cmd = ['godef',
|
||||||
|
\ '-f=' . l:fname,
|
||||||
|
\ '-o=' . go#util#OffsetCursor(),
|
||||||
|
\ '-t']
|
||||||
|
|
||||||
|
if &modified
|
||||||
|
let l:stdin_content = join(go#util#GetLines(), "\n")
|
||||||
|
call add(l:cmd, "-i")
|
||||||
|
let [l:out, l:err] = go#util#ExecInDir(l:cmd, l:stdin_content)
|
||||||
|
else
|
||||||
|
let [l:out, l:err] = go#util#ExecInDir(l:cmd)
|
||||||
|
endif
|
||||||
|
elseif bin_name == 'guru'
|
||||||
|
let cmd = [go#path#CheckBinPath(bin_name)]
|
||||||
|
let buildtags = go#config#BuildTags()
|
||||||
|
if buildtags isnot ''
|
||||||
|
let cmd += ['-tags', buildtags]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let stdin_content = ""
|
||||||
|
|
||||||
|
if &modified
|
||||||
|
let content = join(go#util#GetLines(), "\n")
|
||||||
|
let stdin_content = fname . "\n" . strlen(content) . "\n" . content
|
||||||
|
call add(cmd, "-modified")
|
||||||
|
endif
|
||||||
|
|
||||||
|
call extend(cmd, ["definition", fname . ':#' . go#util#OffsetCursor()])
|
||||||
|
|
||||||
|
if go#util#has_job()
|
||||||
|
let l:state = {}
|
||||||
|
let l:spawn_args = {
|
||||||
|
\ 'cmd': cmd,
|
||||||
|
\ 'complete': function('s:jump_to_declaration_cb', [a:mode, bin_name], l:state),
|
||||||
|
\ 'for': '_',
|
||||||
|
\ 'statustype': 'searching declaration',
|
||||||
|
\ }
|
||||||
|
|
||||||
|
if &modified
|
||||||
|
let l:spawn_args.input = stdin_content
|
||||||
|
endif
|
||||||
|
|
||||||
|
call s:def_job(spawn_args, l:state)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if &modified
|
||||||
|
let [l:out, l:err] = go#util#ExecInDir(l:cmd, l:stdin_content)
|
||||||
|
else
|
||||||
|
let [l:out, l:err] = go#util#ExecInDir(l:cmd)
|
||||||
|
endif
|
||||||
|
elseif bin_name == 'gopls'
|
||||||
|
if !go#config#GoplsEnabled()
|
||||||
|
call go#util#EchoError("go_def_mode is 'gopls', but gopls is disabled")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" reset l:fname when using gopls so that the filename will be converted to
|
||||||
|
" a URI correctly on windows.
|
||||||
|
let l:fname = expand('%')
|
||||||
|
let [l:line, l:col] = go#lsp#lsp#Position()
|
||||||
|
" delegate to gopls, with an empty job object and an exit status of 0
|
||||||
|
" (they're irrelevant for gopls).
|
||||||
|
if a:type
|
||||||
|
call go#lsp#TypeDef(l:fname, l:line, l:col, function('s:jump_to_declaration_cb', [a:mode, 'gopls', {}, 0]))
|
||||||
|
else
|
||||||
|
call go#lsp#Definition(l:fname, l:line, l:col, function('s:jump_to_declaration_cb', [a:mode, 'gopls', {}, 0]))
|
||||||
|
endif
|
||||||
|
return
|
||||||
|
else
|
||||||
|
call go#util#EchoError('go_def_mode value: '. bin_name .' is not valid. Valid values are: [godef, guru, gopls]')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:err
|
||||||
|
call go#util#EchoError(out)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#def#jump_to_declaration(out, a:mode, bin_name)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:jump_to_declaration_cb(mode, bin_name, job, exit_status, data) abort dict
|
||||||
|
if a:exit_status != 0
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#def#jump_to_declaration(a:data[0], a:mode, a:bin_name)
|
||||||
|
|
||||||
|
" capture the active window so that callbacks for jobs, exit_cb and
|
||||||
|
" close_cb, and callbacks for gopls can return to it when a:mode caused a
|
||||||
|
" split.
|
||||||
|
let self.winid = win_getid(winnr())
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" go#def#jump_to_declaration parses out (expected to be
|
||||||
|
" 'filename:line:col: message').
|
||||||
|
function! go#def#jump_to_declaration(out, mode, bin_name) abort
|
||||||
|
let final_out = a:out
|
||||||
|
if a:bin_name == "godef"
|
||||||
|
" append the type information to the same line so it will be parsed
|
||||||
|
" correctly using guru's output format.
|
||||||
|
" This makes it compatible with guru output.
|
||||||
|
let final_out = join(split(a:out, '\n'), ':')
|
||||||
|
endif
|
||||||
|
|
||||||
|
" strip line ending
|
||||||
|
let out = split(final_out, go#util#LineEnding())[0]
|
||||||
|
if go#util#IsWin()
|
||||||
|
let parts = split(out, '\(^[a-zA-Z]\)\@<!:')
|
||||||
|
else
|
||||||
|
let parts = split(out, ':')
|
||||||
|
endif
|
||||||
|
|
||||||
|
if len(parts) == 0
|
||||||
|
call go#util#EchoError('go jump_to_declaration '. a:bin_name .' output is not valid.')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let line = 1
|
||||||
|
let col = 1
|
||||||
|
let ident = 0
|
||||||
|
let filename = parts[0]
|
||||||
|
if len(parts) > 1
|
||||||
|
let line = parts[1]
|
||||||
|
endif
|
||||||
|
if len(parts) > 2
|
||||||
|
let col = parts[2]
|
||||||
|
endif
|
||||||
|
if len(parts) > 3
|
||||||
|
let ident = parts[3]
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Remove anything newer than the current position, just like basic
|
||||||
|
" vim tag support
|
||||||
|
if s:go_stack_level == 0
|
||||||
|
let s:go_stack = []
|
||||||
|
else
|
||||||
|
let s:go_stack = s:go_stack[0:s:go_stack_level-1]
|
||||||
|
endif
|
||||||
|
|
||||||
|
" increment the stack counter
|
||||||
|
let s:go_stack_level += 1
|
||||||
|
|
||||||
|
" push it on to the jumpstack
|
||||||
|
let stack_entry = {'line': line("."), 'col': col("."), 'file': expand('%:p'), 'ident': ident}
|
||||||
|
call add(s:go_stack, stack_entry)
|
||||||
|
|
||||||
|
" needed for restoring back user setting this is because there are two
|
||||||
|
" modes of switchbuf which we need based on the split mode
|
||||||
|
let old_switchbuf = &switchbuf
|
||||||
|
|
||||||
|
normal! m'
|
||||||
|
if filename != fnamemodify(expand("%"), ':p:gs?\\?/?')
|
||||||
|
" jump to existing buffer if, 1. we have enabled it, 2. the buffer is loaded
|
||||||
|
" and 3. there is buffer window number we switch to
|
||||||
|
if go#config#DefReuseBuffer() && bufwinnr(filename) != -1
|
||||||
|
" jump to existing buffer if it exists
|
||||||
|
call win_gotoid(bufwinid(filename))
|
||||||
|
else
|
||||||
|
if &modified
|
||||||
|
let cmd = 'hide edit'
|
||||||
|
else
|
||||||
|
let cmd = 'edit'
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:mode == "tab"
|
||||||
|
let &switchbuf = "useopen,usetab,newtab"
|
||||||
|
if bufloaded(filename) == 0
|
||||||
|
tab split
|
||||||
|
else
|
||||||
|
let cmd = 'sbuf'
|
||||||
|
endif
|
||||||
|
elseif a:mode == "split"
|
||||||
|
split
|
||||||
|
elseif a:mode == "vsplit"
|
||||||
|
vsplit
|
||||||
|
endif
|
||||||
|
|
||||||
|
" open the file and jump to line and column
|
||||||
|
try
|
||||||
|
exec cmd fnameescape(fnamemodify(filename, ':.'))
|
||||||
|
catch
|
||||||
|
if stridx(v:exception, ':E325:') < 0
|
||||||
|
call go#util#EchoError(v:exception)
|
||||||
|
endif
|
||||||
|
endtry
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
call cursor(line, col)
|
||||||
|
|
||||||
|
" also align the line to middle of the view
|
||||||
|
normal! zz
|
||||||
|
|
||||||
|
let &switchbuf = old_switchbuf
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#def#SelectStackEntry() abort
|
||||||
|
let target_window = go#ui#GetReturnWindow()
|
||||||
|
if empty(target_window)
|
||||||
|
let target_window = winnr()
|
||||||
|
endif
|
||||||
|
|
||||||
|
let highlighted_stack_entry = matchstr(getline("."), '^..\zs\(\d\+\)')
|
||||||
|
if !empty(highlighted_stack_entry)
|
||||||
|
execute target_window . "wincmd w"
|
||||||
|
call go#def#Stack(str2nr(highlighted_stack_entry))
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#ui#CloseWindow()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#def#StackUI() abort
|
||||||
|
if len(s:go_stack) == 0
|
||||||
|
call go#util#EchoError("godef stack empty")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let stackOut = ['" <Up>,<Down>:navigate <Enter>:jump <Esc>,q:exit']
|
||||||
|
|
||||||
|
let i = 0
|
||||||
|
while i < len(s:go_stack)
|
||||||
|
let entry = s:go_stack[i]
|
||||||
|
let prefix = ""
|
||||||
|
|
||||||
|
if i == s:go_stack_level
|
||||||
|
let prefix = ">"
|
||||||
|
else
|
||||||
|
let prefix = " "
|
||||||
|
endif
|
||||||
|
|
||||||
|
call add(stackOut, printf("%s %d %s|%d col %d|%s",
|
||||||
|
\ prefix, i+1, entry["file"], entry["line"], entry["col"], entry["ident"]))
|
||||||
|
let i += 1
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
if s:go_stack_level == i
|
||||||
|
call add(stackOut, "> ")
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#ui#OpenWindow("GoDef Stack", stackOut, "godefstack")
|
||||||
|
|
||||||
|
noremap <buffer> <silent> <CR> :<C-U>call go#def#SelectStackEntry()<CR>
|
||||||
|
noremap <buffer> <silent> <Esc> :<C-U>call go#ui#CloseWindow()<CR>
|
||||||
|
noremap <buffer> <silent> q :<C-U>call go#ui#CloseWindow()<CR>
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#def#StackClear(...) abort
|
||||||
|
let s:go_stack = []
|
||||||
|
let s:go_stack_level = 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#def#StackPop(...) abort
|
||||||
|
if len(s:go_stack) == 0
|
||||||
|
call go#util#EchoError("godef stack empty")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if s:go_stack_level == 0
|
||||||
|
call go#util#EchoError("at bottom of the godef stack")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !len(a:000)
|
||||||
|
let numPop = 1
|
||||||
|
else
|
||||||
|
let numPop = a:1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let newLevel = str2nr(s:go_stack_level) - str2nr(numPop)
|
||||||
|
call go#def#Stack(newLevel + 1)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#def#Stack(...) abort
|
||||||
|
if len(s:go_stack) == 0
|
||||||
|
call go#util#EchoError("godef stack empty")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !len(a:000)
|
||||||
|
" Display interactive stack
|
||||||
|
call go#def#StackUI()
|
||||||
|
return
|
||||||
|
else
|
||||||
|
let jumpTarget = a:1
|
||||||
|
endif
|
||||||
|
|
||||||
|
if jumpTarget !~ '^\d\+$'
|
||||||
|
if jumpTarget !~ '^\s*$'
|
||||||
|
call go#util#EchoError("location must be a number")
|
||||||
|
endif
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let jumpTarget = str2nr(jumpTarget) - 1
|
||||||
|
|
||||||
|
if jumpTarget >= 0 && jumpTarget < len(s:go_stack)
|
||||||
|
let s:go_stack_level = jumpTarget
|
||||||
|
let target = s:go_stack[s:go_stack_level]
|
||||||
|
|
||||||
|
" jump
|
||||||
|
if expand('%:p') != target["file"]
|
||||||
|
if &modified
|
||||||
|
exec 'hide edit' target["file"]
|
||||||
|
else
|
||||||
|
exec 'edit' target["file"]
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
call cursor(target["line"], target["col"])
|
||||||
|
normal! zz
|
||||||
|
else
|
||||||
|
call go#util#EchoError("invalid location. Try :GoDefStack to see the list of valid entries")
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function s:def_job(args, state) abort
|
||||||
|
let l:start_options = go#job#Options(a:args)
|
||||||
|
|
||||||
|
let l:state = a:state
|
||||||
|
function! s:exit_cb(next, job, exitval) dict
|
||||||
|
call call(a:next, [a:job, a:exitval])
|
||||||
|
if has_key(self, 'winid')
|
||||||
|
call win_gotoid(self.winid)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
let l:start_options.exit_cb = funcref('s:exit_cb', [l:start_options.exit_cb], l:state)
|
||||||
|
|
||||||
|
function! s:close_cb(next, ch) dict
|
||||||
|
call call(a:next, [a:ch])
|
||||||
|
if has_key(self, 'winid')
|
||||||
|
call win_gotoid(self.winid)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
let l:start_options.close_cb = funcref('s:close_cb', [l:start_options.close_cb], l:state)
|
||||||
|
|
||||||
|
if &modified
|
||||||
|
let l:tmpname = tempname()
|
||||||
|
call writefile(split(a:args.input, "\n"), l:tmpname, "b")
|
||||||
|
let l:start_options.in_io = "file"
|
||||||
|
let l:start_options.in_name = l:tmpname
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#job#Start(a:args.cmd, l:start_options)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
223
sources_non_forked/vim-go/autoload/go/def_test.vim
Normal file
223
sources_non_forked/vim-go/autoload/go/def_test.vim
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
scriptencoding utf-8
|
||||||
|
|
||||||
|
func! Test_jump_to_declaration_guru() abort
|
||||||
|
try
|
||||||
|
let l:filename = 'def/jump.go'
|
||||||
|
let l:lnum = 5
|
||||||
|
let l:col = 6
|
||||||
|
let l:tmp = gotest#load_fixture(l:filename)
|
||||||
|
|
||||||
|
let l:guru_out = printf("%s:%d:%d: defined here as func main", l:filename, l:lnum, l:col)
|
||||||
|
call go#def#jump_to_declaration(l:guru_out, "", 'guru')
|
||||||
|
|
||||||
|
call assert_equal(l:filename, bufname("%"))
|
||||||
|
call assert_equal(l:lnum, getcurpos()[1])
|
||||||
|
call assert_equal(l:col, getcurpos()[2])
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_jump_to_declaration_godef() abort
|
||||||
|
try
|
||||||
|
let l:filename = 'def/jump.go'
|
||||||
|
let l:lnum = 5
|
||||||
|
let l:col = 6
|
||||||
|
let l:tmp = gotest#load_fixture(l:filename)
|
||||||
|
|
||||||
|
let l:godef_out = printf("%s:%d:%d\ndefined here as func main", l:filename, l:lnum, l:col)
|
||||||
|
call go#def#jump_to_declaration(godef_out, "", 'godef')
|
||||||
|
|
||||||
|
call assert_equal(l:filename, bufname("%"))
|
||||||
|
call assert_equal(l:lnum, getcurpos()[1])
|
||||||
|
call assert_equal(l:col, getcurpos()[2])
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_Jump_leaves_lists() abort
|
||||||
|
try
|
||||||
|
let l:filename = 'def/jump.go'
|
||||||
|
let l:tmp = gotest#load_fixture(l:filename)
|
||||||
|
|
||||||
|
let l:expected = [{'lnum': 10, 'bufnr': bufnr('%'), 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'quux'}]
|
||||||
|
|
||||||
|
call setloclist(0, copy(l:expected), 'r' )
|
||||||
|
call setqflist(copy(l:expected), 'r' )
|
||||||
|
|
||||||
|
let l:bufnr = bufnr('%')
|
||||||
|
call cursor(6, 7)
|
||||||
|
|
||||||
|
if !go#util#has_job()
|
||||||
|
let g:go_def_mode='godef'
|
||||||
|
endif
|
||||||
|
call go#def#Jump('', 0)
|
||||||
|
|
||||||
|
if !go#util#has_job()
|
||||||
|
unlet g:go_def_mode
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:start = reltime()
|
||||||
|
while bufnr('%') == l:bufnr && reltimefloat(reltime(l:start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
let l:actual = getloclist(0)
|
||||||
|
call gotest#assert_quickfix(l:actual, l:expected)
|
||||||
|
|
||||||
|
let l:actual = getqflist()
|
||||||
|
call gotest#assert_quickfix(l:actual, l:expected)
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_DefJump_gopls_simple_first() abort
|
||||||
|
if !go#util#has_job()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
let g:go_def_mode = 'gopls'
|
||||||
|
|
||||||
|
let l:tmp = gotest#write_file('simple/firstposition/firstposition.go', [
|
||||||
|
\ 'package firstposition',
|
||||||
|
\ '',
|
||||||
|
\ 'func Example() {',
|
||||||
|
\ "\tid := " . '"foo"',
|
||||||
|
\ "\tprintln(" . '"id:", id)',
|
||||||
|
\ '}',
|
||||||
|
\ ] )
|
||||||
|
|
||||||
|
let l:expected = [0, 4, 2, 0]
|
||||||
|
|
||||||
|
call assert_notequal(l:expected, getpos('.'))
|
||||||
|
|
||||||
|
call go#def#Jump('', 0)
|
||||||
|
|
||||||
|
let l:start = reltime()
|
||||||
|
while getpos('.') != l:expected && reltimefloat(reltime(l:start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call assert_equal(l:expected, getpos('.'))
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
unlet g:go_def_mode
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_DefJump_gopls_simple_last() abort
|
||||||
|
if !go#util#has_job()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
let g:go_def_mode = 'gopls'
|
||||||
|
|
||||||
|
let l:tmp = gotest#write_file('simple/lastposition/lastposition.go', [
|
||||||
|
\ 'package lastposition',
|
||||||
|
\ '',
|
||||||
|
\ 'func Example() {',
|
||||||
|
\ "\tid := " . '"foo"',
|
||||||
|
\ "\tprintln(" . '"id:", id)',
|
||||||
|
\ '}',
|
||||||
|
\ ] )
|
||||||
|
|
||||||
|
let l:expected = [0, 4, 2, 0]
|
||||||
|
|
||||||
|
call assert_notequal(l:expected, getpos('.'))
|
||||||
|
|
||||||
|
call go#def#Jump('', 0)
|
||||||
|
|
||||||
|
let l:start = reltime()
|
||||||
|
while getpos('.') != l:expected && reltimefloat(reltime(l:start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call assert_equal(l:expected, getpos('.'))
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
unlet g:go_def_mode
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_DefJump_gopls_MultipleCodeUnit_first() abort
|
||||||
|
if !go#util#has_job()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
let g:go_def_mode = 'gopls'
|
||||||
|
|
||||||
|
let l:tmp = gotest#write_file('multiplecodeunit/firstposition/firstposition.go', [
|
||||||
|
\ 'package firstposition',
|
||||||
|
\ '',
|
||||||
|
\ 'func Example() {',
|
||||||
|
\ "\t𐐀, id := " . '"foo", "bar"',
|
||||||
|
\ "\tprintln(" . '"(𐐀, id):", 𐐀, id)',
|
||||||
|
\ '}',
|
||||||
|
\ ] )
|
||||||
|
|
||||||
|
let l:expected = [0, 4, 8, 0]
|
||||||
|
call assert_notequal(l:expected, getpos('.'))
|
||||||
|
|
||||||
|
call go#def#Jump('', 0)
|
||||||
|
|
||||||
|
let l:start = reltime()
|
||||||
|
while getpos('.') != l:expected && reltimefloat(reltime(l:start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call assert_equal(l:expected, getpos('.'))
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
unlet g:go_def_mode
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
|
||||||
|
func! Test_DefJump_gopls_MultipleCodeUnit_last() abort
|
||||||
|
if !go#util#has_job()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
let g:go_def_mode = 'gopls'
|
||||||
|
|
||||||
|
let l:tmp = gotest#write_file('multiplecodeunit/lastposition/lastposition.go', [
|
||||||
|
\ 'package lastposition',
|
||||||
|
\ '',
|
||||||
|
\ 'func Example() {',
|
||||||
|
\ "\t𐐀, id := " . '"foo", "bar"',
|
||||||
|
\ "\tprintln(" . '"(𐐀, id):", 𐐀, id)',
|
||||||
|
\ '}',
|
||||||
|
\ ] )
|
||||||
|
|
||||||
|
let l:expected = [0, 4, 8, 0]
|
||||||
|
call assert_notequal(l:expected, getpos('.'))
|
||||||
|
|
||||||
|
call go#def#Jump('', 0)
|
||||||
|
|
||||||
|
let l:start = reltime()
|
||||||
|
while getpos('.') != l:expected && reltimefloat(reltime(l:start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call assert_equal(l:expected, getpos('.'))
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
unlet g:go_def_mode
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
217
sources_non_forked/vim-go/autoload/go/doc.vim
Normal file
217
sources_non_forked/vim-go/autoload/go/doc.vim
Normal file
|
@ -0,0 +1,217 @@
|
||||||
|
" Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
" Use of this source code is governed by a BSD-style
|
||||||
|
" license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
scriptencoding utf-8
|
||||||
|
|
||||||
|
let s:buf_nr = -1
|
||||||
|
|
||||||
|
function! go#doc#OpenBrowser(...) abort
|
||||||
|
if len(a:000) == 0
|
||||||
|
let [l:out, l:err] = go#lsp#DocLink()
|
||||||
|
if l:err
|
||||||
|
call go#util#EchoError(l:out)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if len(l:out) == 0
|
||||||
|
call go#util#EchoWarning("could not find path for doc URL")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:godoc_url = printf('%s/%s', go#config#DocUrl(), l:out)
|
||||||
|
|
||||||
|
call go#util#OpenBrowser(l:godoc_url)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let pkgs = s:godocWord(a:000)
|
||||||
|
if empty(pkgs)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let pkg = pkgs[0]
|
||||||
|
let exported_name = pkgs[1]
|
||||||
|
|
||||||
|
" example url: https://godoc.org/github.com/fatih/set#Set
|
||||||
|
let godoc_url = printf('%s/%s#%s', go#config#DocUrl(), pkg, exported_name)
|
||||||
|
call go#util#OpenBrowser(godoc_url)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#doc#Open(newmode, mode, ...) abort
|
||||||
|
" With argument: run "godoc [arg]".
|
||||||
|
if len(a:000)
|
||||||
|
let [l:out, l:err] = go#util#Exec(['go', 'doc'] + a:000)
|
||||||
|
else " Without argument: use gopls to get documentation
|
||||||
|
let [l:out, l:err] = go#lsp#Doc()
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:err
|
||||||
|
call go#util#EchoError(out)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
call s:GodocView(a:newmode, a:mode, l:out)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:GodocView(newposition, position, content) abort
|
||||||
|
" popup window
|
||||||
|
if go#config#DocPopupWindow()
|
||||||
|
if exists('*popup_atcursor') && exists('*popup_clear')
|
||||||
|
call popup_clear()
|
||||||
|
|
||||||
|
let borderchars = ['-', '|', '-', '|', '+', '+', '+', '+']
|
||||||
|
if &encoding == "utf-8"
|
||||||
|
let borderchars = ['─', '│', '─', '│', '┌', '┐', '┘', '└']
|
||||||
|
endif
|
||||||
|
call popup_atcursor(split(a:content, '\n'), {
|
||||||
|
\ 'padding': [1, 1, 1, 1],
|
||||||
|
\ 'borderchars': borderchars,
|
||||||
|
\ 'border': [1, 1, 1, 1],
|
||||||
|
\ })
|
||||||
|
elseif has('nvim') && exists('*nvim_open_win')
|
||||||
|
let lines = split(a:content, '\n')
|
||||||
|
let height = 0
|
||||||
|
let width = 0
|
||||||
|
for line in lines
|
||||||
|
let lw = strdisplaywidth(line)
|
||||||
|
if lw > width
|
||||||
|
let width = lw
|
||||||
|
endif
|
||||||
|
let height += 1
|
||||||
|
endfor
|
||||||
|
let width += 1 " right margin
|
||||||
|
let max_height = go#config#DocMaxHeight()
|
||||||
|
if height > max_height
|
||||||
|
let height = max_height
|
||||||
|
endif
|
||||||
|
|
||||||
|
let buf = nvim_create_buf(v:false, v:true)
|
||||||
|
call nvim_buf_set_lines(buf, 0, -1, v:true, lines)
|
||||||
|
let opts = {
|
||||||
|
\ 'relative': 'cursor',
|
||||||
|
\ 'row': 1,
|
||||||
|
\ 'col': 0,
|
||||||
|
\ 'width': width,
|
||||||
|
\ 'height': height,
|
||||||
|
\ 'style': 'minimal',
|
||||||
|
\ }
|
||||||
|
call nvim_open_win(buf, v:true, opts)
|
||||||
|
setlocal nomodified nomodifiable filetype=godoc
|
||||||
|
|
||||||
|
" close easily with CR, Esc and q
|
||||||
|
noremap <buffer> <silent> <CR> :<C-U>close<CR>
|
||||||
|
noremap <buffer> <silent> <Esc> :<C-U>close<CR>
|
||||||
|
noremap <buffer> <silent> q :<C-U>close<CR>
|
||||||
|
endif
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" reuse existing buffer window if it exists otherwise create a new one
|
||||||
|
let is_visible = bufexists(s:buf_nr) && bufwinnr(s:buf_nr) != -1
|
||||||
|
if !bufexists(s:buf_nr)
|
||||||
|
execute a:newposition
|
||||||
|
sil file `="[Godoc]"`
|
||||||
|
let s:buf_nr = bufnr('%')
|
||||||
|
elseif bufwinnr(s:buf_nr) == -1
|
||||||
|
execute a:position
|
||||||
|
execute s:buf_nr . 'buffer'
|
||||||
|
elseif bufwinnr(s:buf_nr) != bufwinnr('%')
|
||||||
|
execute bufwinnr(s:buf_nr) . 'wincmd w'
|
||||||
|
endif
|
||||||
|
|
||||||
|
" if window was not visible then resize it
|
||||||
|
if !is_visible
|
||||||
|
if a:position == "split"
|
||||||
|
" cap window height to 20, but resize it for smaller contents
|
||||||
|
let max_height = go#config#DocMaxHeight()
|
||||||
|
let content_height = len(split(a:content, "\n"))
|
||||||
|
if content_height > max_height
|
||||||
|
exe 'resize ' . max_height
|
||||||
|
else
|
||||||
|
exe 'resize ' . content_height
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
" set a sane maximum width for vertical splits. In this case the minimum
|
||||||
|
" that fits the godoc for package http without extra linebreaks and line
|
||||||
|
" numbers on
|
||||||
|
exe 'vertical resize 84'
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
setlocal filetype=godoc
|
||||||
|
setlocal bufhidden=delete
|
||||||
|
setlocal buftype=nofile
|
||||||
|
setlocal noswapfile
|
||||||
|
setlocal nobuflisted
|
||||||
|
setlocal nocursorline
|
||||||
|
setlocal nocursorcolumn
|
||||||
|
setlocal iskeyword+=:
|
||||||
|
setlocal iskeyword-=-
|
||||||
|
|
||||||
|
setlocal modifiable
|
||||||
|
%delete _
|
||||||
|
call append(0, split(a:content, "\n"))
|
||||||
|
sil $delete _
|
||||||
|
setlocal nomodifiable
|
||||||
|
sil normal! gg
|
||||||
|
|
||||||
|
" close easily with enter
|
||||||
|
noremap <buffer> <silent> <CR> :<C-U>close<CR>
|
||||||
|
noremap <buffer> <silent> <Esc> :<C-U>close<CR>
|
||||||
|
" make sure any key that sends an escape as a prefix (e.g. the arrow keys)
|
||||||
|
" don't cause the window to close.
|
||||||
|
nnoremap <buffer> <silent> <Esc>[ <Esc>[
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" returns the package and exported name. exported name might be empty.
|
||||||
|
" ie: fmt and Println
|
||||||
|
" ie: github.com/fatih/set and New
|
||||||
|
function! s:godocWord(args) abort
|
||||||
|
if !executable('godoc')
|
||||||
|
let msg = "godoc command not found."
|
||||||
|
let msg .= " install with: go get golang.org/x/tools/cmd/godoc"
|
||||||
|
call go#util#EchoWarning(msg)
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !len(a:args)
|
||||||
|
let oldiskeyword = &iskeyword
|
||||||
|
setlocal iskeyword+=.
|
||||||
|
let word = expand('<cword>')
|
||||||
|
let &iskeyword = oldiskeyword
|
||||||
|
let word = substitute(word, '[^a-zA-Z0-9\\/._~-]', '', 'g')
|
||||||
|
let words = split(word, '\.\ze[^./]\+$')
|
||||||
|
else
|
||||||
|
let words = a:args
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !len(words)
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
|
||||||
|
let pkg = words[0]
|
||||||
|
if len(words) == 1
|
||||||
|
let exported_name = ""
|
||||||
|
else
|
||||||
|
let exported_name = words[1]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let packages = go#tool#Imports()
|
||||||
|
|
||||||
|
if has_key(packages, pkg)
|
||||||
|
let pkg = packages[pkg]
|
||||||
|
endif
|
||||||
|
|
||||||
|
return [pkg, exported_name]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
83
sources_non_forked/vim-go/autoload/go/fillstruct.vim
Normal file
83
sources_non_forked/vim-go/autoload/go/fillstruct.vim
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
function! go#fillstruct#FillStruct() abort
|
||||||
|
let l:mode = go#config#FillStructMode()
|
||||||
|
if l:mode is 'gopls'
|
||||||
|
call go#lsp#FillStruct()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:cmd = ['fillstruct',
|
||||||
|
\ '-file', bufname(''),
|
||||||
|
\ '-offset', go#util#OffsetCursor(),
|
||||||
|
\ '-line', line('.')]
|
||||||
|
" Needs: https://github.com/davidrjenni/reftools/pull/14
|
||||||
|
"\ '-tags', go#config#BuildTags()]
|
||||||
|
|
||||||
|
let l:buildtags = go#config#BuildTags()
|
||||||
|
if l:buildtags isnot ''
|
||||||
|
let l:cmd += ['-tags', l:buildtags]
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Read from stdin if modified.
|
||||||
|
if &modified
|
||||||
|
call add(l:cmd, '-modified')
|
||||||
|
let [l:out, l:err] = go#util#Exec(l:cmd, go#util#archive())
|
||||||
|
else
|
||||||
|
let [l:out, l:err] = go#util#Exec(l:cmd)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:err
|
||||||
|
call go#util#EchoError(l:out)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:json = json_decode(l:out)
|
||||||
|
catch
|
||||||
|
call go#util#EchoError(l:out)
|
||||||
|
return
|
||||||
|
endtry
|
||||||
|
|
||||||
|
" Output is array:
|
||||||
|
"[
|
||||||
|
" {"start": 92, "end": 106, "code": "mail.Address{\n\tName: \"\",\n\tAddress: \"\",\n}"},
|
||||||
|
" {...second struct...}
|
||||||
|
" ]
|
||||||
|
|
||||||
|
let l:pos = getpos('.')
|
||||||
|
|
||||||
|
try
|
||||||
|
for l:struct in l:json
|
||||||
|
let l:code = split(l:struct['code'], "\n")
|
||||||
|
|
||||||
|
" Add any code before/after the struct.
|
||||||
|
exe l:struct['start'] . 'go'
|
||||||
|
let l:code[0] = getline('.')[:col('.')-1] . l:code[0]
|
||||||
|
exe l:struct['end'] . 'go'
|
||||||
|
let l:code[len(l:code)-1] .= getline('.')[col('.'):]
|
||||||
|
|
||||||
|
" Indent every line except the first one; makes it look nice.
|
||||||
|
let l:indent = repeat("\t", indent('.') / &tabstop)
|
||||||
|
for l:i in range(1, len(l:code)-1)
|
||||||
|
let l:code[l:i] = l:indent . l:code[l:i]
|
||||||
|
endfor
|
||||||
|
|
||||||
|
" Out with the old ...
|
||||||
|
exe 'normal! ' . l:struct['start'] . 'gov' . l:struct['end'] . 'gox'
|
||||||
|
" ... in with the new.
|
||||||
|
call setline('.', l:code[0])
|
||||||
|
call append('.', l:code[1:])
|
||||||
|
endfor
|
||||||
|
finally
|
||||||
|
call setpos('.', l:pos)
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
223
sources_non_forked/vim-go/autoload/go/fillstruct_test.vim
Normal file
223
sources_non_forked/vim-go/autoload/go/fillstruct_test.vim
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
func! Test_fillstruct() abort
|
||||||
|
try
|
||||||
|
let g:go_fillstruct_mode = 'fillstruct'
|
||||||
|
let l:tmp = gotest#write_file('a/a.go', [
|
||||||
|
\ 'package a',
|
||||||
|
\ 'import "net/mail"',
|
||||||
|
\ "var addr = mail.\x1fAddress{}"])
|
||||||
|
|
||||||
|
call go#fillstruct#FillStruct()
|
||||||
|
call gotest#assert_buffer(1, [
|
||||||
|
\ 'var addr = mail.Address{',
|
||||||
|
\ '\tName: "",',
|
||||||
|
\ '\tAddress: "",',
|
||||||
|
\ '}'])
|
||||||
|
finally
|
||||||
|
unlet g:go_fillstruct_mode
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_fillstruct_line() abort
|
||||||
|
try
|
||||||
|
let g:go_fillstruct_mode = 'fillstruct'
|
||||||
|
let l:tmp = gotest#write_file('a/a.go', [
|
||||||
|
\ 'package a',
|
||||||
|
\ 'import "net/mail"',
|
||||||
|
\ "\x1f" . 'var addr = mail.Address{}'])
|
||||||
|
|
||||||
|
call go#fillstruct#FillStruct()
|
||||||
|
call gotest#assert_buffer(1, [
|
||||||
|
\ 'var addr = mail.Address{',
|
||||||
|
\ '\tName: "",',
|
||||||
|
\ '\tAddress: "",',
|
||||||
|
\ '}'])
|
||||||
|
finally
|
||||||
|
unlet g:go_fillstruct_mode
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_fillstruct_two_line() abort
|
||||||
|
try
|
||||||
|
let g:go_fillstruct_mode = 'fillstruct'
|
||||||
|
let l:tmp = gotest#write_file('a/a.go', [
|
||||||
|
\ 'package a',
|
||||||
|
\ 'import (',
|
||||||
|
\ '"fmt"',
|
||||||
|
\ '"net/mail"',
|
||||||
|
\ ')',
|
||||||
|
\ "\x1f" . 'func x() { fmt.Println(mail.Address{}, mail.Address{}) }'])
|
||||||
|
|
||||||
|
call go#fillstruct#FillStruct()
|
||||||
|
call gotest#assert_buffer(1, [
|
||||||
|
\ 'import (',
|
||||||
|
\ '"fmt"',
|
||||||
|
\ '"net/mail"',
|
||||||
|
\ ')',
|
||||||
|
\ 'func x() { fmt.Println(mail.Address{',
|
||||||
|
\ '\tName: "",',
|
||||||
|
\ '\tAddress: "",',
|
||||||
|
\ '}, mail.Address{',
|
||||||
|
\ '\tName: "",',
|
||||||
|
\ '\tAddress: "",',
|
||||||
|
\ '}) }'])
|
||||||
|
finally
|
||||||
|
unlet g:go_fillstruct_mode
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_fillstruct_two_cursor() abort
|
||||||
|
try
|
||||||
|
let g:go_fillstruct_mode = 'fillstruct'
|
||||||
|
let l:tmp = gotest#write_file('a/a.go', [
|
||||||
|
\ 'package a',
|
||||||
|
\ 'import (',
|
||||||
|
\ '"fmt"',
|
||||||
|
\ '"net/mail"',
|
||||||
|
\ ')',
|
||||||
|
\ "func x() { fmt.Println(mail.Address{}, mail.Ad\x1fdress{}) }"])
|
||||||
|
|
||||||
|
call go#fillstruct#FillStruct()
|
||||||
|
call gotest#assert_buffer(1, [
|
||||||
|
\ 'import (',
|
||||||
|
\ '"fmt"',
|
||||||
|
\ '"net/mail"',
|
||||||
|
\ ')',
|
||||||
|
\ 'func x() { fmt.Println(mail.Address{}, mail.Address{',
|
||||||
|
\ '\tName: "",',
|
||||||
|
\ '\tAddress: "",',
|
||||||
|
\ '}) }'])
|
||||||
|
finally
|
||||||
|
unlet g:go_fillstruct_mode
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_gopls_fillstruct() abort
|
||||||
|
try
|
||||||
|
let g:go_fillstruct_mode = 'gopls'
|
||||||
|
let l:tmp = gotest#write_file('a/a.go', [
|
||||||
|
\ 'package a',
|
||||||
|
\ 'import "net/mail"',
|
||||||
|
\ "var addr = mail.\x1fAddress{}"])
|
||||||
|
|
||||||
|
call go#fillstruct#FillStruct()
|
||||||
|
|
||||||
|
let start = reltime()
|
||||||
|
while &modified == 0 && reltimefloat(reltime(start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call gotest#assert_buffer(1, [
|
||||||
|
\ 'var addr = mail.Address{',
|
||||||
|
\ '\tName: "",',
|
||||||
|
\ '\tAddress: "",',
|
||||||
|
\ '}'])
|
||||||
|
finally
|
||||||
|
unlet g:go_fillstruct_mode
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_gopls_fillstruct_line() abort
|
||||||
|
try
|
||||||
|
let g:go_fillstruct_mode = 'gopls'
|
||||||
|
let l:tmp = gotest#write_file('a/a.go', [
|
||||||
|
\ 'package a',
|
||||||
|
\ 'import "net/mail"',
|
||||||
|
\ "\x1f" . 'var addr = mail.Address{}'])
|
||||||
|
|
||||||
|
call go#fillstruct#FillStruct()
|
||||||
|
|
||||||
|
let start = reltime()
|
||||||
|
while &modified == 0 && reltimefloat(reltime(start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call gotest#assert_buffer(1, [
|
||||||
|
\ 'var addr = mail.Address{',
|
||||||
|
\ '\tName: "",',
|
||||||
|
\ '\tAddress: "",',
|
||||||
|
\ '}'])
|
||||||
|
finally
|
||||||
|
unlet g:go_fillstruct_mode
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_gopls_fillstruct_two_line() abort
|
||||||
|
try
|
||||||
|
let g:go_fillstruct_mode = 'gopls'
|
||||||
|
let l:tmp = gotest#write_file('a/a.go', [
|
||||||
|
\ 'package a',
|
||||||
|
\ 'import (',
|
||||||
|
\ '"fmt"',
|
||||||
|
\ '"net/mail"',
|
||||||
|
\ ')',
|
||||||
|
\ "\x1f" . 'func x() { fmt.Println(mail.Address{}, mail.Address{}) }'])
|
||||||
|
|
||||||
|
call go#fillstruct#FillStruct()
|
||||||
|
|
||||||
|
let start = reltime()
|
||||||
|
while &modified == 0 && reltimefloat(reltime(start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
" the fillstruct behavior of gopls is different than fillstruct; the
|
||||||
|
" latter will not expand the struct when the cursor is not on a struct
|
||||||
|
" when there is more than one struct literal on the line.
|
||||||
|
call gotest#assert_buffer(1, [
|
||||||
|
\ 'import (',
|
||||||
|
\ '"fmt"',
|
||||||
|
\ '"net/mail"',
|
||||||
|
\ ')',
|
||||||
|
\ 'func x() { fmt.Println(mail.Address{}, mail.Address{}) }'])
|
||||||
|
finally
|
||||||
|
unlet g:go_fillstruct_mode
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_gopls_fillstruct_two_cursor() abort
|
||||||
|
try
|
||||||
|
let g:go_fillstruct_mode = 'gopls'
|
||||||
|
let l:tmp = gotest#write_file('a/a.go', [
|
||||||
|
\ 'package a',
|
||||||
|
\ 'import (',
|
||||||
|
\ '"fmt"',
|
||||||
|
\ '"net/mail"',
|
||||||
|
\ ')',
|
||||||
|
\ "func x() { fmt.Println(mail.Address{}, mail.Ad\x1fdress{}) }"])
|
||||||
|
|
||||||
|
call go#fillstruct#FillStruct()
|
||||||
|
|
||||||
|
let start = reltime()
|
||||||
|
while &modified == 0 && reltimefloat(reltime(start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call gotest#assert_buffer(1, [
|
||||||
|
\ 'import (',
|
||||||
|
\ '"fmt"',
|
||||||
|
\ '"net/mail"',
|
||||||
|
\ ')',
|
||||||
|
\ 'func x() { fmt.Println(mail.Address{}, mail.Address{',
|
||||||
|
\ '\tName: "",',
|
||||||
|
\ '\tAddress: "",',
|
||||||
|
\ '}) }'])
|
||||||
|
finally
|
||||||
|
unlet g:go_fillstruct_mode
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
231
sources_non_forked/vim-go/autoload/go/fmt.vim
Normal file
231
sources_non_forked/vim-go/autoload/go/fmt.vim
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
" Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
" Use of this source code is governed by a BSD-style
|
||||||
|
" license that can be found in the LICENSE file.
|
||||||
|
"
|
||||||
|
" fmt.vim: Vim command to format Go files with gofmt (and gofmt compatible
|
||||||
|
" toorls, such as goimports).
|
||||||
|
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
" we have those problems :
|
||||||
|
" http://stackoverflow.com/questions/12741977/prevent-vim-from-updating-its-undo-tree
|
||||||
|
" http://stackoverflow.com/questions/18532692/golang-formatter-and-vim-how-to-destroy-history-record?rq=1
|
||||||
|
"
|
||||||
|
" The below function is an improved version that aims to fix all problems.
|
||||||
|
" it doesn't undo changes and break undo history. If you are here reading
|
||||||
|
" this and have VimL experience, please look at the function for
|
||||||
|
" improvements, patches are welcome :)
|
||||||
|
function! go#fmt#Format(withGoimport) abort
|
||||||
|
let l:bin_name = go#config#FmtCommand()
|
||||||
|
if a:withGoimport == 1
|
||||||
|
let l:mode = go#config#ImportsMode()
|
||||||
|
if l:mode == 'gopls'
|
||||||
|
if !go#config#GoplsEnabled()
|
||||||
|
call go#util#EchoError("go_imports_mode is 'gopls', but gopls is disabled")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
call go#lsp#Imports()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:bin_name = 'goimports'
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:bin_name == 'gopls'
|
||||||
|
if !go#config#GoplsEnabled()
|
||||||
|
call go#util#EchoError("go_fmt_command is 'gopls', but gopls is disabled")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
call go#lsp#Format()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if go#config#FmtExperimental()
|
||||||
|
" Using winsaveview to save/restore cursor state has the problem of
|
||||||
|
" closing folds on save:
|
||||||
|
" https://github.com/fatih/vim-go/issues/502
|
||||||
|
" One fix is to use mkview instead. Unfortunately, this sometimes causes
|
||||||
|
" other bad side effects:
|
||||||
|
" https://github.com/fatih/vim-go/issues/728
|
||||||
|
" and still closes all folds if foldlevel>0:
|
||||||
|
" https://github.com/fatih/vim-go/issues/732
|
||||||
|
let l:curw = {}
|
||||||
|
try
|
||||||
|
mkview!
|
||||||
|
catch
|
||||||
|
let l:curw = winsaveview()
|
||||||
|
endtry
|
||||||
|
|
||||||
|
" save our undo file to be restored after we are done. This is needed to
|
||||||
|
" prevent an additional undo jump due to BufWritePre auto command and also
|
||||||
|
" restore 'redo' history because it's getting being destroyed every
|
||||||
|
" BufWritePre
|
||||||
|
let tmpundofile = tempname()
|
||||||
|
exe 'wundo! ' . tmpundofile
|
||||||
|
else
|
||||||
|
" Save cursor position and many other things.
|
||||||
|
let l:curw = winsaveview()
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Write current unsaved buffer to a temp file
|
||||||
|
let l:tmpname = tempname() . '.go'
|
||||||
|
call writefile(go#util#GetLines(), l:tmpname)
|
||||||
|
if go#util#IsWin()
|
||||||
|
let l:tmpname = tr(l:tmpname, '\', '/')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let current_col = col('.')
|
||||||
|
let [l:out, l:err] = go#fmt#run(l:bin_name, l:tmpname, expand('%'))
|
||||||
|
let line_offset = len(readfile(l:tmpname)) - line('$')
|
||||||
|
let l:orig_line = getline('.')
|
||||||
|
|
||||||
|
if l:err == 0
|
||||||
|
call go#fmt#update_file(l:tmpname, expand('%'))
|
||||||
|
elseif !go#config#FmtFailSilently()
|
||||||
|
let l:errors = s:replace_filename(expand('%'), out)
|
||||||
|
call go#fmt#ShowErrors(l:errors)
|
||||||
|
endif
|
||||||
|
|
||||||
|
" We didn't use the temp file, so clean up
|
||||||
|
call delete(l:tmpname)
|
||||||
|
|
||||||
|
if go#config#FmtExperimental()
|
||||||
|
" restore our undo history
|
||||||
|
silent! exe 'rundo ' . tmpundofile
|
||||||
|
call delete(tmpundofile)
|
||||||
|
|
||||||
|
" Restore our cursor/windows positions, folds, etc.
|
||||||
|
if empty(l:curw)
|
||||||
|
silent! loadview
|
||||||
|
else
|
||||||
|
call winrestview(l:curw)
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
" Restore our cursor/windows positions.
|
||||||
|
call winrestview(l:curw)
|
||||||
|
endif
|
||||||
|
|
||||||
|
" be smart and jump to the line the new statement was added/removed and
|
||||||
|
" adjust the column within the line
|
||||||
|
let l:lineno = line('.') + line_offset
|
||||||
|
call cursor(l:lineno, current_col + (len(getline(l:lineno)) - len(l:orig_line)))
|
||||||
|
|
||||||
|
" Syntax highlighting breaks less often.
|
||||||
|
syntax sync fromstart
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" update_file updates the target file with the given formatted source
|
||||||
|
function! go#fmt#update_file(source, target)
|
||||||
|
" remove undo point caused via BufWritePre
|
||||||
|
try | silent undojoin | catch | endtry
|
||||||
|
|
||||||
|
let old_fileformat = &fileformat
|
||||||
|
if exists("*getfperm")
|
||||||
|
" save file permissions
|
||||||
|
let original_fperm = getfperm(a:target)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call rename(a:source, a:target)
|
||||||
|
|
||||||
|
" restore file permissions
|
||||||
|
if exists("*setfperm") && original_fperm != ''
|
||||||
|
call setfperm(a:target , original_fperm)
|
||||||
|
endif
|
||||||
|
|
||||||
|
" reload buffer to reflect latest changes
|
||||||
|
silent edit!
|
||||||
|
|
||||||
|
call go#lsp#DidChange(expand(a:target, ':p'))
|
||||||
|
|
||||||
|
let &fileformat = old_fileformat
|
||||||
|
let &syntax = &syntax
|
||||||
|
|
||||||
|
call go#fmt#CleanErrors()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" run runs the gofmt/goimport command for the given source file and returns
|
||||||
|
" the output of the executed command. Target is the real file to be formatted.
|
||||||
|
function! go#fmt#run(bin_name, source, target)
|
||||||
|
let l:cmd = s:fmt_cmd(a:bin_name, a:source, a:target)
|
||||||
|
if empty(l:cmd)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
return go#util#Exec(l:cmd)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" fmt_cmd returns the command to run as a list.
|
||||||
|
function! s:fmt_cmd(bin_name, source, target)
|
||||||
|
let l:cmd = [a:bin_name, '-w']
|
||||||
|
|
||||||
|
" add the options for binary (if any). go_fmt_options was by default of type
|
||||||
|
" string, however to allow customization it's now a dictionary of binary
|
||||||
|
" name mapping to options.
|
||||||
|
let opts = go#config#FmtOptions()
|
||||||
|
if type(opts) == type({})
|
||||||
|
let opts = has_key(opts, a:bin_name) ? opts[a:bin_name] : ""
|
||||||
|
endif
|
||||||
|
call extend(cmd, split(opts, " "))
|
||||||
|
if a:bin_name is# 'goimports'
|
||||||
|
call extend(cmd, ["-srcdir", a:target])
|
||||||
|
endif
|
||||||
|
|
||||||
|
call add(cmd, a:source)
|
||||||
|
return cmd
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" replace_filename replaces the filename on each line of content with
|
||||||
|
" a:filename.
|
||||||
|
function! s:replace_filename(filename, content) abort
|
||||||
|
let l:errors = split(a:content, '\n')
|
||||||
|
|
||||||
|
let l:errors = map(l:errors, printf('substitute(v:val, ''^.\{-}:'', ''%s:'', '''')', a:filename))
|
||||||
|
return join(l:errors, "\n")
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#fmt#CleanErrors() abort
|
||||||
|
let l:listtype = go#list#Type("GoFmt")
|
||||||
|
|
||||||
|
" clean up previous list
|
||||||
|
if l:listtype == "quickfix"
|
||||||
|
let l:list_title = getqflist({'title': 1})
|
||||||
|
else
|
||||||
|
let l:list_title = getloclist(0, {'title': 1})
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(l:list_title, 'title') && (l:list_title['title'] == 'Format' || l:list_title['title'] == 'GoMetaLinterAutoSave')
|
||||||
|
call go#list#Clean(l:listtype)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" show_errors opens a location list and shows the given errors. If errors is
|
||||||
|
" empty, it closes the the location list.
|
||||||
|
function! go#fmt#ShowErrors(errors) abort
|
||||||
|
let l:errorformat = '%f:%l:%c:\ %m'
|
||||||
|
let l:listtype = go#list#Type("GoFmt")
|
||||||
|
|
||||||
|
call go#list#ParseFormat(l:listtype, l:errorformat, a:errors, 'Format', 0)
|
||||||
|
let l:errors = go#list#Get(l:listtype)
|
||||||
|
|
||||||
|
" this closes the window if there are no errors or it opens
|
||||||
|
" it if there are any.
|
||||||
|
call go#list#Window(l:listtype, len(l:errors))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#fmt#ToggleFmtAutoSave() abort
|
||||||
|
if go#config#FmtAutosave()
|
||||||
|
call go#config#SetFmtAutosave(0)
|
||||||
|
call go#util#EchoProgress("auto fmt disabled")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
call go#config#SetFmtAutosave(1)
|
||||||
|
call go#util#EchoProgress("auto fmt enabled")
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
57
sources_non_forked/vim-go/autoload/go/fmt_test.vim
Normal file
57
sources_non_forked/vim-go/autoload/go/fmt_test.vim
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
func! Test_run_fmt() abort
|
||||||
|
let actual_file = tempname()
|
||||||
|
call writefile(readfile("test-fixtures/fmt/hello.go"), actual_file)
|
||||||
|
|
||||||
|
let expected = join(readfile("test-fixtures/fmt/hello_golden.go"), "\n")
|
||||||
|
|
||||||
|
" run our code
|
||||||
|
call go#fmt#run("gofmt", actual_file, "test-fixtures/fmt/hello.go")
|
||||||
|
|
||||||
|
" this should now contain the formatted code
|
||||||
|
let actual = join(readfile(actual_file), "\n")
|
||||||
|
|
||||||
|
call assert_equal(expected, actual)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_update_file() abort
|
||||||
|
let expected = join(readfile("test-fixtures/fmt/hello_golden.go"), "\n")
|
||||||
|
let source_file = tempname()
|
||||||
|
call writefile(readfile("test-fixtures/fmt/hello_golden.go"), source_file)
|
||||||
|
|
||||||
|
let target_file = tempname()
|
||||||
|
call writefile([""], target_file)
|
||||||
|
|
||||||
|
" update_file now
|
||||||
|
call go#fmt#update_file(source_file, target_file)
|
||||||
|
|
||||||
|
" this should now contain the formatted code
|
||||||
|
let actual = join(readfile(target_file), "\n")
|
||||||
|
|
||||||
|
call assert_equal(expected, actual)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_goimports() abort
|
||||||
|
let $GOPATH = printf('%s/%s', fnamemodify(getcwd(), ':p'), 'test-fixtures/fmt')
|
||||||
|
let actual_file = tempname()
|
||||||
|
call writefile(readfile("test-fixtures/fmt/src/imports/goimports.go"), actual_file)
|
||||||
|
|
||||||
|
let expected = join(readfile("test-fixtures/fmt/src/imports/goimports_golden.go"), "\n")
|
||||||
|
|
||||||
|
" run our code
|
||||||
|
call go#fmt#run("goimports", actual_file, "test-fixtures/fmt/src/imports/goimports.go")
|
||||||
|
|
||||||
|
" this should now contain the formatted code
|
||||||
|
let actual = join(readfile(actual_file), "\n")
|
||||||
|
|
||||||
|
call assert_equal(expected, actual)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
584
sources_non_forked/vim-go/autoload/go/guru.vim
Normal file
584
sources_non_forked/vim-go/autoload/go/guru.vim
Normal file
|
@ -0,0 +1,584 @@
|
||||||
|
" guru.vim -- Vim integration for the Go guru.
|
||||||
|
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
" guru_cmd returns a dict that contains the command to execute guru. args
|
||||||
|
" is dict with following options:
|
||||||
|
" mode : guru mode, such as 'implements'
|
||||||
|
" format : output format, either 'plain' or 'json'
|
||||||
|
" needs_scope : if 1, adds the current package to the scope
|
||||||
|
" selected : if 1, means it's a range of selection, otherwise it picks up the
|
||||||
|
" offset under the cursor
|
||||||
|
" example output:
|
||||||
|
" {'cmd' : ['guru', '-json', 'implements', 'demo/demo.go:#66']}
|
||||||
|
function! s:guru_cmd(args) range abort
|
||||||
|
"if !go#package#InGOPATH()
|
||||||
|
"return {'err': 'guru only supports packages within GOPATH'}
|
||||||
|
"endif
|
||||||
|
let mode = a:args.mode
|
||||||
|
|
||||||
|
let format = a:args.format
|
||||||
|
let needs_scope = a:args.needs_scope
|
||||||
|
let selected = a:args.selected
|
||||||
|
let postype = get(a:args, 'postype', 'cursor')
|
||||||
|
|
||||||
|
let result = {}
|
||||||
|
|
||||||
|
"return with a warning if the binary doesn't exist
|
||||||
|
let bin_path = go#path#CheckBinPath("guru")
|
||||||
|
if empty(bin_path)
|
||||||
|
return {'err': "bin path not found"}
|
||||||
|
endif
|
||||||
|
|
||||||
|
" start constructing the command
|
||||||
|
let cmd = [bin_path, '-tags', go#config#BuildTags()]
|
||||||
|
|
||||||
|
if &modified
|
||||||
|
let result.stdin_content = go#util#archive()
|
||||||
|
call add(cmd, "-modified")
|
||||||
|
endif
|
||||||
|
|
||||||
|
" enable outputting in json format
|
||||||
|
if format == "json"
|
||||||
|
call add(cmd, "-json")
|
||||||
|
endif
|
||||||
|
|
||||||
|
let scopes = go#config#GuruScope()
|
||||||
|
if empty(scopes)
|
||||||
|
" some modes require scope to be defined (such as callers). For these we
|
||||||
|
" choose a sensible setting, which is using the current file's package
|
||||||
|
if needs_scope
|
||||||
|
let pkg = go#package#ImportPath()
|
||||||
|
if pkg == -1
|
||||||
|
return {'err': "current directory is not inside of a valid GOPATH"}
|
||||||
|
endif
|
||||||
|
let scopes = [pkg]
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Add the scope.
|
||||||
|
if !empty(scopes)
|
||||||
|
" guru expect a comma-separated list of patterns.
|
||||||
|
let l:scope = join(scopes, ",")
|
||||||
|
let result.scope = l:scope
|
||||||
|
call extend(cmd, ["-scope", l:scope])
|
||||||
|
endif
|
||||||
|
|
||||||
|
if postype == 'balloon'
|
||||||
|
let pos = printf("#%s", go#util#Offset(v:beval_lnum, v:beval_col))
|
||||||
|
else
|
||||||
|
let pos = printf("#%s", go#util#OffsetCursor())
|
||||||
|
if selected != -1
|
||||||
|
" means we have a range, get it
|
||||||
|
let pos1 = go#util#Offset(line("'<"), col("'<"))
|
||||||
|
let pos2 = go#util#Offset(line("'>"), col("'>"))
|
||||||
|
let pos = printf("#%s,#%s", pos1, pos2)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:filename = fnamemodify(expand("%"), ':p:gs?\\?/?') . ':' . pos
|
||||||
|
call extend(cmd, [mode, l:filename])
|
||||||
|
|
||||||
|
let result.cmd = cmd
|
||||||
|
return result
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" sync_guru runs guru in sync mode with the given arguments
|
||||||
|
function! s:sync_guru(args) abort
|
||||||
|
let result = s:guru_cmd(a:args)
|
||||||
|
if has_key(result, 'err')
|
||||||
|
call go#util#EchoError(result.err)
|
||||||
|
return -1
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !has_key(a:args, 'disable_progress')
|
||||||
|
if a:args.needs_scope
|
||||||
|
call go#util#EchoProgress("analysing with scope ". result.scope .
|
||||||
|
\ " (see ':help go-guru-scope' if this doesn't work)...")
|
||||||
|
elseif a:args.mode !=# 'what'
|
||||||
|
" the query might take time, let us give some feedback
|
||||||
|
call go#util#EchoProgress("analysing ...")
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
" run, forrest run!!!
|
||||||
|
if has_key(l:result, 'stdin_content')
|
||||||
|
let [l:out, l:err] = go#util#Exec(l:result.cmd, l:result.stdin_content)
|
||||||
|
else
|
||||||
|
let [l:out, l:err] = go#util#Exec(l:result.cmd)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(a:args, 'custom_parse')
|
||||||
|
call a:args.custom_parse(l:err, l:out, a:args.mode)
|
||||||
|
else
|
||||||
|
call s:parse_guru_output(l:err, l:out, a:args.mode)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:out
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" async_guru runs guru in async mode with the given arguments
|
||||||
|
function! s:async_guru(args) abort
|
||||||
|
let result = s:guru_cmd(a:args)
|
||||||
|
if has_key(result, 'err')
|
||||||
|
call go#util#EchoError(result.err)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let state = {
|
||||||
|
\ 'mode': a:args.mode,
|
||||||
|
\ 'parse' : get(a:args, 'custom_parse', funcref("s:parse_guru_output"))
|
||||||
|
\ }
|
||||||
|
|
||||||
|
" explicitly bind complete to state so that within it, self will
|
||||||
|
" always refer to state. See :help Partial for more information.
|
||||||
|
let state.complete = function('s:complete', [], state)
|
||||||
|
|
||||||
|
let opts = {
|
||||||
|
\ 'statustype': get(a:args, 'statustype', a:args.mode),
|
||||||
|
\ 'for': '_',
|
||||||
|
\ 'errorformat': "%f:%l.%c-%[%^:]%#:\ %m,%f:%l:%c:\ %m",
|
||||||
|
\ 'complete': state.complete,
|
||||||
|
\ }
|
||||||
|
|
||||||
|
if has_key(a:args, 'disable_progress')
|
||||||
|
let opts.statustype = ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
let opts = go#job#Options(l:opts)
|
||||||
|
|
||||||
|
if has_key(result, 'stdin_content')
|
||||||
|
let l:tmpname = tempname()
|
||||||
|
call writefile(split(result.stdin_content, "\n"), l:tmpname, "b")
|
||||||
|
let l:opts.in_io = "file"
|
||||||
|
let l:opts.in_name = l:tmpname
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#job#Start(result.cmd, opts)
|
||||||
|
|
||||||
|
if a:args.needs_scope && go#config#EchoCommandInfo() && !has_key(a:args, 'disable_progress')
|
||||||
|
call go#util#EchoProgress("analysing with scope " . result.scope .
|
||||||
|
\ " (see ':help go-guru-scope' if this doesn't work)...")
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
function! s:complete(job, exit_status, messages) dict abort
|
||||||
|
let output = join(a:messages, "\n")
|
||||||
|
call self.parse(a:exit_status, output, self.mode)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" run_guru runs the given guru argument
|
||||||
|
function! s:run_guru(args) abort
|
||||||
|
if go#util#has_job()
|
||||||
|
let res = s:async_guru(a:args)
|
||||||
|
else
|
||||||
|
let res = s:sync_guru(a:args)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return res
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Show 'implements' relation for selected package
|
||||||
|
function! go#guru#Implements(selected) abort
|
||||||
|
let args = {
|
||||||
|
\ 'mode': 'implements',
|
||||||
|
\ 'format': 'plain',
|
||||||
|
\ 'selected': a:selected,
|
||||||
|
\ 'needs_scope': 1,
|
||||||
|
\ }
|
||||||
|
|
||||||
|
call s:run_guru(args)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Shows the set of possible objects to which a pointer may point.
|
||||||
|
function! go#guru#PointsTo(selected) abort
|
||||||
|
let l:args = {
|
||||||
|
\ 'mode': 'pointsto',
|
||||||
|
\ 'format': 'plain',
|
||||||
|
\ 'selected': a:selected,
|
||||||
|
\ 'needs_scope': 1,
|
||||||
|
\ }
|
||||||
|
|
||||||
|
call s:run_guru(l:args)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Report the possible constants, global variables, and concrete types that may
|
||||||
|
" appear in a value of type error
|
||||||
|
function! go#guru#Whicherrs(selected) abort
|
||||||
|
let args = {
|
||||||
|
\ 'mode': 'whicherrs',
|
||||||
|
\ 'format': 'plain',
|
||||||
|
\ 'selected': a:selected,
|
||||||
|
\ 'needs_scope': 1,
|
||||||
|
\ }
|
||||||
|
|
||||||
|
|
||||||
|
" TODO(arslan): handle empty case for both sync/async
|
||||||
|
" if empty(out.out)
|
||||||
|
" call go#util#EchoSuccess("no error variables found. Try to change the scope with :GoGuruScope")
|
||||||
|
" return
|
||||||
|
" endif
|
||||||
|
call s:run_guru(args)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Describe selected syntax: definition, methods, etc
|
||||||
|
function! go#guru#Describe(selected) abort
|
||||||
|
let args = {
|
||||||
|
\ 'mode': 'describe',
|
||||||
|
\ 'format': 'plain',
|
||||||
|
\ 'selected': a:selected,
|
||||||
|
\ 'needs_scope': 1,
|
||||||
|
\ }
|
||||||
|
|
||||||
|
call s:run_guru(args)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#guru#DescribeInfo(showstatus) abort
|
||||||
|
|
||||||
|
" check if the version of Vim being tested supports json_decode()
|
||||||
|
if !exists("*json_decode")
|
||||||
|
call go#util#EchoError("GoDescribeInfo requires 'json_decode'. Update your Vim/Neovim version.")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let args = {
|
||||||
|
\ 'mode': 'describe',
|
||||||
|
\ 'format': 'json',
|
||||||
|
\ 'selected': -1,
|
||||||
|
\ 'needs_scope': 0,
|
||||||
|
\ 'custom_parse': function('s:info'),
|
||||||
|
\ 'disable_progress': a:showstatus == 0,
|
||||||
|
\ }
|
||||||
|
|
||||||
|
call s:run_guru(args)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:info(exit_val, output, mode)
|
||||||
|
if a:exit_val != 0
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:output[0] !=# '{'
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if empty(a:output) || type(a:output) != type("")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let result = json_decode(a:output)
|
||||||
|
if type(result) != type({})
|
||||||
|
call go#util#EchoError(printf("malformed output from guru: %s", a:output))
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !has_key(result, 'detail')
|
||||||
|
" if there is no detail check if there is a description and print it
|
||||||
|
if has_key(result, "desc")
|
||||||
|
call go#util#EchoInfo(result["desc"])
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#util#EchoError("detail key is missing. Please open a bug report on vim-go repo.")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let detail = result['detail']
|
||||||
|
let info = ""
|
||||||
|
|
||||||
|
" guru gives different information based on the detail mode. Let try to
|
||||||
|
" extract the most useful information
|
||||||
|
|
||||||
|
if detail == "value"
|
||||||
|
if !has_key(result, 'value')
|
||||||
|
call go#util#EchoError("value key is missing. Please open a bug report on vim-go repo.")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let val = result["value"]
|
||||||
|
if !has_key(val, 'type')
|
||||||
|
call go#util#EchoError("type key is missing (value.type). Please open a bug report on vim-go repo.")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let info = val["type"]
|
||||||
|
elseif detail == "type"
|
||||||
|
if !has_key(result, 'type')
|
||||||
|
call go#util#EchoError("type key is missing. Please open a bug report on vim-go repo.")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let type = result["type"]
|
||||||
|
if !has_key(type, 'type')
|
||||||
|
call go#util#EchoError("type key is missing (type.type). Please open a bug report on vim-go repo.")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let info = type["type"]
|
||||||
|
elseif detail == "package"
|
||||||
|
if !has_key(result, 'package')
|
||||||
|
call go#util#EchoError("package key is missing. Please open a bug report on vim-go repo.")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let package = result["package"]
|
||||||
|
if !has_key(package, 'path')
|
||||||
|
call go#util#EchoError("path key is missing (package.path). Please open a bug report on vim-go repo.")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let info = printf("package %s", package["path"])
|
||||||
|
elseif detail == "unknown"
|
||||||
|
let info = result["desc"]
|
||||||
|
else
|
||||||
|
call go#util#EchoError(printf("unknown detail mode found '%s'. Please open a bug report on vim-go repo", detail))
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#util#ShowInfo(info)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Show possible targets of selected function call
|
||||||
|
function! go#guru#Callees(selected) abort
|
||||||
|
let args = {
|
||||||
|
\ 'mode': 'callees',
|
||||||
|
\ 'format': 'plain',
|
||||||
|
\ 'selected': a:selected,
|
||||||
|
\ 'needs_scope': 1,
|
||||||
|
\ }
|
||||||
|
|
||||||
|
call s:run_guru(args)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Show path from callgraph root to selected function
|
||||||
|
function! go#guru#Callstack(selected) abort
|
||||||
|
let args = {
|
||||||
|
\ 'mode': 'callstack',
|
||||||
|
\ 'format': 'plain',
|
||||||
|
\ 'selected': a:selected,
|
||||||
|
\ 'needs_scope': 1,
|
||||||
|
\ }
|
||||||
|
|
||||||
|
call s:run_guru(args)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Show free variables of selection
|
||||||
|
function! go#guru#Freevars(selected) abort
|
||||||
|
" Freevars requires a selection
|
||||||
|
if a:selected == -1
|
||||||
|
call go#util#EchoError("GoFreevars requires a selection (range) of code")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let args = {
|
||||||
|
\ 'mode': 'freevars',
|
||||||
|
\ 'format': 'plain',
|
||||||
|
\ 'selected': 1,
|
||||||
|
\ 'needs_scope': 0,
|
||||||
|
\ }
|
||||||
|
|
||||||
|
call s:run_guru(args)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Show send/receive corresponding to selected channel op
|
||||||
|
function! go#guru#ChannelPeers(selected) abort
|
||||||
|
let args = {
|
||||||
|
\ 'mode': 'peers',
|
||||||
|
\ 'format': 'plain',
|
||||||
|
\ 'selected': a:selected,
|
||||||
|
\ 'needs_scope': 1,
|
||||||
|
\ }
|
||||||
|
|
||||||
|
call s:run_guru(args)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Show all refs to entity denoted by selected identifier
|
||||||
|
function! go#guru#Referrers(selected) abort
|
||||||
|
let args = {
|
||||||
|
\ 'mode': 'referrers',
|
||||||
|
\ 'format': 'plain',
|
||||||
|
\ 'selected': a:selected,
|
||||||
|
\ 'needs_scope': 0,
|
||||||
|
\ }
|
||||||
|
|
||||||
|
call s:run_guru(args)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" TODO(bc) factor into a new file, sameids.vim and get rid of the guru adapter
|
||||||
|
" in lsp.vim.
|
||||||
|
function! go#guru#SameIds(showstatus) abort
|
||||||
|
" check if the version of Vim being tested supports matchaddpos()
|
||||||
|
if !exists("*matchaddpos")
|
||||||
|
call go#util#EchoError("GoSameIds requires 'matchaddpos'. Update your Vim/Neovim version.")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" check if the version of Vim being tested supports json_decode()
|
||||||
|
if !exists("*json_decode")
|
||||||
|
call go#util#EchoError("GoSameIds requires 'json_decode'. Update your Vim/Neovim version.")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let [l:line, l:col] = getpos('.')[1:2]
|
||||||
|
let [l:line, l:col] = go#lsp#lsp#Position(l:line, l:col)
|
||||||
|
call go#lsp#SameIDs(0, expand('%:p'), l:line, l:col, funcref('s:same_ids_highlight'))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:same_ids_highlight(exit_val, output, mode) abort
|
||||||
|
call go#guru#ClearSameIds() " run after calling guru to reduce flicker.
|
||||||
|
|
||||||
|
if a:output[0] !=# '{'
|
||||||
|
if !go#config#AutoSameids()
|
||||||
|
call go#util#EchoError(a:output)
|
||||||
|
endif
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let result = json_decode(a:output)
|
||||||
|
if type(result) != type({}) && !go#config#AutoSameids()
|
||||||
|
call go#util#EchoError("malformed output from guru")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !has_key(result, 'sameids')
|
||||||
|
if !go#config#AutoSameids()
|
||||||
|
call go#util#EchoError("no same_ids founds for the given identifier")
|
||||||
|
endif
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let poslen = 0
|
||||||
|
for enclosing in result['enclosing']
|
||||||
|
if enclosing['desc'] == 'identifier'
|
||||||
|
let poslen = enclosing['end'] - enclosing['start']
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
" return when there's no identifier to highlight.
|
||||||
|
if poslen == 0
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let same_ids = result['sameids']
|
||||||
|
|
||||||
|
" highlight the lines
|
||||||
|
let l:matches = []
|
||||||
|
for item in same_ids
|
||||||
|
let pos = split(item, ':')
|
||||||
|
let l:matches = add(l:matches, [str2nr(pos[-2]), str2nr(pos[-1]), str2nr(poslen)])
|
||||||
|
endfor
|
||||||
|
|
||||||
|
call go#util#HighlightPositions('goSameId', l:matches)
|
||||||
|
|
||||||
|
if go#config#AutoSameids()
|
||||||
|
" re-apply SameIds at the current cursor position at the time the buffer
|
||||||
|
" is redisplayed: e.g. :edit, :GoRename, etc.
|
||||||
|
augroup vim-go-sameids
|
||||||
|
autocmd! * <buffer>
|
||||||
|
if has('textprop')
|
||||||
|
autocmd BufReadPost <buffer> nested call go#guru#SameIds(0)
|
||||||
|
else
|
||||||
|
autocmd BufWinEnter <buffer> nested call go#guru#SameIds(0)
|
||||||
|
endif
|
||||||
|
augroup end
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" ClearSameIds returns 0 when it removes goSameId groups and non-zero if no
|
||||||
|
" goSameId groups are found.
|
||||||
|
function! go#guru#ClearSameIds() abort
|
||||||
|
let l:cleared = go#util#ClearHighlights('goSameId')
|
||||||
|
|
||||||
|
if !l:cleared
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
" remove the autocmds we defined
|
||||||
|
augroup vim-go-sameids
|
||||||
|
autocmd! * <buffer>
|
||||||
|
augroup end
|
||||||
|
|
||||||
|
return 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#guru#ToggleSameIds() abort
|
||||||
|
if go#guru#ClearSameIds() != 0
|
||||||
|
call go#guru#SameIds(1)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#guru#AutoToggleSameIds() abort
|
||||||
|
if go#config#AutoSameids()
|
||||||
|
call go#util#EchoProgress("sameids auto highlighting disabled")
|
||||||
|
call go#guru#ClearSameIds()
|
||||||
|
call go#config#SetAutoSameids(0)
|
||||||
|
else
|
||||||
|
call go#util#EchoSuccess("sameids auto highlighting enabled")
|
||||||
|
call go#config#SetAutoSameids(1)
|
||||||
|
endif
|
||||||
|
call go#auto#update_autocmd()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
""""""""""""""""""""""""""""""""""""""""
|
||||||
|
"" HELPER FUNCTIONS
|
||||||
|
""""""""""""""""""""""""""""""""""""""""
|
||||||
|
|
||||||
|
" This uses Vim's errorformat to parse the output from Guru's 'plain output
|
||||||
|
" and put it into location list. I believe using errorformat is much more
|
||||||
|
" easier to use. If we need more power we can always switch back to parse it
|
||||||
|
" via regex. Match two possible styles of errorformats:
|
||||||
|
"
|
||||||
|
" 'file:line.col-line2.col2: message'
|
||||||
|
" 'file:line:col: message'
|
||||||
|
"
|
||||||
|
" We discard line2 and col2 for the first errorformat, because it's not
|
||||||
|
" useful and location only has the ability to show one line and column
|
||||||
|
" number
|
||||||
|
function! s:parse_guru_output(exit_val, output, title) abort
|
||||||
|
if a:exit_val
|
||||||
|
call go#util#EchoError(a:output)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let errformat = "%f:%l.%c-%[%^:]%#:\ %m,%f:%l:%c:\ %m"
|
||||||
|
let l:listtype = go#list#Type("_guru")
|
||||||
|
call go#list#ParseFormat(l:listtype, errformat, a:output, a:title, 0)
|
||||||
|
|
||||||
|
let errors = go#list#Get(l:listtype)
|
||||||
|
call go#list#Window(l:listtype, len(errors))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#guru#Scope(...) abort
|
||||||
|
if a:0
|
||||||
|
let scope = a:000
|
||||||
|
if a:0 == 1 && a:1 == '""'
|
||||||
|
let scope = []
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#config#SetGuruScope(scope)
|
||||||
|
if empty(scope)
|
||||||
|
call go#util#EchoSuccess("guru scope is cleared")
|
||||||
|
else
|
||||||
|
call go#util#EchoSuccess("guru scope changed to: ". join(a:000, ","))
|
||||||
|
endif
|
||||||
|
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let scope = go#config#GuruScope()
|
||||||
|
if empty(scope)
|
||||||
|
call go#util#EchoError("guru scope is not set")
|
||||||
|
else
|
||||||
|
call go#util#EchoSuccess("current guru scope: ". join(scope, ","))
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
23
sources_non_forked/vim-go/autoload/go/guru_test.vim
Normal file
23
sources_non_forked/vim-go/autoload/go/guru_test.vim
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
function Test_GuruScope_Set() abort
|
||||||
|
silent call go#guru#Scope("example.com/foo/bar")
|
||||||
|
let actual = go#config#GuruScope()
|
||||||
|
call assert_equal(["example.com/foo/bar"], actual)
|
||||||
|
|
||||||
|
silent call go#guru#Scope('""')
|
||||||
|
silent let actual = go#config#GuruScope()
|
||||||
|
call assert_equal([], actual, "setting scope to empty string should clear")
|
||||||
|
|
||||||
|
if exists('g:go_guru_scope')
|
||||||
|
unlet g:go_guru_scope
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
599
sources_non_forked/vim-go/autoload/go/highlight_test.vim
Normal file
599
sources_non_forked/vim-go/autoload/go/highlight_test.vim
Normal file
|
@ -0,0 +1,599 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
function! Test_gomodVersion_highlight() abort
|
||||||
|
try
|
||||||
|
syntax on
|
||||||
|
|
||||||
|
let l:dir = gotest#write_file('gomodtest/go.mod', [
|
||||||
|
\ 'module github.com/fatih/vim-go',
|
||||||
|
\ '',
|
||||||
|
\ '\x1frequire (',
|
||||||
|
\ '\tversion/simple v1.0.0',
|
||||||
|
\ '\tversion/simple-pre-release v1.0.0-rc',
|
||||||
|
\ '\tversion/simple-pre-release v1.0.0+meta',
|
||||||
|
\ '\tversion/simple-pre-release v1.0.0-rc+meta',
|
||||||
|
\ '\tversion/pseudo/premajor v1.0.0-20060102150405-0123456789abcdef',
|
||||||
|
\ '\tversion/pseudo/prerelease v1.0.0-prerelease.0.20060102150405-0123456789abcdef',
|
||||||
|
\ '\tversion/pseudo/prepatch v1.0.1-0.20060102150405-0123456789abcdef',
|
||||||
|
\ '\tversion/simple/incompatible v2.0.0+incompatible',
|
||||||
|
\ '\tversion/pseudo/premajor/incompatible v2.0.0-20060102150405-0123456789abcdef+incompatible',
|
||||||
|
\ '\tversion/pseudo/prerelease/incompatible v2.0.0-prerelease.0.20060102150405-0123456789abcdef+incompatible',
|
||||||
|
\ '\tversion/pseudo/prepatch/incompatible v2.0.1-0.20060102150405-0123456789abcdef+incompatible',
|
||||||
|
\ ')'])
|
||||||
|
|
||||||
|
let l:lineno = 4
|
||||||
|
let l:lineclose = line('$')
|
||||||
|
while l:lineno < l:lineclose
|
||||||
|
let l:line = getline(l:lineno)
|
||||||
|
let l:col = col([l:lineno, '$']) - 1
|
||||||
|
let l:idx = len(l:line) - 1
|
||||||
|
let l:from = stridx(l:line, ' ') + 1
|
||||||
|
|
||||||
|
while l:idx >= l:from
|
||||||
|
call cursor(l:lineno, l:col)
|
||||||
|
let l:synname = synIDattr(synID(l:lineno, l:col, 1), 'name')
|
||||||
|
let l:errlen = len(v:errors)
|
||||||
|
|
||||||
|
call assert_equal('gomodVersion', l:synname, 'version on line ' . l:lineno)
|
||||||
|
|
||||||
|
" continue at the next line if there was an error at this column;
|
||||||
|
" there's no need to test each column once an error is detected.
|
||||||
|
if l:errlen < len(v:errors)
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:col -= 1
|
||||||
|
let l:idx -= 1
|
||||||
|
endwhile
|
||||||
|
let l:lineno += 1
|
||||||
|
endwhile
|
||||||
|
finally
|
||||||
|
call delete(l:dir, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
function! Test_gomodVersion_incompatible_highlight() abort
|
||||||
|
try
|
||||||
|
syntax on
|
||||||
|
|
||||||
|
let l:dir = gotest#write_file('gomodtest/go.mod', [
|
||||||
|
\ 'module github.com/fatih/vim-go',
|
||||||
|
\ '',
|
||||||
|
\ '\x1frequire (',
|
||||||
|
\ '\tversion/invalid/premajor/incompatible v1.0.0-20060102150405-0123456789abcdef+incompatible',
|
||||||
|
\ '\tversion/invalid/prerelease/incompatible v1.0.0-prerelease.0.20060102150405-0123456789abcdef+incompatible',
|
||||||
|
\ '\tversion/invalid/prepatch/incompatible v1.0.1-0.20060102150405-0123456789abcdef+incompatible',
|
||||||
|
\ ')'])
|
||||||
|
|
||||||
|
let l:lineno = 4
|
||||||
|
let l:lineclose = line('$')
|
||||||
|
while l:lineno < l:lineclose
|
||||||
|
let l:line = getline(l:lineno)
|
||||||
|
let l:col = col([l:lineno, '$']) - 1
|
||||||
|
let l:idx = len(l:line) - 1
|
||||||
|
let l:from = stridx(l:line, '+')
|
||||||
|
|
||||||
|
while l:idx >= l:from
|
||||||
|
call cursor(l:lineno, l:col)
|
||||||
|
let l:synname = synIDattr(synID(l:lineno, l:col, 1), 'name')
|
||||||
|
let l:errlen = len(v:errors)
|
||||||
|
|
||||||
|
call assert_notequal('gomodVersion', l:synname, 'version on line ' . l:lineno)
|
||||||
|
|
||||||
|
" continue at the next line if there was an error at this column;
|
||||||
|
" there's no need to test each column once an error is detected.
|
||||||
|
if l:errlen < len(v:errors)
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:col -= 1
|
||||||
|
let l:idx -= 1
|
||||||
|
endwhile
|
||||||
|
let l:lineno += 1
|
||||||
|
endwhile
|
||||||
|
finally
|
||||||
|
call delete(l:dir, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
function! Test_numeric_literal_highlight() abort
|
||||||
|
syntax on
|
||||||
|
|
||||||
|
let tests = {
|
||||||
|
\ 'lone zero': {'group': 'goDecimalInt', 'value': '0'},
|
||||||
|
\ 'integer': {'group': 'goDecimalInt', 'value': '1234567890'},
|
||||||
|
\ 'integerGrouped': {'group': 'goDecimalInt', 'value': '1_234_567_890'},
|
||||||
|
\ 'hexadecimal': {'group': 'goHexadecimalInt', 'value': '0x0123456789abdef'},
|
||||||
|
\ 'hexadecimalGrouped': {'group': 'goHexadecimalInt', 'value': '0x012_345_678_9ab_def'},
|
||||||
|
\ 'heXadecimal': {'group': 'goHexadecimalInt', 'value': '0X0123456789abdef'},
|
||||||
|
\ 'octal': {'group': 'goOctalInt', 'value': '01234567'},
|
||||||
|
\ 'octalPrefix': {'group': 'goOctalInt', 'value': '0o1234567'},
|
||||||
|
\ 'octalGrouped': {'group': 'goOctalInt', 'value': '0o1_234_567'},
|
||||||
|
\ 'OctalPrefix': {'group': 'goOctalInt', 'value': '0O1234567'},
|
||||||
|
\ 'binaryInt': {'group': 'goBinaryInt', 'value': '0b0101'},
|
||||||
|
\ 'binaryIntGrouped': {'group': 'goBinaryInt', 'value': '0b_01_01'},
|
||||||
|
\ 'BinaryInt': {'group': 'goBinaryInt', 'value': '0B0101'},
|
||||||
|
\ }
|
||||||
|
|
||||||
|
for kv in items(tests)
|
||||||
|
let l:actual = s:numericHighlightGroupInAssignment(kv[0], kv[1].value)
|
||||||
|
call assert_equal(kv[1].group, l:actual, kv[0])
|
||||||
|
endfor
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Test_zero_as_index_element() abort
|
||||||
|
syntax on
|
||||||
|
|
||||||
|
let l:actual = s:numericHighlightGroupInSliceElement('zero-element', '0')
|
||||||
|
call assert_equal('goDecimalInt', l:actual)
|
||||||
|
let l:actual = s:numericHighlightGroupInMultidimensionalSliceElement('zero-element', '0')
|
||||||
|
call assert_equal('goDecimalInt', l:actual, 'multi-dimensional')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Test_zero_as_slice_index() abort
|
||||||
|
syntax on
|
||||||
|
|
||||||
|
let l:actual = s:numericHighlightGroupInSliceIndex('zero-index', '0')
|
||||||
|
call assert_equal('goDecimalInt', l:actual)
|
||||||
|
let l:actual = s:numericHighlightGroupInMultidimensionalSliceIndex('zero-index', '0', '0')
|
||||||
|
|
||||||
|
call assert_equal('goDecimalInt', l:actual, 'multi-dimensional')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Test_zero_as_start_slicing_slice() abort
|
||||||
|
syntax on
|
||||||
|
|
||||||
|
let l:actual = s:numericHighlightGroupInSliceSlicing('slice-slicing', '0', '1')
|
||||||
|
call assert_equal('goDecimalInt', l:actual)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:numericHighlightGroupInAssignment(testname, value)
|
||||||
|
let l:dir = gotest#write_file(printf('numeric/%s.go', a:testname), [
|
||||||
|
\ 'package numeric',
|
||||||
|
\ '',
|
||||||
|
\ printf("var v = %s\x1f", a:value),
|
||||||
|
\ ])
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:pos = getcurpos()
|
||||||
|
let l:actual = synIDattr(synID(l:pos[1], l:pos[2], 1), 'name')
|
||||||
|
return l:actual
|
||||||
|
finally
|
||||||
|
call delete(l:dir, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:numericHighlightGroupInSliceElement(testname, value)
|
||||||
|
let l:dir = gotest#write_file(printf('numeric/slice-element/%s.go', a:testname), [
|
||||||
|
\ 'package numeric',
|
||||||
|
\ '',
|
||||||
|
\ printf("v := []int{%s\x1f}", a:value),
|
||||||
|
\ ])
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:pos = getcurpos()
|
||||||
|
let l:actual = synIDattr(synID(l:pos[1], l:pos[2], 1), 'name')
|
||||||
|
return l:actual
|
||||||
|
finally
|
||||||
|
call delete(l:dir, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:numericHighlightGroupInMultidimensionalSliceElement(testname, value)
|
||||||
|
let l:dir = gotest#write_file(printf('numeric/slice-multidimensional-element/%s.go', a:testname), [
|
||||||
|
\ 'package numeric',
|
||||||
|
\ '',
|
||||||
|
\ printf("v := [][]int{{%s\x1f},{%s}}", a:value, a:value),
|
||||||
|
\ ])
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:pos = getcurpos()
|
||||||
|
let l:actual = synIDattr(synID(l:pos[1], l:pos[2], 1), 'name')
|
||||||
|
return l:actual
|
||||||
|
finally
|
||||||
|
call delete(l:dir, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:numericHighlightGroupInSliceIndex(testname, value)
|
||||||
|
let l:dir = gotest#write_file(printf('numeric/slice-index/%s.go', a:testname), [
|
||||||
|
\ 'package numeric',
|
||||||
|
\ '',
|
||||||
|
\ 'var sl []int',
|
||||||
|
\ printf("println(sl[%s\x1f])", a:value),
|
||||||
|
\ ])
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:pos = getcurpos()
|
||||||
|
let l:actual = synIDattr(synID(l:pos[1], l:pos[2], 1), 'name')
|
||||||
|
return l:actual
|
||||||
|
finally
|
||||||
|
call delete(l:dir, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:numericHighlightGroupInMultidimensionalSliceIndex(testname, first, second)
|
||||||
|
let l:dir = gotest#write_file(printf('numeric/slice-multidimensional-index/%s.go', a:testname), [
|
||||||
|
\ 'package numeric',
|
||||||
|
\ '',
|
||||||
|
\ 'var sl [][]int',
|
||||||
|
\ printf("println(sl[%s\x1f][%s])", a:first, a:second),
|
||||||
|
\ ])
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:pos = getcurpos()
|
||||||
|
let l:actual = synIDattr(synID(l:pos[1], l:pos[2], 1), 'name')
|
||||||
|
return l:actual
|
||||||
|
finally
|
||||||
|
call delete(l:dir, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:numericHighlightGroupInSliceSlicing(testname, from, to)
|
||||||
|
let l:dir = gotest#write_file(printf('numeric/slice-slicing/%s.go', a:testname), [
|
||||||
|
\ 'package numeric',
|
||||||
|
\ '',
|
||||||
|
\ 'var sl = []int{1,2}',
|
||||||
|
\ printf("println(sl[%s\x1f:%s])", a:from, a:to),
|
||||||
|
\ ])
|
||||||
|
try
|
||||||
|
let l:pos = getcurpos()
|
||||||
|
let l:actual = synIDattr(synID(l:pos[1], l:pos[2], 1), 'name')
|
||||||
|
return l:actual
|
||||||
|
finally
|
||||||
|
call delete(l:dir, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Test_diagnostic_after_fmt() abort
|
||||||
|
let g:go_fmt_command = 'gofmt'
|
||||||
|
let g:go_diagnostics_level = 2
|
||||||
|
try
|
||||||
|
call s:diagnostic_after_write( [
|
||||||
|
\ 'package main',
|
||||||
|
\ 'import "fmt"',
|
||||||
|
\ '',
|
||||||
|
\ 'func main() {',
|
||||||
|
\ '',
|
||||||
|
\ "\tfmt.Println(h\x1fello)",
|
||||||
|
\ '}',
|
||||||
|
\ ], [])
|
||||||
|
finally
|
||||||
|
unlet g:go_fmt_command
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Test_diagnostic_after_fmt_change() abort
|
||||||
|
" craft a file that will be changed when its written (gofmt will change it).
|
||||||
|
let g:go_fmt_command = 'gofmt'
|
||||||
|
let g:go_diagnostics_level = 2
|
||||||
|
try
|
||||||
|
call s:diagnostic_after_write( [
|
||||||
|
\ 'package main',
|
||||||
|
\ 'import "fmt"',
|
||||||
|
\ '',
|
||||||
|
\ 'func main() {',
|
||||||
|
\ '',
|
||||||
|
\ "fmt.Println(h\x1fello)",
|
||||||
|
\ '}',
|
||||||
|
\ ], [])
|
||||||
|
finally
|
||||||
|
unlet g:go_fmt_command
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Test_diagnostic_after_fmt_cleared() abort
|
||||||
|
" craft a file that will be fixed when it is written.
|
||||||
|
let g:go_fmt_command = 'gofmt'
|
||||||
|
let g:go_diagnostics_level = 2
|
||||||
|
try
|
||||||
|
call s:diagnostic_after_write( [
|
||||||
|
\ 'package main',
|
||||||
|
\ 'import "fmt"',
|
||||||
|
\ '',
|
||||||
|
\ 'func main() {',
|
||||||
|
\ '',
|
||||||
|
\ "fmt.Println(h\x1fello)",
|
||||||
|
\ '}',
|
||||||
|
\ ], ['hello := "hello, vim-go"'])
|
||||||
|
finally
|
||||||
|
unlet g:go_fmt_command
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Test_diagnostic_after_reload() abort
|
||||||
|
let g:go_diagnostics_level = 2
|
||||||
|
let l:dir = gotest#write_file('diagnostic/after-reload.go', [
|
||||||
|
\ 'package main',
|
||||||
|
\ 'import "fmt"',
|
||||||
|
\ '',
|
||||||
|
\ 'func main() {',
|
||||||
|
\ '',
|
||||||
|
\ "\tfmt.Println(h\x1fello)",
|
||||||
|
\ '}',
|
||||||
|
\ ])
|
||||||
|
try
|
||||||
|
call s:check_diagnostics('', 'goDiagnosticError', 'initial')
|
||||||
|
let l:pos = getcurpos()
|
||||||
|
edit
|
||||||
|
call setpos('.', l:pos)
|
||||||
|
call s:check_diagnostics('', 'goDiagnosticError', 'after-reload')
|
||||||
|
finally
|
||||||
|
call delete(l:dir, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:diagnostic_after_write(contents, changes) abort
|
||||||
|
syntax on
|
||||||
|
|
||||||
|
let g:go_diagnostics_level = 2
|
||||||
|
let l:dir = gotest#write_file('diagnostic/after-write.go', a:contents)
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:pos = getcurpos()
|
||||||
|
call s:check_diagnostics('', 'goDiagnosticError', 'initial')
|
||||||
|
|
||||||
|
" write a:changes to the previous line and make sure l:actual and
|
||||||
|
" l:expected are set so that they won't accidentally match on the next
|
||||||
|
" check.
|
||||||
|
if len(a:changes) > 0
|
||||||
|
call append(l:pos[1]-1, a:changes)
|
||||||
|
let l:actual = 'goDiagnosticError'
|
||||||
|
let l:expected = ''
|
||||||
|
else
|
||||||
|
let l:actual = ''
|
||||||
|
let l:expected = 'goDiagnosticError'
|
||||||
|
endif
|
||||||
|
|
||||||
|
write
|
||||||
|
|
||||||
|
call s:check_diagnostics(l:actual, l:expected, 'after-write')
|
||||||
|
finally
|
||||||
|
call delete(l:dir, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:check_diagnostics(actual, expected, when)
|
||||||
|
let l:actual = a:actual
|
||||||
|
let l:start = reltime()
|
||||||
|
|
||||||
|
while l:actual != a:expected && reltimefloat(reltime(l:start)) < 10
|
||||||
|
" Get the cursor position on each iteration, because the cursor postion
|
||||||
|
" may change between iterations when go#fmt#GoFmt formats, reloads the
|
||||||
|
" file, and moves the cursor to try to keep it where the user expects it
|
||||||
|
" to be when gofmt modifies the files.
|
||||||
|
let l:pos = getcurpos()
|
||||||
|
if !has('textprop')
|
||||||
|
let l:matches = getmatches()
|
||||||
|
if len(l:matches) == 0
|
||||||
|
let l:actual = ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
for l:m in l:matches
|
||||||
|
let l:matchline = l:m.pos1[0]
|
||||||
|
if len(l:m.pos1) < 2
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
let l:matchcol = get(l:m.pos1, 1, 1)
|
||||||
|
if l:pos[1] == l:matchline && l:pos[2] >= l:matchcol && l:pos[2] <= l:matchcol + l:m.pos1[2]
|
||||||
|
" Ideally, we'd check that the cursor is within the match, but when a
|
||||||
|
" tab is added on the current line, the cursor position within the
|
||||||
|
" line will stay constant while the line itself is shifted over by a
|
||||||
|
" column, so just check the line itself instead of checking a precise
|
||||||
|
" cursor location.
|
||||||
|
" if l:pos[1] == l:matchline
|
||||||
|
let l:actual = l:m.group
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
sleep 100m
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:actual = get(prop_list(l:pos[1]), 0, {'type': ''}).type
|
||||||
|
sleep 100m
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call assert_equal(a:expected, l:actual, a:when)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Test_goStringHighlight() abort
|
||||||
|
syntax on
|
||||||
|
|
||||||
|
let l:dir = gotest#write_file('highlight/gostring.go', [
|
||||||
|
\ 'package highlight',
|
||||||
|
\ '',
|
||||||
|
\ 'import (',
|
||||||
|
\ printf("\t%s", '"fmt"'),
|
||||||
|
\ ')',
|
||||||
|
\ '',
|
||||||
|
\ printf('var s = "%s"', "gostring\x1f"),
|
||||||
|
\ ])
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:pos = getcurpos()
|
||||||
|
let l:actual = synIDattr(synID(l:pos[1], l:pos[2], 1), 'name')
|
||||||
|
call assert_equal('goString', l:actual)
|
||||||
|
finally
|
||||||
|
call delete(l:dir, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
function! Test_goImportStringHighlight() abort
|
||||||
|
syntax on
|
||||||
|
|
||||||
|
let l:dir = gotest#write_file('highlight/import.go', [
|
||||||
|
\ 'package highlight',
|
||||||
|
\ '',
|
||||||
|
\ 'import (',
|
||||||
|
\ printf('%s"%s"', "\t", "f\x1fmt"),
|
||||||
|
\ ')',
|
||||||
|
\ '',
|
||||||
|
\ 'var s = fmt.Sprint("gostring")',
|
||||||
|
\ ])
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:pos = getcurpos()
|
||||||
|
let l:actual = synIDattr(synID(l:pos[1], l:pos[2], 1), 'name')
|
||||||
|
call assert_equal('goImportString', l:actual)
|
||||||
|
finally
|
||||||
|
call delete(l:dir, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
function! Test_goReceiverHighlight() abort
|
||||||
|
syntax on
|
||||||
|
|
||||||
|
let l:tests = {
|
||||||
|
\ 'PointerReceiverVar': {'group': 'goReceiverVar', 'value': "t\x1f *T"},
|
||||||
|
\ 'ValueReceiverVar': {'group': 'goReceiverVar', 'value': "t\x1f T"},
|
||||||
|
\ 'PointerReceiverType': {'group': 'goReceiverType', 'value': "t *T\x1f"},
|
||||||
|
\ 'ValueReceiverType': {'group': 'goReceiverType', 'value': "t T\x1f"},
|
||||||
|
\ 'PointerReceiverTypeOmittedVar': {'group': 'goReceiverType', 'value': "*T\x1f"},
|
||||||
|
\ 'ValueReceiverTypeOmittedVar': {'group': 'goReceiverType', 'value': "T\x1f"},
|
||||||
|
\ 'GenericPointerReceiverVar': {'group': 'goReceiverVar', 'value': "g\x1f *G[int]"},
|
||||||
|
\ 'GenericValueReceiverVar': {'group': 'goReceiverVar', 'value': "g\x1f G[int]"},
|
||||||
|
\ 'GenericPointerReceiverType': {'group': 'goReceiverType', 'value': "g *G\x1f[int]"},
|
||||||
|
\ 'GenericValueReceiverType': {'group': 'goReceiverType', 'value': "g G\x1f[int]"},
|
||||||
|
\ 'GenericPointerReceiverTypeOmittedVar': {'group': 'goReceiverType', 'value': "*G\x1f[int]"},
|
||||||
|
\ 'GenericValueReceiverTypeOmittedVar': {'group': 'goReceiverType', 'value': "G\x1f[int]"},
|
||||||
|
\ }
|
||||||
|
|
||||||
|
let g:go_highlight_function_parameters = 1
|
||||||
|
for l:kv in items(l:tests)
|
||||||
|
let l:actual = s:receiverHighlightGroup(l:kv[0], l:kv[1].value)
|
||||||
|
call assert_equal(l:kv[1].group, l:actual, l:kv[0])
|
||||||
|
endfor
|
||||||
|
unlet g:go_highlight_function_parameters
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
function! s:receiverHighlightGroup(testname, value)
|
||||||
|
let l:package = tolower(a:testname)
|
||||||
|
let l:dir = gotest#write_file(printf('%s/%s.go', l:package, a:testname), [
|
||||||
|
\ printf('package %s', l:package),
|
||||||
|
\ '',
|
||||||
|
\ 'type T struct{}',
|
||||||
|
\ 'type G[T any] struct{}',
|
||||||
|
\ printf('func (%s) Foo() {}', a:value),
|
||||||
|
\ ])
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:pos = getcurpos()
|
||||||
|
let l:actual = synIDattr(synID(l:pos[1], l:pos[2], 1), 'name')
|
||||||
|
return l:actual
|
||||||
|
finally
|
||||||
|
call delete(l:dir, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
function! Test_GoTypeHighlight() abort
|
||||||
|
syntax on
|
||||||
|
|
||||||
|
let l:tests = {
|
||||||
|
\ 'StandardType': {'group': 'goTypeName', 'value': "T\x1f"},
|
||||||
|
\ 'GenericType': {'group': 'goTypeName', 'value': "G\x1f[T any]"},
|
||||||
|
\ }
|
||||||
|
|
||||||
|
let g:go_highlight_types = 1
|
||||||
|
for l:kv in items(l:tests)
|
||||||
|
let l:actual = s:typeHighlightGroup(l:kv[0], l:kv[1].value)
|
||||||
|
call assert_equal(l:kv[1].group, l:actual, l:kv[0])
|
||||||
|
endfor
|
||||||
|
unlet g:go_highlight_types
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
function! s:typeHighlightGroup(testname, value)
|
||||||
|
let l:package = tolower(a:testname)
|
||||||
|
let l:dir = gotest#write_file(printf('%s/%s.go', l:package, a:testname), [
|
||||||
|
\ printf('package %s', l:package),
|
||||||
|
\ '',
|
||||||
|
\ printf('type %s struct{}', a:value),
|
||||||
|
\ ])
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:pos = getcurpos()
|
||||||
|
let l:actual = synIDattr(synID(l:pos[1], l:pos[2], 1), 'name')
|
||||||
|
return l:actual
|
||||||
|
finally
|
||||||
|
call delete(l:dir, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
function! Test_goFunction() abort
|
||||||
|
syntax on
|
||||||
|
|
||||||
|
let l:tests = {
|
||||||
|
\ 'StandardFunction': {'group': 'goFunction', 'value': "F\x1f(){}"},
|
||||||
|
\ 'GenericFunction': {'group': 'goFunction', 'value': "G\x1f[T any](_ T){}"},
|
||||||
|
\ }
|
||||||
|
|
||||||
|
let g:go_highlight_functions = 1
|
||||||
|
for l:kv in items(l:tests)
|
||||||
|
let l:actual = s:functionHighlightGroup(l:kv[0], l:kv[1].value)
|
||||||
|
call assert_equal(l:kv[1].group, l:actual, l:kv[0])
|
||||||
|
endfor
|
||||||
|
unlet g:go_highlight_functions
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
function! s:functionHighlightGroup(testname, value)
|
||||||
|
let l:package = tolower(a:testname)
|
||||||
|
let l:dir = gotest#write_file(printf('%s/%s.go', l:package, a:testname), [
|
||||||
|
\ printf('package %s', l:package),
|
||||||
|
\ '',
|
||||||
|
\ printf('func %s', a:value),
|
||||||
|
\ ])
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:pos = getcurpos()
|
||||||
|
let l:actual = synIDattr(synID(l:pos[1], l:pos[2], 1), 'name')
|
||||||
|
return l:actual
|
||||||
|
finally
|
||||||
|
call delete(l:dir, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
function! Test_goFunctionCall() abort
|
||||||
|
syntax on
|
||||||
|
|
||||||
|
let l:tests = {
|
||||||
|
\ 'StandardFunctionCall': {'group': 'goFunctionCall', 'value': "f\x1f()"},
|
||||||
|
\ 'GenericFunctionCall': {'group': 'goFunctionCall', 'value': "g\x1f[int](i)"},
|
||||||
|
\ }
|
||||||
|
|
||||||
|
let g:go_highlight_function_calls = 1
|
||||||
|
for l:kv in items(l:tests)
|
||||||
|
let l:actual = s:functionCallHighlightGroup(l:kv[0], l:kv[1].value)
|
||||||
|
call assert_equal(l:kv[1].group, l:actual, l:kv[0])
|
||||||
|
endfor
|
||||||
|
unlet g:go_highlight_function_calls
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
function! s:functionCallHighlightGroup(testname, value)
|
||||||
|
let l:package = tolower(a:testname)
|
||||||
|
let l:dir = gotest#write_file(printf('%s/%s.go', l:package, a:testname), [
|
||||||
|
\ printf('package %s', l:package),
|
||||||
|
\ '',
|
||||||
|
\ 'func f() {}',
|
||||||
|
\ 'func g[T any](i T) {}',
|
||||||
|
\ 'func init() {',
|
||||||
|
\ printf("\t%s", a:value),
|
||||||
|
\ '}',
|
||||||
|
\ ])
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:pos = getcurpos()
|
||||||
|
let l:actual = synIDattr(synID(l:pos[1], l:pos[2], 1), 'name')
|
||||||
|
return l:actual
|
||||||
|
finally
|
||||||
|
call delete(l:dir, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
26
sources_non_forked/vim-go/autoload/go/iferr.vim
Normal file
26
sources_non_forked/vim-go/autoload/go/iferr.vim
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
function! go#iferr#Generate()
|
||||||
|
let [l:out, l:err] = go#util#Exec(['iferr',
|
||||||
|
\ '-pos=' . go#util#OffsetCursor()], go#util#GetLines())
|
||||||
|
if len(l:out) == 1
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
if getline('.') =~ '^\s*$'
|
||||||
|
silent delete _
|
||||||
|
silent normal! k
|
||||||
|
endif
|
||||||
|
let l:pos = getcurpos()
|
||||||
|
call append(l:pos[1], split(l:out, "\n"))
|
||||||
|
silent normal! j=2j
|
||||||
|
call setpos('.', l:pos)
|
||||||
|
silent normal! 4j
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
175
sources_non_forked/vim-go/autoload/go/impl.vim
Normal file
175
sources_non_forked/vim-go/autoload/go/impl.vim
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
function! go#impl#Impl(...) abort
|
||||||
|
let recv = ""
|
||||||
|
let iface = ""
|
||||||
|
let interactive = 0
|
||||||
|
|
||||||
|
let pos = getpos('.')
|
||||||
|
|
||||||
|
if a:0 is 0
|
||||||
|
" Interactive mode if user didn't pass any arguments.
|
||||||
|
let recv = s:getReceiver()
|
||||||
|
let iface = input("vim-go: generating method stubs for interface: ")
|
||||||
|
redraw!
|
||||||
|
if empty(iface)
|
||||||
|
call go#util#EchoError('usage: interface type is not provided')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
elseif a:0 is 1
|
||||||
|
" we assume the user only passed the interface type,
|
||||||
|
" i.e: ':GoImpl io.Writer'
|
||||||
|
let recv = s:getReceiver()
|
||||||
|
let iface = a:1
|
||||||
|
elseif a:0 > 2
|
||||||
|
" user passed receiver and interface type both,
|
||||||
|
" i.e: 'GoImpl f *Foo io.Writer'
|
||||||
|
let recv = join(a:000[:-2], ' ')
|
||||||
|
let iface = a:000[-1]
|
||||||
|
else
|
||||||
|
call go#util#EchoError('usage: GoImpl {receiver} {interface}')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Make sure we put the generated code *after* the struct.
|
||||||
|
if getline(".") =~ "struct "
|
||||||
|
normal! $%
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
let dirname = fnameescape(expand('%:p:h'))
|
||||||
|
let [result, err] = go#util#Exec(['impl', '-dir', dirname, recv, iface])
|
||||||
|
let result = substitute(result, "\n*$", "", "")
|
||||||
|
if err
|
||||||
|
call go#util#EchoError(result)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if result is# ''
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
put =''
|
||||||
|
silent put =result
|
||||||
|
finally
|
||||||
|
call setpos('.', pos)
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:getReceiver()
|
||||||
|
let receiveType = expand("<cword>")
|
||||||
|
if receiveType == "type"
|
||||||
|
normal! w
|
||||||
|
let receiveType = expand("<cword>")
|
||||||
|
elseif receiveType == "struct"
|
||||||
|
normal! ge
|
||||||
|
let receiveType = expand("<cword>")
|
||||||
|
endif
|
||||||
|
return printf("%s *%s", tolower(receiveType)[0], receiveType)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
if exists('*uniq')
|
||||||
|
function! s:uniq(list)
|
||||||
|
return uniq(a:list)
|
||||||
|
endfunction
|
||||||
|
else
|
||||||
|
" Note: Believe that the list is sorted
|
||||||
|
function! s:uniq(list)
|
||||||
|
let i = len(a:list) - 1
|
||||||
|
while 0 < i
|
||||||
|
if a:list[i-1] ==# a:list[i]
|
||||||
|
call remove(a:list, i)
|
||||||
|
let i -= 2
|
||||||
|
else
|
||||||
|
let i -= 1
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
return a:list
|
||||||
|
endfunction
|
||||||
|
endif
|
||||||
|
|
||||||
|
function! s:root_dirs() abort
|
||||||
|
let dirs = []
|
||||||
|
let root = go#util#env("goroot")
|
||||||
|
if root !=# '' && isdirectory(root)
|
||||||
|
call add(dirs, root)
|
||||||
|
endif
|
||||||
|
|
||||||
|
let paths = map(split(go#util#env("gopath"), go#util#PathListSep()), "substitute(v:val, '\\\\', '/', 'g')")
|
||||||
|
if !empty(filter(paths, 'isdirectory(v:val)'))
|
||||||
|
call extend(dirs, paths)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return dirs
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:go_packages(dirs, arglead) abort
|
||||||
|
let pkgs = []
|
||||||
|
for dir in a:dirs
|
||||||
|
" this may expand to multiple lines
|
||||||
|
let scr_root = expand(dir . '/src/')
|
||||||
|
for pkg in split(globpath(scr_root, a:arglead.'*'), "\n")
|
||||||
|
if isdirectory(pkg)
|
||||||
|
let pkg .= '/'
|
||||||
|
elseif pkg !~ '\.a$'
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
" without this the result can have duplicates in form of
|
||||||
|
" 'encoding/json' and '/encoding/json/'
|
||||||
|
let pkg = go#util#StripPathSep(pkg)
|
||||||
|
|
||||||
|
" remove the scr root and keep the package in tact
|
||||||
|
let pkg = substitute(pkg, scr_root, "", "")
|
||||||
|
call add(pkgs, pkg)
|
||||||
|
endfor
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return pkgs
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:interface_list(pkg) abort
|
||||||
|
let [contents, err] = go#util#Exec(['go', 'doc', a:pkg])
|
||||||
|
if err
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
|
||||||
|
let contents = split(contents, "\n")
|
||||||
|
call filter(contents, 'v:val =~# ''^type\s\+\h\w*\s\+interface''')
|
||||||
|
return map(contents, 'a:pkg . "." . matchstr(v:val, ''^type\s\+\zs\h\w*\ze\s\+interface'')')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Complete package and interface for {interface}
|
||||||
|
function! go#impl#Complete(arglead, cmdline, cursorpos) abort
|
||||||
|
let words = split(a:cmdline, '\s\+', 1)
|
||||||
|
|
||||||
|
if words[-1] ==# ''
|
||||||
|
" if no words are given, just start completing the first package we found
|
||||||
|
return s:uniq(sort(s:go_packages(s:root_dirs(), a:arglead)))
|
||||||
|
elseif words[-1] =~# '^\(\h\w.*\.\%(\h\w*\)\=$\)\@!\S*$'
|
||||||
|
" start matching go packages. It's negate match of the below match
|
||||||
|
return s:uniq(sort(s:go_packages(s:root_dirs(), a:arglead)))
|
||||||
|
elseif words[-1] =~# '^\h\w.*\.\%(\h\w*\)\=$'
|
||||||
|
" match the following, anything that could indicate an interface candidate
|
||||||
|
"
|
||||||
|
" io.
|
||||||
|
" io.Wr
|
||||||
|
" github.com/fatih/color.
|
||||||
|
" github.com/fatih/color.U
|
||||||
|
" github.com/fatih/color.Un
|
||||||
|
let splitted = split(words[-1], '\.', 1)
|
||||||
|
let pkg = join(splitted[:-2], '.')
|
||||||
|
let interface = splitted[-1]
|
||||||
|
return s:uniq(sort(filter(s:interface_list(pkg), 'v:val =~? words[-1]')))
|
||||||
|
else
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
47
sources_non_forked/vim-go/autoload/go/impl_test.vim
Normal file
47
sources_non_forked/vim-go/autoload/go/impl_test.vim
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
func! Test_impl() abort
|
||||||
|
try
|
||||||
|
let l:tmp = gotest#write_file('a/a.go', [
|
||||||
|
\ 'package a',
|
||||||
|
\ '',
|
||||||
|
\ ''])
|
||||||
|
|
||||||
|
call go#impl#Impl('r', 'reader', 'io.Reader')
|
||||||
|
call gotest#assert_buffer(1, [
|
||||||
|
\ 'func (r reader) Read(p []byte) (n int, err error) {',
|
||||||
|
\ ' panic("not implemented") // TODO: Implement',
|
||||||
|
\ '}'])
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_impl_get() abort
|
||||||
|
try
|
||||||
|
let l:tmp = gotest#write_file('a/a.go', [
|
||||||
|
\ 'package a',
|
||||||
|
\ '',
|
||||||
|
\ 'type reader struct {}'])
|
||||||
|
|
||||||
|
call go#impl#Impl('io.Reader')
|
||||||
|
call gotest#assert_buffer(0, [
|
||||||
|
\ 'package a',
|
||||||
|
\ '',
|
||||||
|
\ 'type reader struct {}',
|
||||||
|
\ '',
|
||||||
|
\ 'func (r *reader) Read(p []byte) (n int, err error) {',
|
||||||
|
\ ' panic("not implemented") // TODO: Implement',
|
||||||
|
\ '}'])
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
44
sources_non_forked/vim-go/autoload/go/implements.vim
Normal file
44
sources_non_forked/vim-go/autoload/go/implements.vim
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
function! go#implements#Implements(selected) abort
|
||||||
|
let l:mode = go#config#ImplementsMode()
|
||||||
|
if l:mode == 'guru'
|
||||||
|
call go#guru#Implements(a:selected)
|
||||||
|
return
|
||||||
|
elseif l:mode == 'gopls'
|
||||||
|
if !go#config#GoplsEnabled()
|
||||||
|
call go#util#EchoError("go_implements_mode is 'gopls', but gopls is disabled")
|
||||||
|
endif
|
||||||
|
let [l:line, l:col] = getpos('.')[1:2]
|
||||||
|
let [l:line, l:col] = go#lsp#lsp#Position(l:line, l:col)
|
||||||
|
let l:fname = expand('%:p')
|
||||||
|
call go#lsp#Implements(l:fname, l:line, l:col, funcref('s:parse_output'))
|
||||||
|
return
|
||||||
|
else
|
||||||
|
call go#util#EchoWarning('unknown value for g:go_implements_mode')
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" This uses Vim's errorformat to parse the output and put it into a quickfix
|
||||||
|
" or locationlist.
|
||||||
|
function! s:parse_output(exit_val, output, title) abort
|
||||||
|
if a:exit_val
|
||||||
|
call go#util#EchoError(a:output)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let errformat = ",%f:%l:%c:\ %m"
|
||||||
|
let l:listtype = go#list#Type("GoImplements")
|
||||||
|
call go#list#ParseFormat(l:listtype, errformat, a:output, a:title, 0)
|
||||||
|
|
||||||
|
let errors = go#list#Get(l:listtype)
|
||||||
|
call go#list#Window(l:listtype, len(errors))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
232
sources_non_forked/vim-go/autoload/go/import.vim
Normal file
232
sources_non_forked/vim-go/autoload/go/import.vim
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
" Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
" Use of this source code is governed by a BSD-style
|
||||||
|
" license that can be found in the LICENSE file.
|
||||||
|
"
|
||||||
|
" Check out the docs for more information at /doc/vim-go.txt
|
||||||
|
"
|
||||||
|
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
function! go#import#SwitchImport(enabled, localname, path, bang) abort
|
||||||
|
let view = winsaveview()
|
||||||
|
let path = substitute(a:path, '^\s*\(.\{-}\)\s*$', '\1', '')
|
||||||
|
|
||||||
|
" Quotes are not necessary, so remove them if provided.
|
||||||
|
if path[0] == '"'
|
||||||
|
let path = strpart(path, 1)
|
||||||
|
endif
|
||||||
|
if path[len(path)-1] == '"'
|
||||||
|
let path = strpart(path, 0, len(path) - 1)
|
||||||
|
endif
|
||||||
|
|
||||||
|
" if given a trailing slash, eg. `github.com/user/pkg/`, remove it
|
||||||
|
if path[len(path)-1] == '/'
|
||||||
|
let path = strpart(path, 0, len(path) - 1)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if path == ''
|
||||||
|
call s:Error('Import path not provided')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:bang == "!"
|
||||||
|
let [l:out, l:err] = go#util#Exec(['go', 'get', '-u', '-v', path])
|
||||||
|
if err != 0
|
||||||
|
call s:Error("Can't find import: " . path . ":" . out)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
let exists = go#tool#Exists(path)
|
||||||
|
if exists == -1
|
||||||
|
call s:Error("Can't find import: " . path)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Extract any site prefix (e.g. github.com/).
|
||||||
|
" If other imports with the same prefix are grouped separately,
|
||||||
|
" we will add this new import with them.
|
||||||
|
" Only up to and including the first slash is used.
|
||||||
|
let siteprefix = matchstr(path, "^[^/]*/")
|
||||||
|
|
||||||
|
let qpath = '"' . path . '"'
|
||||||
|
if a:localname != ''
|
||||||
|
let qlocalpath = a:localname . ' ' . qpath
|
||||||
|
else
|
||||||
|
let qlocalpath = qpath
|
||||||
|
endif
|
||||||
|
let indentstr = 0
|
||||||
|
let packageline = -1 " Position of package name statement
|
||||||
|
let appendline = -1 " Position to introduce new import
|
||||||
|
let deleteline = -1 " Position of line with existing import
|
||||||
|
let linesdelta = 0 " Lines added/removed
|
||||||
|
|
||||||
|
" Find proper place to add/remove import.
|
||||||
|
let line = 0
|
||||||
|
while line <= line('$')
|
||||||
|
let linestr = getline(line)
|
||||||
|
|
||||||
|
if linestr =~# '^package\s'
|
||||||
|
let packageline = line
|
||||||
|
let appendline = line
|
||||||
|
|
||||||
|
elseif linestr =~# '^import\s\+(\+)'
|
||||||
|
let appendline = line
|
||||||
|
let appendstr = qlocalpath
|
||||||
|
elseif linestr =~# '^import\s\+('
|
||||||
|
let appendstr = qlocalpath
|
||||||
|
let indentstr = 1
|
||||||
|
let appendline = line
|
||||||
|
let firstblank = -1
|
||||||
|
let lastprefix = ""
|
||||||
|
while line <= line("$")
|
||||||
|
let line = line + 1
|
||||||
|
let linestr = getline(line)
|
||||||
|
let m = matchlist(getline(line), '^\()\|\(\s\+\)\(\w\+\s\+\)\="\(.\+\)"\)')
|
||||||
|
if empty(m)
|
||||||
|
if siteprefix == "" && a:enabled
|
||||||
|
" must be in the first group
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
" record this position, but keep looking
|
||||||
|
if firstblank < 0
|
||||||
|
let firstblank = line
|
||||||
|
endif
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
if m[1] == ')'
|
||||||
|
" if there's no match, add it to the first group
|
||||||
|
if appendline < 0 && firstblank >= 0
|
||||||
|
let appendline = firstblank
|
||||||
|
endif
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
let lastprefix = matchstr(m[4], "^[^/]*/")
|
||||||
|
if a:localname != '' && m[3] != ''
|
||||||
|
let qlocalpath = printf('%-' . (len(m[3])-1) . 's %s', a:localname, qpath)
|
||||||
|
endif
|
||||||
|
let appendstr = m[2] . qlocalpath
|
||||||
|
let indentstr = 0
|
||||||
|
if m[4] == path
|
||||||
|
let appendline = -1
|
||||||
|
let deleteline = line
|
||||||
|
break
|
||||||
|
elseif m[4] < path
|
||||||
|
" don't set candidate position if we have a site prefix,
|
||||||
|
" we've passed a blank line, and this doesn't share the same
|
||||||
|
" site prefix.
|
||||||
|
if siteprefix == "" || firstblank < 0 || match(m[4], "^" . siteprefix) >= 0
|
||||||
|
let appendline = line
|
||||||
|
endif
|
||||||
|
elseif siteprefix != "" && match(m[4], "^" . siteprefix) >= 0
|
||||||
|
" first entry of site group
|
||||||
|
let appendline = line - 1
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
break
|
||||||
|
|
||||||
|
elseif linestr =~# '^import '
|
||||||
|
if appendline == packageline
|
||||||
|
let appendstr = 'import ' . qlocalpath
|
||||||
|
let appendline = line - 1
|
||||||
|
endif
|
||||||
|
let m = matchlist(linestr, '^import\(\s\+\)\(\S*\s*\)"\(.\+\)"')
|
||||||
|
if !empty(m)
|
||||||
|
if m[3] == path
|
||||||
|
let appendline = -1
|
||||||
|
let deleteline = line
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
if m[3] < path
|
||||||
|
let appendline = line
|
||||||
|
endif
|
||||||
|
if a:localname != '' && m[2] != ''
|
||||||
|
let qlocalpath = printf("%s %" . len(m[2])-1 . "s", a:localname, qpath)
|
||||||
|
endif
|
||||||
|
let appendstr = 'import' . m[1] . qlocalpath
|
||||||
|
endif
|
||||||
|
|
||||||
|
elseif linestr =~# '^\(var\|const\|type\|func\)\>'
|
||||||
|
break
|
||||||
|
|
||||||
|
endif
|
||||||
|
let line = line + 1
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
" Append or remove the package import, as requested.
|
||||||
|
if a:enabled
|
||||||
|
if deleteline != -1
|
||||||
|
call s:Error(qpath . ' already being imported')
|
||||||
|
elseif appendline == -1
|
||||||
|
call s:Error('No package line found')
|
||||||
|
else
|
||||||
|
if appendline == packageline
|
||||||
|
call append(appendline + 0, '')
|
||||||
|
call append(appendline + 1, 'import (')
|
||||||
|
call append(appendline + 2, ')')
|
||||||
|
let appendline += 2
|
||||||
|
let linesdelta += 3
|
||||||
|
let appendstr = qlocalpath
|
||||||
|
let indentstr = 1
|
||||||
|
call append(appendline, appendstr)
|
||||||
|
elseif getline(appendline) =~# '^import\s\+(\+)'
|
||||||
|
call setline(appendline, 'import (')
|
||||||
|
call append(appendline + 0, appendstr)
|
||||||
|
call append(appendline + 1, ')')
|
||||||
|
let linesdelta -= 1
|
||||||
|
let indentstr = 1
|
||||||
|
else
|
||||||
|
call append(appendline, appendstr)
|
||||||
|
endif
|
||||||
|
execute appendline + 1
|
||||||
|
if indentstr
|
||||||
|
execute 'normal! >>'
|
||||||
|
endif
|
||||||
|
let linesdelta += 1
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
if deleteline == -1
|
||||||
|
call s:Error(qpath . ' not being imported')
|
||||||
|
else
|
||||||
|
execute deleteline . 'd'
|
||||||
|
let linesdelta -= 1
|
||||||
|
|
||||||
|
if getline(deleteline-1) =~# '^import\s\+(' && getline(deleteline) =~# '^)'
|
||||||
|
" Delete empty import block
|
||||||
|
let deleteline -= 1
|
||||||
|
execute deleteline . "d"
|
||||||
|
execute deleteline . "d"
|
||||||
|
let linesdelta -= 2
|
||||||
|
endif
|
||||||
|
|
||||||
|
if getline(deleteline) == '' && getline(deleteline - 1) == ''
|
||||||
|
" Delete spacing for removed line too.
|
||||||
|
execute deleteline . "d"
|
||||||
|
let linesdelta -= 1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Adjust view for any changes.
|
||||||
|
let view.lnum += linesdelta
|
||||||
|
let view.topline += linesdelta
|
||||||
|
if view.topline < 0
|
||||||
|
let view.topline = 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Put buffer back where it was.
|
||||||
|
call winrestview(view)
|
||||||
|
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
function! s:Error(s) abort
|
||||||
|
echohl Error | echo a:s | echohl None
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
35
sources_non_forked/vim-go/autoload/go/import_test.vim
Normal file
35
sources_non_forked/vim-go/autoload/go/import_test.vim
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
func! Test_SwitchImportAddIgnoresCommented()
|
||||||
|
try
|
||||||
|
let l:tmp = gotest#write_file('import/import.go', [
|
||||||
|
\ 'package import',
|
||||||
|
\ '',
|
||||||
|
\ 'import (',
|
||||||
|
\ "\t" . '// "fmt"',
|
||||||
|
\ "\t" . '"io"',
|
||||||
|
\ "\t" . '"ioutil"',
|
||||||
|
\ "\t" . '"os"',
|
||||||
|
\ ')',
|
||||||
|
\ '',
|
||||||
|
\ 'func main() {',
|
||||||
|
\ ' io.Copy(ioutil.Discard, os.Stdin)',
|
||||||
|
\ ' fmt.Println("import the package")',
|
||||||
|
\ '}',
|
||||||
|
\ ])
|
||||||
|
call go#import#SwitchImport(1, '', 'fmt', 0)
|
||||||
|
|
||||||
|
let l:actual = getline(4)
|
||||||
|
call assert_equal("\t" . '"fmt"', l:actual)
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
72
sources_non_forked/vim-go/autoload/go/indent_test.vim
Normal file
72
sources_non_forked/vim-go/autoload/go/indent_test.vim
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
func! Test_indent_raw_string() abort
|
||||||
|
" The goRawString discovery requires that syntax be enabled.
|
||||||
|
syntax on
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:dir= gotest#write_file('indent/indent.go', [
|
||||||
|
\ 'package main',
|
||||||
|
\ '',
|
||||||
|
\ 'import "fmt"',
|
||||||
|
\ '',
|
||||||
|
\ 'func main() {',
|
||||||
|
\ "\t\x1fconst msg = `",
|
||||||
|
\ '`',
|
||||||
|
\ '\tfmt.Println(msg)',
|
||||||
|
\ '}'])
|
||||||
|
|
||||||
|
silent execute "normal o" . "not indented\<Esc>"
|
||||||
|
let l:indent = indent(line('.'))
|
||||||
|
call assert_equal(0, l:indent)
|
||||||
|
finally
|
||||||
|
call delete(l:dir, 'rf')
|
||||||
|
endtry
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:dir= gotest#write_file('indent/indent.go', [
|
||||||
|
\ 'package main',
|
||||||
|
\ '',
|
||||||
|
\ 'import "fmt"',
|
||||||
|
\ '',
|
||||||
|
\ 'func main() {',
|
||||||
|
\ "\t\x1fmsg := `",
|
||||||
|
\ '`',
|
||||||
|
\ '\tfmt.Println(msg)',
|
||||||
|
\ '}'])
|
||||||
|
|
||||||
|
silent execute "normal o" . "not indented\<Esc>"
|
||||||
|
let l:indent = indent(line('.'))
|
||||||
|
call assert_equal(0, l:indent)
|
||||||
|
finally
|
||||||
|
call delete(l:dir, 'rf')
|
||||||
|
endtry
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:dir= gotest#write_file('indent/indent.go', [
|
||||||
|
\ 'package main',
|
||||||
|
\ '',
|
||||||
|
\ 'import "fmt"',
|
||||||
|
\ '',
|
||||||
|
\ 'func main() {',
|
||||||
|
\ "\tconst msg = `",
|
||||||
|
\ "\t\x1findented",
|
||||||
|
\ '`',
|
||||||
|
\ '\tfmt.Println(msg)',
|
||||||
|
\ '}'])
|
||||||
|
|
||||||
|
silent execute "normal o" . "indented\<Esc>"
|
||||||
|
let l:indent = indent(line('.'))
|
||||||
|
call assert_equal(shiftwidth(), l:indent)
|
||||||
|
finally
|
||||||
|
call delete(l:dir, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
56
sources_non_forked/vim-go/autoload/go/issue.vim
Normal file
56
sources_non_forked/vim-go/autoload/go/issue.vim
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
let s:templatepath = go#util#Join(resolve(expand('<sfile>:p:h:h:h')), '.github', 'ISSUE_TEMPLATE.md')
|
||||||
|
|
||||||
|
function! go#issue#New() abort
|
||||||
|
let body = go#uri#Encode(s:issuebody())
|
||||||
|
let url = "https://github.com/fatih/vim-go/issues/new?body=" . l:body
|
||||||
|
call go#util#OpenBrowser(l:url)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:issuebody() abort
|
||||||
|
let lines = readfile(s:templatepath)
|
||||||
|
|
||||||
|
let rtrimpat = '[[:space:]]\+$'
|
||||||
|
let body = []
|
||||||
|
for l in lines
|
||||||
|
let body = add(body, l)
|
||||||
|
|
||||||
|
if l =~ '^<!-- :version'
|
||||||
|
let out = execute('version')
|
||||||
|
let body = extend(body, split(out, "\n")[0:2])
|
||||||
|
elseif l =~ '^<!-- go version -->'
|
||||||
|
let [out, err] = go#util#Exec(['go', 'version'])
|
||||||
|
let body = add(body, substitute(l:out, rtrimpat, '', ''))
|
||||||
|
elseif l =~ '^<!-- go env -->'
|
||||||
|
let [out, err] = go#util#ExecInDir(['go', 'env'])
|
||||||
|
let body = add(body, substitute(l:out, rtrimpat, '', ''))
|
||||||
|
elseif l=~ '^<!-- gopls version -->'
|
||||||
|
let [out, err] = go#util#Exec(['gopls', 'version'])
|
||||||
|
let body = add(body, substitute(l:out, rtrimpat, '', ''))
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
let body = add(body, "\n#### vim-go configuration:\n<details><summary>vim-go configuration</summary><br><pre>")
|
||||||
|
|
||||||
|
for k in keys(g:)
|
||||||
|
if k =~ '^go_'
|
||||||
|
let body = add(body, 'g:' . k . ' = ' . string(get(g:, k)))
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
let body = add(body, '</pre></details>')
|
||||||
|
|
||||||
|
let body = add(body, printf("\n#### filetype detection configuration:\n<details><summary>filetype detection</summary><br><pre>%s", execute('filetype')))
|
||||||
|
let body = add(body, '</pre></details>')
|
||||||
|
|
||||||
|
return join(body, "\n")
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
573
sources_non_forked/vim-go/autoload/go/job.vim
Normal file
573
sources_non_forked/vim-go/autoload/go/job.vim
Normal file
|
@ -0,0 +1,573 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
" Spawn starts an asynchronous job. See the description of go#job#Options to
|
||||||
|
" understand the args parameter.
|
||||||
|
"
|
||||||
|
" Spawn returns a job.
|
||||||
|
function! go#job#Spawn(cmd, args)
|
||||||
|
let l:options = go#job#Options(a:args)
|
||||||
|
return go#job#Start(a:cmd, l:options)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Options returns callbacks to be used with job_start. It is abstracted to be
|
||||||
|
" used with various go commands, such as build, test, install, etc.. This
|
||||||
|
" allows us to avoid writing the same callback over and over for some
|
||||||
|
" commands. It's fully customizable so each command can change it to its own
|
||||||
|
" logic.
|
||||||
|
"
|
||||||
|
" args is a dictionary with the these keys:
|
||||||
|
" 'bang':
|
||||||
|
" Set to 0 to jump to the first error in the error list.
|
||||||
|
" Defaults to 0.
|
||||||
|
" 'statustype':
|
||||||
|
" The status type to use when updating the status.
|
||||||
|
" See statusline.vim.
|
||||||
|
" 'for':
|
||||||
|
" The g:go_list_type_command key to use to get the error list type to use.
|
||||||
|
" Errors will not be handled when the value is '_'.
|
||||||
|
" Defaults to '_job'
|
||||||
|
" 'errorformat':
|
||||||
|
" The errorformat string to use when parsing errors. Defaults to
|
||||||
|
" &errorformat.
|
||||||
|
" See :help 'errorformat'.
|
||||||
|
" 'complete':
|
||||||
|
" A function to call after the job exits and the channel is closed. The
|
||||||
|
" function will be passed three arguments: the job, its exit code, and the
|
||||||
|
" list of messages received from the channel. The default is a no-op. A
|
||||||
|
" custom value can modify the messages before they are processed by the
|
||||||
|
" returned exit_cb and close_cb callbacks. When the function is called,
|
||||||
|
" the current window will be the window that was hosting the buffer when
|
||||||
|
" the job was started. After it returns, the current window will be
|
||||||
|
" restored to what it was before the function was called.
|
||||||
|
" 'preserveerrors':
|
||||||
|
" A function that will be passed one value, the list type. It should
|
||||||
|
" return a boolean value that indicates whether any errors encountered
|
||||||
|
" should be consider additive to the existing set of errors. This is
|
||||||
|
" mostly useful for a set of commands that are run via autocmds.
|
||||||
|
"
|
||||||
|
" The return value is a dictionary with these keys:
|
||||||
|
" 'callback':
|
||||||
|
" A function suitable to be passed as a job callback handler. See
|
||||||
|
" job-callback.
|
||||||
|
" 'exit_cb':
|
||||||
|
" A function suitable to be passed as a job exit_cb handler. See
|
||||||
|
" job-exit_cb.
|
||||||
|
" 'close_cb':
|
||||||
|
" A function suitable to be passed as a job close_cb handler. See
|
||||||
|
" job-close_cb.
|
||||||
|
" 'cwd':
|
||||||
|
" The path to the directory which contains the current buffer. The
|
||||||
|
" callbacks are configured to expect this directory is the working
|
||||||
|
" directory for the job; it should not be modified by callers.
|
||||||
|
function! go#job#Options(args)
|
||||||
|
let cbs = {}
|
||||||
|
let state = {
|
||||||
|
\ 'winid': win_getid(winnr()),
|
||||||
|
\ 'dir': getcwd(),
|
||||||
|
\ 'jobdir': expand("%:p:h"),
|
||||||
|
\ 'messages': [],
|
||||||
|
\ 'bang': 0,
|
||||||
|
\ 'for': "_job",
|
||||||
|
\ 'exited': 0,
|
||||||
|
\ 'exit_status': 0,
|
||||||
|
\ 'closed': 0,
|
||||||
|
\ 'errorformat': &errorformat,
|
||||||
|
\ 'statustype' : '',
|
||||||
|
\ }
|
||||||
|
|
||||||
|
let cbs.cwd = state.jobdir
|
||||||
|
|
||||||
|
if has_key(a:args, 'bang')
|
||||||
|
let state.bang = a:args.bang
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(a:args, 'for')
|
||||||
|
let state.for = a:args.for
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(a:args, 'statustype')
|
||||||
|
let state.statustype = a:args.statustype
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(a:args, 'errorformat')
|
||||||
|
let state.errorformat = a:args.errorformat
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(a:args, 'preserveerrors')
|
||||||
|
let state.preserveerrors = a:args.preserveerrors
|
||||||
|
endif
|
||||||
|
|
||||||
|
function state.complete(job, exit_status, data)
|
||||||
|
if has_key(self, 'custom_complete')
|
||||||
|
let l:winid = win_getid(winnr())
|
||||||
|
" Always set the active window to the window that was active when the job
|
||||||
|
" was started. Among other things, this makes sure that the correct
|
||||||
|
" window's location list will be populated when the list type is
|
||||||
|
" 'location' and the user has moved windows since starting the job.
|
||||||
|
call win_gotoid(self.winid)
|
||||||
|
call self.custom_complete(a:job, a:exit_status, a:data)
|
||||||
|
call win_gotoid(l:winid)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call self.show_errors(a:job, a:exit_status, a:data)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function state.show_status(job, exit_status) dict
|
||||||
|
if self.statustype == ''
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if go#config#EchoCommandInfo()
|
||||||
|
let prefix = '[' . self.statustype . '] '
|
||||||
|
if a:exit_status == 0
|
||||||
|
call go#util#EchoSuccess(prefix . "SUCCESS")
|
||||||
|
else
|
||||||
|
call go#util#EchoError(prefix . "FAIL")
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
let status = {
|
||||||
|
\ 'desc': 'last status',
|
||||||
|
\ 'type': self.statustype,
|
||||||
|
\ 'state': "success",
|
||||||
|
\ }
|
||||||
|
|
||||||
|
if a:exit_status
|
||||||
|
let status.state = "failed"
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(self, 'started_at')
|
||||||
|
let elapsed_time = reltimestr(reltime(self.started_at))
|
||||||
|
" strip whitespace
|
||||||
|
let elapsed_time = substitute(elapsed_time, '^\s*\(.\{-}\)\s*$', '\1', '')
|
||||||
|
let status.state .= printf(" (%ss)", elapsed_time)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#statusline#Update(self.jobdir, status)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
if has_key(a:args, 'complete')
|
||||||
|
let state.custom_complete = a:args.complete
|
||||||
|
endif
|
||||||
|
|
||||||
|
" explicitly bind _start to state so that within it, self will
|
||||||
|
" always refer to state. See :help Partial for more information.
|
||||||
|
"
|
||||||
|
" _start is intended only for internal use and should not be referenced
|
||||||
|
" outside of this file.
|
||||||
|
let cbs._start = function('s:start', [''], state)
|
||||||
|
|
||||||
|
" explicitly bind callback to state so that within it, self will
|
||||||
|
" always refer to state. See :help Partial for more information.
|
||||||
|
let cbs.callback = function('s:callback', [], state)
|
||||||
|
|
||||||
|
" explicitly bind exit_cb to state so that within it, self will always refer
|
||||||
|
" to state. See :help Partial for more information.
|
||||||
|
let cbs.exit_cb = function('s:exit_cb', [], state)
|
||||||
|
|
||||||
|
" explicitly bind close_cb to state so that within it, self will
|
||||||
|
" always refer to state. See :help Partial for more information.
|
||||||
|
let cbs.close_cb = function('s:close_cb', [], state)
|
||||||
|
|
||||||
|
function state.show_errors(job, exit_status, data)
|
||||||
|
if self.for == '_'
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:winid = win_getid(winnr())
|
||||||
|
" Always set the active window to the window that was active when the job
|
||||||
|
" was started. Among other things, this makes sure that the correct
|
||||||
|
" window's location list will be populated when the list type is
|
||||||
|
" 'location' and the user has moved windows since starting the job.
|
||||||
|
call win_gotoid(self.winid)
|
||||||
|
|
||||||
|
let l:listtype = go#list#Type(self.for)
|
||||||
|
|
||||||
|
let l:preserveerrors = 0
|
||||||
|
if has_key(self, 'preserveerrors')
|
||||||
|
let l:preserveerrors = self.preserveerrors(l:listtype)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:exit_status == 0
|
||||||
|
if !l:preserveerrors
|
||||||
|
call go#list#Clean(l:listtype)
|
||||||
|
call win_gotoid(l:winid)
|
||||||
|
endif
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:listtype = go#list#Type(self.for)
|
||||||
|
if len(a:data) == 0
|
||||||
|
if !l:preserveerrors
|
||||||
|
call go#list#Clean(l:listtype)
|
||||||
|
call win_gotoid(l:winid)
|
||||||
|
endif
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let out = join(self.messages, "\n")
|
||||||
|
|
||||||
|
try
|
||||||
|
" parse the errors relative to self.jobdir
|
||||||
|
call go#util#Chdir(self.jobdir)
|
||||||
|
call go#list#ParseFormat(l:listtype, self.errorformat, out, self.for, l:preserveerrors)
|
||||||
|
let errors = go#list#Get(l:listtype)
|
||||||
|
finally
|
||||||
|
call go#util#Chdir(self.dir)
|
||||||
|
endtry
|
||||||
|
|
||||||
|
if empty(errors)
|
||||||
|
" failed to parse errors, output the original content
|
||||||
|
call go#util#EchoError([self.dir] + self.messages)
|
||||||
|
call win_gotoid(l:winid)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" only open the error window if user was still in the window from which
|
||||||
|
" the job was started.
|
||||||
|
if self.winid == l:winid
|
||||||
|
call go#list#Window(l:listtype, len(errors))
|
||||||
|
if self.bang
|
||||||
|
call win_gotoid(l:winid)
|
||||||
|
else
|
||||||
|
call go#list#JumpToFirst(l:listtype)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
return cbs
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:start(args) dict
|
||||||
|
if go#config#EchoCommandInfo() && self.statustype != ""
|
||||||
|
let prefix = '[' . self.statustype . '] '
|
||||||
|
call go#util#EchoSuccess(prefix . "dispatched")
|
||||||
|
endif
|
||||||
|
|
||||||
|
if self.statustype != ''
|
||||||
|
let status = {
|
||||||
|
\ 'desc': 'current status',
|
||||||
|
\ 'type': self.statustype,
|
||||||
|
\ 'state': "started",
|
||||||
|
\ }
|
||||||
|
|
||||||
|
call go#statusline#Update(self.jobdir, status)
|
||||||
|
endif
|
||||||
|
let self.started_at = reltime()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:callback(chan, msg) dict
|
||||||
|
call add(self.messages, a:msg)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:exit_cb(job, exitval) dict
|
||||||
|
let self.exit_status = a:exitval
|
||||||
|
let self.exited = 1
|
||||||
|
|
||||||
|
call self.show_status(a:job, a:exitval)
|
||||||
|
|
||||||
|
if self.closed || has('nvim')
|
||||||
|
call self.complete(a:job, self.exit_status, self.messages)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:close_cb(ch) dict
|
||||||
|
let self.closed = 1
|
||||||
|
|
||||||
|
if self.exited
|
||||||
|
let job = ch_getjob(a:ch)
|
||||||
|
call self.complete(job, self.exit_status, self.messages)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" go#job#Start runs a job. The options are expected to be the options
|
||||||
|
" suitable for Vim8 jobs. When called from Neovim, Vim8 options will be
|
||||||
|
" transformed to their Neovim equivalents.
|
||||||
|
function! go#job#Start(cmd, options)
|
||||||
|
let l:options = copy(a:options)
|
||||||
|
|
||||||
|
if has('nvim')
|
||||||
|
let l:options = s:neooptions(l:options)
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Verify that the working directory for the job actually exists. Return
|
||||||
|
" early if the directory does not exist. This helps avoid errors when
|
||||||
|
" working with plugins that use virtual files that don't actually exist on
|
||||||
|
" the file system.
|
||||||
|
let l:filedir = expand("%:p:h")
|
||||||
|
if has_key(l:options, 'cwd') && !isdirectory(l:options.cwd)
|
||||||
|
return
|
||||||
|
elseif !isdirectory(l:filedir)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:manualcd = 0
|
||||||
|
if !has_key(l:options, 'cwd')
|
||||||
|
" pre start
|
||||||
|
let l:manualcd = 1
|
||||||
|
let l:dir = go#util#Chdir(filedir)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(l:options, '_start')
|
||||||
|
call l:options._start()
|
||||||
|
" remove _start to play nicely with vim (when vim encounters an unexpected
|
||||||
|
" job option it reports an "E475: invalid argument" error).
|
||||||
|
unlet l:options._start
|
||||||
|
endif
|
||||||
|
|
||||||
|
" noblock was added in 8.1.350; remove it if it's not supported.
|
||||||
|
if has_key(l:options, 'noblock') && (has('nvim') || !has("patch-8.1.350"))
|
||||||
|
call remove(l:options, 'noblock')
|
||||||
|
endif
|
||||||
|
|
||||||
|
if go#util#HasDebug('shell-commands')
|
||||||
|
call go#util#EchoInfo('job command: ' . string(a:cmd))
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has('nvim')
|
||||||
|
let l:input = []
|
||||||
|
if has_key(a:options, 'in_io') && a:options.in_io ==# 'file' && !empty(a:options.in_name)
|
||||||
|
let l:input = readfile(a:options.in_name, "b")
|
||||||
|
endif
|
||||||
|
|
||||||
|
let job = jobstart(a:cmd, l:options)
|
||||||
|
|
||||||
|
if len(l:input) > 0
|
||||||
|
call chansend(job, l:input)
|
||||||
|
" close stdin to signal that no more bytes will be sent.
|
||||||
|
call chanclose(job, 'stdin')
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
let l:cmd = a:cmd
|
||||||
|
if go#util#IsWin()
|
||||||
|
let l:cmd = join(map(copy(a:cmd), function('s:winjobarg')), " ")
|
||||||
|
endif
|
||||||
|
|
||||||
|
let job = job_start(l:cmd, l:options)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:manualcd
|
||||||
|
" post start
|
||||||
|
call go#util#Chdir(l:dir)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return job
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" s:neooptions returns a dictionary of job options suitable for use by Neovim
|
||||||
|
" based on a dictionary of job options suitable for Vim8.
|
||||||
|
function! s:neooptions(options)
|
||||||
|
let l:options = {}
|
||||||
|
let l:options['stdout_buf'] = ''
|
||||||
|
let l:options['stderr_buf'] = ''
|
||||||
|
|
||||||
|
let l:err_mode = get(a:options, 'err_mode', get(a:options, 'mode', ''))
|
||||||
|
let l:out_mode = get(a:options, 'out_mode', get(a:options, 'mode', ''))
|
||||||
|
|
||||||
|
for key in keys(a:options)
|
||||||
|
if key == 'cwd'
|
||||||
|
let l:options['cwd'] = a:options['cwd']
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
if key == 'callback'
|
||||||
|
let l:options['callback'] = a:options['callback']
|
||||||
|
|
||||||
|
if !has_key(a:options, 'out_cb')
|
||||||
|
let l:options['on_stdout'] = function('s:callback2on_stdout', [l:out_mode], l:options)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !has_key(a:options, 'err_cb')
|
||||||
|
let l:options['on_stderr'] = function('s:callback2on_stderr', [l:err_mode], l:options)
|
||||||
|
endif
|
||||||
|
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
if key == 'out_cb'
|
||||||
|
let l:options['out_cb'] = a:options['out_cb']
|
||||||
|
let l:options['on_stdout'] = function('s:on_stdout', [l:out_mode], l:options)
|
||||||
|
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
if key == 'err_cb'
|
||||||
|
let l:options['err_cb'] = a:options['err_cb']
|
||||||
|
let l:options['on_stderr'] = function('s:on_stderr', [l:err_mode], l:options)
|
||||||
|
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
if key == 'exit_cb'
|
||||||
|
let l:options['exit_cb'] = a:options['exit_cb']
|
||||||
|
let l:options['on_exit'] = function('s:on_exit', [], l:options)
|
||||||
|
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
if key == 'close_cb'
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
if key == 'stoponexit'
|
||||||
|
if a:options['stoponexit'] == ''
|
||||||
|
let l:options['detach'] = 1
|
||||||
|
endif
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
return l:options
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:callback2on_stdout(mode, ch, data, event) dict
|
||||||
|
let self.stdout_buf = s:neocb(a:mode, a:ch, self.stdout_buf, a:data, self.callback)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:callback2on_stderr(mode, ch, data, event) dict
|
||||||
|
let self.stderr_buf = s:neocb(a:mode, a:ch, self.stderr_buf, a:data, self.callback)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:on_stdout(mode, ch, data, event) dict
|
||||||
|
let self.stdout_buf = s:neocb(a:mode, a:ch, self.stdout_buf, a:data, self.out_cb)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:on_stderr(mode, ch, data, event) dict
|
||||||
|
let self.stderr_buf = s:neocb(a:mode, a:ch, self.stderr_buf, a:data, self.err_cb )
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:on_exit(jobid, exitval, event) dict
|
||||||
|
call self.exit_cb(a:jobid, a:exitval)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#job#Stop(job) abort
|
||||||
|
if has('nvim')
|
||||||
|
call jobstop(a:job)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
call job_stop(a:job)
|
||||||
|
call go#job#Wait(a:job)
|
||||||
|
return
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#job#Wait(job) abort
|
||||||
|
if has('nvim')
|
||||||
|
call jobwait([a:job])
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
while job_status(a:job) is# 'run'
|
||||||
|
sleep 50m
|
||||||
|
endwhile
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:winjobarg(idx, val) abort
|
||||||
|
if empty(a:val)
|
||||||
|
return '""'
|
||||||
|
endif
|
||||||
|
return a:val
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:neocb(mode, ch, buf, data, callback)
|
||||||
|
" dealing with the channel lines of Neovim is awful. The docs (:help
|
||||||
|
" channel-lines) say:
|
||||||
|
" stream event handlers may receive partial (incomplete) lines. For a
|
||||||
|
" given invocation of on_stdout etc, `a:data` is not guaranteed to end
|
||||||
|
" with a newline.
|
||||||
|
" - `abcdefg` may arrive as `['abc']`, `['defg']`.
|
||||||
|
" - `abc\nefg` may arrive as `['abc', '']`, `['efg']` or `['abc']`,
|
||||||
|
" `['','efg']`, or even `['ab']`, `['c','efg']`.
|
||||||
|
"
|
||||||
|
" Thankfully, though, this is explained a bit better in an issue:
|
||||||
|
" https://github.com/neovim/neovim/issues/3555. Specifically in these two
|
||||||
|
" comments:
|
||||||
|
" * https://github.com/neovim/neovim/issues/3555#issuecomment-152290804
|
||||||
|
" * https://github.com/neovim/neovim/issues/3555#issuecomment-152588749
|
||||||
|
"
|
||||||
|
" The key is
|
||||||
|
" Every item in the list passed to job control callbacks represents a
|
||||||
|
" string after a newline(Except the first, of course). If the program
|
||||||
|
" outputs: "hello\nworld" the corresponding list is ["hello", "world"].
|
||||||
|
" If the program outputs "hello\nworld\n", the corresponding list is
|
||||||
|
" ["hello", "world", ""]. In other words, you can always determine if
|
||||||
|
" the last line received is complete or not.
|
||||||
|
" and
|
||||||
|
" for every list you receive in a callback, all items except the first
|
||||||
|
" represent newlines.
|
||||||
|
|
||||||
|
let l:buf = ''
|
||||||
|
|
||||||
|
" A single empty string means EOF was reached. The first item will never be
|
||||||
|
" an empty string except for when it's the only item and is signaling that
|
||||||
|
" EOF was reached.
|
||||||
|
if len(a:data) == 1 && a:data[0] == ''
|
||||||
|
" when there's nothing buffered, return early so that an
|
||||||
|
" erroneous message will not be added.
|
||||||
|
if a:buf == ''
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:data = [a:buf]
|
||||||
|
else
|
||||||
|
let l:data = copy(a:data)
|
||||||
|
let l:data[0] = a:buf . l:data[0]
|
||||||
|
|
||||||
|
" The last element may be a partial line; save it for next time.
|
||||||
|
if a:mode != 'raw'
|
||||||
|
let l:buf = l:data[-1]
|
||||||
|
let l:data = l:data[:-2]
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:i = 0
|
||||||
|
let l:last = len(l:data) - 1
|
||||||
|
while l:i <= l:last
|
||||||
|
let l:msg = l:data[l:i]
|
||||||
|
if a:mode == 'raw' && l:i < l:last
|
||||||
|
let l:msg = l:msg . "\n"
|
||||||
|
endif
|
||||||
|
if a:mode == 'raw'
|
||||||
|
call s:queueneocb(function(a:callback, [a:ch, l:msg]))
|
||||||
|
else
|
||||||
|
call a:callback(a:ch, l:msg)
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:i += 1
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
return l:buf
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" s:neocbs is used to workaround limitations of how Neovim limits the use of
|
||||||
|
" callbacks. This is particularly important when dealing with a raw channel
|
||||||
|
" whose data triggers further communication and more data on the channel and
|
||||||
|
" both the original response handler and the next response handler are
|
||||||
|
" awaited using go#promise (e.g. as is the case with go#lsp#Rename).
|
||||||
|
let s:neocbs = []
|
||||||
|
function! s:dequeueneocbs(timer) abort
|
||||||
|
for l:Fn in s:neocbs
|
||||||
|
try
|
||||||
|
call remove(s:neocbs, 0)
|
||||||
|
call call(l:Fn, [])
|
||||||
|
finally
|
||||||
|
endtry
|
||||||
|
endfor
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:queueneocb(fn) abort
|
||||||
|
let l:shouldStart = len(s:neocbs) == 0
|
||||||
|
|
||||||
|
let s:neocbs = add(s:neocbs, a:fn)
|
||||||
|
|
||||||
|
if l:shouldStart
|
||||||
|
call timer_start(10, function('s:dequeueneocbs', []))
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
54
sources_non_forked/vim-go/autoload/go/job_test.vim
Normal file
54
sources_non_forked/vim-go/autoload/go/job_test.vim
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
func! Test_JobDirWithSpaces()
|
||||||
|
if !go#util#has_job()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:filename = 'job/dir has spaces/main.go'
|
||||||
|
let l:tmp = gotest#load_fixture(l:filename)
|
||||||
|
call go#util#Chdir(printf('%s/src/job/dir has spaces', l:tmp))
|
||||||
|
call go#util#Exec(['go', 'mod', 'init', 'vim-go.test/job'])
|
||||||
|
|
||||||
|
" set the compiler type so that the errorformat option will be set
|
||||||
|
" correctly.
|
||||||
|
compiler go
|
||||||
|
|
||||||
|
let expected = [{'lnum': 4, 'bufnr': bufnr('%'), 'col': 2, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'undefined: notafunc'}]
|
||||||
|
" clear the quickfix lists
|
||||||
|
call setqflist([], 'r')
|
||||||
|
|
||||||
|
" go build discards any results when it compiles multiple packages. So we
|
||||||
|
" pass the `errors` package just as a placeholder with the current folder
|
||||||
|
" (indicated with '.').
|
||||||
|
let l:cmd = ['go', 'build', '.', 'errors']
|
||||||
|
|
||||||
|
let l:complete = go#promise#New(function('s:complete'), 10000, '')
|
||||||
|
call go#job#Spawn(l:cmd, {
|
||||||
|
\ 'for': 'GoBuild',
|
||||||
|
\ 'complete': l:complete.wrapper,
|
||||||
|
\ 'statustype': 'build'
|
||||||
|
\})
|
||||||
|
|
||||||
|
let l:out = l:complete.await()
|
||||||
|
|
||||||
|
let actual = getqflist()
|
||||||
|
|
||||||
|
call gotest#assert_quickfix(actual, l:expected)
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! s:complete(job, exit_code, messages)
|
||||||
|
return a:messages
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
64
sources_non_forked/vim-go/autoload/go/keyify.vim
Normal file
64
sources_non_forked/vim-go/autoload/go/keyify.vim
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
function! go#keyify#Keyify()
|
||||||
|
" Needs: https://github.com/dominikh/go-tools/pull/272
|
||||||
|
"\ '-tags', go#config#BuildTags(),
|
||||||
|
let l:cmd = ['keyify',
|
||||||
|
\ '-json',
|
||||||
|
\ printf('%s:#%s', fnamemodify(expand('%'), ':p:gs?\\?/?'), go#util#OffsetCursor())]
|
||||||
|
|
||||||
|
let [l:out, l:err] = go#util#Exec(l:cmd)
|
||||||
|
if l:err
|
||||||
|
call go#util#EchoError("non-zero exit code: " . l:out)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
silent! let result = json_decode(l:out)
|
||||||
|
|
||||||
|
" We want to output the error message in case the result isn't a JSON
|
||||||
|
if type(result) != type({})
|
||||||
|
call go#util#EchoError(s:chomp(l:out))
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Because keyify returns the byte before the region we want, we goto the
|
||||||
|
" byte after that
|
||||||
|
execute "goto" result.start + 1
|
||||||
|
let start = getpos('.')
|
||||||
|
execute "goto" result.end
|
||||||
|
let end = getpos('.')
|
||||||
|
|
||||||
|
let vis_start = getpos("'<")
|
||||||
|
let vis_end = getpos("'>")
|
||||||
|
|
||||||
|
" Replace contents between start and end with `replacement`
|
||||||
|
call setpos("'<", start)
|
||||||
|
call setpos("'>", end)
|
||||||
|
|
||||||
|
let select = 'gv'
|
||||||
|
|
||||||
|
" Make sure the visual mode is 'v', to avoid some bugs
|
||||||
|
normal! gv
|
||||||
|
if mode() !=# 'v'
|
||||||
|
let select .= 'v'
|
||||||
|
endif
|
||||||
|
|
||||||
|
silent! execute "normal!" select."\"=result.replacement\<cr>p"
|
||||||
|
|
||||||
|
" Replacement text isn't aligned, so it needs fix
|
||||||
|
normal! '<v'>=
|
||||||
|
|
||||||
|
call setpos("'<", vis_start)
|
||||||
|
call setpos("'>", vis_end)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:chomp(string)
|
||||||
|
return substitute(a:string, '\n\+$', '', '')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
493
sources_non_forked/vim-go/autoload/go/lint.vim
Normal file
493
sources_non_forked/vim-go/autoload/go/lint.vim
Normal file
|
@ -0,0 +1,493 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
function! go#lint#Gometa(bang, autosave, ...) abort
|
||||||
|
let l:metalinter = go#config#MetalinterCommand()
|
||||||
|
|
||||||
|
if a:0 == 0
|
||||||
|
let l:goargs = [expand('%:p:h')]
|
||||||
|
if l:metalinter == 'gopls' || l:metalinter == 'staticcheck'
|
||||||
|
let l:pkg = go#package#ImportPath()
|
||||||
|
if l:pkg == -1
|
||||||
|
call go#util#EchoError('could not determine package name')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:goargs = [l:pkg]
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
let l:goargs = a:000
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:cmd = []
|
||||||
|
let l:linters = a:autosave ? go#config#MetalinterAutosaveEnabled() : go#config#MetalinterEnabled()
|
||||||
|
if l:metalinter == 'golangci-lint'
|
||||||
|
let l:cmd = s:metalintercmd(l:metalinter, len(linters) != 0)
|
||||||
|
if empty(l:cmd)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" add linters to cmd
|
||||||
|
for l:linter in l:linters
|
||||||
|
let l:cmd += ["--enable=".l:linter]
|
||||||
|
endfor
|
||||||
|
elseif l:metalinter == 'staticcheck'
|
||||||
|
let l:cmd = s:metalintercmd(l:metalinter, 0)
|
||||||
|
|
||||||
|
if len(l:linters) > 0
|
||||||
|
let l:cmd += [printf('-checks=%s', join(l:linters, ',' ))]
|
||||||
|
endif
|
||||||
|
elseif l:metalinter != 'gopls'
|
||||||
|
" the user wants something else, let us use it.
|
||||||
|
let l:cmd = split(go#config#MetalinterCommand(), " ")
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:autosave
|
||||||
|
" redraw so that any messages that were displayed while writing the file
|
||||||
|
" will be cleared
|
||||||
|
redraw
|
||||||
|
|
||||||
|
let l:goargs[0] = expand('%:p')
|
||||||
|
if l:metalinter == 'staticcheck' || l:metalinter == "golangci-lint"
|
||||||
|
let l:goargs[0] = expand('%:p:h')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Call metalinter asynchronously.
|
||||||
|
|
||||||
|
if l:metalinter == 'golangci-lint'
|
||||||
|
let l:deadline = go#config#MetalinterDeadline()
|
||||||
|
if l:deadline != ''
|
||||||
|
let l:cmd += ["--deadline=" . l:deadline]
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:cmd += l:goargs
|
||||||
|
|
||||||
|
let l:errformat = s:errorformat(l:metalinter)
|
||||||
|
|
||||||
|
if l:metalinter == 'gopls'
|
||||||
|
if a:autosave
|
||||||
|
let l:messages = go#lsp#AnalyzeFile(expand('%:p'))
|
||||||
|
else
|
||||||
|
let l:import_paths = l:goargs
|
||||||
|
let l:messages = call('go#lsp#Diagnostics', l:import_paths)
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:err = len(l:messages)
|
||||||
|
else
|
||||||
|
if go#util#has_job()
|
||||||
|
if a:autosave
|
||||||
|
let l:for = 'GoMetaLinterAutoSave'
|
||||||
|
else
|
||||||
|
let l:for = 'GoMetaLinter'
|
||||||
|
endif
|
||||||
|
|
||||||
|
call s:lint_job(l:metalinter, {'cmd': l:cmd, 'statustype': l:metalinter, 'errformat': l:errformat, 'for': l:for}, a:bang, a:autosave)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let [l:out, l:err] = go#util#Exec(l:cmd)
|
||||||
|
let l:messages = split(out, "\n")
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:autosave
|
||||||
|
let l:listtype = go#list#Type('GoMetaLinterAutoSave')
|
||||||
|
let l:for = 'GoMetaLinterAutoSave'
|
||||||
|
else
|
||||||
|
let l:listtype = go#list#Type('GoMetaLinter')
|
||||||
|
let l:for = 'GoMetaLinter'
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:err == 0
|
||||||
|
if !s:preserveerrors(a:autosave, l:listtype)
|
||||||
|
call go#list#Clean(l:listtype)
|
||||||
|
endif
|
||||||
|
call go#util#EchoSuccess('[metalinter] PASS')
|
||||||
|
else
|
||||||
|
let l:winid = win_getid(winnr())
|
||||||
|
" Parse and populate our location list
|
||||||
|
|
||||||
|
if a:autosave
|
||||||
|
call s:metalinterautosavecomplete(l:metalinter, fnamemodify(expand('%:p'), ':.'), 0, 1, l:messages)
|
||||||
|
endif
|
||||||
|
call go#list#ParseFormat(l:listtype, l:errformat, l:messages, l:for, s:preserveerrors(a:autosave, l:listtype))
|
||||||
|
|
||||||
|
let errors = go#list#Get(l:listtype)
|
||||||
|
call go#list#Window(l:listtype, len(errors))
|
||||||
|
|
||||||
|
if a:autosave || a:bang
|
||||||
|
call win_gotoid(l:winid)
|
||||||
|
else
|
||||||
|
call go#list#JumpToFirst(l:listtype)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lint#Diagnostics(bang, ...) abort
|
||||||
|
if a:0 == 0
|
||||||
|
let l:pkg = go#package#ImportPath()
|
||||||
|
if l:pkg == -1
|
||||||
|
call go#util#EchoError('could not determine package name')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:import_paths = [l:pkg]
|
||||||
|
else
|
||||||
|
let l:import_paths = call('go#util#ExpandPattern', a:000)
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:errformat = s:errorformat('gopls')
|
||||||
|
|
||||||
|
let l:messages = call('go#lsp#Diagnostics', l:import_paths)
|
||||||
|
|
||||||
|
let l:listtype = go#list#Type("GoDiagnostics")
|
||||||
|
|
||||||
|
" Parse and populate the quickfix list
|
||||||
|
let l:winid = win_getid(winnr())
|
||||||
|
call go#list#ParseFormat(l:listtype, l:errformat, l:messages, 'GoDiagnostics', 0)
|
||||||
|
|
||||||
|
let l:errors = go#list#Get(l:listtype)
|
||||||
|
|
||||||
|
if len(l:errors) == 0
|
||||||
|
call go#list#Clean(l:listtype)
|
||||||
|
call go#util#EchoSuccess('[diagnostics] PASS')
|
||||||
|
else
|
||||||
|
call go#list#Window(l:listtype, len(errors))
|
||||||
|
|
||||||
|
if a:bang
|
||||||
|
call win_gotoid(l:winid)
|
||||||
|
else
|
||||||
|
call go#list#JumpToFirst(l:listtype)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Golint calls 'golint' on the current directory. Any warnings are populated in
|
||||||
|
" the location list
|
||||||
|
function! go#lint#Golint(bang, ...) abort
|
||||||
|
call go#cmd#autowrite()
|
||||||
|
|
||||||
|
let l:type = 'lint'
|
||||||
|
let l:status = {
|
||||||
|
\ 'desc': 'current status',
|
||||||
|
\ 'type': l:type,
|
||||||
|
\ 'state': "started",
|
||||||
|
\ }
|
||||||
|
if go#config#EchoCommandInfo()
|
||||||
|
call go#util#EchoProgress(printf('[%s] analyzing...', l:type))
|
||||||
|
endif
|
||||||
|
call go#statusline#Update(expand('%:p:h'), l:status)
|
||||||
|
|
||||||
|
if a:0 == 0
|
||||||
|
let [l:out, l:err] = go#util#Exec([go#config#GolintBin(), expand('%:p:h')])
|
||||||
|
else
|
||||||
|
let [l:out, l:err] = go#util#Exec([go#config#GolintBin()] + a:000)
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:status.state = 'success'
|
||||||
|
let l:state = 'PASS'
|
||||||
|
let l:listtype = go#list#Type("GoLint")
|
||||||
|
if !empty(l:out)
|
||||||
|
let l:status.state = 'failed'
|
||||||
|
let l:state = 'FAIL'
|
||||||
|
|
||||||
|
let l:winid = win_getid(winnr())
|
||||||
|
call go#list#Parse(l:listtype, l:out, "GoLint", 0)
|
||||||
|
let l:errors = go#list#Get(l:listtype)
|
||||||
|
call go#list#Window(l:listtype, len(l:errors))
|
||||||
|
|
||||||
|
if a:bang
|
||||||
|
call win_gotoid(l:winid)
|
||||||
|
else
|
||||||
|
call go#list#JumpToFirst(l:listtype)
|
||||||
|
endif
|
||||||
|
if go#config#EchoCommandInfo()
|
||||||
|
call go#util#EchoError(printf('[%s] %s', l:type, l:state))
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
call go#list#Clean(l:listtype)
|
||||||
|
if go#config#EchoCommandInfo()
|
||||||
|
call go#util#EchoSuccess(printf('[%s] %s', l:type, l:state))
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
call go#statusline#Update(expand('%:p:h'), l:status)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Vet calls 'go vet' on the current buffer's directory. Any warnings are
|
||||||
|
" populated in the location list
|
||||||
|
function! go#lint#Vet(bang, ...) abort
|
||||||
|
call go#cmd#autowrite()
|
||||||
|
|
||||||
|
let l:cmd = ['go', 'vet']
|
||||||
|
|
||||||
|
let buildtags = go#config#BuildTags()
|
||||||
|
if buildtags isnot ''
|
||||||
|
let l:cmd += ['-tags', buildtags]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:0 == 0
|
||||||
|
let l:import_path = go#package#ImportPath()
|
||||||
|
if l:import_path == -1
|
||||||
|
call go#util#EchoError('could not determine package')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let l:cmd = add(l:cmd, l:import_path)
|
||||||
|
else
|
||||||
|
let l:cmd = extend(l:cmd, a:000)
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:type = 'go vet'
|
||||||
|
if go#config#EchoCommandInfo()
|
||||||
|
call go#util#EchoProgress(printf('[%s] analyzing...', l:type))
|
||||||
|
endif
|
||||||
|
let l:status = {
|
||||||
|
\ 'desc': 'current status',
|
||||||
|
\ 'type': l:type,
|
||||||
|
\ 'state': "started",
|
||||||
|
\ }
|
||||||
|
call go#statusline#Update(expand('%:p:h'), l:status)
|
||||||
|
|
||||||
|
let [l:out, l:err] = go#util#ExecInDir(l:cmd)
|
||||||
|
|
||||||
|
let l:status.state = 'success'
|
||||||
|
let l:state = 'PASS'
|
||||||
|
|
||||||
|
let l:listtype = go#list#Type("GoVet")
|
||||||
|
if l:err != 0
|
||||||
|
let l:status.state = 'failed'
|
||||||
|
let l:state = 'FAIL'
|
||||||
|
|
||||||
|
let l:winid = win_getid(winnr())
|
||||||
|
let l:errorformat = "%-Gexit status %\\d%\\+," . &errorformat
|
||||||
|
let l:dir = go#util#Chdir(expand('%:p:h'))
|
||||||
|
try
|
||||||
|
call go#list#ParseFormat(l:listtype, l:errorformat, out, "GoVet", 0)
|
||||||
|
finally
|
||||||
|
call go#util#Chdir(l:dir)
|
||||||
|
endtry
|
||||||
|
let l:errors = go#list#Get(l:listtype)
|
||||||
|
|
||||||
|
if empty(l:errors)
|
||||||
|
call go#util#EchoError(l:out)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#list#Window(l:listtype, len(l:errors))
|
||||||
|
if !empty(l:errors) && !a:bang
|
||||||
|
call go#list#JumpToFirst(l:listtype)
|
||||||
|
else
|
||||||
|
call win_gotoid(l:winid)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if go#config#EchoCommandInfo()
|
||||||
|
call go#util#EchoError(printf('[%s] %s', l:type, l:state))
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
call go#list#Clean(l:listtype)
|
||||||
|
if go#config#EchoCommandInfo()
|
||||||
|
call go#util#EchoSuccess(printf('[%s] %s', l:type, l:state))
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
call go#statusline#Update(expand('%:p:h'), l:status)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" ErrCheck calls 'errcheck' for the given packages. Any warnings are populated in
|
||||||
|
" the location list
|
||||||
|
function! go#lint#Errcheck(bang, ...) abort
|
||||||
|
call go#cmd#autowrite()
|
||||||
|
|
||||||
|
let l:cmd = [go#config#ErrcheckBin(), '-abspath']
|
||||||
|
|
||||||
|
let buildtags = go#config#BuildTags()
|
||||||
|
if buildtags isnot ''
|
||||||
|
let l:cmd += ['-tags', buildtags]
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:0 == 0
|
||||||
|
let l:import_path = go#package#ImportPath()
|
||||||
|
if l:import_path == -1
|
||||||
|
call go#util#EchoError('could not determine package')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let l:cmd = add(l:cmd, l:import_path)
|
||||||
|
else
|
||||||
|
let l:cmd = extend(l:cmd, a:000)
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:type = 'errcheck'
|
||||||
|
if go#config#EchoCommandInfo()
|
||||||
|
call go#util#EchoProgress(printf('[%s] analyzing...', l:type))
|
||||||
|
endif
|
||||||
|
let l:status = {
|
||||||
|
\ 'desc': 'current status',
|
||||||
|
\ 'type': l:type,
|
||||||
|
\ 'state': "started",
|
||||||
|
\ }
|
||||||
|
redraw
|
||||||
|
|
||||||
|
call go#statusline#Update(expand('%:p:h'), l:status)
|
||||||
|
|
||||||
|
let [l:out, l:err] = go#util#ExecInDir(l:cmd)
|
||||||
|
|
||||||
|
let l:status.state = 'success'
|
||||||
|
let l:state = 'PASS'
|
||||||
|
|
||||||
|
let l:listtype = go#list#Type("GoErrCheck")
|
||||||
|
if l:err != 0
|
||||||
|
let l:status.state = 'failed'
|
||||||
|
let l:state = 'FAIL'
|
||||||
|
|
||||||
|
let l:winid = win_getid(winnr())
|
||||||
|
|
||||||
|
if l:err == 1
|
||||||
|
let l:errformat = "%f:%l:%c:\ %m,%f:%l:%c\ %#%m"
|
||||||
|
" Parse and populate our location list
|
||||||
|
call go#list#ParseFormat(l:listtype, l:errformat, split(out, "\n"), 'Errcheck', 0)
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:errors = go#list#Get(l:listtype)
|
||||||
|
if empty(l:errors)
|
||||||
|
call go#util#EchoError(l:out)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !empty(errors)
|
||||||
|
call go#list#Populate(l:listtype, l:errors, 'Errcheck')
|
||||||
|
call go#list#Window(l:listtype, len(l:errors))
|
||||||
|
if !a:bang
|
||||||
|
call go#list#JumpToFirst(l:listtype)
|
||||||
|
else
|
||||||
|
call win_gotoid(l:winid)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
if go#config#EchoCommandInfo()
|
||||||
|
call go#util#EchoError(printf('[%s] %s', l:type, l:state))
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
call go#list#Clean(l:listtype)
|
||||||
|
if go#config#EchoCommandInfo()
|
||||||
|
call go#util#EchoSuccess(printf('[%s] %s', l:type, l:state))
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
call go#statusline#Update(expand('%:p:h'), l:status)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lint#ToggleMetaLinterAutoSave() abort
|
||||||
|
if go#config#MetalinterAutosave()
|
||||||
|
call go#config#SetMetalinterAutosave(0)
|
||||||
|
call go#util#EchoProgress("auto metalinter disabled")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
call go#config#SetMetalinterAutosave(1)
|
||||||
|
call go#util#EchoProgress("auto metalinter enabled")
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:lint_job(metalinter, args, bang, autosave)
|
||||||
|
let l:opts = {
|
||||||
|
\ 'statustype': a:args.statustype,
|
||||||
|
\ 'errorformat': a:args.errformat,
|
||||||
|
\ 'for': 'GoMetaLinter',
|
||||||
|
\ 'bang': a:bang,
|
||||||
|
\ }
|
||||||
|
|
||||||
|
if a:autosave
|
||||||
|
let l:opts.for = 'GoMetaLinterAutoSave'
|
||||||
|
" s:metalinterautosavecomplete is needed for staticcheck and golangci-lint
|
||||||
|
let l:opts.complete = funcref('s:metalinterautosavecomplete', [a:metalinter, expand('%:p:t')])
|
||||||
|
let l:opts.preserveerrors = funcref('s:preserveerrors', [a:autosave])
|
||||||
|
endif
|
||||||
|
|
||||||
|
" autowrite is not enabled for jobs
|
||||||
|
call go#cmd#autowrite()
|
||||||
|
|
||||||
|
call go#job#Spawn(a:args.cmd, l:opts)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:metalintercmd(metalinter, haslinter)
|
||||||
|
let l:cmd = []
|
||||||
|
let l:bin_path = go#path#CheckBinPath(a:metalinter)
|
||||||
|
if !empty(l:bin_path)
|
||||||
|
if a:metalinter == "golangci-lint"
|
||||||
|
let l:cmd = s:golangcilintcmd(l:bin_path, a:haslinter)
|
||||||
|
elseif a:metalinter == 'staticcheck'
|
||||||
|
let l:cmd = [l:bin_path]
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:cmd
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:golangcilintcmd(bin_path, haslinter)
|
||||||
|
let l:cmd = [a:bin_path]
|
||||||
|
let l:cmd += ["run"]
|
||||||
|
let l:cmd += ["--print-issued-lines=false"]
|
||||||
|
let l:cmd += ['--build-tags', go#config#BuildTags()]
|
||||||
|
" do not use the default exclude patterns, because doing so causes golint
|
||||||
|
" problems about missing doc strings to be ignored and other things that
|
||||||
|
" golint identifies.
|
||||||
|
let l:cmd += ["--exclude-use-default=false"]
|
||||||
|
|
||||||
|
if a:haslinter
|
||||||
|
let l:cmd += ["--disable-all"]
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:cmd
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:metalinterautosavecomplete(metalinter, filepath, job, exit_code, messages)
|
||||||
|
if !(a:metalinter == 'golangci-lint' || a:metalinter == 'staticcheck')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if len(a:messages) == 0
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:idx = 0
|
||||||
|
for l:item in a:messages
|
||||||
|
" leave in any messages that report errors about a:filepath or that report
|
||||||
|
" more general problems that prevent golangci-lint from linting
|
||||||
|
" a:filepath.
|
||||||
|
if l:item =~# '^' . a:filepath . ':' || (a:metalinter == 'golangci-lint' && l:item =~# '^level=')
|
||||||
|
let l:idx += 1
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
call remove(a:messages, l:idx)
|
||||||
|
endfor
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:errorformat(metalinter) abort
|
||||||
|
if a:metalinter == 'golangci-lint'
|
||||||
|
" Golangci-lint can output the following:
|
||||||
|
" <file>:<line>:<column>: <message> (<linter>)
|
||||||
|
" This can be defined by the following errorformat:
|
||||||
|
return 'level=%tarning\ msg="%m:\ [%f:%l:%c:\ %.%#]",level=%tarning\ msg="%m",level=%trror\ msg="%m:\ [%f:%l:%c:\ %.%#]",level=%trror\ msg="%m",%f:%l:%c:\ %m,%f:%l:\ %m,%f:%l\ %m'
|
||||||
|
elseif a:metalinter == 'staticcheck'
|
||||||
|
return '%f:%l:%c:\ %m'
|
||||||
|
elseif a:metalinter == 'gopls'
|
||||||
|
let l:efm = ''
|
||||||
|
let l:level = go#config#DiagnosticsLevel()
|
||||||
|
|
||||||
|
if l:level == 0
|
||||||
|
return '%-G%f:%l:%c:%t:\ %m,%-G%f:%l:%c::\ %m,%-G%f:%l::%t:\ %m'
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:level < 2
|
||||||
|
let l:efm = '%-G%f:%l:%c:W:\ %m,%-G%f:%l::W:\ %m,'
|
||||||
|
endif
|
||||||
|
return l:efm . '%f:%l:%c:%t:\ %m,%f:%l:%c::\ %m,%f:%l::%t:\ %m'
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:preserveerrors(autosave, listtype) abort
|
||||||
|
return a:autosave && a:listtype == go#list#Type("GoFmt") && go#config#FmtAutosave() && isdirectory(expand('%:p:h'))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
600
sources_non_forked/vim-go/autoload/go/lint_test.vim
Normal file
600
sources_non_forked/vim-go/autoload/go/lint_test.vim
Normal file
|
@ -0,0 +1,600 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
func! Test_GometaGolangciLint() abort
|
||||||
|
call s:gometa('golangci-lint')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_GometaStaticcheck() abort
|
||||||
|
call s:gometa('staticcheck')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! s:gometa(metalinter) abort
|
||||||
|
let RestoreGOPATH = go#util#SetEnv('GOPATH', fnamemodify(getcwd(), ':p') . 'test-fixtures/lint')
|
||||||
|
call go#util#Chdir('test-fixtures/lint/src/foo')
|
||||||
|
silent exe 'e! ' . $GOPATH . '/src/foo/foo.go'
|
||||||
|
|
||||||
|
try
|
||||||
|
let g:go_metalinter_command = a:metalinter
|
||||||
|
let l:vim = s:vimdir()
|
||||||
|
let expected = [
|
||||||
|
\ {'lnum': 1, 'bufnr': bufnr('%'), 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'at least one file in a package should have a package comment (ST1000)'},
|
||||||
|
\ ]
|
||||||
|
if a:metalinter == 'golangci-lint'
|
||||||
|
let expected = [
|
||||||
|
\ {'lnum': 5, 'bufnr': bufnr('%'), 'col': 1, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': 'exported: exported function MissingFooDoc should have comment or be unexported (revive)'}
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
" clear the quickfix list
|
||||||
|
call setqflist([], 'r')
|
||||||
|
|
||||||
|
let g:go_metalinter_enabled = ['ST1000']
|
||||||
|
if a:metalinter == 'golangci-lint'
|
||||||
|
let g:go_metalinter_enabled = ['revive']
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#lint#Gometa(0, 0, $GOPATH . '/src/foo')
|
||||||
|
|
||||||
|
let actual = getqflist()
|
||||||
|
let start = reltime()
|
||||||
|
while len(actual) == 0 && reltimefloat(reltime(start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
let actual = copy(getqflist())
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
" sort the results, because golangci-lint seems to be returning the golint
|
||||||
|
" deprecation notice in a non-deterministic order.
|
||||||
|
call sort(l:actual)
|
||||||
|
call sort(l:expected)
|
||||||
|
|
||||||
|
call gotest#assert_quickfix(actual, expected)
|
||||||
|
finally
|
||||||
|
call call(RestoreGOPATH, [])
|
||||||
|
unlet g:go_metalinter_enabled
|
||||||
|
unlet g:go_metalinter_command
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
"func! Test_GometaGolangciLint_shadow() abort
|
||||||
|
" call s:gometa_shadow('golangci-lint')
|
||||||
|
"endfunc
|
||||||
|
"
|
||||||
|
"func! s:gometa_shadow(metalinter) abort
|
||||||
|
" let RestoreGOPATH = go#util#SetEnv('GOPATH', fnamemodify(getcwd(), ':p') . 'test-fixtures/lint')
|
||||||
|
" silent exe 'e! ' . $GOPATH . '/src/lint/golangci-lint/problems/shadow/problems.go'
|
||||||
|
"
|
||||||
|
" try
|
||||||
|
" let g:go_metalinter_command = a:metalinter
|
||||||
|
" let expected = [
|
||||||
|
" \ {'lnum': 4, 'bufnr': bufnr('%'), 'col': 7, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': 'w', 'module': '', 'text': '[runner] Can''t run linter golint: golint: analysis skipped: errors in package'},
|
||||||
|
" \ {'lnum': 4, 'bufnr': bufnr('%'), 'col': 7, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': 'e', 'module': '', 'text': 'Running error: golint: analysis skipped: errors in package'}
|
||||||
|
" \ ]
|
||||||
|
"
|
||||||
|
" " clear the quickfix list
|
||||||
|
" call setqflist([], 'r')
|
||||||
|
"
|
||||||
|
" let g:go_metalinter_enabled = ['golint']
|
||||||
|
"
|
||||||
|
" call go#lint#Gometa(0, 0)
|
||||||
|
"
|
||||||
|
" let actual = getqflist()
|
||||||
|
" let start = reltime()
|
||||||
|
" while len(actual) == 0 && reltimefloat(reltime(start)) < 10
|
||||||
|
" sleep 100m
|
||||||
|
" let actual = getqflist()
|
||||||
|
" endwhile
|
||||||
|
"
|
||||||
|
" call gotest#assert_quickfix(actual, expected)
|
||||||
|
" finally
|
||||||
|
" call call(RestoreGOPATH, [])
|
||||||
|
" unlet g:go_metalinter_enabled
|
||||||
|
" unlet g:go_metalinter_command
|
||||||
|
" endtry
|
||||||
|
"endfunc
|
||||||
|
|
||||||
|
func! Test_GometaAutoSaveGolangciLint() abort
|
||||||
|
call s:gometaautosave('golangci-lint', 0)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_GometaAutoSaveStaticcheck() abort
|
||||||
|
call s:gometaautosave('staticcheck', 0)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_GometaAutoSaveGopls() abort
|
||||||
|
let g:go_gopls_staticcheck = 1
|
||||||
|
let g:go_diagnostics_level = 2
|
||||||
|
call s:gometaautosave('gopls', 0)
|
||||||
|
unlet g:go_gopls_staticcheck
|
||||||
|
unlet g:go_diagnostics_level
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_GometaAutoSaveGolangciLintKeepsErrors() abort
|
||||||
|
call s:gometaautosave('golangci-lint', 1)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_GometaAutoSaveStaticcheckKeepsErrors() abort
|
||||||
|
call s:gometaautosave('staticcheck', 1)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! s:gometaautosave(metalinter, withList) abort
|
||||||
|
let l:tmp = gotest#load_fixture('lint/src/lint/lint.go')
|
||||||
|
|
||||||
|
try
|
||||||
|
let g:go_metalinter_command = a:metalinter
|
||||||
|
let l:vim = s:vimdir()
|
||||||
|
let l:expected = [
|
||||||
|
\ {'lnum': 1, 'bufnr': bufnr('%'), 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'at least one file in a package should have a package comment (ST1000)'},
|
||||||
|
\ ]
|
||||||
|
if a:metalinter == 'gopls'
|
||||||
|
let l:expected = []
|
||||||
|
" let l:expected = [
|
||||||
|
" \ {'lnum': 1, 'bufnr': bufnr('%'), 'col': 1, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': 'W', 'module': '', 'text': 'at least one file in a package should have a package comment'}
|
||||||
|
" \ ]
|
||||||
|
elseif a:metalinter == 'golangci-lint'
|
||||||
|
let l:expected = [
|
||||||
|
\ {'lnum': 5, 'bufnr': bufnr('%'), 'col': 1, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': 'exported: exported function MissingDoc should have comment or be unexported (revive)'}
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:list = []
|
||||||
|
if a:withList
|
||||||
|
let l:list = [
|
||||||
|
\ {'lnum': 1, 'bufnr': bufnr('%'), 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'before metalinter'}
|
||||||
|
\ ]
|
||||||
|
let l:expected = extend(copy(l:list), l:expected)
|
||||||
|
endif
|
||||||
|
|
||||||
|
" set the location list
|
||||||
|
call setloclist(0, l:list, 'r')
|
||||||
|
|
||||||
|
let g:go_metalinter_autosave_enabled = ['ST1000']
|
||||||
|
if a:metalinter == 'golangci-lint'
|
||||||
|
let g:go_metalinter_autosave_enabled = ['revive']
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#lint#Gometa(0, 1)
|
||||||
|
|
||||||
|
let l:actual = getloclist(0)
|
||||||
|
let l:start = reltime()
|
||||||
|
while len(l:actual) != len(l:expected) && reltimefloat(reltime(l:start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
let l:actual = copy(getloclist(0))
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
" sort the results, because golangci-lint seems to be returning the golint
|
||||||
|
" deprecation notice in a non-deterministic order.
|
||||||
|
call sort(l:actual)
|
||||||
|
call sort(l:expected)
|
||||||
|
|
||||||
|
call gotest#assert_quickfix(l:actual, l:expected)
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
unlet g:go_metalinter_autosave_enabled
|
||||||
|
unlet g:go_metalinter_command
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_GometaGolangciLint_importabs() abort
|
||||||
|
call s:gometa_importabs('golangci-lint')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! s:gometa_importabs(metalinter) abort
|
||||||
|
let RestoreGOPATH = go#util#SetEnv('GOPATH', fnamemodify(getcwd(), ':p') . 'test-fixtures/lint')
|
||||||
|
silent exe 'e! ' . $GOPATH . '/src/lint/golangci-lint/problems/importabs/problems.go'
|
||||||
|
|
||||||
|
try
|
||||||
|
let g:go_metalinter_command = a:metalinter
|
||||||
|
|
||||||
|
let expected = [
|
||||||
|
\ {'lnum': 3, 'bufnr': bufnr('%'), 'col': 8, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': '"/quux" imported but not used (typecheck)'},
|
||||||
|
\ {'lnum': 0, 'bufnr': 0, 'col': 0, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': 'w', 'module': '', 'text': '[runner] The linter ''golint'' is deprecated (since v1.41.0) due to: The repository of the linter has been archived by the owner. Replaced by revive.'},
|
||||||
|
\ ]
|
||||||
|
" clear the quickfix list
|
||||||
|
call setqflist([], 'r')
|
||||||
|
|
||||||
|
let g:go_metalinter_enabled = ['golint']
|
||||||
|
|
||||||
|
call go#lint#Gometa(0, 0)
|
||||||
|
|
||||||
|
let actual = getqflist()
|
||||||
|
let start = reltime()
|
||||||
|
while len(actual) == 0 && reltimefloat(reltime(start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
let actual = copy(getqflist())
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
" sort the results, because golangci-lint seems to be returning the golint
|
||||||
|
" deprecation notice in a non-deterministic order.
|
||||||
|
call sort(l:actual)
|
||||||
|
call sort(l:expected)
|
||||||
|
|
||||||
|
call gotest#assert_quickfix(actual, expected)
|
||||||
|
finally
|
||||||
|
call call(RestoreGOPATH, [])
|
||||||
|
unlet g:go_metalinter_enabled
|
||||||
|
unlet g:go_metalinter_command
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
"func! Test_GometaAutoSaveGolangciLint_importabs() abort
|
||||||
|
" call s:gometaautosave_importabs('golangci-lint')
|
||||||
|
"endfunc
|
||||||
|
"
|
||||||
|
"func! s:gometaautosave_importabs(metalinter) abort
|
||||||
|
" let RestoreGOPATH = go#util#SetEnv('GOPATH', fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/lint')
|
||||||
|
" silent exe 'e! ' . $GOPATH . '/src/lint/golangci-lint/problems/importabs/ok.go'
|
||||||
|
"
|
||||||
|
" try
|
||||||
|
" let g:go_metalinter_command = a:metalinter
|
||||||
|
" let expected = [
|
||||||
|
" \ {'lnum': 3, 'bufnr': bufnr('%')+1, 'col': 8, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': 'w', 'module': '', 'text': '[runner] Can''t run linter golint: golint: analysis skipped: errors in package'},
|
||||||
|
" \ {'lnum': 3, 'bufnr': bufnr('%')+1, 'col': 8, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': 'e', 'module': '', 'text': 'Running error: golint: analysis skipped: errors in package'}
|
||||||
|
" \ ]
|
||||||
|
"
|
||||||
|
" " clear the location list
|
||||||
|
" call setloclist(0, [], 'r')
|
||||||
|
"
|
||||||
|
" let g:go_metalinter_autosave_enabled = ['golint']
|
||||||
|
"
|
||||||
|
" call go#lint#Gometa(0, 1)
|
||||||
|
"
|
||||||
|
" let actual = getloclist(0)
|
||||||
|
" let start = reltime()
|
||||||
|
" while len(actual) == 0 && reltimefloat(reltime(start)) < 10
|
||||||
|
" sleep 100m
|
||||||
|
" let actual = getloclist(0)
|
||||||
|
" endwhile
|
||||||
|
"
|
||||||
|
" call gotest#assert_quickfix(actual, expected)
|
||||||
|
" finally
|
||||||
|
" call call(RestoreGOPATH, [])
|
||||||
|
" unlet g:go_metalinter_autosave_enabled
|
||||||
|
" unlet g:go_metalinter_command
|
||||||
|
" endtry
|
||||||
|
"endfunc
|
||||||
|
"
|
||||||
|
"func! Test_GometaGolangciLint_multiple() abort
|
||||||
|
" call s:gometa_multiple('golangci-lint')
|
||||||
|
"endfunc
|
||||||
|
|
||||||
|
func! s:gometa_multiple(metalinter) abort
|
||||||
|
let RestoreGOPATH = go#util#SetEnv('GOPATH', fnamemodify(getcwd(), ':p') . 'test-fixtures/lint')
|
||||||
|
silent exe 'e! ' . $GOPATH . '/src/lint/golangci-lint/problems/multiple/problems.go'
|
||||||
|
|
||||||
|
try
|
||||||
|
let g:go_metalinter_command = a:metalinter
|
||||||
|
let expected = [
|
||||||
|
\ {'lnum': 0, 'bufnr': 0, 'col': 0, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': 'w', 'module': '', 'text': '[runner] The linter ''golint'' is deprecated (since v1.41.0) due to: The repository of the linter has been archived by the owner. Replaced by revive.'},
|
||||||
|
\ {'lnum': 8, 'bufnr': bufnr('%'), 'col': 7, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': 'time.Sleep undefined (type int has no field or method Sleep) (typecheck)'},
|
||||||
|
\ {'lnum': 4, 'bufnr': bufnr('%'), 'col': 2, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': '"time" imported but not used (typecheck)'}
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
" clear the quickfix list
|
||||||
|
call setqflist([], 'r')
|
||||||
|
|
||||||
|
let g:go_metalinter_enabled = ['revive']
|
||||||
|
|
||||||
|
call go#lint#Gometa(0, 0)
|
||||||
|
|
||||||
|
let actual = getqflist()
|
||||||
|
let start = reltime()
|
||||||
|
while len(actual) == 0 && reltimefloat(reltime(start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
let actual = copy(getqflist())
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
" sort the results, because golangci-lint seems to be returning the golint
|
||||||
|
" deprecation notice in a non-deterministic order.
|
||||||
|
call sort(l:actual)
|
||||||
|
call sort(l:expected)
|
||||||
|
|
||||||
|
call gotest#assert_quickfix(actual, expected)
|
||||||
|
finally
|
||||||
|
call call(RestoreGOPATH, [])
|
||||||
|
unlet g:go_metalinter_enabled
|
||||||
|
unlet g:go_metalinter_command
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_GometaAutoSaveGolangciLint_multiple() abort
|
||||||
|
call s:gometaautosave_multiple('golangci-lint')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! s:gometaautosave_multiple(metalinter) abort
|
||||||
|
let RestoreGOPATH = go#util#SetEnv('GOPATH', fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/lint')
|
||||||
|
silent exe 'e! ' . $GOPATH . '/src/lint/golangci-lint/problems/multiple/problems.go'
|
||||||
|
|
||||||
|
try
|
||||||
|
let g:go_metalinter_command = a:metalinter
|
||||||
|
let expected = [
|
||||||
|
\ {'lnum': 0, 'bufnr': 0, 'col': 0, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': 'w', 'module': '', 'text': '[runner] The linter ''golint'' is deprecated (since v1.41.0) due to: The repository of the linter has been archived by the owner. Replaced by revive.'},
|
||||||
|
\ {'lnum': 8, 'bufnr': bufnr('%'), 'col': 7, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': 'time.Sleep undefined (type int has no field or method Sleep) (typecheck)'},
|
||||||
|
\ {'lnum': 4, 'bufnr': bufnr('%'), 'col': 2, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': '"time" imported but not used (typecheck)'}
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
" clear the location list
|
||||||
|
call setloclist(0, [], 'r')
|
||||||
|
|
||||||
|
let g:go_metalinter_autosave_enabled = ['golint']
|
||||||
|
|
||||||
|
call go#lint#Gometa(0, 1)
|
||||||
|
|
||||||
|
let actual = getloclist(0)
|
||||||
|
let start = reltime()
|
||||||
|
while len(actual) == 0 && reltimefloat(reltime(start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
let actual = copy(getloclist(0))
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
" sort the results, because golangci-lint seems to be returning the golint
|
||||||
|
" deprecation notice in a non-deterministic order.
|
||||||
|
call sort(l:actual)
|
||||||
|
call sort(l:expected)
|
||||||
|
|
||||||
|
call gotest#assert_quickfix(actual, expected)
|
||||||
|
finally
|
||||||
|
call call(RestoreGOPATH, [])
|
||||||
|
unlet g:go_metalinter_autosave_enabled
|
||||||
|
unlet g:go_metalinter_command
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_Vet() abort
|
||||||
|
let l:tmp = gotest#load_fixture('lint/src/vet/vet.go')
|
||||||
|
|
||||||
|
try
|
||||||
|
let expected = [
|
||||||
|
\ {'lnum': 7, 'bufnr': bufnr('%'), 'col': 2, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'fmt.Printf format %d has arg str of wrong type string'}
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
let [l:goversion, l:err] = go#util#Exec(['go', 'env', 'GOVERSION'])
|
||||||
|
let l:goversion = split(l:goversion, "\n")[0]
|
||||||
|
if l:goversion < 'go1.18'
|
||||||
|
let expected = [
|
||||||
|
\ {'lnum': 7, 'bufnr': bufnr('%'), 'col': 2, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'Printf format %d has arg str of wrong type string'}
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let winnr = winnr()
|
||||||
|
|
||||||
|
" clear the quickfix list
|
||||||
|
call setqflist([], 'r')
|
||||||
|
|
||||||
|
call go#lint#Vet(1)
|
||||||
|
|
||||||
|
let actual = getqflist()
|
||||||
|
let start = reltime()
|
||||||
|
while len(actual) == 0 && reltimefloat(reltime(start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
let actual = getqflist()
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call gotest#assert_quickfix(actual, expected)
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_Vet_subdir() abort
|
||||||
|
let l:tmp = gotest#load_fixture('lint/src/vet/vet.go')
|
||||||
|
|
||||||
|
" go up one directory to easily test that go vet's file paths are handled
|
||||||
|
" correctly when the working directory is not the directory that contains
|
||||||
|
" the file being vetted.
|
||||||
|
call go#util#Chdir('..')
|
||||||
|
|
||||||
|
try
|
||||||
|
let expected = [
|
||||||
|
\ {'lnum': 7, 'bufnr': bufnr('%'), 'col': 2, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'fmt.Printf format %d has arg str of wrong type string'}
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
let [l:goversion, l:err] = go#util#Exec(['go', 'env', 'GOVERSION'])
|
||||||
|
let l:goversion = split(l:goversion, "\n")[0]
|
||||||
|
if l:goversion < 'go1.18'
|
||||||
|
let expected = [
|
||||||
|
\ {'lnum': 7, 'bufnr': bufnr('%'), 'col': 2, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'Printf format %d has arg str of wrong type string'}
|
||||||
|
\ ]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let winnr = winnr()
|
||||||
|
|
||||||
|
" clear the quickfix list
|
||||||
|
call setqflist([], 'r')
|
||||||
|
|
||||||
|
call go#lint#Vet(1)
|
||||||
|
|
||||||
|
let actual = getqflist()
|
||||||
|
let start = reltime()
|
||||||
|
while len(actual) == 0 && reltimefloat(reltime(start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
let actual = getqflist()
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call gotest#assert_quickfix(actual, expected)
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_Vet_compilererror() abort
|
||||||
|
let l:tmp = gotest#load_fixture('lint/src/vet/compilererror/compilererror.go')
|
||||||
|
|
||||||
|
try
|
||||||
|
let expected = [
|
||||||
|
\ {'lnum': 6, 'bufnr': bufnr('%'), 'col': 22, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': "missing ',' before newline in argument list (and 1 more errors)"}
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
let winnr = winnr()
|
||||||
|
|
||||||
|
" clear the quickfix list
|
||||||
|
call setqflist([], 'r')
|
||||||
|
|
||||||
|
call go#lint#Vet(1)
|
||||||
|
|
||||||
|
let actual = getqflist()
|
||||||
|
let start = reltime()
|
||||||
|
while len(actual) == 0 && reltimefloat(reltime(start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
let actual = getqflist()
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call gotest#assert_quickfix(actual, expected)
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_Lint_GOPATH() abort
|
||||||
|
let RestoreGO111MODULE = go#util#SetEnv('GO111MODULE', 'off')
|
||||||
|
let RestoreGOPATH = go#util#SetEnv('GOPATH', fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/lint')
|
||||||
|
|
||||||
|
silent exe 'e! ' . $GOPATH . '/src/lint/quux.go'
|
||||||
|
silent exe 'e! ' . $GOPATH . '/src/lint/lint.go'
|
||||||
|
compiler go
|
||||||
|
|
||||||
|
let expected = [
|
||||||
|
\ {'lnum': 5, 'bufnr': bufnr('%'), 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'exported function MissingDoc should have comment or be unexported'},
|
||||||
|
\ {'lnum': 5, 'bufnr': bufnr('test-fixtures/lint/src/lint/quux.go'), 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'exported function AlsoMissingDoc should have comment or be unexported'}
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
let winnr = winnr()
|
||||||
|
|
||||||
|
" clear the quickfix list
|
||||||
|
call setqflist([], 'r')
|
||||||
|
|
||||||
|
call go#lint#Golint(1)
|
||||||
|
|
||||||
|
let actual = getqflist()
|
||||||
|
let start = reltime()
|
||||||
|
while len(actual) == 0 && reltimefloat(reltime(start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
let actual = getqflist()
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
" sort the results for deterministic ordering
|
||||||
|
call sort(actual)
|
||||||
|
call sort(expected)
|
||||||
|
|
||||||
|
call gotest#assert_quickfix(actual, expected)
|
||||||
|
|
||||||
|
"call assert_report(execute('ls'))
|
||||||
|
|
||||||
|
call call(RestoreGOPATH, [])
|
||||||
|
call call(RestoreGO111MODULE, [])
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_Lint_NullModule() abort
|
||||||
|
let RestoreGO111MODULE = go#util#SetEnv('GO111MODULE', 'off')
|
||||||
|
silent exe 'e! ' . fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/lint/src/lint/quux.go'
|
||||||
|
silent exe 'e! ' . fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/lint/src/lint/lint.go'
|
||||||
|
compiler go
|
||||||
|
|
||||||
|
let expected = [
|
||||||
|
\ {'lnum': 5, 'bufnr': bufnr('%'), 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'exported function MissingDoc should have comment or be unexported'},
|
||||||
|
\ {'lnum': 5, 'bufnr': bufnr('test-fixtures/lint/src/lint/quux.go'), 'col': 1, 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'pattern': '', 'text': 'exported function AlsoMissingDoc should have comment or be unexported'}
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
let winnr = winnr()
|
||||||
|
|
||||||
|
" clear the quickfix list
|
||||||
|
call setqflist([], 'r')
|
||||||
|
|
||||||
|
call go#lint#Golint(1)
|
||||||
|
|
||||||
|
let actual = getqflist()
|
||||||
|
let start = reltime()
|
||||||
|
while len(actual) == 0 && reltimefloat(reltime(start)) < 10
|
||||||
|
sleep 100m
|
||||||
|
let actual = getqflist()
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
" sort the results for deterministic ordering
|
||||||
|
call sort(actual)
|
||||||
|
call sort(expected)
|
||||||
|
|
||||||
|
call gotest#assert_quickfix(actual, expected)
|
||||||
|
call call(RestoreGO111MODULE, [])
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_Errcheck() abort
|
||||||
|
let RestoreGOPATH = go#util#SetEnv('GOPATH', fnamemodify(getcwd(), ':p') . 'test-fixtures/lint')
|
||||||
|
silent exe 'e! ' . $GOPATH . '/src/errcheck/errcheck.go'
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:bufnr = bufnr('')
|
||||||
|
let expected = [
|
||||||
|
\ {'lnum': 9, 'bufnr': bufnr(''), 'col': 9, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': ":\tio.Copy(os.Stdout, os.Stdin)"},
|
||||||
|
\ {'lnum': 10, 'bufnr': bufnr('')+1, 'col': 9, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': ":\tio.Copy(os.Stdout, os.Stdin)"},
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
" clear the quickfix list
|
||||||
|
call setqflist([], 'r')
|
||||||
|
|
||||||
|
call go#lint#Errcheck(1)
|
||||||
|
|
||||||
|
call gotest#assert_quickfix(getqflist(), expected)
|
||||||
|
call assert_equal(l:bufnr, bufnr(''))
|
||||||
|
finally
|
||||||
|
call call(RestoreGOPATH, [])
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_Errcheck_options() abort
|
||||||
|
let RestoreGOPATH = go#util#SetEnv('GOPATH', fnamemodify(getcwd(), ':p') . 'test-fixtures/lint')
|
||||||
|
silent exe 'e! ' . $GOPATH . '/src/errcheck/errcheck.go'
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:bufnr = bufnr('')
|
||||||
|
let expected = [
|
||||||
|
\ {'lnum': 9, 'bufnr': bufnr(''), 'col': 9, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': ":\tio.Copy(os.Stdout, os.Stdin)"},
|
||||||
|
\ ]
|
||||||
|
|
||||||
|
" clear the quickfix list
|
||||||
|
call setqflist([], 'r')
|
||||||
|
|
||||||
|
call go#lint#Errcheck(1, '-ignoretests')
|
||||||
|
|
||||||
|
call gotest#assert_quickfix(getqflist(), expected)
|
||||||
|
call assert_equal(l:bufnr, bufnr(''))
|
||||||
|
finally
|
||||||
|
call call(RestoreGOPATH, [])
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_Errcheck_compilererror() abort
|
||||||
|
let l:tmp = gotest#load_fixture('lint/src/errcheck/compilererror/compilererror.go')
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:bufnr = bufnr('')
|
||||||
|
let expected = []
|
||||||
|
|
||||||
|
" clear the quickfix list
|
||||||
|
call setqflist([], 'r')
|
||||||
|
|
||||||
|
call go#lint#Errcheck(1)
|
||||||
|
|
||||||
|
call gotest#assert_quickfix(getqflist(), expected)
|
||||||
|
call assert_equal(l:bufnr, bufnr(''))
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! s:vimdir()
|
||||||
|
let l:vim = "vim-8.2"
|
||||||
|
if has('nvim')
|
||||||
|
let l:vim = 'nvim'
|
||||||
|
elseif v:version == 800
|
||||||
|
let l:vim = 'vim-8.0'
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:vim
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
190
sources_non_forked/vim-go/autoload/go/list.vim
Normal file
190
sources_non_forked/vim-go/autoload/go/list.vim
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
" Window opens the list with the given height up to 10 lines maximum.
|
||||||
|
" Otherwise g:go_loclist_height is used.
|
||||||
|
"
|
||||||
|
" If no or zero height is given it closes the window by default.
|
||||||
|
" To prevent this, set g:go_list_autoclose = 0
|
||||||
|
function! go#list#Window(listtype, ...) abort
|
||||||
|
" we don't use lwindow to close the location list as we need also the
|
||||||
|
" ability to resize the window. So, we are going to use lopen and lclose
|
||||||
|
" for a better user experience. If the number of errors in a current
|
||||||
|
" location list increases/decreases, cwindow will not resize when a new
|
||||||
|
" updated height is passed. lopen in the other hand resizes the screen.
|
||||||
|
if !a:0 || a:1 == 0
|
||||||
|
call go#list#Close(a:listtype)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let height = go#config#ListHeight()
|
||||||
|
if height == 0
|
||||||
|
" prevent creating a large location height for a large set of numbers
|
||||||
|
if a:1 > 10
|
||||||
|
let height = 10
|
||||||
|
else
|
||||||
|
let height = a:1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:listtype == "locationlist"
|
||||||
|
exe 'lopen ' . height
|
||||||
|
else
|
||||||
|
exe 'copen ' . height
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
" Get returns the current items from the list
|
||||||
|
function! go#list#Get(listtype) abort
|
||||||
|
if a:listtype == "locationlist"
|
||||||
|
return getloclist(0)
|
||||||
|
else
|
||||||
|
return getqflist()
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Populate populate the list with the given items
|
||||||
|
function! go#list#Populate(listtype, items, title) abort
|
||||||
|
if a:listtype == "locationlist"
|
||||||
|
call setloclist(0, a:items, 'r')
|
||||||
|
call setloclist(0, [], 'a', {'title': a:title})
|
||||||
|
else
|
||||||
|
call setqflist(a:items, 'r')
|
||||||
|
call setqflist([], 'a', {'title': a:title})
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Parse parses the given items based on the specified errorformat and
|
||||||
|
" populates the list.
|
||||||
|
function! go#list#ParseFormat(listtype, errformat, items, title, add) abort
|
||||||
|
" backup users errorformat, will be restored once we are finished
|
||||||
|
let old_errorformat = &errorformat
|
||||||
|
|
||||||
|
" parse and populate the location list
|
||||||
|
let &errorformat = a:errformat
|
||||||
|
try
|
||||||
|
call go#list#Parse(a:listtype, a:items, a:title, a:add)
|
||||||
|
finally
|
||||||
|
"restore back
|
||||||
|
let &errorformat = old_errorformat
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Parse parses the given items based on the global errorformat and
|
||||||
|
" populates the list.
|
||||||
|
function! go#list#Parse(listtype, items, title, add) abort
|
||||||
|
let l:list = []
|
||||||
|
if a:add
|
||||||
|
let l:list = go#list#Get(a:listtype)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:listtype == "locationlist"
|
||||||
|
if a:add
|
||||||
|
laddexpr a:items
|
||||||
|
else
|
||||||
|
lgetexpr a:items
|
||||||
|
endif
|
||||||
|
call setloclist(0, [], 'a', {'title': a:title})
|
||||||
|
else
|
||||||
|
if a:add
|
||||||
|
caddexpr a:items
|
||||||
|
else
|
||||||
|
cgetexpr a:items
|
||||||
|
endif
|
||||||
|
call setqflist([], 'a', {'title': a:title})
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" JumpToFirst jumps to the first item in the location list
|
||||||
|
function! go#list#JumpToFirst(listtype) abort
|
||||||
|
if a:listtype == "locationlist"
|
||||||
|
ll 1
|
||||||
|
else
|
||||||
|
cc 1
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Clean cleans and closes the location list
|
||||||
|
function! go#list#Clean(listtype) abort
|
||||||
|
if a:listtype == "locationlist"
|
||||||
|
lex []
|
||||||
|
else
|
||||||
|
cex []
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#list#Close(a:listtype)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Close closes the location list
|
||||||
|
function! go#list#Close(listtype) abort
|
||||||
|
let autoclose_window = go#config#ListAutoclose()
|
||||||
|
if !autoclose_window
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:listtype == "locationlist"
|
||||||
|
lclose
|
||||||
|
else
|
||||||
|
cclose
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:listtype(listtype) abort
|
||||||
|
let listtype = go#config#ListType()
|
||||||
|
if empty(listtype)
|
||||||
|
return a:listtype
|
||||||
|
endif
|
||||||
|
|
||||||
|
return listtype
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" s:default_list_type_commands is the defaults that will be used for each of
|
||||||
|
" the supported commands (see documentation for g:go_list_type_commands). When
|
||||||
|
" defining a default, quickfix should be used if the command operates on
|
||||||
|
" multiple files, while locationlist should be used if the command operates on a
|
||||||
|
" single file or buffer. Keys that begin with an underscore are not supported
|
||||||
|
" in g:go_list_type_commands.
|
||||||
|
let s:default_list_type_commands = {
|
||||||
|
\ "GoBuild": "quickfix",
|
||||||
|
\ "GoDiagnostics": "quickfix",
|
||||||
|
\ "GoDebug": "quickfix",
|
||||||
|
\ "GoErrCheck": "quickfix",
|
||||||
|
\ "GoFmt": "locationlist",
|
||||||
|
\ "GoGenerate": "quickfix",
|
||||||
|
\ "GoInstall": "quickfix",
|
||||||
|
\ "GoLint": "quickfix",
|
||||||
|
\ "GoMetaLinter": "quickfix",
|
||||||
|
\ "GoMetaLinterAutoSave": "locationlist",
|
||||||
|
\ "GoModFmt": "locationlist",
|
||||||
|
\ "GoModifyTags": "locationlist",
|
||||||
|
\ "GoRename": "quickfix",
|
||||||
|
\ "GoRun": "quickfix",
|
||||||
|
\ "GoTest": "quickfix",
|
||||||
|
\ "GoVet": "quickfix",
|
||||||
|
\ "GoReferrers": "locationlist",
|
||||||
|
\ "GoImplements": "locationlist",
|
||||||
|
\ "GoCallers": "locationlist",
|
||||||
|
\ "_guru": "locationlist",
|
||||||
|
\ "_term": "locationlist",
|
||||||
|
\ "_job": "locationlist",
|
||||||
|
\ }
|
||||||
|
|
||||||
|
function! go#list#Type(for) abort
|
||||||
|
let l:listtype = s:listtype(get(s:default_list_type_commands, a:for))
|
||||||
|
if l:listtype == "0"
|
||||||
|
call go#util#EchoError(printf(
|
||||||
|
\ "unknown list type command value found ('%s'). Please open a bug report in the vim-go repo.",
|
||||||
|
\ a:for))
|
||||||
|
let l:listtype = "quickfix"
|
||||||
|
endif
|
||||||
|
|
||||||
|
return get(go#config#ListTypeCommands(), a:for, l:listtype)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
2035
sources_non_forked/vim-go/autoload/go/lsp.vim
Normal file
2035
sources_non_forked/vim-go/autoload/go/lsp.vim
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,63 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
let s:Text = 1
|
||||||
|
let s:Method = 2
|
||||||
|
let s:Function = 3
|
||||||
|
let s:Constructor = 4
|
||||||
|
let s:Field = 5
|
||||||
|
let s:Variable = 6
|
||||||
|
let s:Class = 7
|
||||||
|
let s:Interface = 8
|
||||||
|
let s:Module = 9
|
||||||
|
let s:Property = 10
|
||||||
|
let s:Unit = 11
|
||||||
|
let s:Value = 12
|
||||||
|
let s:Enum = 13
|
||||||
|
let s:Keyword = 14
|
||||||
|
let s:Snippet = 15
|
||||||
|
let s:Color = 16
|
||||||
|
let s:File = 17
|
||||||
|
let s:Reference = 18
|
||||||
|
let s:Folder = 19
|
||||||
|
let s:EnumMember = 20
|
||||||
|
let s:Constant = 21
|
||||||
|
let s:Struct = 22
|
||||||
|
let s:Event = 23
|
||||||
|
let s:Operator = 24
|
||||||
|
let s:TypeParameter = 25
|
||||||
|
|
||||||
|
function! go#lsp#completionitemkind#Vim(kind) abort
|
||||||
|
if a:kind == s:Method || a:kind == s:Function || a:kind == s:Constructor
|
||||||
|
return 'f'
|
||||||
|
elseif a:kind == s:Variable || a:kind == s:Constant
|
||||||
|
return 'v'
|
||||||
|
elseif a:kind == s:Field || a:kind == s:Property
|
||||||
|
return 'm'
|
||||||
|
elseif a:kind == s:Class || a:kind == s:Interface || a:kind == s:Struct
|
||||||
|
return 't'
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#completionitemkind#IsFunction(kind) abort
|
||||||
|
if a:kind == s:Function
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#completionitemkind#IsMethod(kind) abort
|
||||||
|
if a:kind == s:Method
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
19
sources_non_forked/vim-go/autoload/go/lsp/filechangetype.vim
Normal file
19
sources_non_forked/vim-go/autoload/go/lsp/filechangetype.vim
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
let s:fct = {
|
||||||
|
\ 'Created': 1,
|
||||||
|
\ 'Changed': 2,
|
||||||
|
\ 'Deleted': 3,
|
||||||
|
\ }
|
||||||
|
|
||||||
|
function! go#lsp#filechangetype#FileChangeType(name)
|
||||||
|
return s:fct[a:name]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
72
sources_non_forked/vim-go/autoload/go/lsp/lsp.vim
Normal file
72
sources_non_forked/vim-go/autoload/go/lsp/lsp.vim
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
" go#lsp#lsp#Position returns the LSP text position. If no arguments are
|
||||||
|
" provided, the cursor position is assumed. Otherwise, there should be two
|
||||||
|
" arguments: the line and the column.
|
||||||
|
function! go#lsp#lsp#Position(...)
|
||||||
|
if a:0 < 2
|
||||||
|
let [l:line, l:col] = getpos('.')[1:2]
|
||||||
|
else
|
||||||
|
let l:line = a:1
|
||||||
|
let l:col = a:2
|
||||||
|
endif
|
||||||
|
let l:content = getline(l:line)
|
||||||
|
|
||||||
|
" LSP uses 0-based lines.
|
||||||
|
return [l:line - 1, s:character(l:line, l:col-1)]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:strlen(str) abort
|
||||||
|
let l:runes = split(a:str, '\zs')
|
||||||
|
return len(l:runes) + len(filter(l:runes, 'char2nr(v:val)>=0x10000'))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:character(line, col) abort
|
||||||
|
return s:strlen(getline(a:line)[:col([a:line, a:col - 1])])
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" go#lsp#PositionOf returns len(content[0:units]) where units is utf-16 code
|
||||||
|
" units. This is mostly useful for converting LSP text position to vim
|
||||||
|
" position.
|
||||||
|
function! go#lsp#lsp#PositionOf(content, units, ...) abort
|
||||||
|
if a:units == 0
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:remaining = a:units
|
||||||
|
let l:str = ''
|
||||||
|
for l:rune in split(a:content, '\zs')
|
||||||
|
if l:remaining < 0
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
let l:remaining -= 1
|
||||||
|
if char2nr(l:rune) >= 0x10000
|
||||||
|
let l:remaining -= 1
|
||||||
|
endif
|
||||||
|
let l:str = l:str . l:rune
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return len(l:str)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#lsp#SeverityToErrorType(severity) abort
|
||||||
|
if a:severity == 1
|
||||||
|
return 'E'
|
||||||
|
elseif a:severity == 2
|
||||||
|
return 'W'
|
||||||
|
elseif a:severity == 3
|
||||||
|
return 'I'
|
||||||
|
elseif a:severity == 4
|
||||||
|
return 'I'
|
||||||
|
endif
|
||||||
|
|
||||||
|
return ''
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
32
sources_non_forked/vim-go/autoload/go/lsp/lsp_test.vim
Normal file
32
sources_non_forked/vim-go/autoload/go/lsp/lsp_test.vim
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
scriptencoding utf-8
|
||||||
|
|
||||||
|
function! Test_PositionOf_Simple()
|
||||||
|
let l:actual = go#lsp#lsp#PositionOf("just ascii", 3)
|
||||||
|
call assert_equal(4, l:actual)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
|
||||||
|
function! Test_PositionOf_MultiByte()
|
||||||
|
" ⌘ is U+2318, which encodes to three bytes in utf-8 and 1 code unit in
|
||||||
|
" utf-16.
|
||||||
|
let l:actual = go#lsp#lsp#PositionOf("⌘⌘ foo", 3)
|
||||||
|
call assert_equal(8, l:actual)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
function! Test_PositionOf_MultipleCodeUnit()
|
||||||
|
" 𐐀 is U+10400, which encodes to 4 bytes in utf-8 and 2 code units in
|
||||||
|
" utf-16.
|
||||||
|
let l:actual = go#lsp#lsp#PositionOf("𐐀 bar", 3)
|
||||||
|
call assert_equal(6, l:actual)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
438
sources_non_forked/vim-go/autoload/go/lsp/message.vim
Normal file
438
sources_non_forked/vim-go/autoload/go/lsp/message.vim
Normal file
|
@ -0,0 +1,438 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
function! go#lsp#message#Initialize(wd) abort
|
||||||
|
return {
|
||||||
|
\ 'notification': 0,
|
||||||
|
\ 'method': 'initialize',
|
||||||
|
\ 'params': {
|
||||||
|
\ 'processId': getpid(),
|
||||||
|
\ 'rootUri': go#path#ToURI(a:wd),
|
||||||
|
\ 'capabilities': {
|
||||||
|
\ 'workspace': {
|
||||||
|
\ 'workspaceFolders': v:true,
|
||||||
|
\ 'didChangeConfiguration': {
|
||||||
|
\ 'dynamicRegistration': v:true,
|
||||||
|
\ },
|
||||||
|
\ 'workspaceEdit': {
|
||||||
|
\ 'documentChanges': v:true,
|
||||||
|
\ },
|
||||||
|
\ 'configuration': v:true,
|
||||||
|
\ },
|
||||||
|
\ 'textDocument': {
|
||||||
|
\ 'hover': {
|
||||||
|
\ 'contentFormat': ['plaintext'],
|
||||||
|
\ },
|
||||||
|
\ 'completion': {
|
||||||
|
\ 'completionItem': {
|
||||||
|
\ 'snippetSupport': go#config#GoplsUsePlaceholders() ? v:true : v:false,
|
||||||
|
\ },
|
||||||
|
\ },
|
||||||
|
\ 'codeAction': {
|
||||||
|
\ 'codeActionLiteralSupport': {
|
||||||
|
\ 'codeActionKind': {
|
||||||
|
\ 'valueSet': ['source.organizeImports', 'refactor.rewrite'],
|
||||||
|
\ },
|
||||||
|
\ },
|
||||||
|
\ },
|
||||||
|
\ }
|
||||||
|
\ },
|
||||||
|
\ 'workspaceFolders': [s:workspaceFolder(0, a:wd)],
|
||||||
|
\ }
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#Initialized() abort
|
||||||
|
return {
|
||||||
|
\ 'notification': 1,
|
||||||
|
\ 'method': 'initialized',
|
||||||
|
\ 'params': {},
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#Shutdown() abort
|
||||||
|
return {
|
||||||
|
\ 'notification': 0,
|
||||||
|
\ 'method': 'shutdown',
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#Format(file) abort
|
||||||
|
return {
|
||||||
|
\ 'notification': 0,
|
||||||
|
\ 'method': 'textDocument/formatting',
|
||||||
|
\ 'params': {
|
||||||
|
\ 'textDocument': {
|
||||||
|
\ 'uri': go#path#ToURI(a:file)
|
||||||
|
\ },
|
||||||
|
\ 'options': {
|
||||||
|
\ 'insertSpaces': v:false,
|
||||||
|
\ },
|
||||||
|
\ }
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#CodeActionImports(file) abort
|
||||||
|
return s:codeAction('source.organizeImports', a:file)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#CodeActionFillStruct(file, line, col) abort
|
||||||
|
return go#lsp#message#CodeActionRefactorRewrite(a:file, a:line, a:col, a:line, a:col)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#CodeActionRefactorRewrite(file, startline, startcol, endline, endcol) abort
|
||||||
|
let l:startpos = s:position(a:startline, a:startcol)
|
||||||
|
let l:endpos = s:position(a:endline, a:endcol)
|
||||||
|
|
||||||
|
let l:request = s:codeAction('refactor.rewrite', a:file)
|
||||||
|
|
||||||
|
let l:request.params = extend(l:request.params,
|
||||||
|
\ {
|
||||||
|
\ 'range': {
|
||||||
|
\ 'start': l:startpos,
|
||||||
|
\ 'end': l:endpos,
|
||||||
|
\ }
|
||||||
|
\ })
|
||||||
|
|
||||||
|
return l:request
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:codeAction(name, file) abort
|
||||||
|
return {
|
||||||
|
\ 'notification': 0,
|
||||||
|
\ 'method': 'textDocument/codeAction',
|
||||||
|
\ 'params': {
|
||||||
|
\ 'textDocument': {
|
||||||
|
\ 'uri': go#path#ToURI(a:file)
|
||||||
|
\ },
|
||||||
|
\ 'range': {
|
||||||
|
\ 'start': s:position(0, 0),
|
||||||
|
\ 'end': s:position(line('$'), 0),
|
||||||
|
\ },
|
||||||
|
\ 'context': {
|
||||||
|
\ 'only': [a:name],
|
||||||
|
\ },
|
||||||
|
\ }
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#Exit() abort
|
||||||
|
return {
|
||||||
|
\ 'notification': 1,
|
||||||
|
\ 'method': 'exit',
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#WorkspaceFoldersResult(dirs) abort
|
||||||
|
return map(copy(a:dirs), function('s:workspaceFolder', []))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#Definition(file, line, col) abort
|
||||||
|
let l:params = s:textDocumentPositionParams(a:file, a:line, a:col)
|
||||||
|
return {
|
||||||
|
\ 'notification': 0,
|
||||||
|
\ 'method': 'textDocument/definition',
|
||||||
|
\ 'params': l:params,
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#TypeDefinition(file, line, col) abort
|
||||||
|
let l:params = s:textDocumentPositionParams(a:file, a:line, a:col)
|
||||||
|
return {
|
||||||
|
\ 'notification': 0,
|
||||||
|
\ 'method': 'textDocument/typeDefinition',
|
||||||
|
\ 'params': l:params,
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#Implementation(file, line, col) abort
|
||||||
|
let l:params = s:textDocumentPositionParams(a:file, a:line, a:col)
|
||||||
|
return {
|
||||||
|
\ 'notification': 0,
|
||||||
|
\ 'method': 'textDocument/implementation',
|
||||||
|
\ 'params': l:params,
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#DidOpen(file, content, version) abort
|
||||||
|
return {
|
||||||
|
\ 'notification': 1,
|
||||||
|
\ 'method': 'textDocument/didOpen',
|
||||||
|
\ 'params': {
|
||||||
|
\ 'textDocument': {
|
||||||
|
\ 'uri': go#path#ToURI(a:file),
|
||||||
|
\ 'languageId': 'go',
|
||||||
|
\ 'text': a:content,
|
||||||
|
\ 'version': a:version,
|
||||||
|
\ }
|
||||||
|
\ }
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#DidChange(file, content, version) abort
|
||||||
|
return {
|
||||||
|
\ 'notification': 1,
|
||||||
|
\ 'method': 'textDocument/didChange',
|
||||||
|
\ 'params': {
|
||||||
|
\ 'textDocument': {
|
||||||
|
\ 'uri': go#path#ToURI(a:file),
|
||||||
|
\ 'version': a:version,
|
||||||
|
\ },
|
||||||
|
\ 'contentChanges': [
|
||||||
|
\ {
|
||||||
|
\ 'text': a:content,
|
||||||
|
\ }
|
||||||
|
\ ]
|
||||||
|
\ }
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#DidChangeWatchedFile(file, ct) abort
|
||||||
|
return {
|
||||||
|
\ 'notification': 1,
|
||||||
|
\ 'method': 'workspace/didChangeWatchedFiles',
|
||||||
|
\ 'params': {
|
||||||
|
\ 'changes': [
|
||||||
|
\ {
|
||||||
|
\ 'uri': go#path#ToURI(a:file),
|
||||||
|
\ 'type': go#lsp#filechangetype#FileChangeType(a:ct),
|
||||||
|
\ },
|
||||||
|
\ ],
|
||||||
|
\ }
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#DidClose(file) abort
|
||||||
|
return {
|
||||||
|
\ 'notification': 1,
|
||||||
|
\ 'method': 'textDocument/didClose',
|
||||||
|
\ 'params': {
|
||||||
|
\ 'textDocument': {
|
||||||
|
\ 'uri': go#path#ToURI(a:file),
|
||||||
|
\ }
|
||||||
|
\ }
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#Completion(file, line, col) abort
|
||||||
|
let l:params = s:textDocumentPositionParams(a:file, a:line, a:col)
|
||||||
|
return {
|
||||||
|
\ 'notification': 0,
|
||||||
|
\ 'method': 'textDocument/completion',
|
||||||
|
\ 'params': l:params,
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#References(file, line, col) abort
|
||||||
|
let l:params = s:textDocumentPositionParams(a:file, a:line, a:col)
|
||||||
|
let l:params.context = {'includeDeclaration': v:true}
|
||||||
|
return {
|
||||||
|
\ 'notification': 0,
|
||||||
|
\ 'method': 'textDocument/references',
|
||||||
|
\ 'params': l:params,
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#PrepareCallHierarchy(file, line, col) abort
|
||||||
|
let l:params = s:textDocumentPositionParams(a:file, a:line, a:col)
|
||||||
|
return {
|
||||||
|
\ 'notification': 0,
|
||||||
|
\ 'method': 'textDocument/prepareCallHierarchy',
|
||||||
|
\ 'params': l:params,
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#IncomingCalls(item) abort
|
||||||
|
return {
|
||||||
|
\ 'notification': 0,
|
||||||
|
\ 'method': 'callHierarchy/incomingCalls',
|
||||||
|
\ 'params': {
|
||||||
|
\ 'item': a:item,
|
||||||
|
\ }
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#Hover(file, line, col) abort
|
||||||
|
let l:params = s:textDocumentPositionParams(a:file, a:line, a:col)
|
||||||
|
return {
|
||||||
|
\ 'notification': 0,
|
||||||
|
\ 'method': 'textDocument/hover',
|
||||||
|
\ 'params': l:params,
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#Rename(file, line, col, newName) abort
|
||||||
|
let l:params = s:textDocumentPositionParams(a:file, a:line, a:col)
|
||||||
|
let l:params.newName = a:newName
|
||||||
|
return {
|
||||||
|
\ 'notification': 0,
|
||||||
|
\ 'method': 'textDocument/rename',
|
||||||
|
\ 'params': l:params,
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#ChangeWorkspaceFolders(add, remove) abort
|
||||||
|
let l:addDirs = map(copy(a:add), function('s:workspaceFolder', []))
|
||||||
|
let l:removeDirs = map(copy(a:remove), function('s:workspaceFolder', []))
|
||||||
|
|
||||||
|
return {
|
||||||
|
\ 'notification': 1,
|
||||||
|
\ 'method': 'workspace/didChangeWorkspaceFolders',
|
||||||
|
\ 'params': {
|
||||||
|
\ 'event': {
|
||||||
|
\ 'removed': l:removeDirs,
|
||||||
|
\ 'added': l:addDirs,
|
||||||
|
\ },
|
||||||
|
\ }
|
||||||
|
\ }
|
||||||
|
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#ConfigurationResult(items) abort
|
||||||
|
let l:result = []
|
||||||
|
|
||||||
|
" results must be in the same order as the items
|
||||||
|
for l:item in a:items
|
||||||
|
let l:workspace = go#path#FromURI(l:item.scopeUri)
|
||||||
|
let l:config = {
|
||||||
|
\ 'buildFlags': [],
|
||||||
|
\ 'hoverKind': 'Structured',
|
||||||
|
\ }
|
||||||
|
let l:buildtags = go#config#BuildTags()
|
||||||
|
if buildtags isnot ''
|
||||||
|
let l:config.buildFlags = extend(l:config.buildFlags, ['-tags', go#config#BuildTags()])
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:deepCompletion = go#config#GoplsDeepCompletion()
|
||||||
|
let l:matcher = go#config#GoplsMatcher()
|
||||||
|
let l:completeUnimported = go#config#GoplsCompleteUnimported()
|
||||||
|
let l:staticcheck = go#config#GoplsStaticCheck()
|
||||||
|
let l:usePlaceholder = go#config#GoplsUsePlaceholders()
|
||||||
|
let l:tempModfile = go#config#GoplsTempModfile()
|
||||||
|
let l:analyses = go#config#GoplsAnalyses()
|
||||||
|
let l:local = go#config#GoplsLocal()
|
||||||
|
if type(l:local) is v:t_dict
|
||||||
|
let l:local = get(l:local, l:workspace, v:null)
|
||||||
|
endif
|
||||||
|
let l:gofumpt = go#config#GoplsGofumpt()
|
||||||
|
let l:settings = go#config#GoplsSettings()
|
||||||
|
|
||||||
|
if l:deepCompletion isnot v:null
|
||||||
|
if l:deepCompletion
|
||||||
|
let l:config.deepCompletion = v:true
|
||||||
|
else
|
||||||
|
let l:config.deepCompletion = v:false
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:matcher isnot v:null
|
||||||
|
let l:config.matcher = l:matcher
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:completeUnimported isnot v:null
|
||||||
|
if l:completeUnimported
|
||||||
|
let l:config.completeUnimported = v:true
|
||||||
|
else
|
||||||
|
let l:config.completeUnimported = v:false
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:staticcheck isnot v:null
|
||||||
|
if l:staticcheck
|
||||||
|
let l:config.staticcheck = v:true
|
||||||
|
else
|
||||||
|
let l:config.staticcheck = v:false
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:usePlaceholder isnot v:null
|
||||||
|
if l:usePlaceholder
|
||||||
|
let l:config.usePlaceholders = v:true
|
||||||
|
else
|
||||||
|
let l:config.usePlaceholders = v:false
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:tempModfile isnot v:null
|
||||||
|
if l:tempModfile
|
||||||
|
let l:config.tempModfile = v:true
|
||||||
|
else
|
||||||
|
let l:config.tempModfile = v:false
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:analyses isnot v:null
|
||||||
|
let l:config.analyses = l:analyses
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:local isnot v:null
|
||||||
|
let l:config.local = l:local
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:gofumpt isnot v:null
|
||||||
|
if l:gofumpt
|
||||||
|
let l:config.gofumpt = v:true
|
||||||
|
else
|
||||||
|
let l:config.gofumpt = v:false
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:settings isnot v:null
|
||||||
|
let l:config = extend(l:config, l:settings, 'keep')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:result = add(l:result, deepcopy(l:config))
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return l:result
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#ExecuteCommand(cmd, args) abort
|
||||||
|
return {
|
||||||
|
\ 'notification': 0,
|
||||||
|
\ 'method': 'workspace/executeCommand',
|
||||||
|
\ 'params': {
|
||||||
|
\ 'command': a:cmd,
|
||||||
|
\ 'arguments': a:args,
|
||||||
|
\ }
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#ApplyWorkspaceEditResponse(ok) abort
|
||||||
|
return {
|
||||||
|
\ 'applied': a:ok,
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#lsp#message#PrepareRename(file, line, col) abort
|
||||||
|
let l:params = s:textDocumentPositionParams(a:file, a:line, a:col)
|
||||||
|
return {
|
||||||
|
\ 'notification': 0,
|
||||||
|
\ 'method': 'textDocument/prepareRename',
|
||||||
|
\ 'params': l:params,
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:workspaceFolder(key, val) abort
|
||||||
|
return {'uri': go#path#ToURI(a:val), 'name': a:val}
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:position(line, col) abort
|
||||||
|
return {'line': a:line, 'character': a:col}
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:textDocumentPositionParams(fname, line, col) abort
|
||||||
|
return {
|
||||||
|
\ 'textDocument': {
|
||||||
|
\ 'uri': go#path#ToURI(a:fname)
|
||||||
|
\ },
|
||||||
|
\ 'position': s:position(a:line, a:col),
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
97
sources_non_forked/vim-go/autoload/go/lsp_test.vim
Normal file
97
sources_non_forked/vim-go/autoload/go/lsp_test.vim
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
scriptencoding utf-8
|
||||||
|
|
||||||
|
function! Test_GetSimpleTextPosition()
|
||||||
|
call s:getinfo('lsp text position should align with cursor position after ascii only', 'ascii')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Test_GetMultiByteTextPosition()
|
||||||
|
call s:getinfo('lsp text position should align with cursor position after two place of interest symbols ⌘⌘', 'multi-byte')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Test_GetMultipleCodeUnitTextPosition()
|
||||||
|
call s:getinfo('lsp text position should align with cursor position after Deseret Capital Letter Long I 𐐀', 'multi-code-units')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:getinfo(str, name)
|
||||||
|
if !go#util#has_job()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
let g:go_info_mode = 'gopls'
|
||||||
|
|
||||||
|
let l:tmp = gotest#write_file(a:name . '/position/position.go', [
|
||||||
|
\ 'package position',
|
||||||
|
\ '',
|
||||||
|
\ 'func Example() {',
|
||||||
|
\ "\tid := " . '"foo"',
|
||||||
|
\ "\tprintln(" .'"' . a:str . '", id)',
|
||||||
|
\ '}',
|
||||||
|
\ ] )
|
||||||
|
|
||||||
|
let l:expected = 'var id string'
|
||||||
|
let l:actual = go#lsp#GetInfo()
|
||||||
|
call assert_equal(l:expected, l:actual)
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
unlet g:go_info_mode
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
func! Test_Format() abort
|
||||||
|
try
|
||||||
|
let expected = join(readfile("test-fixtures/lsp/fmt/format_golden.go"), "\n")
|
||||||
|
let l:tmp = gotest#load_fixture('lsp/fmt/format.go')
|
||||||
|
|
||||||
|
call go#lsp#Format()
|
||||||
|
|
||||||
|
" this should now contain the formatted code
|
||||||
|
let actual = join(go#util#GetLines(), "\n")
|
||||||
|
|
||||||
|
call assert_equal(expected, actual)
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_Format_SingleNewline() abort
|
||||||
|
try
|
||||||
|
let expected = join(readfile("test-fixtures/lsp/fmt/format_golden.go"), "\n")
|
||||||
|
let l:tmp = gotest#load_fixture('lsp/fmt/newline.go')
|
||||||
|
|
||||||
|
call go#lsp#Format()
|
||||||
|
|
||||||
|
" this should now contain the formatted code
|
||||||
|
let actual = join(go#util#GetLines(), "\n")
|
||||||
|
|
||||||
|
call assert_equal(expected, actual)
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_Imports() abort
|
||||||
|
try
|
||||||
|
let expected = join(readfile("test-fixtures/lsp/imports/imports_golden.go"), "\n")
|
||||||
|
let l:tmp = gotest#load_fixture('lsp/imports/imports.go')
|
||||||
|
|
||||||
|
call go#lsp#Imports()
|
||||||
|
|
||||||
|
" this should now contain the expected imports code
|
||||||
|
let actual = join(go#util#GetLines(), "\n")
|
||||||
|
|
||||||
|
call assert_equal(expected, actual)
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
147
sources_non_forked/vim-go/autoload/go/mod.vim
Normal file
147
sources_non_forked/vim-go/autoload/go/mod.vim
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
let s:go_major_version = ""
|
||||||
|
|
||||||
|
function! go#mod#Format() abort
|
||||||
|
" go mod only exists in `v1.11`
|
||||||
|
if empty(s:go_major_version)
|
||||||
|
let tokens = matchlist(go#util#Exec(['go', 'version']), '\d\+.\(\d\+\)\(\.\d\+\)\? ')
|
||||||
|
if len(tokens) > 0
|
||||||
|
let s:go_major_version = str2nr(tokens[1])
|
||||||
|
else
|
||||||
|
let s:go_major_version = ""
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !empty(s:go_major_version) && s:go_major_version < "11"
|
||||||
|
call go#util#EchoError("Go v1.11 is required to format go.mod file")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let fname = fnamemodify(expand("%"), ':p:gs?\\?/?')
|
||||||
|
|
||||||
|
" Save cursor position and many other things.
|
||||||
|
let l:curw = winsaveview()
|
||||||
|
|
||||||
|
" Write current unsaved buffer to a temp file
|
||||||
|
let l:tmpname = tempname() . '.mod'
|
||||||
|
call writefile(go#util#GetLines(), l:tmpname)
|
||||||
|
if go#util#IsWin()
|
||||||
|
let l:tmpname = tr(l:tmpname, '\', '/')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let current_col = col('.')
|
||||||
|
let l:args = ['go', 'mod', 'edit', '--fmt', l:tmpname]
|
||||||
|
let [l:out, l:err] = go#util#Exec(l:args)
|
||||||
|
let diff_offset = len(readfile(l:tmpname)) - line('$')
|
||||||
|
|
||||||
|
if l:err == 0
|
||||||
|
call go#mod#update_file(l:tmpname, fname)
|
||||||
|
else
|
||||||
|
let errors = s:parse_errors(fname, l:out)
|
||||||
|
call s:show_errors(errors)
|
||||||
|
endif
|
||||||
|
|
||||||
|
" We didn't use the temp file, so clean up
|
||||||
|
call delete(l:tmpname)
|
||||||
|
|
||||||
|
" Restore our cursor/windows positions.
|
||||||
|
call winrestview(l:curw)
|
||||||
|
|
||||||
|
" be smart and jump to the line the new statement was added/removed
|
||||||
|
call cursor(line('.') + diff_offset, current_col)
|
||||||
|
|
||||||
|
" Syntax highlighting breaks less often.
|
||||||
|
syntax sync fromstart
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" update_file updates the target file with the given formatted source
|
||||||
|
function! go#mod#update_file(source, target)
|
||||||
|
" remove undo point caused via BufWritePre
|
||||||
|
try | silent undojoin | catch | endtry
|
||||||
|
|
||||||
|
let old_fileformat = &fileformat
|
||||||
|
if exists("*getfperm")
|
||||||
|
" save file permissions
|
||||||
|
let original_fperm = getfperm(a:target)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call rename(a:source, a:target)
|
||||||
|
|
||||||
|
" restore file permissions
|
||||||
|
if exists("*setfperm") && original_fperm != ''
|
||||||
|
call setfperm(a:target , original_fperm)
|
||||||
|
endif
|
||||||
|
|
||||||
|
" reload buffer to reflect latest changes
|
||||||
|
silent edit!
|
||||||
|
|
||||||
|
let &fileformat = old_fileformat
|
||||||
|
let &syntax = &syntax
|
||||||
|
|
||||||
|
let l:listtype = go#list#Type("GoModFmt")
|
||||||
|
|
||||||
|
" clean up previous list
|
||||||
|
if l:listtype == "quickfix"
|
||||||
|
let l:list_title = getqflist({'title': 1})
|
||||||
|
else
|
||||||
|
let l:list_title = getloclist(0, {'title': 1})
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(l:list_title, "title") && l:list_title['title'] == "Format"
|
||||||
|
call go#list#Clean(l:listtype)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" parse_errors parses the given errors and returns a list of parsed errors
|
||||||
|
function! s:parse_errors(filename, content) abort
|
||||||
|
let splitted = split(a:content, '\n')
|
||||||
|
|
||||||
|
" list of errors to be put into location list
|
||||||
|
let errors = []
|
||||||
|
for line in splitted
|
||||||
|
let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\s*\(.*\)')
|
||||||
|
if !empty(tokens)
|
||||||
|
call add(errors,{
|
||||||
|
\"filename": a:filename,
|
||||||
|
\"lnum": tokens[2],
|
||||||
|
\"text": tokens[3],
|
||||||
|
\ })
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return errors
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" show_errors opens a location list and shows the given errors. If the given
|
||||||
|
" errors is empty, it closes the the location list
|
||||||
|
function! s:show_errors(errors) abort
|
||||||
|
let l:listtype = go#list#Type("GoModFmt")
|
||||||
|
if !empty(a:errors)
|
||||||
|
call go#list#Populate(l:listtype, a:errors, 'Format')
|
||||||
|
call go#util#EchoError("GoModFmt returned error")
|
||||||
|
endif
|
||||||
|
|
||||||
|
" this closes the window if there are no errors or it opens
|
||||||
|
" it if there is any
|
||||||
|
call go#list#Window(l:listtype, len(a:errors))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#mod#ToggleModFmtAutoSave() abort
|
||||||
|
if go#config#ModFmtAutosave()
|
||||||
|
call go#config#SetModFmtAutosave(0)
|
||||||
|
call go#util#EchoProgress("auto mod fmt disabled")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
call go#config#SetModFmtAutosave(1)
|
||||||
|
call go#util#EchoProgress("auto mod fmt enabled")
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
346
sources_non_forked/vim-go/autoload/go/package.vim
Normal file
346
sources_non_forked/vim-go/autoload/go/package.vim
Normal file
|
@ -0,0 +1,346 @@
|
||||||
|
" Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
" Use of this source code is governed by a BSD-style
|
||||||
|
" license that can be found in the LICENSE file.
|
||||||
|
"
|
||||||
|
" This file provides a utility function that performs auto-completion of
|
||||||
|
" package names, for use by other commands.
|
||||||
|
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
let s:goos = $GOOS
|
||||||
|
let s:goarch = $GOARCH
|
||||||
|
|
||||||
|
if len(s:goos) == 0
|
||||||
|
if exists('g:golang_goos')
|
||||||
|
let s:goos = g:golang_goos
|
||||||
|
elseif has('win32') || has('win64')
|
||||||
|
let s:goos = 'windows'
|
||||||
|
elseif has('macunix')
|
||||||
|
let s:goos = 'darwin'
|
||||||
|
else
|
||||||
|
let s:goos = '*'
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if len(s:goarch) == 0
|
||||||
|
if exists('g:golang_goarch')
|
||||||
|
let s:goarch = g:golang_goarch
|
||||||
|
else
|
||||||
|
let s:goarch = '*'
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
function! s:paths() abort
|
||||||
|
let dirs = []
|
||||||
|
|
||||||
|
if !exists("s:goroot")
|
||||||
|
if executable('go')
|
||||||
|
let s:goroot = go#util#env("goroot")
|
||||||
|
if go#util#ShellError() != 0
|
||||||
|
call go#util#EchoError('`go env GOROOT` failed')
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
let s:goroot = $GOROOT
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if len(s:goroot) != 0 && isdirectory(s:goroot)
|
||||||
|
let dirs += [s:goroot]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let workspaces = split(go#path#Default(), go#util#PathListSep())
|
||||||
|
if workspaces != []
|
||||||
|
let dirs += workspaces
|
||||||
|
endif
|
||||||
|
|
||||||
|
return dirs
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:module() abort
|
||||||
|
let [l:out, l:err] = go#util#ExecInDir(['go', 'list', '-m', '-f', '{{.Dir}}'])
|
||||||
|
if l:err != 0
|
||||||
|
return {}
|
||||||
|
endif
|
||||||
|
let l:dir = split(l:out, '\n')[0]
|
||||||
|
|
||||||
|
let [l:out, l:err] = go#util#ExecInDir(['go', 'list', '-m', '-f', '{{.Path}}'])
|
||||||
|
if l:err != 0
|
||||||
|
return {}
|
||||||
|
endif
|
||||||
|
let l:path = split(l:out, '\n')[0]
|
||||||
|
|
||||||
|
return {'dir': l:dir, 'path': l:path}
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:vendordirs() abort
|
||||||
|
let l:vendorsuffix = go#util#PathSep() . 'vendor'
|
||||||
|
let l:module = s:module()
|
||||||
|
if empty(l:module)
|
||||||
|
let [l:root, l:err] = go#util#ExecInDir(['go', 'list', '-f', '{{.Root}}'])
|
||||||
|
if l:err != 0
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
if empty(l:root)
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:root = split(l:root, '\n')[0] . go#util#PathSep() . 'src'
|
||||||
|
|
||||||
|
let [l:dir, l:err] = go#util#ExecInDir(['go', 'list', '-f', '{{.Dir}}'])
|
||||||
|
if l:err != 0
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
let l:dir = split(l:dir, '\n')[0]
|
||||||
|
|
||||||
|
let l:vendordirs = []
|
||||||
|
while l:dir != l:root
|
||||||
|
let l:vendordir = l:dir . l:vendorsuffix
|
||||||
|
if isdirectory(l:vendordir)
|
||||||
|
let l:vendordirs = add(l:vendordirs, l:vendordir)
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:dir = fnamemodify(l:dir, ':h')
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
return l:vendordirs
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:vendordir = l:module.dir . l:vendorsuffix
|
||||||
|
if !isdirectory(l:vendordir)
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
return [l:vendordir]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
let s:import_paths = {}
|
||||||
|
" ImportPath returns the import path of the package for current buffer. It
|
||||||
|
" returns -1 if the import path cannot be determined.
|
||||||
|
function! go#package#ImportPath() abort
|
||||||
|
let l:dir = expand("%:p:h")
|
||||||
|
if has_key(s:import_paths, dir)
|
||||||
|
return s:import_paths[l:dir]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:importpath = go#package#FromPath(l:dir)
|
||||||
|
if type(l:importpath) == type(0)
|
||||||
|
return -1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let s:import_paths[l:dir] = l:importpath
|
||||||
|
|
||||||
|
return l:importpath
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
let s:in_gopath = {}
|
||||||
|
" InGOPATH returns TRUE when the package of the current buffer is within
|
||||||
|
" GOPATH.
|
||||||
|
function! go#package#InGOPATH() abort
|
||||||
|
let l:dir = expand("%:p:h")
|
||||||
|
if has_key(s:in_gopath, dir)
|
||||||
|
return s:in_gopath[l:dir][0] !=# '_'
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
" turn off module support so that `go list` will report the package name
|
||||||
|
" with a leading '_' when the current buffer is not within GOPATH.
|
||||||
|
let Restore_modules = go#util#SetEnv('GO111MODULE', 'off')
|
||||||
|
let [l:out, l:err] = go#util#ExecInDir(['go', 'list'])
|
||||||
|
if l:err != 0
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:importpath = split(l:out, '\n')[0]
|
||||||
|
if len(l:importpath) > 0
|
||||||
|
let s:in_gopath[l:dir] = l:importpath
|
||||||
|
endif
|
||||||
|
finally
|
||||||
|
call call(Restore_modules, [])
|
||||||
|
endtry
|
||||||
|
|
||||||
|
return len(l:importpath) > 0 && l:importpath[0] !=# '_'
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" go#package#FromPath returns the import path of arg. -1 is returned when arg
|
||||||
|
" does not specify a package. -2 is returned when arg is a relative path
|
||||||
|
" outside of GOPATH, not in a module, and not below the current working
|
||||||
|
" directory. A relative path is returned when in a null module at or below the
|
||||||
|
" current working directory..
|
||||||
|
function! go#package#FromPath(arg) abort
|
||||||
|
let l:path = fnamemodify(a:arg, ':p')
|
||||||
|
if !isdirectory(l:path)
|
||||||
|
let l:path = fnamemodify(l:path, ':h')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:dir = go#util#Chdir(l:path)
|
||||||
|
try
|
||||||
|
if glob("*.go") == ""
|
||||||
|
" There's no Go code in this directory. We might be in a module directory
|
||||||
|
" which doesn't have any code at this level. To avoid `go list` making a
|
||||||
|
" bunch of HTTP requests to fetch dependencies, short-circuit `go list`
|
||||||
|
" and return -1 immediately.
|
||||||
|
if !empty(s:module())
|
||||||
|
return -1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
let [l:out, l:err] = go#util#Exec(['go', 'list'])
|
||||||
|
if l:err != 0
|
||||||
|
return -1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:importpath = split(l:out, '\n')[0]
|
||||||
|
finally
|
||||||
|
call go#util#Chdir(l:dir)
|
||||||
|
endtry
|
||||||
|
|
||||||
|
" go list returns '_CURRENTDIRECTORY' if the directory is in a null module
|
||||||
|
" (i.e. neither in GOPATH nor in a module). Return a relative import path
|
||||||
|
" if possible or an error if that is the case.
|
||||||
|
if l:importpath[0] ==# '_'
|
||||||
|
let l:relativeimportpath = fnamemodify(l:importpath[1:], ':.')
|
||||||
|
if go#util#IsWin()
|
||||||
|
let l:relativeimportpath = substitute(l:relativeimportpath, '\\', '/', 'g')
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:relativeimportpath == l:importpath[1:]
|
||||||
|
return '.'
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:relativeimportpath[0] == '/'
|
||||||
|
return -2
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:importpath= printf('./%s', l:relativeimportpath)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:importpath
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#package#CompleteMembers(package, member) abort
|
||||||
|
let [l:content, l:err] = go#util#Exec(['go', 'doc', a:package])
|
||||||
|
if l:err || !len(content)
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
|
||||||
|
let lines = filter(split(content, "\n"),"v:val !~ '^\\s\\+$'")
|
||||||
|
try
|
||||||
|
let mx1 = '^\s\+\(\S+\)\s\+=\s\+.*'
|
||||||
|
let mx2 = '^\%(const\|var\|type\|func\) \([A-Z][^ (]\+\).*'
|
||||||
|
let candidates = map(filter(copy(lines), 'v:val =~ mx1'),
|
||||||
|
\ 'substitute(v:val, mx1, "\\1", "")')
|
||||||
|
\ + map(filter(copy(lines), 'v:val =~ mx2'),
|
||||||
|
\ 'substitute(v:val, mx2, "\\1", "")')
|
||||||
|
return filter(candidates, '!stridx(v:val, a:member)')
|
||||||
|
catch
|
||||||
|
return []
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#package#Complete(ArgLead, CmdLine, CursorPos) abort
|
||||||
|
let words = split(a:CmdLine, '\s\+', 1)
|
||||||
|
|
||||||
|
" do not complete package members for these commands
|
||||||
|
let neglect_commands = ["GoImportAs", "GoGuruScope"]
|
||||||
|
|
||||||
|
if len(words) > 2 && index(neglect_commands, words[0]) == -1
|
||||||
|
" Complete package members
|
||||||
|
return go#package#CompleteMembers(words[1], words[2])
|
||||||
|
endif
|
||||||
|
|
||||||
|
let dirs = s:paths()
|
||||||
|
let module = s:module()
|
||||||
|
|
||||||
|
if len(dirs) == 0 && empty(module)
|
||||||
|
" should not happen
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
|
||||||
|
let vendordirs = s:vendordirs()
|
||||||
|
|
||||||
|
let l:modcache = go#util#env('gomodcache')
|
||||||
|
|
||||||
|
let ret = {}
|
||||||
|
for dir in dirs
|
||||||
|
" this may expand to multiple lines
|
||||||
|
let root = split(expand(dir . '/pkg/' . s:goos . '_' . s:goarch), "\n")
|
||||||
|
if l:modcache != ''
|
||||||
|
let root = add(root, l:modcache)
|
||||||
|
else
|
||||||
|
let root = add(root, expand(dir . '/pkg/mod'))
|
||||||
|
endif
|
||||||
|
let root = add(root, expand(dir . '/src'), )
|
||||||
|
let root = extend(root, vendordirs)
|
||||||
|
let root = add(root, module)
|
||||||
|
for item in root
|
||||||
|
" item may be a dictionary when operating in a module.
|
||||||
|
if type(item) == type({})
|
||||||
|
if empty(item)
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
let dir = item.dir
|
||||||
|
let path = item.path
|
||||||
|
else
|
||||||
|
let dir = item
|
||||||
|
let path = item
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !empty(module) && dir ==# module.dir
|
||||||
|
if stridx(a:ArgLead, module.path) == 0
|
||||||
|
if len(a:ArgLead) != len(module.path)
|
||||||
|
let glob = globpath(module.dir, substitute(a:ArgLead, module.path . '/\?', '', '').'*')
|
||||||
|
else
|
||||||
|
let glob = module.dir
|
||||||
|
endif
|
||||||
|
elseif stridx(module.path, a:ArgLead) == 0 && stridx(module.path, '/', len(a:ArgLead)) < 0
|
||||||
|
" use the module directory when module.path begins wih a:ArgLead and
|
||||||
|
" module.path does not have any path segments after a:ArgLead.
|
||||||
|
let glob = module.dir
|
||||||
|
else
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
let glob = globpath(dir, a:ArgLead.'*')
|
||||||
|
endif
|
||||||
|
for candidate in split(glob)
|
||||||
|
if isdirectory(candidate)
|
||||||
|
" TODO(bc): use wildignore instead of filtering out vendor
|
||||||
|
" directories manually?
|
||||||
|
if fnamemodify(candidate, ':t') == 'vendor'
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
" if path contains version info, strip it out
|
||||||
|
let vidx = strridx(candidate, '@')
|
||||||
|
if vidx >= 0
|
||||||
|
let candidate = strpart(candidate, 0, vidx)
|
||||||
|
endif
|
||||||
|
let candidate .= '/'
|
||||||
|
elseif candidate !~ '\.a$'
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
if dir !=# path
|
||||||
|
let candidate = substitute(candidate, '^' . dir, path, 'g')
|
||||||
|
else
|
||||||
|
let candidate = candidate[len(dir)+1:]
|
||||||
|
endif
|
||||||
|
" replace a backslash with a forward slash and drop .a suffixes
|
||||||
|
let candidate = substitute(substitute(candidate, '[\\]', '/', 'g'),
|
||||||
|
\ '\.a$', '', 'g')
|
||||||
|
|
||||||
|
" without this the result can have duplicates in form of
|
||||||
|
" 'encoding/json' and '/encoding/json/'
|
||||||
|
let candidate = go#util#StripPathSep(candidate)
|
||||||
|
|
||||||
|
let ret[candidate] = candidate
|
||||||
|
endfor
|
||||||
|
endfor
|
||||||
|
endfor
|
||||||
|
return sort(keys(ret))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
62
sources_non_forked/vim-go/autoload/go/package_test.vim
Normal file
62
sources_non_forked/vim-go/autoload/go/package_test.vim
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
func! Test_Complete_GOPATH_simple() abort
|
||||||
|
let $GOPATH = fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/package'
|
||||||
|
silent exe 'edit ' . $GOPATH . '/src/package/package.go'
|
||||||
|
call s:complete('package', ['package'])
|
||||||
|
call delete(printf('%s/pkg', $GOPATH), 'rf')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_Complete_Module_simple() abort
|
||||||
|
silent exe 'edit ' . fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/package/src/package/package.go'
|
||||||
|
call s:complete('package', ['package'])
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_Complete_GOPATH_subdirs() abort
|
||||||
|
let $GOPATH = fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/package'
|
||||||
|
silent exe 'edit ' . $GOPATH . '/src/package/package.go'
|
||||||
|
call s:complete('package/', ['package/bar', 'package/baz'])
|
||||||
|
call delete(printf('%s/pkg', $GOPATH), 'rf')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_Complete_Module_subdirs() abort
|
||||||
|
silent exe 'edit ' . fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/package/src/package/package.go'
|
||||||
|
call s:complete('package/', ['package/bar', 'package/baz'])
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_Complete_GOPATH_baronly() abort
|
||||||
|
let $GOPATH = fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/package'
|
||||||
|
silent exe 'edit ' . $GOPATH . '/src/package/package.go'
|
||||||
|
call s:complete('package/bar', ['package/bar'])
|
||||||
|
call delete(printf('%s/pkg', $GOPATH), 'rf')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_Complete_Module_baronly() abort
|
||||||
|
silent exe 'edit ' . fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/package/src/package/package.go'
|
||||||
|
call s:complete('package/bar', ['package/bar'])
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_Complete_GOPATH_vendor() abort
|
||||||
|
let $GOPATH = fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/package'
|
||||||
|
silent exe 'edit ' . $GOPATH . '/src/package/package.go'
|
||||||
|
call s:complete('foo', ['foo'])
|
||||||
|
call delete(printf('%s/pkg', $GOPATH), 'rf')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_Complete_Module_vendor() abort
|
||||||
|
silent exe 'edit ' . fnameescape(fnamemodify(getcwd(), ':p')) . 'test-fixtures/package/src/package/package.go'
|
||||||
|
call s:complete('foo', ['foo'])
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! s:complete(arglead, expected) abort
|
||||||
|
let l:candidates = go#package#Complete(a:arglead, '', 1)
|
||||||
|
call assert_equal(a:expected, l:candidates)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
195
sources_non_forked/vim-go/autoload/go/path.vim
Normal file
195
sources_non_forked/vim-go/autoload/go/path.vim
Normal file
|
@ -0,0 +1,195 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
" initial_go_path is used to store the initial GOPATH that was set when Vim
|
||||||
|
" was started. It's used with :GoPathClear to restore the GOPATH when the user
|
||||||
|
" changed it explicitly via :GoPath. Initially it's empty. It's being set when
|
||||||
|
" :GoPath is used
|
||||||
|
let s:initial_go_path = ""
|
||||||
|
|
||||||
|
" GoPath sets or echos the current GOPATH. If no arguments are passed it
|
||||||
|
" echoes the current GOPATH, if an argument is passed it replaces the current
|
||||||
|
" GOPATH with it. If two double quotes are passed (the empty string in go),
|
||||||
|
" it'll clear the GOPATH and will restore to the initial GOPATH.
|
||||||
|
function! go#path#GoPath(...) abort
|
||||||
|
" no argument, show GOPATH
|
||||||
|
if len(a:000) == 0
|
||||||
|
echo go#path#Default()
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" we have an argument, replace GOPATH
|
||||||
|
" clears the current manually set GOPATH and restores it to the
|
||||||
|
" initial GOPATH, which was set when Vim was started.
|
||||||
|
if len(a:000) == 1 && a:1 == '""'
|
||||||
|
if !empty(s:initial_go_path)
|
||||||
|
let $GOPATH = s:initial_go_path
|
||||||
|
let s:initial_go_path = ""
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#util#EchoInfo("GOPATH restored to ". $GOPATH)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#util#EchoInfo("GOPATH changed to ". a:1)
|
||||||
|
let s:initial_go_path = $GOPATH
|
||||||
|
let $GOPATH = a:1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Default returns the default GOPATH. If GOPATH is not set, it uses the
|
||||||
|
" default GOPATH set starting with Go 1.8. This GOPATH can be retrieved via
|
||||||
|
" 'go env GOPATH'
|
||||||
|
function! go#path#Default() abort
|
||||||
|
if $GOPATH == ""
|
||||||
|
" use default GOPATH via go env
|
||||||
|
return go#util#env("gopath")
|
||||||
|
endif
|
||||||
|
|
||||||
|
return $GOPATH
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" s:HasPath checks whether the given path exists in GOPATH environment variable
|
||||||
|
" or not
|
||||||
|
function! s:HasPath(path) abort
|
||||||
|
let go_paths = split(go#path#Default(), go#util#PathListSep())
|
||||||
|
let last_char = strlen(a:path) - 1
|
||||||
|
|
||||||
|
" check cases of '/foo/bar/' and '/foo/bar'
|
||||||
|
if a:path[last_char] == go#util#PathSep()
|
||||||
|
let withSep = a:path
|
||||||
|
let noSep = strpart(a:path, 0, last_char)
|
||||||
|
else
|
||||||
|
let withSep = a:path . go#util#PathSep()
|
||||||
|
let noSep = a:path
|
||||||
|
endif
|
||||||
|
|
||||||
|
let hasA = index(go_paths, withSep) != -1
|
||||||
|
let hasB = index(go_paths, noSep) != -1
|
||||||
|
return hasA || hasB
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" BinPath returns the binary path of installed go tools.
|
||||||
|
function! go#path#BinPath() abort
|
||||||
|
let l:bin_path = go#config#BinPath()
|
||||||
|
if l:bin_path isnot ""
|
||||||
|
return l:bin_path
|
||||||
|
endif
|
||||||
|
|
||||||
|
" check if our global custom path is set, if not check if GOBIN is set so
|
||||||
|
" we can use it, otherwise use default GOPATH
|
||||||
|
let l:bin_path = go#util#env('gobin')
|
||||||
|
if l:bin_path isnot ''
|
||||||
|
let l:bin_path = $GOBIN
|
||||||
|
else
|
||||||
|
let l:go_paths = split(go#path#Default(), go#util#PathListSep())
|
||||||
|
if len(l:go_paths) == 0
|
||||||
|
return '' "nothing found
|
||||||
|
endif
|
||||||
|
let l:bin_path = expand(l:go_paths[0] . '/bin/')
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:bin_path
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" CheckBinPath checks whether the given binary exists or not and returns the
|
||||||
|
" path of the binary, respecting the go_bin_path and go_search_bin_path_first
|
||||||
|
" settings. It returns an empty string if the binary doesn't exist.
|
||||||
|
function! go#path#CheckBinPath(binpath) abort
|
||||||
|
" remove whitespaces if user applied something like 'goimports '
|
||||||
|
let binpath = substitute(a:binpath, '^\s*\(.\{-}\)\s*$', '\1', '')
|
||||||
|
|
||||||
|
" save original path
|
||||||
|
let old_path = $PATH
|
||||||
|
|
||||||
|
" check if we have an appropriate bin_path
|
||||||
|
let go_bin_path = go#path#BinPath()
|
||||||
|
if !empty(go_bin_path)
|
||||||
|
" append our GOBIN and GOPATH paths and be sure they can be found there...
|
||||||
|
" let us search in our GOBIN and GOPATH paths
|
||||||
|
" respect the ordering specified by go_search_bin_path_first
|
||||||
|
if go#config#SearchBinPathFirst()
|
||||||
|
let $PATH = go_bin_path . go#util#PathListSep() . $PATH
|
||||||
|
else
|
||||||
|
let $PATH = $PATH . go#util#PathListSep() . go_bin_path
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
" if it's in PATH just return it
|
||||||
|
if executable(binpath)
|
||||||
|
if exists('*exepath')
|
||||||
|
let binpath = exepath(binpath)
|
||||||
|
endif
|
||||||
|
let $PATH = old_path
|
||||||
|
|
||||||
|
if go#util#IsUsingCygwinShell() == 1
|
||||||
|
return s:CygwinPath(binpath)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return binpath
|
||||||
|
endif
|
||||||
|
|
||||||
|
" just get the basename
|
||||||
|
let basename = fnamemodify(binpath, ":t")
|
||||||
|
if !executable(basename)
|
||||||
|
call go#util#EchoError(printf("could not find '%s'. Run :GoInstallBinaries to fix it", basename))
|
||||||
|
|
||||||
|
" restore back!
|
||||||
|
let $PATH = old_path
|
||||||
|
return ""
|
||||||
|
endif
|
||||||
|
|
||||||
|
let $PATH = old_path
|
||||||
|
|
||||||
|
if go#util#IsUsingCygwinShell() == 1
|
||||||
|
return s:CygwinPath(a:binpath)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return go_bin_path . go#util#PathSep() . basename
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:CygwinPath(path)
|
||||||
|
return substitute(a:path, '\\', '/', "g")
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" go#path#ToURI converts path to a file URI. path should be an absolute path.
|
||||||
|
" Relative paths cannot be properly converted to a URI; when path is a
|
||||||
|
" relative path, the file scheme will not be prepended.
|
||||||
|
function! go#path#ToURI(path)
|
||||||
|
let l:absolute = !go#util#IsWin() && a:path[0] is# '/'
|
||||||
|
let l:prefix = ''
|
||||||
|
let l:path = a:path
|
||||||
|
|
||||||
|
if go#util#IsWin() && l:path[1:2] is# ':\'
|
||||||
|
let l:absolute = 1
|
||||||
|
let l:prefix = '/' . l:path[0:1]
|
||||||
|
let l:path = l:path[2:]
|
||||||
|
endif
|
||||||
|
|
||||||
|
return substitute(
|
||||||
|
\ (l:absolute ? 'file://' : '') . l:prefix . go#uri#EncodePath(l:path),
|
||||||
|
\ '\\',
|
||||||
|
\ '/',
|
||||||
|
\ 'g',
|
||||||
|
\)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#path#FromURI(uri) abort
|
||||||
|
let l:i = len('file://')
|
||||||
|
let l:encoded_path = a:uri[: l:i - 1] is# 'file://' ? a:uri[l:i :] : a:uri
|
||||||
|
|
||||||
|
let l:path = go#uri#Decode(l:encoded_path)
|
||||||
|
|
||||||
|
" If the path is like /C:/foo/bar, it should be C:\foo\bar instead.
|
||||||
|
if go#util#IsWin() && l:path =~# '^/[a-zA-Z]:'
|
||||||
|
let l:path = substitute(l:path[1:], '/', '\\', 'g')
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:path
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
78
sources_non_forked/vim-go/autoload/go/play.vim
Normal file
78
sources_non_forked/vim-go/autoload/go/play.vim
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
function! go#play#Share(count, line1, line2) abort
|
||||||
|
if !executable('curl')
|
||||||
|
call go#util#EchoError('cannot share: curl cannot be found')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let content = join(getline(a:line1, a:line2), "\n")
|
||||||
|
let share_file = tempname()
|
||||||
|
call writefile(split(content, "\n"), share_file, "b")
|
||||||
|
|
||||||
|
let l:cmd = ['curl', '-s',
|
||||||
|
\ '-H', 'Content-Type: text/plain; charset=utf-8',
|
||||||
|
\ '-X', 'POST', 'https://go.dev/_/share',
|
||||||
|
\ '--data-binary', '@' . l:share_file]
|
||||||
|
let [l:snippet_id, l:err] = go#util#Exec(l:cmd)
|
||||||
|
|
||||||
|
" we can remove the temp file because it's now posted.
|
||||||
|
call delete(share_file)
|
||||||
|
|
||||||
|
if l:err != 0
|
||||||
|
call go#util#EchoError(['A error has occurred. Run this command to see what the problem is:', go#util#Shelljoin(l:cmd)])
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let url = printf("https://go.dev/play/p/%s", snippet_id)
|
||||||
|
|
||||||
|
" copy to clipboard
|
||||||
|
if has('unix') && !has('xterm_clipboard') && !has('clipboard')
|
||||||
|
let @" = url
|
||||||
|
else
|
||||||
|
let @+ = url
|
||||||
|
endif
|
||||||
|
|
||||||
|
if go#config#PlayOpenBrowser()
|
||||||
|
call go#util#OpenBrowser(url)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#util#EchoInfo('snippet uploaded: ' . url)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
function! s:get_visual_content() abort
|
||||||
|
let save_regcont = @"
|
||||||
|
let save_regtype = getregtype('"')
|
||||||
|
silent! normal! gvy
|
||||||
|
let content = @"
|
||||||
|
call setreg('"', save_regcont, save_regtype)
|
||||||
|
return content
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" modified version of
|
||||||
|
" http://stackoverflow.com/questions/1533565/how-to-get-visually-selected-text-in-vimscript
|
||||||
|
" another function that returns the content of visual selection, it's not used
|
||||||
|
" but might be useful in the future
|
||||||
|
function! s:get_visual_selection() abort
|
||||||
|
let [lnum1, col1] = getpos("'<")[1:2]
|
||||||
|
let [lnum2, col2] = getpos("'>")[1:2]
|
||||||
|
|
||||||
|
" check if the the visual mode is used before
|
||||||
|
if lnum1 == 0 || lnum2 == 0 || col1 == 0 || col2 == 0
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let lines = getline(lnum1, lnum2)
|
||||||
|
let lines[-1] = lines[-1][: col2 - (&selection == 'inclusive' ? 1 : 2)]
|
||||||
|
let lines[0] = lines[0][col1 - 1:]
|
||||||
|
return join(lines, "\n")
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
58
sources_non_forked/vim-go/autoload/go/promise.vim
Normal file
58
sources_non_forked/vim-go/autoload/go/promise.vim
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
scriptencoding utf-8
|
||||||
|
|
||||||
|
" New returns a promise. A promise's primary purpose is to make async jobs
|
||||||
|
" synchronous by awaiting fn.
|
||||||
|
"
|
||||||
|
" A promise is a dictionary with two keys:
|
||||||
|
" 'wrapper':
|
||||||
|
" A function that wraps fn. It can be used in place of fn.
|
||||||
|
" 'await':
|
||||||
|
" A function that waits for wrapper to be called and returns the value
|
||||||
|
" returned by fn. Returns default if timeout expires.
|
||||||
|
function! go#promise#New(fn, timeout, default) abort
|
||||||
|
let l:state = {}
|
||||||
|
|
||||||
|
" explicitly bind to state so that within l:promise's methods, self will
|
||||||
|
" always refer to state. See :help Partial for more information.
|
||||||
|
return {
|
||||||
|
\ 'wrapper': function('s:wrapper', [a:fn, a:default], l:state),
|
||||||
|
\ 'await': function('s:await', [a:timeout, a:default], l:state),
|
||||||
|
\ }
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:wrapper(fn, default, ...) dict
|
||||||
|
try
|
||||||
|
let self.retval = call(a:fn, a:000)
|
||||||
|
catch
|
||||||
|
let self.retval = substitute(v:exception, '^Vim', '', '')
|
||||||
|
let self.exception = 1
|
||||||
|
endtry
|
||||||
|
return self.retval
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:await(timeout, default) dict
|
||||||
|
let l:timer = timer_start(a:timeout, function('s:setretval', [a:default], self))
|
||||||
|
while !has_key(self, 'retval')
|
||||||
|
sleep 50m
|
||||||
|
endwhile
|
||||||
|
call timer_stop(l:timer)
|
||||||
|
|
||||||
|
if get(self, 'exception', 0)
|
||||||
|
throw self.retval
|
||||||
|
endif
|
||||||
|
return self.retval
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:setretval(val, timer) dict
|
||||||
|
let self.retval = a:val
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
41
sources_non_forked/vim-go/autoload/go/promise_test.vim
Normal file
41
sources_non_forked/vim-go/autoload/go/promise_test.vim
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
func! Test_PromiseNew() abort
|
||||||
|
let l:sut = go#promise#New(function('s:work', []), 100, -1)
|
||||||
|
call assert_true(has_key(l:sut, 'wrapper'))
|
||||||
|
call assert_true(has_key(l:sut, 'await'))
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_PromiseAwait() abort
|
||||||
|
let l:expected = 1
|
||||||
|
let l:default = -1
|
||||||
|
let l:sut = go#promise#New(function('s:work', [l:expected]), 100, l:default)
|
||||||
|
|
||||||
|
call timer_start(10, l:sut.wrapper)
|
||||||
|
|
||||||
|
let l:actual = call(l:sut.await, [])
|
||||||
|
call assert_equal(l:expected, l:actual)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_PromiseAwait_Timeout() abort
|
||||||
|
let l:desired = 1
|
||||||
|
let l:expected = -1
|
||||||
|
let l:sut = go#promise#New(function('s:work', [l:desired]), 10, l:expected)
|
||||||
|
|
||||||
|
call timer_start(100, l:sut.wrapper)
|
||||||
|
|
||||||
|
let l:actual = call(l:sut.await, [])
|
||||||
|
call assert_equal(l:expected, l:actual)
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! s:work(val, timer)
|
||||||
|
return a:val
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
44
sources_non_forked/vim-go/autoload/go/referrers.vim
Normal file
44
sources_non_forked/vim-go/autoload/go/referrers.vim
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
function! go#referrers#Referrers(selected) abort
|
||||||
|
let l:mode = go#config#ReferrersMode()
|
||||||
|
if l:mode == 'guru'
|
||||||
|
call go#guru#Referrers(a:selected)
|
||||||
|
return
|
||||||
|
elseif l:mode == 'gopls'
|
||||||
|
if !go#config#GoplsEnabled()
|
||||||
|
call go#util#EchoError("go_referrers_mode is 'gopls', but gopls is disabled")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let [l:line, l:col] = getpos('.')[1:2]
|
||||||
|
let [l:line, l:col] = go#lsp#lsp#Position(l:line, l:col)
|
||||||
|
let l:fname = expand('%:p')
|
||||||
|
call go#lsp#Referrers(l:fname, l:line, l:col, funcref('s:parse_output'))
|
||||||
|
return
|
||||||
|
else
|
||||||
|
call go#util#EchoWarning('unknown value for g:go_referrers_mode')
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" This uses Vim's errorformat to parse the output and put it into a quickfix
|
||||||
|
" or locationlist.
|
||||||
|
function! s:parse_output(exit_val, output, title) abort
|
||||||
|
if a:exit_val
|
||||||
|
call go#util#EchoError(a:output)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let errformat = ",%f:%l:%c:\ %m"
|
||||||
|
let l:listtype = go#list#Type("GoReferrers")
|
||||||
|
call go#list#ParseFormat(l:listtype, errformat, a:output, a:title, 0)
|
||||||
|
|
||||||
|
let errors = go#list#Get(l:listtype)
|
||||||
|
call go#list#Window(l:listtype, len(errors))
|
||||||
|
endfunction
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
152
sources_non_forked/vim-go/autoload/go/rename.vim
Normal file
152
sources_non_forked/vim-go/autoload/go/rename.vim
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
function! go#rename#Rename(bang, ...) abort
|
||||||
|
let to_identifier = ""
|
||||||
|
if a:0 == 0
|
||||||
|
let ask = printf("vim-go: rename '%s' to: ", expand("<cword>"))
|
||||||
|
let prefill = go#config#GorenamePrefill()
|
||||||
|
if prefill != ''
|
||||||
|
let to_identifier = input(ask, eval(prefill))
|
||||||
|
else
|
||||||
|
let to_identifier = input(ask)
|
||||||
|
endif
|
||||||
|
redraw!
|
||||||
|
if empty(to_identifier)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
let to_identifier = a:1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:bin = go#config#RenameCommand()
|
||||||
|
|
||||||
|
" return with a warning if the bin doesn't exist
|
||||||
|
let bin_path = go#path#CheckBinPath(l:bin)
|
||||||
|
if empty(bin_path)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let fname = expand('%:p')
|
||||||
|
let pos = go#util#OffsetCursor()
|
||||||
|
let offset = printf('%s:#%d', fname, pos)
|
||||||
|
|
||||||
|
if l:bin == 'gopls'
|
||||||
|
call go#lsp#Rename(to_identifier)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let args = []
|
||||||
|
if l:bin == 'gorename'
|
||||||
|
let l:args = extend(l:args, ['-tags', go#config#BuildTags(), '-offset', offset, '-to', to_identifier])
|
||||||
|
else
|
||||||
|
call go#util#EchoWarning('unexpected rename command')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:cmd = extend([l:bin_path], l:args)
|
||||||
|
|
||||||
|
if go#util#has_job()
|
||||||
|
call s:rename_job({
|
||||||
|
\ 'cmd': cmd,
|
||||||
|
\ 'bang': a:bang,
|
||||||
|
\})
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:wd = go#util#ModuleRoot()
|
||||||
|
if l:wd == -1
|
||||||
|
let l:wd = expand("%:p:h")
|
||||||
|
endif
|
||||||
|
|
||||||
|
let [l:out, l:err] = go#util#ExecInWorkDir(l:cmd, l:wd)
|
||||||
|
call s:parse_errors(l:err, a:bang, split(l:out, '\n'))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function s:rename_job(args)
|
||||||
|
let l:job_opts = {
|
||||||
|
\ 'bang': a:args.bang,
|
||||||
|
\ 'for': 'GoRename',
|
||||||
|
\ 'statustype': 'gorename',
|
||||||
|
\ }
|
||||||
|
|
||||||
|
" autowrite is not enabled for jobs
|
||||||
|
call go#cmd#autowrite()
|
||||||
|
let l:cbs = go#job#Options(l:job_opts)
|
||||||
|
|
||||||
|
let l:wd = go#util#ModuleRoot()
|
||||||
|
if l:wd != -1
|
||||||
|
let l:cbs.cwd = l:wd
|
||||||
|
endif
|
||||||
|
|
||||||
|
" wrap l:cbs.exit_cb in s:exit_cb.
|
||||||
|
let l:cbs.exit_cb = funcref('s:exit_cb', [l:cbs.exit_cb])
|
||||||
|
|
||||||
|
call go#job#Start(a:args.cmd, l:cbs)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:reload_changed() abort
|
||||||
|
" reload all files to reflect the new changes. We explicitly call
|
||||||
|
" checktime to trigger a reload of all files. See
|
||||||
|
" http://www.mail-archive.com/vim@vim.org/msg05900.html for more info
|
||||||
|
" about the autoread bug
|
||||||
|
let current_autoread = &autoread
|
||||||
|
set autoread
|
||||||
|
silent! checktime
|
||||||
|
let &autoread = current_autoread
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" s:exit_cb reloads any changed buffers and then calls next.
|
||||||
|
function! s:exit_cb(next, job, exitval) abort
|
||||||
|
call s:reload_changed()
|
||||||
|
call call(a:next, [a:job, a:exitval])
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function s:parse_errors(exit_val, bang, out)
|
||||||
|
" reload all files to reflect the new changes. We explicitly call
|
||||||
|
" checktime to trigger a reload of all files. See
|
||||||
|
" http://www.mail-archive.com/vim@vim.org/msg05900.html for more info
|
||||||
|
" about the autoread bug
|
||||||
|
let current_autoread = &autoread
|
||||||
|
set autoread
|
||||||
|
silent! checktime
|
||||||
|
let &autoread = current_autoread
|
||||||
|
|
||||||
|
let l:listtype = go#list#Type("GoRename")
|
||||||
|
if a:exit_val != 0
|
||||||
|
let errors = go#util#ParseErrors(a:out)
|
||||||
|
call go#list#Populate(l:listtype, errors, 'Rename')
|
||||||
|
call go#list#Window(l:listtype, len(errors))
|
||||||
|
if !empty(errors) && !a:bang
|
||||||
|
call go#list#JumpToFirst(l:listtype)
|
||||||
|
elseif empty(errors)
|
||||||
|
" failed to parse errors, output the original content
|
||||||
|
call go#util#EchoError(a:out)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" strip out newline on the end that gorename puts. If we don't remove, it
|
||||||
|
" will trigger the 'Hit ENTER to continue' prompt
|
||||||
|
call go#list#Clean(l:listtype)
|
||||||
|
call go#util#EchoSuccess(a:out[0])
|
||||||
|
|
||||||
|
" refresh the buffer so we can see the new content
|
||||||
|
silent execute ":e"
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Commandline completion: original, unexported camelCase, and exported
|
||||||
|
" CamelCase.
|
||||||
|
function! go#rename#Complete(lead, cmdline, cursor)
|
||||||
|
let l:word = expand('<cword>')
|
||||||
|
return filter(uniq(sort(
|
||||||
|
\ [l:word, go#util#camelcase(l:word), go#util#pascalcase(l:word)])),
|
||||||
|
\ 'strpart(v:val, 0, len(a:lead)) == a:lead')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
124
sources_non_forked/vim-go/autoload/go/statusline.vim
Normal file
124
sources_non_forked/vim-go/autoload/go/statusline.vim
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
" Statusline
|
||||||
|
""""""""""""""""""""""""""""""""
|
||||||
|
|
||||||
|
" s:statuses is a global reference to all statuses. It stores the statuses per
|
||||||
|
" import paths (map[string]status), where each status is unique per its
|
||||||
|
" type. Current status dict is in form:
|
||||||
|
" {
|
||||||
|
" 'desc' : 'Job description',
|
||||||
|
" 'state' : 'Job state, such as success, failure, etc..',
|
||||||
|
" 'type' : 'Job type, such as build, test, etc..'
|
||||||
|
" 'created_at' : 'Time it was created as seconds since 1st Jan 1970'
|
||||||
|
" }
|
||||||
|
let s:statuses = {}
|
||||||
|
|
||||||
|
" timer_id for cleaner
|
||||||
|
let s:timer_id = 0
|
||||||
|
|
||||||
|
" last_status stores the last generated text per status
|
||||||
|
let s:last_status = ""
|
||||||
|
|
||||||
|
" Show returns the current status of the job for 20 seconds (configurable). It
|
||||||
|
" displays it in form of 'desc: [type|state]' if there is any state available,
|
||||||
|
" if not it returns an empty string. This function should be plugged directly
|
||||||
|
" into the statusline.
|
||||||
|
function! go#statusline#Show() abort
|
||||||
|
" lazy initialization of the cleaner
|
||||||
|
if !s:timer_id
|
||||||
|
let interval = go#config#StatuslineDuration()
|
||||||
|
let s:timer_id = timer_start(interval, function('go#statusline#Clear'), {'repeat': -1})
|
||||||
|
endif
|
||||||
|
|
||||||
|
" nothing to show
|
||||||
|
if empty(s:statuses)
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
let status_dir = expand('%:p:h')
|
||||||
|
|
||||||
|
if !has_key(s:statuses, status_dir)
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
let status = s:statuses[status_dir]
|
||||||
|
if !has_key(status, 'desc') || !has_key(status, 'state') || !has_key(status, 'type')
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
let status_text = printf("[%s|%s]", status.type, status.state)
|
||||||
|
if empty(status_text)
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
" only update highlight if status has changed.
|
||||||
|
if status_text != s:last_status
|
||||||
|
if status.state =~ "success" || status.state =~ "finished" || status.state =~ "pass" || status.state =~ 'initialized'
|
||||||
|
hi goStatusLineColor cterm=bold ctermbg=76 ctermfg=22 guibg=#5fd700 guifg=#005f00
|
||||||
|
elseif status.state =~ "started" || status.state =~ "analysing" || status.state =~ "compiling" || status.state =~ 'initializing'
|
||||||
|
hi goStatusLineColor cterm=bold ctermbg=208 ctermfg=88 guibg=#ff8700 guifg=#870000
|
||||||
|
elseif status.state =~ "failed"
|
||||||
|
hi goStatusLineColor cterm=bold ctermbg=196 ctermfg=52 guibg=#ff0000 guifg=#5f0000
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
let s:last_status = status_text
|
||||||
|
return status_text
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Update updates (adds) the statusline for the given status_dir with the
|
||||||
|
" given status dict. It overrides any previously set status.
|
||||||
|
function! go#statusline#Update(status_dir, status) abort
|
||||||
|
let a:status.created_at = reltime()
|
||||||
|
let s:statuses[a:status_dir] = a:status
|
||||||
|
|
||||||
|
" force to update the statusline, otherwise the user needs to move the
|
||||||
|
" cursor
|
||||||
|
exe 'let &ro = &ro'
|
||||||
|
|
||||||
|
" before we stop the timer, check if we have any previous jobs to be cleaned
|
||||||
|
" up. Otherwise every job will reset the timer when this function is called
|
||||||
|
" and thus old jobs will never be cleaned
|
||||||
|
call s:clear()
|
||||||
|
|
||||||
|
" also reset the timer, so the user has time to see it in the statusline.
|
||||||
|
" Setting the timer_id to 0 will cause a new timer to be created the next
|
||||||
|
" time the go#statusline#Show() is called.
|
||||||
|
call timer_stop(s:timer_id)
|
||||||
|
let s:timer_id = 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Clear clears all currently stored statusline data. The timer_id argument is
|
||||||
|
" just a placeholder so we can pass it to a timer_start() function if needed.
|
||||||
|
function! go#statusline#Clear(timer_id) abort
|
||||||
|
call s:clear()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:clear()
|
||||||
|
for [status_dir, status] in items(s:statuses)
|
||||||
|
let elapsed_time = reltimestr(reltime(status.created_at))
|
||||||
|
" strip whitespace
|
||||||
|
let elapsed_time = substitute(elapsed_time, '^\s*\(.\{-}\)\s*$', '\1', '')
|
||||||
|
|
||||||
|
if str2nr(elapsed_time) > 10
|
||||||
|
call remove(s:statuses, status_dir)
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
if len(s:statuses) == 0
|
||||||
|
let s:statuses = {}
|
||||||
|
endif
|
||||||
|
|
||||||
|
" force to update the statusline, otherwise the user needs to move the
|
||||||
|
" cursor
|
||||||
|
exe 'let &ro = &ro'
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
224
sources_non_forked/vim-go/autoload/go/tags.vim
Normal file
224
sources_non_forked/vim-go/autoload/go/tags.vim
Normal file
|
@ -0,0 +1,224 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
" mapped to :GoAddTags
|
||||||
|
function! go#tags#Add(start, end, count, ...) abort
|
||||||
|
let fname = fnamemodify(expand("%"), ':p:gs?\\?/?')
|
||||||
|
let offset = 0
|
||||||
|
if a:count == -1
|
||||||
|
let offset = go#util#OffsetCursor()
|
||||||
|
endif
|
||||||
|
|
||||||
|
let test_mode = 0
|
||||||
|
call call("go#tags#run", [a:start, a:end, offset, "add", fname, test_mode] + a:000)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" mapped to :GoRemoveTags
|
||||||
|
function! go#tags#Remove(start, end, count, ...) abort
|
||||||
|
let fname = fnamemodify(expand("%"), ':p:gs?\\?/?')
|
||||||
|
let offset = 0
|
||||||
|
if a:count == -1
|
||||||
|
let offset = go#util#OffsetCursor()
|
||||||
|
endif
|
||||||
|
|
||||||
|
let test_mode = 0
|
||||||
|
call call("go#tags#run", [a:start, a:end, offset, "remove", fname, test_mode] + a:000)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" run runs gomodifytag. This is an internal test so we can test it
|
||||||
|
function! go#tags#run(start, end, offset, mode, fname, test_mode, ...) abort
|
||||||
|
" do not split this into multiple lines, somehow tests fail in that case
|
||||||
|
let args = {'mode': a:mode,'start': a:start,'end': a:end,'offset': a:offset,'fname': a:fname,'cmd_args': a:000}
|
||||||
|
|
||||||
|
if &modified
|
||||||
|
let args["modified"] = 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:result = s:create_cmd(args)
|
||||||
|
if has_key(result, 'err')
|
||||||
|
call go#util#EchoError(result.err)
|
||||||
|
return -1
|
||||||
|
endif
|
||||||
|
|
||||||
|
if &modified
|
||||||
|
let filename = expand("%:p:gs!\\!/!")
|
||||||
|
let content = join(go#util#GetLines(), "\n")
|
||||||
|
let in = filename . "\n" . strlen(content) . "\n" . content
|
||||||
|
let [l:out, l:err] = go#util#Exec(l:result.cmd, in)
|
||||||
|
else
|
||||||
|
let [l:out, l:err] = go#util#Exec(l:result.cmd)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:err != 0
|
||||||
|
call go#util#EchoError(out)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:test_mode
|
||||||
|
exe 'edit ' . a:fname
|
||||||
|
endif
|
||||||
|
|
||||||
|
call s:write_out(out)
|
||||||
|
|
||||||
|
if a:test_mode
|
||||||
|
exe 'write! ' . a:fname
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
|
||||||
|
" write_out writes back the given output to the current buffer
|
||||||
|
func s:write_out(out) abort
|
||||||
|
" not a json output
|
||||||
|
if a:out[0] !=# '{'
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" nothing to do
|
||||||
|
if empty(a:out) || type(a:out) != type("")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let result = json_decode(a:out)
|
||||||
|
if type(result) != type({})
|
||||||
|
call go#util#EchoError(printf("malformed output from gomodifytags: %s", a:out))
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let lines = result['lines']
|
||||||
|
let start_line = result['start']
|
||||||
|
let end_line = result['end']
|
||||||
|
|
||||||
|
let index = 0
|
||||||
|
for line in range(start_line, end_line)
|
||||||
|
call setline(line, lines[index])
|
||||||
|
let index += 1
|
||||||
|
endfor
|
||||||
|
|
||||||
|
if has_key(result, 'errors')
|
||||||
|
let l:winnr = winnr()
|
||||||
|
let l:listtype = go#list#Type("GoModifyTags")
|
||||||
|
call go#list#ParseFormat(l:listtype, "%f:%l:%c:%m", result['errors'], "gomodifytags", 0)
|
||||||
|
call go#list#Window(l:listtype, len(result['errors']))
|
||||||
|
|
||||||
|
"prevent jumping to quickfix list
|
||||||
|
exe l:winnr . "wincmd w"
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
|
||||||
|
" create_cmd returns a dict that contains the command to execute gomodifytags
|
||||||
|
func s:create_cmd(args) abort
|
||||||
|
if !exists("*json_decode")
|
||||||
|
return {'err': "requires 'json_decode'. Update your Vim/Neovim version."}
|
||||||
|
endif
|
||||||
|
|
||||||
|
let bin_path = go#path#CheckBinPath('gomodifytags')
|
||||||
|
if empty(bin_path)
|
||||||
|
return {'err': "gomodifytags does not exist"}
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:start = a:args.start
|
||||||
|
let l:end = a:args.end
|
||||||
|
let l:offset = a:args.offset
|
||||||
|
let l:mode = a:args.mode
|
||||||
|
let l:cmd_args = a:args.cmd_args
|
||||||
|
let l:modifytags_transform = go#config#AddtagsTransform()
|
||||||
|
let l:modifytags_skip_unexported = go#config#AddtagsSkipUnexported()
|
||||||
|
|
||||||
|
" start constructing the command
|
||||||
|
let cmd = [bin_path]
|
||||||
|
call extend(cmd, ["-format", "json"])
|
||||||
|
call extend(cmd, ["-file", a:args.fname])
|
||||||
|
call extend(cmd, ["-transform", l:modifytags_transform])
|
||||||
|
|
||||||
|
if l:modifytags_skip_unexported
|
||||||
|
call extend(cmd, ["-skip-unexported"])
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has_key(a:args, "modified")
|
||||||
|
call add(cmd, "-modified")
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:offset != 0
|
||||||
|
call extend(cmd, ["-offset", l:offset])
|
||||||
|
else
|
||||||
|
let range = printf("%d,%d", l:start, l:end)
|
||||||
|
call extend(cmd, ["-line", range])
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:mode == "add"
|
||||||
|
let l:tags = []
|
||||||
|
let l:options = []
|
||||||
|
|
||||||
|
if !empty(l:cmd_args)
|
||||||
|
for item in l:cmd_args
|
||||||
|
let splitted = split(item, ",")
|
||||||
|
|
||||||
|
" tag only
|
||||||
|
if len(splitted) == 1
|
||||||
|
call add(l:tags, splitted[0])
|
||||||
|
endif
|
||||||
|
|
||||||
|
" options only
|
||||||
|
if len(splitted) == 2
|
||||||
|
call add(l:tags, splitted[0])
|
||||||
|
call add(l:options, printf("%s=%s", splitted[0], splitted[1]))
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
|
||||||
|
" default value
|
||||||
|
if empty(l:tags)
|
||||||
|
let l:tags = ["json"]
|
||||||
|
endif
|
||||||
|
|
||||||
|
" construct tags
|
||||||
|
call extend(cmd, ["-add-tags", join(l:tags, ",")])
|
||||||
|
|
||||||
|
" construct options
|
||||||
|
if !empty(l:options)
|
||||||
|
call extend(cmd, ["-add-options", join(l:options, ",")])
|
||||||
|
endif
|
||||||
|
elseif l:mode == "remove"
|
||||||
|
if empty(l:cmd_args)
|
||||||
|
call add(cmd, "-clear-tags")
|
||||||
|
else
|
||||||
|
let l:tags = []
|
||||||
|
let l:options = []
|
||||||
|
for item in l:cmd_args
|
||||||
|
let splitted = split(item, ",")
|
||||||
|
|
||||||
|
" tag only
|
||||||
|
if len(splitted) == 1
|
||||||
|
call add(l:tags, splitted[0])
|
||||||
|
endif
|
||||||
|
|
||||||
|
" options only
|
||||||
|
if len(splitted) == 2
|
||||||
|
call add(l:options, printf("%s=%s", splitted[0], splitted[1]))
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
" construct tags
|
||||||
|
if !empty(l:tags)
|
||||||
|
call extend(cmd, ["-remove-tags", join(l:tags, ",")])
|
||||||
|
endif
|
||||||
|
|
||||||
|
" construct options
|
||||||
|
if !empty(l:options)
|
||||||
|
call extend(cmd, ["-remove-options", join(l:options, ",")])
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
return {'err': printf("unknown mode: %s", l:mode)}
|
||||||
|
endif
|
||||||
|
|
||||||
|
return {'cmd': cmd}
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
52
sources_non_forked/vim-go/autoload/go/tags_test.vim
Normal file
52
sources_non_forked/vim-go/autoload/go/tags_test.vim
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
func! TestAddTags() abort
|
||||||
|
try
|
||||||
|
let l:tmp = gotest#load_fixture('tags/add_all_input.go')
|
||||||
|
silent call go#tags#run(0, 0, 40, "add", bufname(''), 1)
|
||||||
|
call gotest#assert_fixture('tags/add_all_golden.go')
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
|
||||||
|
func! TestAddTags_WithOptions() abort
|
||||||
|
try
|
||||||
|
let l:tmp = gotest#load_fixture('tags/add_all_input.go')
|
||||||
|
silent call go#tags#run(0, 0, 40, "add", bufname(''), 1, 'json,omitempty')
|
||||||
|
call gotest#assert_fixture('tags/add_all_golden_options.go')
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! TestAddTags_AddOptions() abort
|
||||||
|
try
|
||||||
|
let l:tmp = gotest#load_fixture('tags/add_all_input.go')
|
||||||
|
silent call go#tags#run(0, 0, 40, "add", bufname(''), 1, 'json')
|
||||||
|
call gotest#assert_fixture('tags/add_all_golden.go')
|
||||||
|
silent call go#tags#run(0, 0, 40, "add", bufname(''), 1, 'json,omitempty')
|
||||||
|
call gotest#assert_fixture('tags/add_all_golden_options.go')
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_remove_tags() abort
|
||||||
|
try
|
||||||
|
let l:tmp = gotest#load_fixture('tags/remove_all_input.go')
|
||||||
|
silent call go#tags#run(0, 0, 40, "remove", bufname(''), 1)
|
||||||
|
call gotest#assert_fixture('tags/remove_all_golden.go')
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim:ts=2:sts=2:sw=2:et
|
61
sources_non_forked/vim-go/autoload/go/template.vim
Normal file
61
sources_non_forked/vim-go/autoload/go/template.vim
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
let s:current_file = resolve(expand("<sfile>"))
|
||||||
|
|
||||||
|
function! go#template#create() abort
|
||||||
|
let l:go_template_use_pkg = go#config#TemplateUsePkg()
|
||||||
|
let l:root_dir = fnamemodify(s:current_file, ':h:h:h')
|
||||||
|
|
||||||
|
let l:package_name = go#tool#PackageName()
|
||||||
|
|
||||||
|
" if we can't figure out any package name (i.e. no Go files in the directory)
|
||||||
|
" from the directory create the template or use the directory as the name.
|
||||||
|
if l:package_name == -1
|
||||||
|
if l:go_template_use_pkg == 1
|
||||||
|
let l:path = fnamemodify(expand('%:p:h'), ':t')
|
||||||
|
let l:content = printf("package %s", l:path)
|
||||||
|
call append(0, l:content)
|
||||||
|
else
|
||||||
|
let l:filename = expand('%:t')
|
||||||
|
if l:filename =~ "_test.go$"
|
||||||
|
let l:template_file = go#config#TemplateTestFile()
|
||||||
|
else
|
||||||
|
let l:template_file = go#config#TemplateFile()
|
||||||
|
endif
|
||||||
|
" If template_file is an absolute path, use it as-is. This is to support
|
||||||
|
" overrides pointing to templates outside of the vim-go plugin dir
|
||||||
|
if fnamemodify(l:template_file, ':p') != l:template_file
|
||||||
|
let l:template_file = go#util#Join(l:root_dir, "templates", l:template_file)
|
||||||
|
endif
|
||||||
|
|
||||||
|
silent exe 'keepalt 0r ' . fnameescape(l:template_file)
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
let l:content = printf("package %s", l:package_name)
|
||||||
|
call append(0, l:content)
|
||||||
|
endif
|
||||||
|
" checking that the last line is empty shouldn't be necessary, but for some
|
||||||
|
" reason the last line isn't the expected empty line when run via tests.
|
||||||
|
if getline('$') is ''
|
||||||
|
$delete _
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#template#ToggleAutoCreate() abort
|
||||||
|
if go#config#TemplateAutocreate()
|
||||||
|
call go#config#SetTemplateAutocreate(0)
|
||||||
|
call go#util#EchoProgress("auto template create disabled")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
call go#config#SetTemplateAutocreate(1)
|
||||||
|
call go#util#EchoProgress("auto template create enabled")
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
62
sources_non_forked/vim-go/autoload/go/template_test.vim
Normal file
62
sources_non_forked/vim-go/autoload/go/template_test.vim
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
func! Test_TemplateCreate() abort
|
||||||
|
try
|
||||||
|
let l:tmp = gotest#write_file('foo/empty.txt', [''])
|
||||||
|
|
||||||
|
edit foo/bar.go
|
||||||
|
|
||||||
|
call gotest#assert_buffer(1, [
|
||||||
|
\ 'func main() {',
|
||||||
|
\ '\tfmt.Println("vim-go")',
|
||||||
|
\ '}'])
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:tmp = gotest#write_file('foo/empty.txt', [''])
|
||||||
|
edit foo/bar_test.go
|
||||||
|
|
||||||
|
call gotest#assert_buffer(1, [
|
||||||
|
\ 'func TestHelloWorld(t *testing.T) {',
|
||||||
|
\ '\t// t.Fatal("not implemented")',
|
||||||
|
\ '}'])
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_TemplateCreate_UsePkg() abort
|
||||||
|
try
|
||||||
|
let l:tmp = gotest#write_file('foo/empty.txt', [''])
|
||||||
|
|
||||||
|
let g:go_template_use_pkg = 1
|
||||||
|
edit foo/bar.go
|
||||||
|
|
||||||
|
call gotest#assert_buffer(0, ['package foo'])
|
||||||
|
finally
|
||||||
|
unlet g:go_template_use_pkg
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_TemplateCreate_PackageExists() abort
|
||||||
|
try
|
||||||
|
let l:tmp = gotest#write_file('quux/quux.go', ['package foo'])
|
||||||
|
|
||||||
|
edit quux/bar.go
|
||||||
|
|
||||||
|
call gotest#assert_buffer(0, ['package foo'])
|
||||||
|
finally
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
274
sources_non_forked/vim-go/autoload/go/term.vim
Normal file
274
sources_non_forked/vim-go/autoload/go/term.vim
Normal file
|
@ -0,0 +1,274 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
let s:bufnameprefix = 'goterm://'
|
||||||
|
|
||||||
|
" new creates a new terminal with the given command. Mode is set based on the
|
||||||
|
" global variable g:go_term_mode, which is by default set to :vsplit
|
||||||
|
function! go#term#new(bang, cmd, errorformat) abort
|
||||||
|
return go#term#newmode(a:bang, a:cmd, a:errorformat, go#config#TermMode())
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" go#term#newmode creates a new terminal with the given command and window mode.
|
||||||
|
function! go#term#newmode(bang, cmd, errorformat, mode) abort
|
||||||
|
let l:mode = a:mode
|
||||||
|
if empty(l:mode)
|
||||||
|
let l:mode = go#config#TermMode()
|
||||||
|
endif
|
||||||
|
|
||||||
|
if go#config#TermReuse()
|
||||||
|
call s:closeterm()
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:state = {
|
||||||
|
\ 'cmd': a:cmd,
|
||||||
|
\ 'bang' : a:bang,
|
||||||
|
\ 'winid': win_getid(winnr()),
|
||||||
|
\ 'stdout': [],
|
||||||
|
\ 'stdout_buf': '',
|
||||||
|
\ 'errorformat': a:errorformat,
|
||||||
|
\ }
|
||||||
|
|
||||||
|
" execute the command in the current file's directory
|
||||||
|
let l:dir = go#util#Chdir(expand('%:p:h'))
|
||||||
|
|
||||||
|
execute l:mode . ' __go_term__'
|
||||||
|
setlocal filetype=goterm
|
||||||
|
setlocal bufhidden=delete
|
||||||
|
setlocal winfixheight
|
||||||
|
" TODO(bc)?: setlocal winfixwidth
|
||||||
|
setlocal noswapfile
|
||||||
|
setlocal nobuflisted
|
||||||
|
|
||||||
|
" setup job for nvim
|
||||||
|
if has('nvim')
|
||||||
|
" explicitly bind callbacks to state so that within them, self will always
|
||||||
|
" refer to state. See :help Partial for more information.
|
||||||
|
"
|
||||||
|
" Don't set an on_stderr, because it will be passed the same data as
|
||||||
|
" on_stdout. See https://github.com/neovim/neovim/issues/2836
|
||||||
|
let l:job = {
|
||||||
|
\ 'on_stdout': function('s:on_stdout', [], state),
|
||||||
|
\ 'on_exit' : function('s:on_exit', [], state),
|
||||||
|
\ }
|
||||||
|
let l:state.id = termopen(a:cmd, l:job)
|
||||||
|
let l:state.termwinid = win_getid(winnr())
|
||||||
|
let s:lasttermwinid = l:state.termwinid
|
||||||
|
call go#util#Chdir(l:dir)
|
||||||
|
|
||||||
|
" resize new term if needed.
|
||||||
|
let l:height = go#config#TermHeight()
|
||||||
|
let l:width = go#config#TermWidth()
|
||||||
|
|
||||||
|
" Adjust the window width or height depending on whether it's a vertical or
|
||||||
|
" horizontal split.
|
||||||
|
if l:mode =~ "vertical" || l:mode =~ "vsplit" || l:mode =~ "vnew"
|
||||||
|
exe 'vertical resize ' . l:width
|
||||||
|
elseif mode =~ "split" || mode =~ "new"
|
||||||
|
exe 'resize ' . l:height
|
||||||
|
endif
|
||||||
|
" we also need to resize the pty, so there you go...
|
||||||
|
call jobresize(l:state.id, l:width, l:height)
|
||||||
|
|
||||||
|
" setup term for vim8
|
||||||
|
elseif has('terminal')
|
||||||
|
" Not great randomness, but "good enough" for our purpose here.
|
||||||
|
let l:rnd = sha256(printf('%s%s', reltimestr(reltime()), fnamemodify(bufname(''), ":p")))
|
||||||
|
let l:termname = printf("%s%s", s:bufnameprefix, l:rnd)
|
||||||
|
|
||||||
|
let l:term = {
|
||||||
|
\ 'out_cb': function('s:out_cb', [], state),
|
||||||
|
\ 'exit_cb' : function('s:exit_cb', [], state),
|
||||||
|
\ 'curwin': 1,
|
||||||
|
\ 'term_name': l:termname,
|
||||||
|
\ }
|
||||||
|
|
||||||
|
if l:mode =~ "vertical" || l:mode =~ "vsplit" || l:mode =~ "vnew"
|
||||||
|
let l:term["vertical"] = l:mode
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:state.id = term_start(a:cmd, l:term)
|
||||||
|
let l:state.termwinid = win_getid(bufwinnr(l:state.id))
|
||||||
|
let s:lasttermwinid = l:state.termwinid
|
||||||
|
call go#util#Chdir(l:dir)
|
||||||
|
|
||||||
|
" resize new term if needed.
|
||||||
|
let l:height = go#config#TermHeight()
|
||||||
|
let l:width = go#config#TermWidth()
|
||||||
|
|
||||||
|
" Adjust the window width or height depending on whether it's a vertical or
|
||||||
|
" horizontal split.
|
||||||
|
if l:mode =~ "vertical" || l:mode =~ "vsplit" || l:mode =~ "vnew"
|
||||||
|
exe 'vertical resize ' . l:width
|
||||||
|
elseif mode =~ "split" || mode =~ "new"
|
||||||
|
exe 'resize ' . l:height
|
||||||
|
endif
|
||||||
|
"if exists(*term_setsize)
|
||||||
|
"call term_setsize(l:state.id, l:height, l:width)
|
||||||
|
"endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
call win_gotoid(l:state.winid)
|
||||||
|
return l:state.id
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" out_cb continually concat's the self.stdout_buf on recv of stdout
|
||||||
|
" and sets self.stdout to the new-lined split content in self.stdout_buf
|
||||||
|
func! s:out_cb(channel, msg) dict abort
|
||||||
|
let self.stdout_buf = self.stdout_buf . a:msg
|
||||||
|
let self.stdout = split(self.stdout_buf, '\n')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:on_stdout(job_id, data, event) dict abort
|
||||||
|
" A single empty string means EOF was reached. The first item will never be
|
||||||
|
" the empty string except for when it's the only item and is signaling that
|
||||||
|
" EOF was reached.
|
||||||
|
if len(a:data) == 1 && a:data[0] == ''
|
||||||
|
" when there's nothing buffered, return early so that an
|
||||||
|
" erroneous message will not be added.
|
||||||
|
if self.stdout_buf == ''
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let self.stdout = add(self.stdout, self.stdout_buf)
|
||||||
|
else
|
||||||
|
let l:data = copy(a:data)
|
||||||
|
let l:data[0] = self.stdout_buf . l:data[0]
|
||||||
|
|
||||||
|
" The last element may be a partial line; save it for next time.
|
||||||
|
let self.stdout_buf = l:data[-1]
|
||||||
|
let self.stdout = extend(self.stdout, l:data[:-2])
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" vim8 exit callback
|
||||||
|
function! s:exit_cb(job_id, exit_status) dict abort
|
||||||
|
call s:handle_exit(a:job_id, a:exit_status, self)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" nvim exit callback
|
||||||
|
function! s:on_exit(job_id, exit_status, event) dict abort
|
||||||
|
call s:handle_exit(a:job_id, a:exit_status, self)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" handle_exit implements both vim8 and nvim exit callbacks
|
||||||
|
func s:handle_exit(job_id, exit_status, state) abort
|
||||||
|
let l:winid = win_getid(winnr())
|
||||||
|
call win_gotoid(a:state.winid)
|
||||||
|
|
||||||
|
let l:listtype = go#list#Type("_term")
|
||||||
|
|
||||||
|
if a:exit_status == 0
|
||||||
|
call go#list#Clean(l:listtype)
|
||||||
|
call win_gotoid(l:winid)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:bufdir = expand('%:p:h')
|
||||||
|
if !isdirectory(l:bufdir)
|
||||||
|
call go#util#EchoWarning('terminal job failure not processed, because the job''s working directory no longer exists')
|
||||||
|
call win_gotoid(l:winid)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" change to directory where the command was run. If we do not do this the
|
||||||
|
" quickfix items will have the incorrect paths.
|
||||||
|
" see: https://github.com/fatih/vim-go/issues/2400
|
||||||
|
let l:dir = go#util#Chdir(l:bufdir)
|
||||||
|
|
||||||
|
let l:title = a:state.cmd
|
||||||
|
if type(l:title) == v:t_list
|
||||||
|
let l:title = join(a:state.cmd)
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:i = 0
|
||||||
|
while l:i < len(a:state.stdout)
|
||||||
|
let a:state.stdout[l:i] = substitute(a:state.stdout[l:i], "\r$", '', 'g')
|
||||||
|
let l:i += 1
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
call go#list#ParseFormat(l:listtype, a:state.errorformat, a:state.stdout, l:title, 0)
|
||||||
|
let l:errors = go#list#Get(l:listtype)
|
||||||
|
call go#list#Window(l:listtype, len(l:errors))
|
||||||
|
|
||||||
|
" close terminal; we don't need it anymore
|
||||||
|
if go#config#TermCloseOnExit()
|
||||||
|
call win_gotoid(a:state.termwinid)
|
||||||
|
close!
|
||||||
|
endif
|
||||||
|
|
||||||
|
if empty(l:errors)
|
||||||
|
call go#util#EchoError( '[' . l:title . '] ' . "FAIL")
|
||||||
|
call go#util#Chdir(l:dir)
|
||||||
|
call win_gotoid(l:winid)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:state.bang
|
||||||
|
call go#util#Chdir(l:dir)
|
||||||
|
call win_gotoid(l:winid)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
call win_gotoid(a:state.winid)
|
||||||
|
call go#list#JumpToFirst(l:listtype)
|
||||||
|
|
||||||
|
" change back to original working directory
|
||||||
|
call go#util#Chdir(l:dir)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! go#term#ToggleCloseOnExit() abort
|
||||||
|
if go#config#TermCloseOnExit()
|
||||||
|
call go#config#SetTermCloseOnExit(0)
|
||||||
|
call go#util#EchoProgress("term close on exit disabled")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
call go#config#SetTermCloseOnExit(1)
|
||||||
|
call go#util#EchoProgress("term close on exit enabled")
|
||||||
|
return
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:closeterm()
|
||||||
|
if !exists('s:lasttermwinid')
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:termwinid = s:lasttermwinid
|
||||||
|
unlet s:lasttermwinid
|
||||||
|
let l:info = getwininfo(l:termwinid)
|
||||||
|
if empty(l:info)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:info = l:info[0]
|
||||||
|
|
||||||
|
if !get(l:info, 'terminal', 0) is 1
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has('nvim')
|
||||||
|
if 'goterm' == nvim_buf_get_option(nvim_win_get_buf(l:termwinid), 'filetype')
|
||||||
|
call nvim_win_close(l:termwinid, v:true)
|
||||||
|
endif
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if stridx(bufname(winbufnr(l:termwinid)), s:bufnameprefix, 0) == 0
|
||||||
|
let l:winid = win_getid()
|
||||||
|
call win_gotoid(l:termwinid)
|
||||||
|
close!
|
||||||
|
call win_gotoid(l:winid)
|
||||||
|
endif
|
||||||
|
catch
|
||||||
|
call go#util#EchoError(printf("vim-go: %s", v:exception))
|
||||||
|
endtry
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
94
sources_non_forked/vim-go/autoload/go/term_test.vim
Normal file
94
sources_non_forked/vim-go/autoload/go/term_test.vim
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
" don't spam the user when Vim is started in Vi compatibility mode
|
||||||
|
let s:cpo_save = &cpo
|
||||||
|
set cpo&vim
|
||||||
|
|
||||||
|
func! Test_GoTermNewMode()
|
||||||
|
if !(has('nvim') || has('terminal'))
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:filename = 'term/term.go'
|
||||||
|
let l:tmp = gotest#load_fixture(l:filename)
|
||||||
|
exe 'cd ' . l:tmp . '/src/term'
|
||||||
|
|
||||||
|
let expected = expand('%:p')
|
||||||
|
|
||||||
|
let cmd = "go run ". go#util#Shelljoin(go#tool#Files())
|
||||||
|
|
||||||
|
set nosplitright
|
||||||
|
call go#term#new(0, cmd, &errorformat)
|
||||||
|
let actual = expand('%:p')
|
||||||
|
call assert_equal(actual, l:expected)
|
||||||
|
|
||||||
|
finally
|
||||||
|
sleep 50m
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_GoTermNewMode_SplitRight()
|
||||||
|
if !(has('nvim') || has('terminal'))
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:filename = 'term/term.go'
|
||||||
|
let l:tmp = gotest#load_fixture(l:filename)
|
||||||
|
exe 'cd ' . l:tmp . '/src/term'
|
||||||
|
|
||||||
|
let expected = expand('%:p')
|
||||||
|
|
||||||
|
let cmd = "go run ". go#util#Shelljoin(go#tool#Files())
|
||||||
|
|
||||||
|
set splitright
|
||||||
|
call go#term#new(0, cmd, &errorformat)
|
||||||
|
let actual = expand('%:p')
|
||||||
|
call assert_equal(actual, l:expected)
|
||||||
|
|
||||||
|
finally
|
||||||
|
sleep 50m
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
set nosplitright
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func! Test_GoTermReuse()
|
||||||
|
if !(has('nvim') || has('terminal'))
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
try
|
||||||
|
let l:filename = 'term/term.go'
|
||||||
|
let l:tmp = gotest#load_fixture(l:filename)
|
||||||
|
exe 'cd ' . l:tmp . '/src/term'
|
||||||
|
|
||||||
|
let expected = expand('%:p')
|
||||||
|
|
||||||
|
let cmd = "go run ". go#util#Shelljoin(go#tool#Files())
|
||||||
|
|
||||||
|
set nosplitright
|
||||||
|
|
||||||
|
let g:go_term_reuse = 1
|
||||||
|
call go#term#new(0, cmd, &errorformat)
|
||||||
|
let actual = expand('%:p')
|
||||||
|
call assert_equal(actual, l:expected)
|
||||||
|
call assert_equal(3, len(getwininfo()))
|
||||||
|
|
||||||
|
call go#term#new(0, cmd, &errorformat)
|
||||||
|
let actual = expand('%:p')
|
||||||
|
call assert_equal(actual, l:expected)
|
||||||
|
|
||||||
|
call assert_equal(3, len(getwininfo()))
|
||||||
|
finally
|
||||||
|
sleep 50m
|
||||||
|
unlet g:go_term_reuse
|
||||||
|
call delete(l:tmp, 'rf')
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" restore Vi compatibility settings
|
||||||
|
let &cpo = s:cpo_save
|
||||||
|
unlet s:cpo_save
|
||||||
|
|
||||||
|
" vim: sw=2 ts=2 et
|
|
@ -0,0 +1,5 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
notafunc()
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package complete
|
||||||
|
|
||||||
|
type T struct {
|
||||||
|
V string
|
||||||
|
}
|
||||||
|
|
||||||
|
func Example(s string) {
|
||||||
|
Example("")
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
func Example() {
|
||||||
|
foo()
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
// +build constrained
|
||||||
|
|
||||||
|
package config
|
||||||
|
|
||||||
|
// foo is constrained and this comment exists to make the line numbers different than foo.go
|
||||||
|
func foo() {
|
||||||
|
println("foo")
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
// +build !constrained
|
||||||
|
|
||||||
|
package config
|
||||||
|
|
||||||
|
func foo() {
|
||||||
|
println("foo")
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
module config
|
||||||
|
|
||||||
|
go 1.13
|
|
@ -0,0 +1,7 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("vim-go"
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("vim-go")
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("vim-go")
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("vim-go")
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("vim-go")
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package main
|
||||||
|
func Foo(log *logging.TestLogger) {
|
||||||
|
log.Debug("vim-go")
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("vim-go")
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
logging "gh.com/gi/foo-logging"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Foo(log *logging.TestLogger) {
|
||||||
|
log.Debug("vim-go")
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("vim-go")
|
||||||
|
}
|
12
sources_non_forked/vim-go/autoload/go/test-fixtures/fmt/src/imports/vendor/gh.com/gi/foo-logging/logger.go
generated
vendored
Normal file
12
sources_non_forked/vim-go/autoload/go/test-fixtures/fmt/src/imports/vendor/gh.com/gi/foo-logging/logger.go
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package logging
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type TestLogger struct {
|
||||||
|
Value string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *TestLogger) Debug(msg string) {
|
||||||
|
fmt.Println(msg)
|
||||||
|
fmt.Println(l.Value)
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
notafunc()
|
||||||
|
println("vim-go")
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("vim-go"
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package errcheck
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func foo() {
|
||||||
|
io.Copy(os.Stdout, os.Stdin)
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue