[mirror] Make your go dev experience better github.com/olexsmir/gopher.nvim
neovim golang

sync develop and main (#68)

* healthcheck: refactoring, remove deprecation wanings (#35)

* refactor(checkhealth): remove deprecation warnings, complete rewrite

* refactor(checkhealth): rename util file

* style(healthchecker): reformat lua in vim file

* refactor(health): move all report function into table

* add editorconfig (#36)

* refactor of public plugin's api (#37)

* refactor: move all plugin functionality to init.lua

* fix(commands): now it uses correct module paths

* refactor(config): change way how it handles options

* refactor(gotests): use correct config, change way how deps required, fix some typos

* fix(healthchecker): use correct config

* refactor(iferr): change api

* refactor(impl): change api

* refactor(installer): change api

* refactor(struct_tags): change way of importting deps

* refactor(struct_tags): rename M to struct_tags

* run stylua

* refactor(dap): make it all in one file, and make some refactoring

* refactor(_utils): change way how it organizes

* fix: use new _utils api

* refactor(_utils.health): reorganize module

* refactor(_utils.ts): some renameing, moving requires lines

* run stylua

* update tooling (#38)

* chore: delete pre-commit

* chore: switch from makefile to taskfile

* chore(ci): update and add one more linter

* chore(editorconfig): add config for Go

* chore(editorconfig): remove max_line_length

* fix: editorconfig-check on README.md

* feat: run tests independent from user's nvim config

* remove editorconfig-checker

* fix(config): now it not removes .setup() from itself after calling
.setup()

* fix(config): now it works correctly

* chore: update taskfile, and linter config

* feat(config): make it optional to call .setup()

* run tests independent of user nvim setup (#39)

* chore(lua_ls): now lua_ls knows about testing functions

* spec: change way how tests srtuctured

* test(config): refactor tests

* test: utils

* refactor(utils): remove not used function

* chore(ci): add test runner

* chore(ci): remove taskfile from deps

* fix: now it works

* fix(dap): now dlv uses cmd to run from config

* chore(ci): run tests on many versions of nvim

* refactor: commands runner (#42)

* feat(utils): first impl of own commands runner

* refactor(gotests): uses own runner instead of vendored

* refactor(utils): back to plenary.job

* refactor(gotests): use new runner, clean code

* fix(runner): now it returns output correctly

* refactor(iferr): use vim.system

i have tried to use _utils.runner, but i can't figure out how to make `< file.go` for the command

* refactor(impl): use new runner

* refactor(installer): use new runner

* refactor(struct_tags): use new runner

* refactor: commands such as :GoGet runs with new runner

* refactor: throw errors in more lua way, i think

* refactor(utils): notify now has title

* refactor: use more correct way of notifying

* refactor(runner): write error message on error

* add ability for setting custom tools options (#44)

* feat(gotests): add custom templates support

* feat(struct_tags): add support for custom `transform` option

* fix(health): check if bin is installed, and added message about treesitter parser

* fix: fix iferr config (#56)

* Add support for named tests (#50)

* fix(typo): README.md (#47)

* feat: add support for named tests

* test

* tags in table

* debug installer msg

* test

* hardcoded @develop

* get gotests tag from setup()

* update readme

* store install tag in urls table

* removed gotests tag

* update README.md

* remove urls installer index reference

* remove named arg from add_test()

* .

* update README.md

* update README.md

---------

Co-authored-by: Steve M <gearcog@users.noreply.github.com>

* reformat .editorconfig config

* refactor(api)!: mave tags and gotests api into their sub tables

* add help file, and docs (#59)

* idk how good this idea is

* this could be working but i still cant figure out how to run it

* ignore tags that mini.doc gens, but why?

* chore(taskfile): force exiting after tests

because i got infinit ci

* chore(ci): add more nvim versions to run on

* chore: update taskfile

* feat: add docs generator

* docs: its only begining

* refactor: update docgen script

* docs: write some more

* docs(config): update

* docs: update readme

* language

* hope it would work

* what about that?

* maybe this would work?

* update md

* upd

* WHY DOESNT IT WORKING

* idk by but 0.9.3 just fails the ci, so i deleted it from suite

* again update, why does markdown not work in embeded html

* maybe it can help?

* upd

* again update

* kinda fix

* fix: formatting

* again some updating

* some readme updating

* fix, this shouldnt be in repo

* i finnaly undertood how to fix this fking skill issue

* fix(struct_tags): typo

* refactor(docs): change the order in generated file

* docs: install deps

* refactor(scripts): rename doc-gen script

* docs(impl): write docs

* docs(dap): add doc

* stylua .

* docs(struct_tags): add doc

* docs(gotests): add docs

* docs(iferr): add docs

* docs(comment): add doc

* update CONTRIBUTING.md

* docs(README): talk about `develop` branch

* docs: update README.md

* refactor(health): keep in mind new way of health check (#63)

* feat: add logger (#64)

* refactor(health): keep in mind new way of health check (#63)

* feat(log): add logger module

* refactor(utils): remove unused code

* refactor(log, utils): get plugin name from config

* refactor(logger): add some type annotations

* refactor(utils): log notifications

* feat: LOGGER™

* feat(config): TYPES

* refactor(log): dont give a thing about var that is not even declared

* feat(log): add easy way to open log

* refactor(log): some types

* update types

* docs: regen

* fix(log): make setting log level by config work

* feat(iferr): write error to log file if occur

* feat(gotests): add logger

* add deprecation message (#67)

---------

Co-authored-by: Arne Van Maele <93863978+arnevm123@users.noreply.github.com>
Co-authored-by: Alex <49870662+ysomad@users.noreply.github.com>
Co-authored-by: Steve M <gearcog@users.noreply.github.com>

authored by olexsmir.xyz Steve M Arne Van Maele Alex and committed by GitHub a995af34 ac27f4b6

+16
.editorconfig
··· 1 + root = true 2 + 3 + [*] 4 + indent_style = space 5 + indent_size = 4 6 + end_of_line = lf 7 + insert_final_newline = true 8 + trim_trailing_whitespace = true 9 + charset = utf-8 10 + 11 + [*.{md,yml,yaml,toml,lua,vim}] 12 + indent_size = 2 13 + 14 + [*.go] 15 + indent_style = tab 16 + indent_size = 4
-24
.github/workflows/ci.yml
··· 1 - name: Format and lint 2 - on: [push, pull_request] 3 - 4 - jobs: 5 - format: 6 - name: stylua 7 - runs-on: ubuntu-latest 8 - steps: 9 - - uses: actions/checkout@v2 10 - - uses: JohnnyMorganz/stylua-action@1.0.0 11 - with: 12 - token: ${{ secrets.GITHUB_TOKEN }} 13 - version: 0.14.0 14 - args: --check . 15 - 16 - lint: 17 - name: selene 18 - runs-on: ubuntu-latest 19 - steps: 20 - - uses: actions/checkout@v2 21 - - uses: NTBBloodbath/selene-action@v1.0.0 22 - with: 23 - token: ${{ secrets.GITHUB_TOKEN }} 24 - args: --display-style=quiet .
+19
.github/workflows/linters.yml
··· 1 + name: linters 2 + on: [push, pull_request] 3 + 4 + jobs: 5 + linters: 6 + name: linters 7 + runs-on: ubuntu-latest 8 + steps: 9 + - uses: actions/checkout@v3 10 + - uses: JohnnyMorganz/stylua-action@v3 11 + with: 12 + token: ${{ secrets.GITHUB_TOKEN }} 13 + version: latest 14 + args: --check . 15 + 16 + - uses: NTBBloodbath/selene-action@v1.0.0 17 + with: 18 + token: ${{ secrets.GITHUB_TOKEN }} 19 + args: .
+44
.github/workflows/tests.yml
··· 1 + name: tests 2 + on: [push, pull_request] 3 + 4 + jobs: 5 + tests: 6 + strategy: 7 + matrix: 8 + os: [ubuntu-latest] 9 + nvim_version: 10 + - nightly 11 + - v0.7.0 12 + - v0.7.2 13 + - v0.8.0 14 + - v0.8.1 15 + - v0.8.2 16 + - v0.8.3 17 + - v0.9.0 18 + - v0.9.1 19 + - v0.9.2 20 + - v0.9.4 21 + - v0.9.5 22 + runs-on: ${{ matrix.os }} 23 + steps: 24 + - name: Install Task 25 + uses: arduino/setup-task@v1 26 + with: 27 + version: 3.x 28 + repo-token: ${{ secrets.GITHUB_TOKEN }} 29 + 30 + - uses: actions/checkout@v3 31 + 32 + - name: Install Neovim 33 + run: | 34 + mkdir -p /tmp/nvim 35 + wget -q https://github.com/neovim/neovim/releases/download/${{ matrix.nvim_version }}/nvim.appimage -O /tmp/nvim/nvim.appimage 36 + cd /tmp/nvim 37 + chmod a+x ./nvim.appimage 38 + ./nvim.appimage --appimage-extract 39 + echo "/tmp/nvim/squashfs-root/usr/bin/" >> $GITHUB_PATH 40 + 41 + - name: Run Tests 42 + run: | 43 + nvim --version 44 + task test
+2 -1
.gitignore
··· 1 - playground/ 1 + /playground/ 2 + /.tests/
+10
.luarc.json
··· 1 + { 2 + "diagnostics.globals": [ 3 + "describe", 4 + "it", 5 + "before_each", 6 + "after_each", 7 + "before_all", 8 + "after_all" 9 + ] 10 + }
-15
.pre-commit-config.yaml
··· 1 - repos: 2 - - repo: local 3 - hooks: 4 - - id: stylua 5 - name: StyLua 6 - language: rust 7 - entry: stylua 8 - types: [lua] 9 - args: ["--check", "-"] 10 - - id: selene 11 - name: Selene 12 - language: rust 13 - entry: selene 14 - types: [lua] 15 - args: ["-"]
+45 -3
CONTRIBUTING.md
··· 1 1 # Contributing to `gopher.nvim` 2 2 3 - Thank you for looking to contributing 3 + Thank you for taking the time to submit some code to gopher.nvim. It means a lot! 4 + 5 + ### Task running 6 + 7 + In this codebase for running tasks is used [Taskfile](https://taskfile.dev). 8 + You can install it with: 9 + ```bash 10 + go install github.com/go-task/task/v3/cmd/task@latest 11 + ``` 4 12 5 13 ### Styling and formatting 6 14 ··· 8 16 You can install these with: 9 17 10 18 ```bash 11 - cargo install stylua 12 - cargo install selene 19 + sudo pacman -S selene stylua 20 + # or whatever is your package manager 21 + # or way of installing pkgs 22 + ``` 23 + 24 + For formatting use this following commands, or setup your editor to integrate with selene/stylua: 25 + ```bash 26 + task format 27 + task format:check # will check if your code formatted 28 + task lint 29 + ``` 30 + 31 + ### Documentation 32 + 33 + Here we are using [mini.doc](https://github.com/echasnovski/mini.nvim/blob/main/readmes/mini-doc.md) 34 + for generating help files based on EmmyLua-like annotations in comments 35 + 36 + You can generate docs with: 37 + ```bash 38 + task docgen 39 + ``` 40 + 41 + ### Commit messages 42 + We use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/), please follow it. 43 + 44 + ### Testing 45 + 46 + For testing this plugins uses [plenary.nvim](https://github.com/nvim-lua/plenary.nvim). 47 + All tests live in [/spec](https://github.com/olexsmir/gopher.nvim/tree/main/spec) dir. 48 + 49 + You can run tests with: 50 + ```bash 51 + task test 52 + # also there are some aliases for that 53 + task tests 54 + task spec 13 55 ```
-11
Makefile
··· 1 - .PHONY: 2 - .SILENT: 3 - 4 - format: 5 - stylua **/*.lua 6 - 7 - lint: 8 - selene **/*.lua 9 - 10 - test: 11 - nvim --headless -u ./spec/minimal_init.vim -c "PlenaryBustedDirectory spec {minimal_init='./spec/minimal_init.vim'}"
+162 -88
README.md
··· 4 4 5 5 Minimalistic plugin for Go development in Neovim written in Lua. 6 6 7 - It's not an LSP tool, the main goal of this plugin is add go tooling support in Neovim. 7 + It's **NOT** an LSP tool, the main goal of this plugin is to add go tooling support in Neovim. 8 8 9 - ## Install 9 + > If you want to use new and maybe undocumented, and unstable features you might use [develop](https://github.com/olexsmir/gopher.nvim/tree/develop) branch. 10 10 11 - Pre-dependency: [go](https://github.com/golang/go) (tested on 1.17 and 1.18) 11 + ## Install (using [lazy.nvim](https://github.com/folke/lazy.nvim)) 12 + 13 + Pre-dependency: 14 + 15 + - [Go](https://github.com/golang/go) 16 + - `go` treesitter parser, install by `:TSInstall go` 12 17 13 18 ```lua 14 - use { 19 + { 15 20 "olexsmir/gopher.nvim", 16 - requires = { -- dependencies 21 + ft = "go", 22 + -- branch = "develop", -- if you want develop branch 23 + -- keep in mind, it might break everything 24 + dependencies = { 17 25 "nvim-lua/plenary.nvim", 18 26 "nvim-treesitter/nvim-treesitter", 27 + "mfussenegger/nvim-dap", -- (optional) only if you use `gopher.dap` 19 28 }, 29 + -- (optional) will update plugin's deps on every update 30 + build = function() 31 + vim.cmd.GoInstallDeps() 32 + end, 33 + ---@type gopher.Config 34 + opts = {}, 20 35 } 21 36 ``` 22 37 23 - Also, run `TSInstall go` if `go` parser if isn't installed yet. 38 + ## Configuratoin 24 39 25 - ## Config 40 + > [!IMPORTANT] 41 + > 42 + > If you need more info look `:h gopher.nvim` 26 43 27 - By `.setup` function you can configure the plugin. 28 - 29 - Note: 30 - 31 - - `installer` does not install the tool in user set path 44 + **Take a look at default options** 32 45 33 46 ```lua 34 47 require("gopher").setup { 35 48 commands = { 36 49 go = "go", 37 50 gomodifytags = "gomodifytags", 38 - gotests = "~/go/bin/gotests", -- also you can set custom command path 51 + gotests = "gotests", 39 52 impl = "impl", 40 53 iferr = "iferr", 54 + dlv = "dlv", 55 + }, 56 + gotests = { 57 + -- gotests doesn't have template named "default" so this plugin uses "default" to set the default template 58 + template = "default", 59 + -- path to a directory containing custom test code templates 60 + template_dir = nil, 61 + -- switch table tests from using slice to map (with test name for the key) 62 + -- works only with gotests installed from develop branch 63 + named = false, 64 + }, 65 + gotag = { 66 + transform = "snakecase", 41 67 }, 42 68 } 43 69 ``` 44 70 45 71 ## Features 46 72 47 - 1. Installation requires this go tool: 73 + <!-- markdownlint-disable --> 48 74 49 - ```vim 50 - :GoInstallDeps 51 - ``` 75 + <details> 76 + <summary> 77 + <b>Install plugin's go deps</b> 78 + </summary> 52 79 53 - It will install next tools: 80 + ```vim 81 + :GoInstallDeps 82 + ``` 54 83 55 - - [gomodifytags](https://github.com/fatih/gomodifytags) 56 - - [impl](https://github.com/josharian/impl) 57 - - [gotests](https://github.com/cweill/gotests) 58 - - [iferr](https://github.com/koron/iferr) 84 + This will install the following tools: 59 85 60 - 2. Modify struct tags: 61 - By default `json` tag will be added/removed, if not set: 86 + - [gomodifytags](https://github.com/fatih/gomodifytags) 87 + - [impl](https://github.com/josharian/impl) 88 + - [gotests](https://github.com/cweill/gotests) 89 + - [iferr](https://github.com/koron/iferr) 90 + - [dlv](github.com/go-delve/delve/cmd/dlv) 91 + </details> 62 92 63 - ```vim 64 - :GoTagAdd json " For add json tag 65 - :GoTagRm yaml " For remove yaml tag 66 - ``` 93 + <details> 94 + <summary> 95 + <b>Add and remove tags for structs via <a href="https://github.com/fatih/gomodifytags">gomodifytags</a></b> 96 + </summary> 67 97 68 - 3. Run `go mod` command: 98 + By default `json` tag will be added/removed, if not set: 69 99 70 - ```vim 71 - :GoMod tidy " Runs `go mod tidy` 72 - :GoMod init asdf " Runs `go mod init asdf` 73 - ``` 100 + ```vim 101 + " add json tag 102 + :GoTagAdd json 74 103 75 - 4. Run `go get` command 104 + " remove yaml tag 105 + :GoTagRm yaml 106 + ``` 76 107 77 - Link can have a `http` or `https` prefix. 108 + ```lua 109 + -- or you can use lua api 110 + require("gopher").tags.add "xml" 111 + require("gopher").tags.rm "proto" 112 + ``` 113 + </details> 78 114 79 - You can provide more than one package url: 115 + <details> 116 + <summary> 117 + <b>Generating tests via <a href="https://github.com/cweill/gotests">gotests</a></b> 118 + </summary> 80 119 81 - ```vim 82 - :GoGet github.com/gorilla/mux 83 - ``` 120 + ```vim 121 + " Generate one test for a specific function/method(one under cursor) 122 + :GoTestAdd 84 123 85 - 5. Interface implementation 124 + " Generate all tests for all functions/methods in the current file 125 + :GoTestsAll 86 126 87 - Command syntax: 127 + " Generate tests for only exported functions/methods in the current file 128 + :GoTestsExp 129 + ``` 88 130 89 - ```vim 90 - :GoImpl [receiver] [interface] 131 + ```lua 132 + -- or you can use lua api 133 + require("gopher").test.add() 134 + require("gopher").test.exported() 135 + require("gopher").test.all() 136 + ``` 91 137 92 - " Also you can put cursor on the struct and run: 93 - :GoImpl [interface] 94 - ``` 138 + For named tests see `:h gopher.nvim-gotests-named` 139 + </details> 95 140 96 - Example of usage: 141 + <details> 142 + <summary> 143 + <b>Run commands like <code>go mod/get/etc</code> inside of nvim</b> 144 + </summary> 97 145 98 - ```vim 99 - " Example 100 - :GoImpl r Read io.Reader 101 - " or simply put your cursor in the struct and run: 102 - :GoImpl io.Reader 103 - ``` 146 + ```vim 147 + :GoGet github.com/gorilla/mux 148 + 149 + " Link can have an `http` or `https` prefix. 150 + :GoGet https://github.com/lib/pq 151 + 152 + " You can provide more than one package url 153 + :GoGet github.com/jackc/pgx/v5 github.com/google/uuid/ 154 + 155 + " go mod commands 156 + :GoMod tidy 157 + :GoMod init new-shiny-project 104 158 105 - 6. Generate tests with [gotests](https://github.com/cweill/gotests) 159 + " go work commands 160 + :GoWork sync 106 161 107 - Generate one test for a specific function/method: 162 + " run go generate in cwd 163 + :GoGenerate 108 164 109 - ```vim 110 - :GoTestAdd 111 - ``` 165 + " run go generate for the current file 166 + :GoGenerate % 167 + ``` 168 + </details> 112 169 113 - Generate all tests for all functions/methods in current file: 170 + <details> 171 + <summary> 172 + <b>Interface implementation via <a href="https://github.com/josharian/impl">impl<a></b> 173 + </summary> 114 174 115 - ```vim 116 - :GoTestsAll 117 - ``` 175 + Syntax of the command: 176 + ```vim 177 + :GoImpl [receiver] [interface] 118 178 119 - Generate tests only for exported functions/methods in current file: 179 + " also you can put a cursor on the struct and run 180 + :GoImpl [interface] 181 + ``` 120 182 121 - ```vim 122 - :GoTestsExp 123 - ``` 183 + Usage examples: 184 + ```vim 185 + :GoImpl r Read io.Reader 186 + :GoImpl Write io.Writer 124 187 125 - 7. Run `go generate` command; 188 + " or you can simply put a cursor on the struct and run 189 + :GoImpl io.Reader 190 + ``` 191 + </details> 126 192 127 - ```vim 128 - " Run `go generate` in cwd path 129 - :GoGenerate 193 + <details> 194 + <summary> 195 + <b>Generate boilerplate for doc comments</b> 196 + </summary> 130 197 131 - " Run `go generate` for current file 132 - :GoGenerate % 133 - ``` 198 + First set a cursor on **public** package/function/interface/struct and execute: 134 199 135 - 8. Generate doc comment 200 + ```vim 201 + :GoCmt 202 + ``` 203 + </details> 136 204 137 - First set a cursor on **public** package/function/interface/struct and execute: 138 205 139 - ```vim 140 - :GoCmt 141 - ``` 206 + <details> 207 + <summary> 208 + <b>Generate <code>if err != nil {</code> via <a href="https://github.com/koron/iferr">iferr</a></b> 209 + </summary> 142 210 143 - 9. Generate `if err` 211 + Set the cursor on the line with `err` and execute 144 212 145 - Set cursor on the line with **err** and execute: 213 + ```vim 214 + :GoIfErr 215 + ``` 216 + </details> 146 217 147 - ```vim 148 - :GoIfErr 149 - ``` 218 + <details> 219 + <summary> 220 + <b>Setup <a href="https://github.com/mfussenegger/nvim-dap">nvim-dap</a> for go in one line</b> 221 + </summary> 150 222 151 - 10. Setup nvim-dap for go in one line. 223 + THIS FEATURE WILL BE REMOVED IN `0.1.6` 152 224 153 - Notice: [nvim-dap](https://github.com/mfussenegger/nvim-dap) is required 225 + note [nvim-dap](https://github.com/mfussenegger/nvim-dap) has to be installed 154 226 155 - ```lua 156 - require"gopher.dap".setup() 157 - ``` 227 + ```lua 228 + require("gopher.dap").setup() 229 + ``` 230 + </details> 158 231 159 232 ## Contributing 160 233 ··· 164 237 165 238 - [go.nvim](https://github.com/ray-x/go.nvim) 166 239 - [nvim-dap-go](https://github.com/leoluz/nvim-dap-go) 240 + - [iferr](https://github.com/koron/iferr)
+49
Taskfile.yml
··· 1 + version: "3" 2 + tasks: 3 + format: 4 + desc: formats all lua files in repo 5 + cmds: 6 + - stylua . 7 + 8 + lint: 9 + desc: runs all linters 10 + cmds: 11 + - task: selene 12 + - task: stylua:check 13 + 14 + selene: 15 + desc: runs lua linter(selene) 16 + cmds: 17 + - selene . 18 + 19 + stylua:check: 20 + desc: runs stylua in check mode 21 + cmds: 22 + - stylua --check . 23 + 24 + stylua: 25 + desc: runs lua formatter 26 + cmds: 27 + - stylua . 28 + 29 + test: 30 + desc: runs all tests 31 + aliases: [tests, spec] 32 + cmds: 33 + - | 34 + nvim --headless \ 35 + -u ./scripts/minimal_init.lua \ 36 + -c "PlenaryBustedDirectory spec \ 37 + {minimal_init='./scripts/minimal_init.lua' \ 38 + ,sequential=true}" \ 39 + -c ":qa!" 40 + 41 + docgen: 42 + desc: generate vimhelp 43 + cmds: 44 + - | 45 + nvim --noplugin \ 46 + --headless \ 47 + -u "./scripts/minimal_init.lua" \ 48 + -c "luafile ./scripts/docgen.lua" \ 49 + -c ":qa!"
+1 -1
autoload/health/gopher.vim
··· 1 1 function! health#gopher#check() 2 - lua require"gopher.health".check() 2 + lua require("gopher.health").check() 3 3 endfunction
+1
doc/.gitignore
··· 1 + /tags
+220
doc/gopher.nvim.txt
··· 1 + *gopher.nvim* 2 + 3 + ============================================================================== 4 + 5 + gopher.nvim is a minimalistic plugin for Go development in Neovim written in Lua. 6 + It's not an LSP tool, the main goal of this plugin is add go tooling support in Neovim. 7 + 8 + ------------------------------------------------------------------------------ 9 + *gopher.nvim-table-of-contents* 10 + Table of Contents 11 + Setup....................................................|gopher.nvim-setup| 12 + Install dependencies..............................|gopher.nvim-install-deps| 13 + Configuration...........................................|gopher.nvim-config| 14 + Modifty struct tags................................|gopher.nvim-struct-tags| 15 + Auto implementation of interface methods..................|gopher.nvim-impl| 16 + Generating unit tests boilerplate......................|gopher.nvim-gotests| 17 + Iferr....................................................|gopher.nvim-iferr| 18 + Generate comments.....................................|gopher.nvim-comments| 19 + Setup `nvim-dap` for Go......................................|gopher.nvim-dap| 20 + 21 + ------------------------------------------------------------------------------ 22 + *gopher.nvim-setup* 23 + `gopher.setup`({user_config}) 24 + Setup function. This method simply merges default configs with opts table. 25 + You can read more about configuration at |gopher.nvim-config| 26 + Calling this function is optional, if you ok with default settings. Look |gopher.nvim.config-defaults| 27 + 28 + Usage ~ 29 + `require("gopher").setup {}` (replace `{}` with your `config` table) 30 + Parameters ~ 31 + {user_config} gopher.Config 32 + 33 + ------------------------------------------------------------------------------ 34 + *gopher.nvim-install-deps* 35 + `gopher.install_deps` 36 + Gopher.nvim implements most of its features using third-party tools. 37 + To install these tools, you can run `:GoInstallDeps` command 38 + or call `require("gopher").install_deps()` if you want ues lua api. 39 + 40 + 41 + ============================================================================== 42 + ------------------------------------------------------------------------------ 43 + *gopher.nvim-config* 44 + config it is the place where you can configure the plugin. 45 + also this is optional is you're ok with default settings. 46 + You can look at default options |gopher.nvim-config-defaults| 47 + 48 + ------------------------------------------------------------------------------ 49 + *gopher.nvim-config-defaults* 50 + `default_config` 51 + >lua 52 + local default_config = { 53 + --minidoc_replace_end 54 + 55 + -- log level, you might consider using DEBUG or TRACE for degugging the plugin 56 + ---@type number 57 + log_level = vim.log.levels.INFO, 58 + 59 + -- user specified paths to binaries 60 + ---@class gopher.ConfigCommand 61 + commands = { 62 + go = "go", 63 + gomodifytags = "gomodifytags", 64 + gotests = "gotests", 65 + impl = "impl", 66 + iferr = "iferr", 67 + dlv = "dlv", 68 + }, 69 + ---@class gopher.ConfigGotests 70 + gotests = { 71 + -- gotests doesn't have template named "default" so this plugin uses "default" to set the default template 72 + template = "default", 73 + -- path to a directory containing custom test code templates 74 + ---@type string|nil 75 + template_dir = nil, 76 + -- switch table tests from using slice to map (with test name for the key) 77 + -- works only with gotests installed from develop branch 78 + named = false, 79 + }, 80 + ---@class gopher.ConfigGoTag 81 + gotag = { 82 + ---@type gopher.ConfigGoTagTransform 83 + transform = "snakecase", 84 + }, 85 + } 86 + < 87 + Class ~ 88 + {gopher.Config} 89 + 90 + 91 + ============================================================================== 92 + ------------------------------------------------------------------------------ 93 + *gopher.nvim-struct-tags* 94 + struct-tags is utilizing the `gomodifytags` tool to add or remove tags to struct fields. 95 + Usage ~ 96 + - put your coursor on the struct 97 + - run `:GoTagAdd json` to add json tags to struct fields 98 + - run `:GoTagRm json` to remove json tags to struct fields 99 + 100 + note: if you dont spesify the tag it will use `json` as default 101 + 102 + simple example: 103 + >go 104 + // before 105 + type User struct { 106 + // ^ put your cursor here 107 + // run `:GoTagAdd yaml` 108 + ID int 109 + Name string 110 + } 111 + 112 + // after 113 + type User struct { 114 + ID int `yaml:id` 115 + Name string `yaml:name` 116 + } 117 + < 118 + 119 + 120 + ============================================================================== 121 + ------------------------------------------------------------------------------ 122 + *gopher.nvim-impl* 123 + impl is utilizing the `impl` tool to generate method stubs for interfaces. 124 + Usage ~ 125 + 126 + 1. put your coursor on the struct on which you want implement the interface 127 + and run `:GoImpl io.Reader` 128 + which will automatically choose the reciver for the methods and 129 + implement the `io.Reader` interface 130 + 2. same as previous but with custom receiver, so put your coursor on the struct 131 + run `:GoImpl w io.Writer` 132 + where `w` is the receiver and `io.Writer` is the interface 133 + 3. specift receiver, struct, and interface 134 + there's no need to put your coursor on the struct if you specify all arguments 135 + `:GoImpl r RequestReader io.Reader` 136 + where `r` is the receiver, `RequestReader` is the struct and `io.Reader` is the interface 137 + 138 + simple example: 139 + >go 140 + type BytesReader struct{} 141 + // ^ put your cursor here 142 + // run `:GoImpl b io.Reader` 143 + 144 + // this is what you will get 145 + func (b *BytesReader) Read(p []byte) (n int, err error) { 146 + panic("not implemented") // TODO: Implement 147 + } 148 + < 149 + 150 + 151 + ============================================================================== 152 + ------------------------------------------------------------------------------ 153 + *gopher.nvim-gotests* 154 + gotests is utilizing the `gotests` tool to generate unit tests boilerplate. 155 + Usage ~ 156 + 157 + - generate unit test for spesisfic function/method 158 + - to specift the function/method put your cursor on it 159 + - run `:GoTestAdd` 160 + 161 + - generate unit tests for all functions/methods in current file 162 + - run `:GoTestsAll` 163 + 164 + - generate unit tests only for exported(public) functions/methods 165 + - run `:GoTestsExp` 166 + 167 + you can also specify the template to use for generating the tests. see |gopher.nvim-config| 168 + more details about templates can be found at: https://github.com/cweill/gotests 169 + 170 + 171 + ------------------------------------------------------------------------------ 172 + *gopher.nvim-gotests-named* 173 + 174 + if you prefare using named tests, you can enable it in the config. 175 + but you would need to install `gotests@develop` because stable version doesn't support this feature. 176 + you can do it with: 177 + >lua 178 + -- simply run go get in your shell: 179 + go install github.com/cweill/gotests/...@develop 180 + 181 + -- if you want to install it within neovim, you can use one of this: 182 + 183 + vim.fn.jobstart("go install github.com/cweill/gotests/...@develop") 184 + 185 + -- or if you want to use mason: 186 + require("mason-tool-installer").setup { 187 + ensure_installed = { 188 + { "gotests", version = "develop" }, 189 + } 190 + } 191 + < 192 + 193 + if you choose to install `gotests` within neovim, i recommend adding it to your `build` section in your |lazy.nvim| 194 + 195 + 196 + ============================================================================== 197 + ------------------------------------------------------------------------------ 198 + *gopher.nvim-iferr* 199 + if you're using `iferr` tool, this module provides a way to automatically insert `if err != nil` check. 200 + Usage ~ 201 + execute `:GoIfErr` near any err variable to insert the check 202 + 203 + 204 + ============================================================================== 205 + ------------------------------------------------------------------------------ 206 + *gopher.nvim-comments* 207 + Usage ~ 208 + Execute `:GoCmt` to generate a comment for the current function/method/struct/etc on this line. 209 + This module provides a way to generate comments for Go code. 210 + 211 + 212 + ============================================================================== 213 + ------------------------------------------------------------------------------ 214 + *gopher.nvim-dap* 215 + This module sets up `nvim-dap` for Go. 216 + Usage ~ 217 + just call `require("gopher.dap").setup()`, and you're good to go. 218 + 219 + 220 + vim:tw=78:ts=8:noet:ft=help:norl:
-17
lua/gopher/_utils/_health.lua
··· 1 - return { 2 - ---@param lib string 3 - ---@return boolean 4 - lualib_is_found = function(lib) 5 - local is_found, _ = pcall(require, lib) 6 - return is_found 7 - end, 8 - 9 - ---@param bin string 10 - ---@return boolean 11 - binary_is_found = function(bin) 12 - if vim.fn.executable(bin) == 1 then 13 - return true 14 - end 15 - return false 16 - end, 17 - }
-40
lua/gopher/_utils/commands.lua
··· 1 - ---Run any go commands like `go generate`, `go get`, `go mod` 2 - ---@param cmd string 3 - ---@param ... string|string[] 4 - return function(cmd, ...) 5 - local Job = require "plenary.job" 6 - local c = require("gopher.config").config.commands 7 - local u = require "gopher._utils" 8 - 9 - local args = { ... } 10 - if #args == 0 then 11 - u.notify("please provice any arguments", "error") 12 - return 13 - end 14 - 15 - if cmd == "generate" and #args == 1 and args[1] == "%" then 16 - args[1] = vim.fn.expand "%" ---@diagnostic disable-line: missing-parameter 17 - elseif cmd == "get" then 18 - for i, arg in ipairs(args) do 19 - ---@diagnostic disable-next-line: param-type-mismatch 20 - local m = string.match(arg, "^https://(.*)$") or string.match(arg, "^http://(.*)$") or arg 21 - table.remove(args, i) 22 - table.insert(args, i, m) 23 - end 24 - end 25 - 26 - local cmd_args = vim.list_extend({ cmd }, args) ---@diagnostic disable-line: missing-parameter 27 - Job:new({ 28 - command = c.go, 29 - args = cmd_args, 30 - on_exit = function(_, retval) 31 - if retval ~= 0 then 32 - u.notify("command 'go " .. unpack(cmd_args) .. "' exited with code " .. retval, "error") 33 - u.notify(cmd .. " " .. unpack(cmd_args), "debug") 34 - return 35 - end 36 - 37 - u.notify("go " .. cmd .. " was success runned", "info") 38 - end, 39 - }):start() 40 - end
+33
lua/gopher/_utils/health_util.lua
··· 1 + local h = vim.health or require "health" 2 + local health = {} 3 + 4 + health.start = h.start or h.report_start 5 + health.ok = h.ok or h.report_ok 6 + health.warn = h.warn or h.report_warn 7 + health.error = h.error or h.report_error 8 + health.info = h.info or h.report_info 9 + 10 + ---@param module string 11 + ---@return boolean 12 + function health.is_lualib_found(module) 13 + local is_found, _ = pcall(require, module) 14 + return is_found 15 + end 16 + 17 + ---@param bin string 18 + ---@return boolean 19 + function health.is_binary_found(bin) 20 + if vim.fn.executable(bin) == 1 then 21 + return true 22 + end 23 + return false 24 + end 25 + 26 + ---@param ft string 27 + ---@return boolean 28 + function health.is_treesitter_parser_available(ft) 29 + local ok, parser = pcall(vim.treesitter.get_parser, 0, ft) 30 + return ok and parser ~= nil 31 + end 32 + 33 + return health
+30 -44
lua/gopher/_utils/init.lua
··· 1 - ---@diagnostic disable: param-type-mismatch 2 - return { 3 - ---@param t table 4 - ---@return boolean 5 - empty = function(t) 6 - if t == nil then 7 - return true 8 - end 1 + local c = require "gopher.config" 2 + local log = require "gopher._utils.log" 3 + local utils = {} 9 4 10 - return next(t) == nil 11 - end, 12 - 13 - ---@param s string 14 - ---@return string 15 - rtrim = function(s) 16 - local n = #s 17 - while n > 0 and s:find("^%s", n) do 18 - n = n - 1 19 - end 5 + ---@param msg string 6 + ---@param lvl number 7 + function utils.deferred_notify(msg, lvl) 8 + vim.defer_fn(function() 9 + vim.notify(msg, lvl, { 10 + title = c.___plugin_name, 11 + }) 12 + log.debug(msg) 13 + end, 0) 14 + end 20 15 21 - return s:sub(1, n) 22 - end, 23 - 24 - ---@param msg string 25 - ---@param lvl string|integer 26 - notify = function(msg, lvl) 27 - local l 28 - if lvl == "error" or lvl == 4 then 29 - l = vim.log.levels.ERROR 30 - elseif lvl == "info" or lvl == 2 then 31 - l = vim.log.levels.INFO 32 - elseif lvl == "debug" or lvl == 1 then 33 - l = vim.log.levels.DEBUG 34 - end 16 + ---@param msg string 17 + ---@param lvl? number 18 + function utils.notify(msg, lvl) 19 + lvl = lvl or vim.log.levels.INFO 20 + vim.notify(msg, lvl, { 21 + title = c.___plugin_name, 22 + }) 23 + log.debug(msg) 24 + end 35 25 36 - vim.defer_fn(function() 37 - vim.notify(msg, l) 38 - end, 0) 39 - end, 26 + -- safe require 27 + ---@param module string module name 28 + function utils.sreq(module) 29 + local ok, m = pcall(require, module) 30 + assert(ok, string.format("gopher.nvim dependency error: %s not installed", module)) 31 + return m 32 + end 40 33 41 - ---safe require 42 - ---@param name string module name 43 - sreq = function(name) 44 - local ok, m = pcall(require, name) 45 - assert(ok, string.format("gopher.nvim dependency error: %s not installed", name)) 46 - return m 47 - end, 48 - } 34 + return utils
+170
lua/gopher/_utils/log.lua
··· 1 + -- thanks https://github.com/tjdevries/vlog.nvim 2 + -- and https://github.com/williamboman/mason.nvim 3 + -- for the code i have stolen(or have inspected by idk) 4 + local c = require "gopher.config" 5 + 6 + ---@class Gopher.Logger 7 + ---@field get_outfile fun():string 8 + ---@field trace fun(...) 9 + ---@field fmt_trace fun(...) 10 + ---@field debug fun(...) 11 + ---@field fmt_debug fun(...) 12 + ---@field info fun(...) 13 + ---@field fmt_info fun(...) 14 + ---@field warn fun(...) 15 + ---@field fmt_warn fun(...) 16 + ---@field error fun(...) 17 + ---@field fmt_error fun(...) 18 + 19 + local config = { 20 + -- Name of the plugin. Prepended to log messages 21 + name = c.___plugin_name, 22 + 23 + -- Should print the output to neovim while running 24 + -- values: 'sync','async',false 25 + use_console = vim.env.GOPHER_VERBOSE_LOGS == "1", 26 + 27 + -- Should highlighting be used in console (using echohl) 28 + highlights = true, 29 + 30 + -- Should write to a file 31 + use_file = true, 32 + 33 + -- Level configuration 34 + modes = { 35 + { name = "trace", hl = "Comment", level = vim.log.levels.TRACE }, 36 + { name = "debug", hl = "Comment", level = vim.log.levels.DEBUG }, 37 + { name = "info", hl = "None", level = vim.log.levels.INFO }, 38 + { name = "warn", hl = "WarningMsg", level = vim.log.levels.WARN }, 39 + { name = "error", hl = "ErrorMsg", level = vim.log.levels.ERROR }, 40 + }, 41 + 42 + -- Can limit the number of decimals displayed for floats 43 + float_precision = 0.01, 44 + } 45 + 46 + ---@type Gopher.Logger 47 + ---@diagnostic disable-next-line: missing-fields 48 + local log = {} 49 + 50 + ---@return string 51 + function log.get_outfile() 52 + return table.concat { 53 + (vim.fn.has "nvim-0.8.0" == 1) and vim.fn.stdpath "log" or vim.fn.stdpath "cache", 54 + ("/%s.log"):format(config.name), 55 + } 56 + end 57 + 58 + -- selene: allow(incorrect_standard_library_use) 59 + local unpack = unpack or table.unpack 60 + 61 + do 62 + local round = function(x, increment) 63 + increment = increment or 1 64 + x = x / increment 65 + return (x > 0 and math.floor(x + 0.5) or math.ceil(x - 0.5)) * increment 66 + end 67 + 68 + local tbl_has_tostring = function(tbl) 69 + local mt = getmetatable(tbl) 70 + return mt and mt.__tostring ~= nil 71 + end 72 + 73 + local make_string = function(...) 74 + local t = {} 75 + for i = 1, select("#", ...) do 76 + local x = select(i, ...) 77 + 78 + if type(x) == "number" and config.float_precision then 79 + x = tostring(round(x, config.float_precision)) 80 + elseif type(x) == "table" and not tbl_has_tostring(x) then 81 + x = vim.inspect(x) 82 + else 83 + x = tostring(x) 84 + end 85 + 86 + t[#t + 1] = x 87 + end 88 + return table.concat(t, " ") 89 + end 90 + 91 + local log_at_level = function(level_config, message_maker, ...) 92 + -- Return early if we're below the current_log_level 93 + -- 94 + -- the log level source get from config directly because otherwise it doesnt work 95 + if level_config.level < c.log_level then 96 + return 97 + end 98 + local nameupper = level_config.name:upper() 99 + 100 + local msg = message_maker(...) 101 + local info = debug.getinfo(2, "Sl") 102 + local lineinfo = info.short_src .. ":" .. info.currentline 103 + 104 + -- Output to console 105 + if config.use_console then 106 + local log_to_console = function() 107 + local console_string = 108 + string.format("[%-6s%s] %s: %s", nameupper, os.date "%H:%M:%S", lineinfo, msg) 109 + 110 + if config.highlights and level_config.hl then 111 + vim.cmd(string.format("echohl %s", level_config.hl)) 112 + end 113 + 114 + local split_console = vim.split(console_string, "\n") 115 + for _, v in ipairs(split_console) do 116 + local formatted_msg = string.format("[%s] %s", config.name, vim.fn.escape(v, [["\]])) 117 + 118 + ---@diagnostic disable-next-line: param-type-mismatch 119 + local ok = pcall(vim.cmd, string.format([[echom "%s"]], formatted_msg)) 120 + if not ok then 121 + vim.api.nvim_out_write(msg .. "\n") 122 + end 123 + end 124 + 125 + if config.highlights and level_config.hl then 126 + vim.cmd "echohl NONE" 127 + end 128 + end 129 + if config.use_console == "sync" and not vim.in_fast_event() then 130 + log_to_console() 131 + else 132 + vim.schedule(log_to_console) 133 + end 134 + end 135 + 136 + -- Output to log file 137 + if config.use_file then 138 + local fp = assert(io.open(log.get_outfile(), "a")) 139 + local str = string.format("[%-6s%s] %s: %s\n", nameupper, os.date(), lineinfo, msg) 140 + fp:write(str) 141 + fp:close() 142 + end 143 + end 144 + 145 + for _, x in ipairs(config.modes) do 146 + -- log.info("these", "are", "separated") 147 + log[x.name] = function(...) ---@diagnostic disable-line: assign-type-mismatch 148 + return log_at_level(x, make_string, ...) 149 + end 150 + 151 + -- log.fmt_info("These are %s strings", "formatted") 152 + log[("fmt_%s"):format(x.name)] = function(...) ---@diagnostic disable-line: assign-type-mismatch 153 + return log_at_level(x, function(...) 154 + local passed = { ... } 155 + local fmt = table.remove(passed, 1) 156 + local inspected = {} 157 + for _, v in ipairs(passed) do 158 + if type(v) == "table" and tbl_has_tostring(v) then 159 + table.insert(inspected, v) 160 + else 161 + table.insert(inspected, vim.inspect(v)) 162 + end 163 + end 164 + return string.format(fmt, unpack(inspected)) 165 + end, ...) 166 + end 167 + end 168 + end 169 + 170 + return log
+53
lua/gopher/_utils/runner/gocmd.lua
··· 1 + local r = require "gopher._utils.runner" 2 + local c = require("gopher.config").commands 3 + local u = require "gopher._utils" 4 + local gocmd = {} 5 + 6 + ---@param args string[] 7 + ---@return string[] 8 + local function if_get(args) 9 + for i, arg in ipairs(args) do 10 + local m = string.match(arg, "^https://(.*)$") or string.match(arg, "^http://(.*)$") or arg 11 + table.remove(args, i) 12 + table.insert(args, i, m) 13 + end 14 + return args 15 + end 16 + 17 + ---@param args unknown[] 18 + ---@return string[] 19 + local function if_generate(args) 20 + if #args == 1 and args[1] == "%" then 21 + args[1] = vim.fn.expand "%" 22 + end 23 + return args 24 + end 25 + 26 + ---@param subcmd string 27 + ---@param args string[] 28 + ---@return string[]|nil 29 + function gocmd.run(subcmd, args) 30 + if #args == 0 then 31 + error "please provice any arguments" 32 + end 33 + 34 + if subcmd == "get" then 35 + args = if_get(args) 36 + end 37 + 38 + if subcmd == "generate" then 39 + args = if_generate(args) 40 + end 41 + 42 + return r.sync(c.go, { 43 + args = { subcmd, unpack(args) }, 44 + on_exit = function(data, status) 45 + if status ~= 0 then 46 + error("gocmd failed: " .. data) 47 + end 48 + u.notify(c.go .. " " .. subcmd .. " successful runned") 49 + end, 50 + }) 51 + end 52 + 53 + return gocmd
+33
lua/gopher/_utils/runner/init.lua
··· 1 + local Job = require "plenary.job" 2 + local runner = {} 3 + 4 + ---@class gopher.RunnerOpts 5 + ---@field args? string[] 6 + ---@field cwd? string? 7 + ---@field on_exit? fun(data:string, status:number) 8 + 9 + ---@param cmd string 10 + ---@param opts gopher.RunnerOpts 11 + ---@return string[]|nil 12 + function runner.sync(cmd, opts) 13 + local output 14 + Job:new({ 15 + command = cmd, 16 + args = opts.args, 17 + cwd = opts.cwd, 18 + on_stderr = function(_, data) 19 + vim.print(data) 20 + end, 21 + on_exit = function(data, status) 22 + output = data:result() 23 + vim.schedule(function() 24 + if opts.on_exit then 25 + opts.on_exit(output, status) 26 + end 27 + end) 28 + end, 29 + }):sync(60000 --[[1 min]]) 30 + return output 31 + end 32 + 33 + return runner
+14 -14
lua/gopher/_utils/ts/init.lua
··· 1 1 ---@diagnostic disable: param-type-mismatch 2 2 local nodes = require "gopher._utils.ts.nodes" 3 3 local u = require "gopher._utils" 4 - local M = { 4 + local ts = { 5 5 querys = { 6 6 struct_block = [[((type_declaration (type_spec name:(type_identifier) @struct.name type: (struct_type)))@struct.declaration)]], 7 7 em_struct_block = [[(field_declaration name:(field_identifier)@struct.name type: (struct_type)) @struct.declaration]], ··· 27 27 ---@param bufnr string|nil 28 28 ---@param do_notify boolean|nil 29 29 ---@return table|nil 30 - function M.get_struct_node_at_pos(row, col, bufnr, do_notify) 30 + function ts.get_struct_node_at_pos(row, col, bufnr, do_notify) 31 31 local notify = do_notify or true 32 - local query = M.querys.struct_block .. " " .. M.querys.em_struct_block 32 + local query = ts.querys.struct_block .. " " .. ts.querys.em_struct_block 33 33 local bufn = bufnr or vim.api.nvim_get_current_buf() 34 34 local ns = nodes.nodes_at_cursor(query, get_name_defaults(), bufn, row, col) 35 35 if ns == nil then 36 36 if notify then 37 - u.notify("struct not found", "warn") 37 + u.deferred_notify("struct not found", vim.log.levels.WARN) 38 38 end 39 39 else 40 40 return ns[#ns] ··· 46 46 ---@param bufnr string|nil 47 47 ---@param do_notify boolean|nil 48 48 ---@return table|nil 49 - function M.get_func_method_node_at_pos(row, col, bufnr, do_notify) 49 + function ts.get_func_method_node_at_pos(row, col, bufnr, do_notify) 50 50 local notify = do_notify or true 51 - local query = M.querys.func .. " " .. M.querys.method_name 51 + local query = ts.querys.func .. " " .. ts.querys.method_name 52 52 local bufn = bufnr or vim.api.nvim_get_current_buf() 53 53 local ns = nodes.nodes_at_cursor(query, get_name_defaults(), bufn, row, col) 54 54 if ns == nil then 55 55 if notify then 56 - u.notify("function not found", "warn") 56 + u.deferred_notify("function not found", vim.log.levels.WARN) 57 57 end 58 58 else 59 59 return ns[#ns] ··· 65 65 ---@param bufnr string|nil 66 66 ---@param do_notify boolean|nil 67 67 ---@return table|nil 68 - function M.get_package_node_at_pos(row, col, bufnr, do_notify) 68 + function ts.get_package_node_at_pos(row, col, bufnr, do_notify) 69 69 local notify = do_notify or true 70 70 -- stylua: ignore 71 71 if row > 10 then return end 72 - local query = M.querys.package 72 + local query = ts.querys.package 73 73 local bufn = bufnr or vim.api.nvim_get_current_buf() 74 74 local ns = nodes.nodes_at_cursor(query, get_name_defaults(), bufn, row, col) 75 75 if ns == nil then 76 76 if notify then 77 - u.notify("package not found", "warn") 77 + u.deferred_notify("package not found", vim.log.levels.WARN) 78 78 return nil 79 79 end 80 80 else ··· 87 87 ---@param bufnr string|nil 88 88 ---@param do_notify boolean|nil 89 89 ---@return table|nil 90 - function M.get_interface_node_at_pos(row, col, bufnr, do_notify) 90 + function ts.get_interface_node_at_pos(row, col, bufnr, do_notify) 91 91 local notify = do_notify or true 92 - local query = M.querys.interface 92 + local query = ts.querys.interface 93 93 local bufn = bufnr or vim.api.nvim_get_current_buf() 94 94 local ns = nodes.nodes_at_cursor(query, get_name_defaults(), bufn, row, col) 95 95 if ns == nil then 96 96 if notify then 97 - u.notify("interface not found", "warn") 97 + u.deferred_notify("interface not found", vim.log.levels.WARN) 98 98 end 99 99 else 100 100 return ns[#ns] 101 101 end 102 102 end 103 103 104 - return M 104 + return ts
+12 -8
lua/gopher/_utils/ts/nodes.lua
··· 1 + local ts_query = require "nvim-treesitter.query" 2 + local parsers = require "nvim-treesitter.parsers" 3 + local locals = require "nvim-treesitter.locals" 4 + local u = require "gopher._utils" 1 5 local M = {} 2 6 3 7 local function intersects(row, col, sRow, sCol, eRow, eCol) ··· 53 57 ---@param pos_row string 54 58 ---@return string 55 59 function M.get_all_nodes(query, lang, _, bufnr, pos_row, _) 56 - local ts_query = require "nvim-treesitter.query" 57 - local parsers = require "nvim-treesitter.parsers" 58 - local locals = require "nvim-treesitter.locals" 59 - 60 60 bufnr = bufnr or 0 61 61 pos_row = pos_row or 30000 62 62 ··· 113 113 ---@param col string 114 114 ---@return table 115 115 function M.nodes_at_cursor(query, default, bufnr, row, col) 116 - local u = require "gopher._utils" 117 - 118 116 bufnr = bufnr or vim.api.nvim_get_current_buf() 119 117 local ft = vim.api.nvim_buf_get_option(bufnr, "ft") 120 118 if row == nil or col == nil then ··· 123 121 124 122 local nodes = M.get_all_nodes(query, ft, default, bufnr, row, col) 125 123 if nodes == nil then 126 - u.notify("Unable to find any nodes. Place your cursor on a go symbol and try again", "debug") 124 + u.deferred_notify( 125 + "Unable to find any nodes. Place your cursor on a go symbol and try again", 126 + vim.log.levels.DEBUG 127 + ) 127 128 return nil 128 129 end 129 130 130 131 nodes = M.sort_nodes(M.intersect_nodes(nodes, row, col)) 131 132 if nodes == nil or #nodes == 0 then 132 - u.notify("Unable to find any nodes at pos. " .. tostring(row) .. ":" .. tostring(col), "debug") 133 + u.deferred_notify( 134 + "Unable to find any nodes at pos. " .. tostring(row) .. ":" .. tostring(col), 135 + vim.log.levels.DEBUG 136 + ) 133 137 return nil 134 138 end 135 139
-29
lua/gopher/api.lua
··· 1 - local API = {} 2 - local tags = require "gopher.struct_tags" 3 - local tests = require "gopher.gotests" 4 - local cmd = require "gopher._utils.commands" 5 - 6 - API.install_deps = require "gopher.installer" 7 - API.tags_add = tags.add 8 - API.tags_rm = tags.remove 9 - API.impl = require "gopher.impl" 10 - API.iferr = require "gopher.iferr" 11 - API.comment = require "gopher.comment" 12 - API.test_add = tests.func_test 13 - API.test_exported = tests.all_exported_tests 14 - API.tests_all = tests.all_tests 15 - 16 - API.get = function(...) 17 - cmd("get", ...) 18 - end 19 - API.mod = function(...) 20 - cmd("mod", ...) 21 - end 22 - API.generate = function(...) 23 - cmd("generate", ...) 24 - end 25 - API.work = function(...) 26 - cmd("work", ...) 27 - end 28 - 29 - return API
+9
lua/gopher/comment.lua
··· 1 + ---@toc_entry Generate comments 2 + ---@tag gopher.nvim-comments 3 + ---@usage Execute `:GoCmt` to generate a comment for the current function/method/struct/etc on this line. 4 + ---@text This module provides a way to generate comments for Go code. 5 + 6 + local log = require "gopher._utils.log" 7 + 1 8 local function generate(row, col) 2 9 local ts_utils = require "gopher._utils.ts" 3 10 local comment, ns = nil, nil ··· 32 39 return function() 33 40 local row, col = unpack(vim.api.nvim_win_get_cursor(0)) 34 41 local comment, ns = generate(row + 1, col + 1) 42 + 43 + log.debug("generated comment: " .. comment) 35 44 36 45 vim.api.nvim_win_set_cursor(0, { 37 46 ns.dim.s.r,
+82 -26
lua/gopher/config.lua
··· 1 - ---@class Config 2 - ---@field commands ConfigCommands 1 + ---@toc_entry Configuration 2 + ---@tag gopher.nvim-config 3 + ---@text config it is the place where you can configure the plugin. 4 + --- also this is optional is you're ok with default settings. 5 + --- You can look at default options |gopher.nvim-config-defaults| 3 6 4 - ---@class ConfigCommands 5 - ---@field go string 6 - ---@field gomodifytags string 7 - ---@field gotests string 8 - ---@field impl string 9 - ---@field iferr string 10 - ---@field dlv string 7 + ---@type gopher.Config 8 + ---@private 9 + local config = {} 11 10 12 - local M = { 13 - ---@type Config 14 - config = { 15 - ---set custom commands for tools 16 - commands = { 17 - go = "go", 18 - gomodifytags = "gomodifytags", 19 - gotests = "gotests", 20 - impl = "impl", 21 - iferr = "iferr", 22 - dlv = "dlv", 23 - }, 11 + ---@tag gopher.nvim-config.ConfigGoTagTransform 12 + ---@text Possible values for |gopher.Config|.gotag.transform: 13 + --- 14 + ---@private 15 + ---@alias gopher.ConfigGoTagTransform 16 + ---| "snakecase" "GopherUser" -> "gopher_user" 17 + ---| "camelcase" "GopherUser" -> "gopherUser" 18 + ---| "lispcase" "GopherUser" -> "gopher-user" 19 + ---| "pascalcase" "GopherUser" -> "GopherUser" 20 + ---| "titlecase" "GopherUser" -> "Gopher User" 21 + ---| "keep" keeps the original field name 22 + 23 + --minidoc_replace_start { 24 + 25 + ---@tag gopher.nvim-config-defaults 26 + ---@eval return MiniDoc.afterlines_to_code(MiniDoc.current.eval_section):gsub(">", ">lua") 27 + --- 28 + ---@class gopher.Config 29 + local default_config = { 30 + --minidoc_replace_end 31 + 32 + -- log level, you might consider using DEBUG or TRACE for degugging the plugin 33 + ---@type number 34 + log_level = vim.log.levels.INFO, 35 + 36 + -- user specified paths to binaries 37 + ---@class gopher.ConfigCommand 38 + commands = { 39 + go = "go", 40 + gomodifytags = "gomodifytags", 41 + gotests = "gotests", 42 + impl = "impl", 43 + iferr = "iferr", 44 + dlv = "dlv", 45 + }, 46 + ---@class gopher.ConfigGotests 47 + gotests = { 48 + -- gotests doesn't have template named "default" so this plugin uses "default" to set the default template 49 + template = "default", 50 + -- path to a directory containing custom test code templates 51 + ---@type string|nil 52 + template_dir = nil, 53 + -- switch table tests from using slice to map (with test name for the key) 54 + -- works only with gotests installed from develop branch 55 + named = false, 56 + }, 57 + ---@class gopher.ConfigGoTag 58 + gotag = { 59 + ---@type gopher.ConfigGoTagTransform 60 + transform = "snakecase", 24 61 }, 25 62 } 63 + --minidoc_afterlines_end 26 64 27 - ---Plugin setup function 28 - ---@param opts Config user config 29 - function M.setup(opts) 30 - M.config = vim.tbl_deep_extend("force", M.config, opts or {}) 65 + ---@type gopher.Config 66 + ---@private 67 + local _config = default_config 68 + 69 + -- I am kinda secret so don't tell anyone about me 70 + -- even dont use me 71 + -- 72 + -- if you don't belive me that i am secret see 73 + -- the line below it says @private 74 + ---@private 75 + _config.___plugin_name = "gopher.nvim" ---@diagnostic disable-line: inject-field 76 + 77 + ---@param user_config? gopher.Config 78 + ---@private 79 + function config.setup(user_config) 80 + _config = vim.tbl_deep_extend("force", default_config, user_config or {}) 31 81 end 32 82 33 - return M 83 + setmetatable(config, { 84 + __index = function(_, key) 85 + return _config[key] 86 + end, 87 + }) 88 + 89 + return config
+129
lua/gopher/dap.lua
··· 1 + ---@toc_entry Setup `nvim-dap` for Go 2 + ---@tag gopher.nvim-dap 3 + ---@text This module sets up `nvim-dap` for Go. 4 + ---@usage just call `require("gopher.dap").setup()`, and you're good to go. 5 + 6 + local c = require "gopher.config" 7 + local dap = {} 8 + 9 + dap.adapter = function(callback, config) 10 + local host = config.host or "127.0.0.1" 11 + local port = config.port or "38697" 12 + local addr = string.format("%s:%s", host, port) 13 + 14 + local handle, pid_or_err 15 + local stdout = assert(vim.loop.new_pipe(false)) 16 + local opts = { 17 + stdio = { nil, stdout }, 18 + args = { "dap", "-l", addr }, 19 + detached = true, 20 + } 21 + 22 + handle, pid_or_err = vim.loop.spawn(c.commands.dlv, opts, function(status) 23 + if not stdout or not handle then 24 + return 25 + end 26 + 27 + stdout:close() 28 + handle:close() 29 + if status ~= 0 then 30 + print("dlv exited with code", status) 31 + end 32 + end) 33 + 34 + assert(handle, "Error running dlv: " .. tostring(pid_or_err)) 35 + if stdout then 36 + stdout:read_start(function(err, chunk) 37 + assert(not err, err) 38 + if chunk then 39 + vim.schedule(function() 40 + require("dap.repl").append(chunk) 41 + end) 42 + end 43 + end) 44 + end 45 + 46 + -- wait for delve to start 47 + vim.defer_fn(function() 48 + callback { type = "server", host = "127.0.0.1", port = port } 49 + end, 100) 50 + end 51 + 52 + local function args_input() 53 + vim.ui.input({ prompt = "Args: " }, function(input) 54 + return vim.split(input or "", " ") 55 + end) 56 + end 57 + 58 + local function get_arguments() 59 + local co = coroutine.running() 60 + if co then 61 + return coroutine.create(function() 62 + local args = args_input() 63 + coroutine.resume(co, args) 64 + end) 65 + else 66 + return args_input() 67 + end 68 + end 69 + 70 + dap.configuration = { 71 + { 72 + type = "go", 73 + name = "Debug", 74 + request = "launch", 75 + program = "${file}", 76 + }, 77 + { 78 + type = "go", 79 + name = "Debug (Arguments)", 80 + request = "launch", 81 + program = "${file}", 82 + args = get_arguments, 83 + }, 84 + { 85 + type = "go", 86 + name = "Debug Package", 87 + request = "launch", 88 + program = "${fileDirname}", 89 + }, 90 + { 91 + type = "go", 92 + name = "Attach", 93 + mode = "local", 94 + request = "attach", 95 + processId = require("dap.utils").pick_process, 96 + }, 97 + { 98 + type = "go", 99 + name = "Debug test", 100 + request = "launch", 101 + mode = "test", 102 + program = "${file}", 103 + }, 104 + { 105 + type = "go", 106 + name = "Debug test (go.mod)", 107 + request = "launch", 108 + mode = "test", 109 + program = "./${relativeFileDirname}", 110 + }, 111 + } 112 + 113 + -- sets ups nvim-dap for Go in one function call. 114 + function dap.setup() 115 + vim.deprecate( 116 + "gopher.dap", 117 + "you might consider setting up `nvim-dap` manually, or using another plugin(https://github.com/leoluz/nvim-dap-go)", 118 + "v0.1.6", 119 + "gopher" 120 + ) 121 + 122 + local ok, d = pcall(require, "dap") 123 + assert(ok, "gopher.nvim dependency error: dap not installed") 124 + 125 + d.adapters.go = dap.adapter 126 + d.configurations.go = dap.configuration 127 + end 128 + 129 + return dap
-98
lua/gopher/dap/config.lua
··· 1 - ---@diagnostic disable: param-type-mismatch 2 - local function get_arguments() 3 - local function get() 4 - vim.ui.input({ prompt = "Args: " }, function(input) 5 - return vim.split(input or "", " ") ---@diagnostic disable-line: missing-parameter 6 - end) 7 - end 8 - 9 - local co = coroutine.running() 10 - if co then 11 - return coroutine.create(function() 12 - local args = get() 13 - coroutine.resume(co, args) 14 - end) 15 - else 16 - return get() 17 - end 18 - end 19 - 20 - return { 21 - adapter = function(callback, config) 22 - local handle, pid_or_err 23 - local stdout = vim.loop.new_pipe(false) 24 - local host = config.host or "127.0.0.1" 25 - local port = config.port or "38697" 26 - local addr = string.format("%s:%s", host, port) 27 - local opts = { 28 - stdio = { nil, stdout }, 29 - args = { "dap", "-l", addr }, 30 - detached = true, 31 - } 32 - 33 - handle, pid_or_err = vim.loop.spawn("dlv", opts, function(code) 34 - stdout:close() 35 - handle:close() 36 - if code ~= 0 then 37 - print("dlv exited with code", code) 38 - end 39 - end) 40 - 41 - assert(handle, "Error running dlv: " .. tostring(pid_or_err)) 42 - stdout:read_start(function(err, chunk) 43 - assert(not err, err) 44 - if chunk then 45 - vim.schedule(function() 46 - require("dap.repl").append(chunk) 47 - end) 48 - end 49 - end) 50 - 51 - -- Wait for delve to start 52 - vim.defer_fn(function() 53 - callback { type = "server", host = "127.0.0.1", port = port } 54 - end, 100) 55 - end, 56 - configuration = { 57 - { 58 - type = "go", 59 - name = "Debug", 60 - request = "launch", 61 - program = "${file}", 62 - }, 63 - { 64 - type = "go", 65 - name = "Debug (Arguments)", 66 - request = "launch", 67 - program = "${file}", 68 - args = get_arguments, 69 - }, 70 - { 71 - type = "go", 72 - name = "Debug Package", 73 - request = "launch", 74 - program = "${fileDirname}", 75 - }, 76 - { 77 - type = "go", 78 - name = "Attach", 79 - mode = "local", 80 - request = "attach", 81 - processId = require("dap.utils").pick_process, 82 - }, 83 - { 84 - type = "go", 85 - name = "Debug test", 86 - request = "launch", 87 - mode = "test", 88 - program = "${file}", 89 - }, 90 - { 91 - type = "go", 92 - name = "Debug test (go.mod)", 93 - request = "launch", 94 - mode = "test", 95 - program = "./${relativeFileDirname}", 96 - }, 97 - }, 98 - }
-13
lua/gopher/dap/init.lua
··· 1 - local M = {} 2 - 3 - ---setup nvim-dap for golang using 4 - function M.setup() 5 - local cfg = require "gopher.dap.config" 6 - local u = require "gopher._utils" 7 - 8 - local dap = u.sreq "dap" 9 - dap.adapters.go = cfg.adapter 10 - dap.configurations.go = cfg.configuration 11 - end 12 - 13 - return M
+85 -54
lua/gopher/gotests.lua
··· 1 + ---@toc_entry Generating unit tests boilerplate 2 + ---@tag gopher.nvim-gotests 3 + ---@text gotests is utilizing the `gotests` tool to generate unit tests boilerplate. 4 + ---@usage 5 + --- - generate unit test for spesisfic function/method 6 + --- - to specift the function/method put your cursor on it 7 + --- - run `:GoTestAdd` 8 + --- 9 + --- - generate unit tests for all functions/methods in current file 10 + --- - run `:GoTestsAll` 11 + --- 12 + --- - generate unit tests only for exported(public) functions/methods 13 + --- - run `:GoTestsExp` 14 + --- 15 + --- you can also specify the template to use for generating the tests. see |gopher.nvim-config| 16 + --- more details about templates can be found at: https://github.com/cweill/gotests 17 + --- 18 + 19 + ---@tag gopher.nvim-gotests-named 20 + ---@text 21 + --- if you prefare using named tests, you can enable it in the config. 22 + --- but you would need to install `gotests@develop` because stable version doesn't support this feature. 23 + --- you can do it with: 24 + --- >lua 25 + --- -- simply run go get in your shell: 26 + --- go install github.com/cweill/gotests/...@develop 27 + --- 28 + --- -- if you want to install it within neovim, you can use one of this: 29 + --- 30 + --- vim.fn.jobstart("go install github.com/cweill/gotests/...@develop") 31 + --- 32 + --- -- or if you want to use mason: 33 + --- require("mason-tool-installer").setup { 34 + --- ensure_installed = { 35 + --- { "gotests", version = "develop" }, 36 + --- } 37 + --- } 38 + --- < 39 + --- 40 + --- if you choose to install `gotests` within neovim, i recommend adding it to your `build` section in your |lazy.nvim| 41 + 42 + local c = require "gopher.config" 43 + local ts_utils = require "gopher._utils.ts" 44 + local r = require "gopher._utils.runner" 1 45 local u = require "gopher._utils" 2 - local M = {} 46 + local log = require "gopher._utils.log" 47 + local gotests = {} 48 + 49 + ---@param args table 50 + ---@private 51 + local function add_test(args) 52 + if c.gotests.named then 53 + table.insert(args, "-named") 54 + end 55 + 56 + if c.gotests.template_dir then 57 + table.insert(args, "-template_dir") 58 + table.insert(args, c.gotests.template_dir) 59 + end 60 + 61 + if c.gotests.template ~= "default" then 62 + table.insert(args, "-template") 63 + table.insert(args, c.gotests.template) 64 + end 3 65 4 - ---@param cmd_args table 5 - local function run(cmd_args) 6 - local Job = require "plenary.job" 7 - local c = require("gopher.config").config.commands 66 + table.insert(args, "-w") 67 + table.insert(args, vim.fn.expand "%") 68 + 69 + log.debug("generating tests with args: ", args) 8 70 9 - Job:new({ 10 - command = c.gotests, 11 - args = cmd_args, 12 - on_exit = function(_, retval) 13 - if retval ~= 0 then 14 - u.notify("command 'go " .. unpack(cmd_args) .. "' exited with code " .. retval, "error") 15 - return 71 + return r.sync(c.commands.gotests, { 72 + args = args, 73 + on_exit = function(data, status) 74 + if not status == 0 then 75 + error("gotests failed: " .. data) 16 76 end 17 77 18 - u.notify("unit test(s) generated", "info") 78 + u.notify "unit test(s) generated" 19 79 end, 20 - }):start() 80 + }) 21 81 end 22 82 23 - ---@param args table 24 - local function add_test(args) 25 - local fpath = vim.fn.expand "%" ---@diagnostic disable-line: missing-parameter 26 - table.insert(args, "-w") 27 - table.insert(args, fpath) 28 - run(args) 29 - end 30 - 31 - ---generate unit test for one function 32 - ---@param parallel boolean 33 - function M.func_test(parallel) 34 - local ts_utils = require "gopher._utils.ts" 35 - 83 + -- generate unit test for one function 84 + function gotests.func_test() 36 85 local ns = ts_utils.get_func_method_node_at_pos(unpack(vim.api.nvim_win_get_cursor(0))) 37 86 if ns == nil or ns.name == nil then 38 - u.notify("cursor on func/method and execute the command again", "info") 87 + u.notify("cursor on func/method and execute the command again", vim.log.levels.WARN) 39 88 return 40 89 end 41 90 42 - local cmd_args = { "-only", ns.name } 43 - if parallel then 44 - table.insert(cmd_args, "-parallel") 45 - end 46 - 47 - add_test(cmd_args) 91 + add_test { "-only", ns.name } 48 92 end 49 93 50 - ---generate unit tests for all functions in current file 51 - ---@param parallel boolean 52 - function M.all_tests(parallel) 53 - local cmd_args = { "-all" } 54 - if parallel then 55 - table.insert(cmd_args, "-parallel") 56 - end 57 - 58 - add_test(cmd_args) 94 + -- generate unit tests for all functions in current file 95 + function gotests.all_tests() 96 + add_test { "-all" } 59 97 end 60 98 61 - ---generate unit tests for all exported functions 62 - ---@param parallel boolean 63 - function M.all_exported_tests(parallel) 64 - local cmd_args = {} 65 - if parallel then 66 - table.insert(cmd_args, "-parallel") 67 - end 68 - 69 - table.insert(cmd_args, "-exported") 70 - add_test(cmd_args) 99 + -- generate unit tests for all exported functions 100 + function gotests.all_exported_tests() 101 + add_test { "-exported" } 71 102 end 72 103 73 - return M 104 + return gotests
+54 -28
lua/gopher/health.lua
··· 1 - local c = require("gopher.config").config.commands 1 + local health = {} 2 + local cmd = require("gopher.config").commands 3 + local u = require "gopher._utils.health_util" 2 4 3 - local requried_for_work_msg = "Gopher.nvim will not work without it!" 4 - local M = { 5 - _required = { 6 - plugins = { 7 - { lib = "plenary", help = requried_for_work_msg }, 8 - { lib = "nvim-treesitter", help = requried_for_work_msg }, 9 - { lib = "dap", help = "Required for set upping debugger" }, 5 + local deps = { 6 + plugin = { 7 + { lib = "dap", msg = "required for `gopher.dap`", optional = true }, 8 + { lib = "plenary", msg = "required for everyting in gopher.nvim", optional = false }, 9 + { lib = "nvim-treesitter", msg = "required for everyting in gopher.nvim", optional = false }, 10 + }, 11 + bin = { 12 + { 13 + bin = cmd.go, 14 + msg = "required for `:GoGet`, `:GoMod`, `:GoGenerate`, `:GoWork`, `:GoInstallDeps`", 15 + optional = false, 10 16 }, 11 - binarys = { 12 - { bin = c.go, help = "required for GoMod, GoGet, GoGenerate command" }, 13 - { bin = c.gomodifytags, help = "required for modify struct tags" }, 14 - { bin = c.impl, help = "required for interface implementing" }, 15 - { bin = c.gotests, help = "required for test(s) generation" }, 16 - { bin = c.dlv, help = "required for debugger(nvim-dap)" }, 17 + { bin = cmd.gomodifytags, msg = "required for `:GoTagAdd`, `:GoTagRm`", optional = false }, 18 + { bin = cmd.impl, msg = "required for `:GoImpl`", optional = false }, 19 + { bin = cmd.iferr, msg = "required for `:GoIfErr`", optional = false }, 20 + { 21 + bin = cmd.gotests, 22 + msg = "required for `:GoTestAdd`, `:GoTestsAll`, `:GoTestsExp`", 23 + optional = false, 17 24 }, 25 + { bin = cmd.dlv, msg = "required for debugging, (`nvim-dap`, `gopher.dap`)", optional = true }, 26 + }, 27 + treesitter = { 28 + { parser = "go", msg = "required for `gopher.nvim`", optional = false }, 18 29 }, 19 30 } 20 31 21 - function M.check() 22 - local health = vim.health or require "health" 23 - local u = require "gopher._utils._health" 32 + function health.check() 33 + u.start "required plugins" 34 + for _, plugin in ipairs(deps.plugin) do 35 + if u.is_lualib_found(plugin.lib) then 36 + u.ok(plugin.lib .. " installed") 37 + else 38 + if plugin.optional then 39 + u.warn(plugin.lib .. " not found, " .. plugin.msg) 40 + else 41 + u.error(plugin.lib .. " not found, " .. plugin.msg) 42 + end 43 + end 44 + end 24 45 25 - health.report_start "Required plugins" 26 - for _, plugin in ipairs(M._required.plugins) do 27 - if u.lualib_is_found(plugin.lib) then 28 - health.report_ok(plugin.lib .. " installed.") 46 + u.start "required binaries" 47 + u.info "all those binaries can be installed by `:GoInstallDeps`" 48 + for _, bin in ipairs(deps.bin) do 49 + if u.is_binary_found(bin.bin) then 50 + u.ok(bin.bin .. " installed") 29 51 else 30 - health.report_error(plugin.lib .. " not found. " .. plugin.help) 52 + if bin.optional then 53 + u.warn(bin.bin .. " not found, " .. bin.msg) 54 + else 55 + u.error(bin.bin .. " not found, " .. bin.msg) 56 + end 31 57 end 32 58 end 33 59 34 - health.report_start "Required go tools" 35 - for _, binary in ipairs(M._required.binarys) do 36 - if u.binary_is_found(binary.bin) then 37 - health.report_ok(binary.bin .. " installed") 60 + u.start "required treesitter parsers" 61 + for _, parser in ipairs(deps.treesitter) do 62 + if u.is_treesitter_parser_available(parser.parser) then 63 + u.ok(parser.parser .. " parser installed") 38 64 else 39 - health.report_warn(binary.bin .. " is not installed but " .. binary.help) 65 + u.error(parser.parser .. " parser not found, " .. parser.msg) 40 66 end 41 67 end 42 68 end 43 69 44 - return M 70 + return health
+16 -11
lua/gopher/iferr.lua
··· 1 - ---Add iferr declaration 2 - ---That's Lua of vimscript implementation of: 3 - ---github.com/koron/iferr 4 - return function() 5 - local c = require("gopher.config").config.commands 6 - local u = require "gopher._utils" 1 + ---@toc_entry Iferr 2 + ---@tag gopher.nvim-iferr 3 + ---@text if you're using `iferr` tool, this module provides a way to automatically insert `if err != nil` check. 4 + ---@usage execute `:GoIfErr` near any err variable to insert the check 5 + 6 + local c = require "gopher.config" 7 + local log = require "gopher._utils.log" 8 + local iferr = {} 7 9 10 + -- That's Lua implementation: github.com/koron/iferr 11 + function iferr.iferr() 8 12 local boff = vim.fn.wordcount().cursor_bytes 9 - local cmd = (c.iferr .. " -pos " .. boff) 10 - local data = vim.fn.systemlist(cmd, vim.fn.bufnr "%") 13 + local pos = vim.fn.getcurpos()[2] 11 14 15 + local data = vim.fn.systemlist((c.commands.iferr .. " -pos " .. boff), vim.fn.bufnr "%") 12 16 if vim.v.shell_error ~= 0 then 13 - u.notify("command " .. cmd .. " exited with code " .. vim.v.shell_error, "error") 14 - return 17 + error("iferr failed: " .. data) 18 + log.error("failed. output: " .. data) 15 19 end 16 20 17 - local pos = vim.fn.getcurpos()[2] 18 21 vim.fn.append(pos, data) 19 22 vim.cmd [[silent normal! j=2j]] 20 23 vim.fn.setpos(".", pos) 21 24 end 25 + 26 + return iferr
+51 -28
lua/gopher/impl.lua
··· 1 + ---@toc_entry Auto implementation of interface methods 2 + ---@tag gopher.nvim-impl 3 + ---@text impl is utilizing the `impl` tool to generate method stubs for interfaces. 4 + ---@usage 5 + --- 1. put your coursor on the struct on which you want implement the interface 6 + --- and run `:GoImpl io.Reader` 7 + --- which will automatically choose the reciver for the methods and 8 + --- implement the `io.Reader` interface 9 + --- 2. same as previous but with custom receiver, so put your coursor on the struct 10 + --- run `:GoImpl w io.Writer` 11 + --- where `w` is the receiver and `io.Writer` is the interface 12 + --- 3. specift receiver, struct, and interface 13 + --- there's no need to put your coursor on the struct if you specify all arguments 14 + --- `:GoImpl r RequestReader io.Reader` 15 + --- where `r` is the receiver, `RequestReader` is the struct and `io.Reader` is the interface 16 + --- 17 + --- simple example: 18 + --- >go 19 + --- type BytesReader struct{} 20 + --- // ^ put your cursor here 21 + --- // run `:GoImpl b io.Reader` 22 + --- 23 + --- // this is what you will get 24 + --- func (b *BytesReader) Read(p []byte) (n int, err error) { 25 + --- panic("not implemented") // TODO: Implement 26 + --- } 27 + --- < 28 + 29 + local c = require("gopher.config").commands 30 + local r = require "gopher._utils.runner" 31 + local ts_utils = require "gopher._utils.ts" 1 32 local u = require "gopher._utils" 33 + local impl = {} 2 34 3 35 ---@return string 36 + ---@private 4 37 local function get_struct() 5 - local ts_utils = require "gopher._utils.ts" 6 - 7 38 local ns = ts_utils.get_struct_node_at_pos(unpack(vim.api.nvim_win_get_cursor(0))) 8 39 if ns == nil then 9 - u.notify("put cursor on a struct or specify a receiver", "info") 40 + u.deferred_notify("put cursor on a struct or specify a receiver", vim.log.levels.INFO) 10 41 return "" 11 42 end 12 43 ··· 18 49 return ns.name 19 50 end 20 51 21 - return function(...) 22 - local c = require("gopher.config").config.commands 23 - local Job = require "plenary.job" 24 - 52 + function impl.impl(...) 25 53 local args = { ... } 26 54 local iface, recv_name = "", "" 27 55 local recv = get_struct() ··· 30 58 iface = vim.fn.input "impl: generating method stubs for interface: " 31 59 vim.cmd "redraw!" 32 60 if iface == "" then 33 - u.notify("usage: GoImpl f *File io.Reader", "info") 61 + u.deferred_notify("usage: GoImpl f *File io.Reader", vim.log.levels.INFO) 34 62 return 35 63 end 36 64 elseif #args == 1 then -- :GoImpl io.Reader ··· 48 76 recv = string.format("%s %s", recv_name, recv) 49 77 end 50 78 51 - -- stylua: ignore 52 - local cmd_args = { 53 - "-dir", vim.fn.fnameescape(vim.fn.expand "%:p:h"), ---@diagnostic disable-line: missing-parameter 54 - recv, 55 - iface 56 - } 57 - 58 - local res_data 59 - Job:new({ 60 - command = c.impl, 61 - args = cmd_args, 62 - on_exit = function(data, retval) 63 - if retval ~= 0 then 64 - u.notify("command 'impl " .. unpack(cmd_args) .. "' exited with code " .. retval, "error") 65 - return 79 + local output = r.sync(c.impl, { 80 + args = { 81 + "-dir", 82 + vim.fn.fnameescape(vim.fn.expand "%:p:h" --[[@as string]]), 83 + recv, 84 + iface, 85 + }, 86 + on_exit = function(data, status) 87 + if not status == 0 then 88 + error("impl failed: " .. data) 66 89 end 67 - 68 - res_data = data:result() 69 90 end, 70 - }):sync() 91 + }) 71 92 72 93 local pos = vim.fn.getcurpos()[2] 73 - table.insert(res_data, 1, "") 74 - vim.fn.append(pos, res_data) 94 + table.insert(output, 1, "") 95 + vim.fn.append(pos, output) 75 96 end 97 + 98 + return impl
+68 -3
lua/gopher/init.lua
··· 1 - local GOPHER = {} 1 + --- *gopher.nvim* 2 + --- 3 + --- ============================================================================== 4 + --- 5 + --- gopher.nvim is a minimalistic plugin for Go development in Neovim written in Lua. 6 + --- It's not an LSP tool, the main goal of this plugin is add go tooling support in Neovim. 7 + 8 + --- Table of Contents 9 + ---@tag gopher.nvim-table-of-contents 10 + ---@toc 11 + 12 + local log = require "gopher._utils.log" 13 + local tags = require "gopher.struct_tags" 14 + local tests = require "gopher.gotests" 15 + local gocmd = require("gopher._utils.runner.gocmd").run 16 + local gopher = {} 17 + 18 + ---@toc_entry Setup 19 + ---@tag gopher.nvim-setup 20 + ---@text Setup function. This method simply merges default configs with opts table. 21 + --- You can read more about configuration at |gopher.nvim-config| 22 + --- Calling this function is optional, if you ok with default settings. Look |gopher.nvim.config-defaults| 23 + --- 24 + ---@usage `require("gopher").setup {}` (replace `{}` with your `config` table) 25 + ---@param user_config gopher.Config 26 + gopher.setup = function(user_config) 27 + log.debug "setting up config" 28 + require("gopher.config").setup(user_config) 29 + log.debug(vim.inspect(user_config)) 30 + end 31 + 32 + ---@toc_entry Install dependencies 33 + ---@tag gopher.nvim-install-deps 34 + ---@text Gopher.nvim implements most of its features using third-party tools. 35 + --- To install these tools, you can run `:GoInstallDeps` command 36 + --- or call `require("gopher").install_deps()` if you want ues lua api. 37 + gopher.install_deps = require("gopher.installer").install_deps 38 + 39 + gopher.impl = require("gopher.impl").impl 40 + gopher.iferr = require("gopher.iferr").iferr 41 + gopher.comment = require "gopher.comment" 42 + 43 + gopher.tags = { 44 + add = tags.add, 45 + rm = tags.remove, 46 + } 47 + 48 + gopher.test = { 49 + add = tests.func_test, 50 + exported = tests.all_exported_tests, 51 + all = tests.all_tests, 52 + } 53 + 54 + gopher.get = function(...) 55 + gocmd("get", { ... }) 56 + end 57 + 58 + gopher.mod = function(...) 59 + gocmd("mod", { ... }) 60 + end 61 + 62 + gopher.generate = function(...) 63 + gocmd("generate", { ... }) 64 + end 2 65 3 - GOPHER.setup = require("gopher.config").setup 66 + gopher.work = function(...) 67 + gocmd("work", { ... }) 68 + end 4 69 5 - return GOPHER 70 + return gopher
+14 -13
lua/gopher/installer.lua
··· 1 + local c = require("gopher.config").commands 2 + local r = require "gopher._utils.runner" 3 + local u = require "gopher._utils" 4 + local installer = {} 5 + 1 6 local urls = { 2 7 gomodifytags = "github.com/fatih/gomodifytags", 3 8 impl = "github.com/josharian/impl", ··· 8 13 9 14 ---@param pkg string 10 15 local function install(pkg) 11 - local Job = require "plenary.job" 12 - local u = require "gopher._utils" 13 - 14 16 local url = urls[pkg] .. "@latest" 15 - 16 - Job:new({ 17 - command = "go", 17 + r.sync(c.go, { 18 18 args = { "install", url }, 19 - on_exit = function(_, retval) 20 - if retval ~= 0 then 21 - u.notify("command 'go install " .. url .. "' exited with code " .. retval, "error") 19 + on_exit = function(data, status) 20 + if not status == 0 then 21 + error("go install failed: " .. data) 22 22 return 23 23 end 24 - 25 - u.notify("install " .. url .. " finished", "info ") 24 + u.notify("installed: " .. url) 26 25 end, 27 - }):start() 26 + }) 28 27 end 29 28 30 29 ---Install required go deps 31 - return function() 30 + function installer.install_deps() 32 31 for pkg, _ in pairs(urls) do 33 32 install(pkg) 34 33 end 35 34 end 35 + 36 + return installer
+43 -34
lua/gopher/struct_tags.lua
··· 1 - local M = {} 1 + ---@toc_entry Modifty struct tags 2 + ---@tag gopher.nvim-struct-tags 3 + ---@text struct-tags is utilizing the `gomodifytags` tool to add or remove tags to struct fields. 4 + ---@usage - put your coursor on the struct 5 + --- - run `:GoTagAdd json` to add json tags to struct fields 6 + --- - run `:GoTagRm json` to remove json tags to struct fields 7 + --- 8 + --- note: if you dont spesify the tag it will use `json` as default 9 + --- 10 + --- simple example: 11 + --- >go 12 + --- // before 13 + --- type User struct { 14 + --- // ^ put your cursor here 15 + --- // run `:GoTagAdd yaml` 16 + --- ID int 17 + --- Name string 18 + --- } 19 + --- 20 + --- // after 21 + --- type User struct { 22 + --- ID int `yaml:id` 23 + --- Name string `yaml:name` 24 + --- } 25 + --- < 26 + 27 + local ts_utils = require "gopher._utils.ts" 28 + local r = require "gopher._utils.runner" 29 + local c = require "gopher.config" 30 + local struct_tags = {} 2 31 3 32 local function modify(...) 4 - local ts_utils = require "gopher._utils.ts" 5 - local Job = require "plenary.job" 6 - local c = require("gopher.config").config.commands 7 - local u = require "gopher._utils" 8 - 9 33 local fpath = vim.fn.expand "%" ---@diagnostic disable-line: missing-parameter 10 34 local ns = ts_utils.get_struct_node_at_pos(unpack(vim.api.nvim_win_get_cursor(0))) 11 35 if ns == nil then ··· 14 38 15 39 -- stylua: ignore 16 40 local cmd_args = { 41 + "-transform", c.gotag.transform, 17 42 "-format", "json", 18 43 "-file", fpath, 19 44 "-w" ··· 40 65 table.insert(cmd_args, "json") 41 66 end 42 67 43 - -- get result of "gomodifytags" works 44 - local res_data 45 - Job:new({ 46 - command = c.gomodifytags, 68 + local output = r.sync(c.commands.gomodifytags, { 47 69 args = cmd_args, 48 - on_exit = function(data, retval) 49 - if retval ~= 0 then 50 - u.notify( 51 - "command 'gomodifytags " .. unpack(cmd_args) .. "' exited with code " .. retval, 52 - "error" 53 - ) 54 - return 70 + on_exit = function(data, status) 71 + if not status == 0 then 72 + error("gotag failed: " .. data) 55 73 end 56 - 57 - res_data = data:result() 58 74 end, 59 - }):sync() 75 + }) 60 76 61 77 -- decode goted value 62 - local tagged = vim.json.decode(table.concat(res_data)) 78 + local tagged = vim.json.decode(table.concat(output)) 63 79 if 64 80 tagged.errors ~= nil 65 81 or tagged.lines == nil 66 82 or tagged["start"] == nil 67 83 or tagged["start"] == 0 68 84 then 69 - u.notify("failed to set tags " .. vim.inspect(tagged), "error") 85 + error("failed to set tags " .. vim.inspect(tagged)) 70 86 end 71 87 72 - for i, v in ipairs(tagged.lines) do 73 - tagged.lines[i] = u.rtrim(v) 74 - end 75 - 76 - -- write goted tags 77 88 vim.api.nvim_buf_set_lines( 78 89 0, 79 90 tagged.start - 1, ··· 84 95 vim.cmd "write" 85 96 end 86 97 87 - ---add tags to struct under cursor 88 - ---@param ... unknown 89 - function M.add(...) 98 + -- add tags to struct under cursor 99 + function struct_tags.add(...) 90 100 local arg = { ... } 91 101 if #arg == nil or arg == "" then 92 102 arg = { "json" } ··· 100 110 modify(unpack(cmd_args)) 101 111 end 102 112 103 - ---remove tags to struct under cursor 104 - ---@param ... unknown 105 - function M.remove(...) 113 + -- remove tags to struct under cursor 114 + function struct_tags.remove(...) 106 115 local arg = { ... } 107 116 if #arg == nil or arg == "" then 108 117 arg = { "json" } ··· 116 125 modify(unpack(cmd_args)) 117 126 end 118 127 119 - return M 128 + return struct_tags
+14 -13
plugin/gopher.vim
··· 1 - command! -nargs=* GoTagAdd :lua require"gopher.api".tags_add(<f-args>) 2 - command! -nargs=* GoTagRm :lua require"gopher.api".tags_rm(<f-args>) 3 - command! -nargs=* GoTestAdd :lua require"gopher.api".test_add(<f-args>) 4 - command! -nargs=* GoTestsAll :lua require"gopher.api".tests_all(<f-args>) 5 - command! -nargs=* GoTestsExp :lua require"gopher.api".test_exported(<f-args>) 6 - command! -nargs=* GoMod :lua require"gopher.api".mod(<f-args>) 7 - command! -nargs=* GoGet :lua require"gopher.api".get(<f-args>) 8 - command! -nargs=* GoWork :lua require"gopher.api".work(<f-args>) 9 - command! -nargs=* GoImpl :lua require"gopher.api".impl(<f-args>) 10 - command! -nargs=* GoGenerate :lua require"gopher.api".generate(<f-args>) 11 - command! GoCmt :lua require"gopher.api".comment() 12 - command! GoIfErr :lua require"gopher.api".iferr() 13 - command! GoInstallDeps :lua require"gopher.api".install_deps() 1 + command! -nargs=* GoTagAdd :lua require"gopher".tags.add(<f-args>) 2 + command! -nargs=* GoTagRm :lua require"gopher".tags.rm(<f-args>) 3 + command! GoTestAdd :lua require"gopher".test.add() 4 + command! GoTestsAll :lua require"gopher".test.all() 5 + command! GoTestsExp :lua require"gopher".test.exported() 6 + command! -nargs=* GoMod :lua require"gopher".mod(<f-args>) 7 + command! -nargs=* GoGet :lua require"gopher".get(<f-args>) 8 + command! -nargs=* GoWork :lua require"gopher".work(<f-args>) 9 + command! -nargs=* GoImpl :lua require"gopher".impl(<f-args>) 10 + command! -nargs=* GoGenerate :lua require"gopher".generate(<f-args>) 11 + command! GoCmt :lua require"gopher".comment() 12 + command! GoIfErr :lua require"gopher".iferr() 13 + command! GoInstallDeps :lua require"gopher".install_deps() 14 + command! GopherLog :lua vim.cmd("tabnew " .. require("gopher._utils.log").get_outfile())
+33
scripts/docgen.lua
··· 1 + ---@diagnostic disable: undefined-global 2 + --# selene: allow(undefined_variable) 3 + 4 + local okay, minidoc = pcall(require, "mini.doc") 5 + if not okay then 6 + error "mini.doc not found, please install it. https://github.com/echasnovski/mini.doc" 7 + return 8 + end 9 + 10 + local files = { 11 + "lua/gopher/init.lua", 12 + "lua/gopher/config.lua", 13 + "lua/gopher/struct_tags.lua", 14 + "lua/gopher/impl.lua", 15 + "lua/gopher/gotests.lua", 16 + "lua/gopher/iferr.lua", 17 + "lua/gopher/comment.lua", 18 + "lua/gopher/dap.lua", 19 + } 20 + 21 + minidoc.setup() 22 + 23 + local hooks = vim.deepcopy(minidoc.default_hooks) 24 + hooks.write_pre = function(lines) 25 + -- Remove first two lines with `======` and `------` delimiters to comply 26 + -- with `:h local-additions` template 27 + table.remove(lines, 1) 28 + table.remove(lines, 1) 29 + 30 + return lines 31 + end 32 + 33 + MiniDoc.generate(files, "doc/gopher.nvim.txt", { hooks = hooks })
+34
scripts/minimal_init.lua
··· 1 + local function root(p) 2 + local f = debug.getinfo(1, "S").source:sub(2) 3 + return vim.fn.fnamemodify(f, ":p:h:h") .. "/" .. (p or "") 4 + end 5 + 6 + local function install_plug(plugin) 7 + local name = plugin:match ".*/(.*)" 8 + local package_root = root ".tests/site/pack/deps/start/" 9 + if not vim.loop.fs_stat(package_root .. name) then 10 + print("Installing " .. plugin) 11 + vim.fn.mkdir(package_root, "p") 12 + vim.fn.system { 13 + "git", 14 + "clone", 15 + "--depth=1", 16 + "https://github.com/" .. plugin .. ".git", 17 + package_root .. "/" .. name, 18 + } 19 + end 20 + end 21 + 22 + vim.cmd [[set runtimepath=$VIMRUNTIME]] 23 + vim.opt.runtimepath:append(root()) 24 + vim.opt.packpath = { root ".tests/site" } 25 + vim.notify = print 26 + 27 + install_plug "nvim-lua/plenary.nvim" 28 + install_plug "nvim-treesitter/nvim-treesitter" 29 + install_plug "echasnovski/mini.doc" -- used for docs generation 30 + 31 + vim.env.XDG_CONFIG_HOME = root ".tests/config" 32 + vim.env.XDG_DATA_HOME = root ".tests/data" 33 + vim.env.XDG_STATE_HOME = root ".tests/state" 34 + vim.env.XDG_CACHE_HOME = root ".tests/cache"
+2 -1
selene.toml
··· 1 - std="nvim+lua51" 1 + std = "nvim+lua52" 2 + exclude = [".tests/*"]
-41
spec/gopher_config_spec.lua
··· 1 - describe("gopher.config", function() 2 - it("can be required", function() 3 - require "gopher.config" 4 - end) 5 - 6 - it(".setup() when gets empty table not edit config", function() 7 - local c = require "gopher.config" 8 - c.setup {} 9 - 10 - assert.are.same(c.config.commands.go, "go") 11 - assert.are.same(c.config.commands.gomodifytags, "gomodifytags") 12 - assert.are.same(c.config.commands.gotests, "gotests") 13 - assert.are.same(c.config.commands.impl, "impl") 14 - end) 15 - 16 - it(".setup() when get one custom value sets that", function() 17 - local c = require "gopher.config" 18 - c.setup { commands = { 19 - go = "custom_go", 20 - } } 21 - 22 - assert.are.same(c.config.commands.go, "custom_go") 23 - end) 24 - 25 - it(".setup() when get all custom values sets it", function() 26 - local c = require "gopher.config" 27 - c.setup { 28 - commands = { 29 - go = "go1.18", 30 - gomodifytags = "user-gomodifytags", 31 - gotests = "gotests", 32 - impl = "goimpl", 33 - }, 34 - } 35 - 36 - assert.are.same(c.config.commands.go, "go1.18") 37 - assert.are.same(c.config.commands.gomodifytags, "user-gomodifytags") 38 - assert.are.same(c.config.commands.gotests, "gotests") 39 - assert.are.same(c.config.commands.impl, "goimpl") 40 - end) 41 - end)
-5
spec/gopher_spec.lua
··· 1 - describe("gopher", function() 2 - it("can be required", function() 3 - require "gopher" 4 - end) 5 - end)
-49
spec/gopher_struct_tags_spec.lua
··· 1 - local cur_dir = vim.fn.expand "%:p:h" 2 - 3 - describe("gopher.struct_tags", function() 4 - it("can be required", function() 5 - require "gopher.struct_tags" 6 - end) 7 - 8 - it("can add json tag to struct", function() 9 - local tag = require "gopher.struct_tags" 10 - local temp_file = vim.fn.tempname() .. ".go" 11 - local input_file = vim.fn.readfile(cur_dir .. "/spec/fixtures/tags/add_input.go") 12 - local output_file = 13 - vim.fn.join(vim.fn.readfile(cur_dir .. "/spec/fixtures/tags/add_output.go"), "\n") 14 - 15 - vim.fn.writefile(input_file, temp_file) 16 - vim.cmd("silent exe 'e " .. temp_file .. "'") 17 - vim.bo.filetype = "go" 18 - 19 - local bufn = vim.fn.bufnr(0) 20 - vim.fn.setpos(".", { bufn, 3, 6, 0 }) 21 - tag.add() 22 - 23 - vim.wait(100) 24 - assert.are.same(output_file, vim.fn.join(vim.fn.readfile(temp_file), "\n")) 25 - 26 - vim.cmd("bd! " .. temp_file) 27 - end) 28 - 29 - it("can remove json tag from struct", function() 30 - local tag = require "gopher.struct_tags" 31 - local temp_file = vim.fn.tempname() .. ".go" 32 - local input_file = vim.fn.readfile(cur_dir .. "/spec/fixtures/tags/remove_input.go") 33 - local output_file = 34 - vim.fn.join(vim.fn.readfile(cur_dir .. "/spec/fixtures/tags/remove_output.go"), "\n") 35 - 36 - vim.fn.writefile(input_file, temp_file) 37 - vim.cmd("silent exe 'e " .. temp_file .. "'") 38 - vim.bo.filetype = "go" 39 - 40 - local bufn = vim.fn.bufnr() 41 - vim.fn.setpos(".", { bufn, 3, 6, 0 }) 42 - tag.remove() 43 - 44 - vim.wait(100) 45 - assert.are.same(output_file, vim.fn.join(vim.fn.readfile(temp_file), "\n")) 46 - 47 - vim.cmd("bd! " .. temp_file) 48 - end) 49 - end)
-19
spec/gopher_utils_spec.lua
··· 1 - describe("gopher._utils", function() 2 - it("can be requried", function() 3 - require "gopher._utils" 4 - end) 5 - 6 - it(".empty() with non-empty talbe", function() 7 - local empty = require("gopher._utils").empty 8 - local res = empty { first = "1", second = 2 } 9 - 10 - assert.are.same(res, false) 11 - end) 12 - 13 - it(".empty() with empty talbe", function() 14 - local empty = require("gopher._utils").empty 15 - local res = empty {} 16 - 17 - assert.are.same(res, true) 18 - end) 19 - end)
-4
spec/minimal_init.vim
··· 1 - set rtp+=. 2 - packadd plenary.nvim 3 - packadd nvim-treesitter 4 - packadd nvim-dap
+29
spec/units/config_spec.lua
··· 1 + describe("gopher.config", function() 2 + it(".setup() should provide default when .setup() is not called", function() 3 + local c = require "gopher.config" 4 + 5 + assert.are.same(c.commands.go, "go") 6 + assert.are.same(c.commands.gomodifytags, "gomodifytags") 7 + assert.are.same(c.commands.gotests, "gotests") 8 + assert.are.same(c.commands.impl, "impl") 9 + assert.are.same(c.commands.iferr, "iferr") 10 + assert.are.same(c.commands.dlv, "dlv") 11 + end) 12 + 13 + it(".setup() should change options on users config", function() 14 + local c = require "gopher.config" 15 + c.setup { 16 + commands = { 17 + go = "go1.420", 18 + gomodifytags = "iDontUseRustBtw", 19 + }, 20 + } 21 + 22 + assert.are.same(c.commands.go, "go1.420") 23 + assert.are.same(c.commands.gomodifytags, "iDontUseRustBtw") 24 + assert.are.same(c.commands.gotests, "gotests") 25 + assert.are.same(c.commands.impl, "impl") 26 + assert.are.same(c.commands.iferr, "iferr") 27 + assert.are.same(c.commands.dlv, "dlv") 28 + end) 29 + end)
+15
spec/units/utils_spec.lua
··· 1 + describe("gopher._utils", function() 2 + local u = require "gopher._utils" 3 + 4 + describe(".sreq()", function() 5 + it("can require existing module", function() 6 + assert.are.same(require "gopher", u.sreq "gopher") 7 + end) 8 + 9 + it("cannot require non-existing module", function() 10 + assert.has.errors(function() 11 + u.sreq "iDontExistBtw" 12 + end) 13 + end) 14 + end) 15 + end)