Rewrite the little Go program
- Use Cobra instead of Magefile - Use Neovim's Go client library to get the data and config directories. This is more reliable than guessing from XDG variables then falling back to $HOME.
This commit is contained in:
parent
962c4cd89e
commit
0f01c172ff
|
@ -0,0 +1 @@
|
|||
/pkg-install
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"neoconf": {
|
||||
"live_reload": false,
|
||||
"import": {
|
||||
"vscode": false
|
||||
}
|
||||
},
|
||||
"lspconfig": {
|
||||
"gopls": {
|
||||
"gopls.buildFlags": [
|
||||
"-tags=mage"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -60,6 +60,6 @@ This Neovim config used to live within [my dotfiles](/FollieHiyuki/dotfiles-ansi
|
|||
|
||||
### Why not using [mason.nvim](https://github.com/williamboman/mason.nvim)?
|
||||
|
||||
Most things installed via **mason.nvim** are binaries linked to glibc, which are incompatible to run on the Linux distribution I use - [AlpineLinux](https://alpinelinux.org). I resolved to custom [mage](https://magefile.org) tasks instead. The [tasks' source code](./magefile.go) is pretty simple and naive, but it works for me.
|
||||
Most things installed via **mason.nvim** are binaries linked to glibc, which are incompatible to run on the Linux distribution I use - [AlpineLinux](https://alpinelinux.org). I resolved to custom Go program instead. The code is pretty simple and naive, but it works for me.
|
||||
|
||||
External LSP servers that can't be installed directly from AlpineLinux's repositories, or with simple `cargo/go install` commands, are defined inside [pkgs.yaml](./pkgs.yaml) file.
|
||||
|
|
5
go.mod
5
go.mod
|
@ -5,8 +5,9 @@ go 1.20
|
|||
require (
|
||||
github.com/go-playground/validator/v10 v10.16.0
|
||||
github.com/goccy/go-yaml v1.11.2
|
||||
github.com/magefile/mage v1.15.0
|
||||
github.com/neovim/go-client v1.2.2-0.20230716041012-dd77a916541b
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spf13/cobra v1.8.0
|
||||
golang.org/x/sync v0.6.0
|
||||
mvdan.cc/sh/v3 v3.7.0
|
||||
)
|
||||
|
@ -16,9 +17,11 @@ require (
|
|||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
golang.org/x/crypto v0.18.0 // indirect
|
||||
golang.org/x/net v0.20.0 // indirect
|
||||
golang.org/x/sys v0.16.0 // indirect
|
||||
|
|
12
go.sum
12
go.sum
|
@ -1,3 +1,4 @@
|
|||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
|
@ -17,22 +18,29 @@ github.com/go-playground/validator/v10 v10.16.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QX
|
|||
github.com/goccy/go-yaml v1.11.2 h1:joq77SxuyIs9zzxEjgyLBugMQ9NEgTWxXfz2wVqwAaQ=
|
||||
github.com/goccy/go-yaml v1.11.2/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg=
|
||||
github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/neovim/go-client v1.2.2-0.20230716041012-dd77a916541b h1:JDchP8fWykRzJLiq5cUQ47vKkP8UY0I1yzgGDTSpYRI=
|
||||
github.com/neovim/go-client v1.2.2-0.20230716041012-dd77a916541b/go.mod h1:UBsOERb5epbeQT0nyPTZkmUPTffRYBcHvrXXidr1NQQ=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.10.1-0.20230524175051-ec119421bb97 h1:3RPlVWzZ/PDqmVuf/FKHARG5EMid/tl7cv54Sw/QRVY=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
|
||||
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"LuaSnip": { "branch": "master", "commit": "2dbef19461198630b3d7c39f414d09fb07d1fdd2" },
|
||||
"SchemaStore.nvim": { "branch": "main", "commit": "f877fa4f16b04c8d2e253539e1803a0850833272" },
|
||||
"SchemaStore.nvim": { "branch": "main", "commit": "11d661ae5e08f19b5256661a6491a66fa26cdcfc" },
|
||||
"aerial.nvim": { "branch": "master", "commit": "e9661d4f739508377f42528fd08a85c4c8feba6e" },
|
||||
"alpha-nvim": { "branch": "main", "commit": "4b36c1ca9ea475bdc006896657cf1ccc486aeffa" },
|
||||
"better-escape.nvim": { "branch": "master", "commit": "7e86edafb8c7e73699e0320f225464a298b96d12" },
|
||||
|
@ -12,16 +12,16 @@
|
|||
"cmp-fish": { "branch": "main", "commit": "8ae7bfb1b3251d433c4adf4e64396ef929fbd91f" },
|
||||
"cmp-nvim-lsp": { "branch": "main", "commit": "5af77f54de1b16c34b23cba810150689a3a90312" },
|
||||
"cmp_luasnip": { "branch": "master", "commit": "05a9ab28b53f71d1aece421ef32fee2cb857a843" },
|
||||
"conform.nvim": { "branch": "master", "commit": "3d59cbd01a4b74124c5a6fb23b8cc63e5c2db3d5" },
|
||||
"conform.nvim": { "branch": "master", "commit": "4588008a7c5b57fbff97fdfb529c059235cdc7ee" },
|
||||
"dial.nvim": { "branch": "master", "commit": "27eb570085db2ef44bff4f620d3806039184651c" },
|
||||
"diffview.nvim": { "branch": "main", "commit": "3dc498c9777fe79156f3d32dddd483b8b3dbd95f" },
|
||||
"dressing.nvim": { "branch": "master", "commit": "42d767b04c50a6966c9633e3968bc65c0c2f2bfc" },
|
||||
"emmylua-nvim": { "branch": "master", "commit": "0fd565dbaef5a24a5fb6c015d7d7fa670a474fac" },
|
||||
"dressing.nvim": { "branch": "master", "commit": "6f212262061a2120e42da0d1e87326e8a41c0478" },
|
||||
"emmylua-nvim": { "branch": "master", "commit": "015200711c5c6178a026d96ab042a3788b41310f" },
|
||||
"flash.nvim": { "branch": "main", "commit": "48817af25f51c0590653bbc290866e4890fe1cbe" },
|
||||
"flatten.nvim": { "branch": "main", "commit": "a999f1abd8fa9f8e2447a65726f9f44288c26f3f" },
|
||||
"friendly-snippets": { "branch": "main", "commit": "69a2c1675b66e002799f5eef803b87a12f593049" },
|
||||
"flatten.nvim": { "branch": "main", "commit": "92c59ae6200e6b04aff167577ebb8a9035a6d2b3" },
|
||||
"friendly-snippets": { "branch": "main", "commit": "b8fae73a479ae0a1c54f5c98fa687ae8a0addc53" },
|
||||
"git-conflict.nvim": { "branch": "main", "commit": "4c8e252b87d54d944c1e56bfb477f78b6fdaf661" },
|
||||
"gitsigns.nvim": { "branch": "main", "commit": "c5ff7628e19a47ec14d3657294cc074ecae27b99" },
|
||||
"gitsigns.nvim": { "branch": "main", "commit": "2c2463dbd82eddd7dbab881c3a62cfbfbe3c67ae" },
|
||||
"headlines.nvim": { "branch": "master", "commit": "e3d7bfdf40e41a020d966d35f8b48d75b90367d2" },
|
||||
"heirline.nvim": { "branch": "master", "commit": "1b6f12e011f225a26aa162905cbf68804479e7e6" },
|
||||
"inc-rename.nvim": { "branch": "main", "commit": "6f9b5f9cb237e12935144cdc535322b8c93c1b25" },
|
||||
|
@ -30,20 +30,20 @@
|
|||
"lazy.nvim": { "branch": "main", "commit": "28126922c9b54e35a192ac415788f202c3944c9f" },
|
||||
"lsp_lines.nvim": { "branch": "main", "commit": "cf2306dd332e34a3e91075b40bdd4f6db824b2ee" },
|
||||
"markdown-preview.nvim": { "branch": "master", "commit": "a923f5fc5ba36a3b17e289dc35dc17f66d0548ee" },
|
||||
"mini.ai": { "branch": "main", "commit": "f7787cff9cc42004f722ca1e64e6af4e64e34177" },
|
||||
"mini.align": { "branch": "main", "commit": "708c0265b1513a00c83c181bff3d237741031cd1" },
|
||||
"mini.ai": { "branch": "main", "commit": "3ad9d455a91b8bf3c24d4e50518d9a6b9dddb42c" },
|
||||
"mini.align": { "branch": "main", "commit": "20f5a1a93d86a7e82eaca9334212e54058ef3562" },
|
||||
"mini.animate": { "branch": "main", "commit": "6cec625114007527ff8a82316dba858046f9746f" },
|
||||
"mini.bufremove": { "branch": "main", "commit": "020243bfed8c8b941f2c20626faf3ea39c0c0e1b" },
|
||||
"mini.comment": { "branch": "main", "commit": "67f00d3ebbeae15e84584d971d0c32aad4f4f3a4" },
|
||||
"mini.comment": { "branch": "main", "commit": "b0b359ada4293cdcea7ab4072dfd5b031aac3f8e" },
|
||||
"mini.move": { "branch": "main", "commit": "03a16d64e58da0a871de6493c3d8fa1101baef46" },
|
||||
"mini.pairs": { "branch": "main", "commit": "552062017ff207e1f35f7028bfb3f27c7421d22d" },
|
||||
"mini.surround": { "branch": "main", "commit": "7bf8915ba15d7a4f3c2afe7868d3c15a858d73f1" },
|
||||
"neo-tree.nvim": { "branch": "main", "commit": "e578fe7a5832421b0d2c5b3c0a7a1e40e0f6a47a" },
|
||||
"neoconf.nvim": { "branch": "main", "commit": "cfc29315288515849aa54c05828d49f01f033b66" },
|
||||
"mini.surround": { "branch": "main", "commit": "5ceb6a12d3761bc719fbdad5432c89333deb1498" },
|
||||
"neo-tree.nvim": { "branch": "main", "commit": "c2a9e81699021f4ccaac7c574cc42ca4211a499a" },
|
||||
"neoconf.nvim": { "branch": "main", "commit": "bf04719b3b25ba5f6a059c0a10ee67e5996bdc4c" },
|
||||
"neogen": { "branch": "main", "commit": "70127baaff25611deaf1a29d801fc054ad9d2dc1" },
|
||||
"neogit": { "branch": "master", "commit": "ce0c369ccdba3f644a3b28f4c053421f435352c9" },
|
||||
"neotest": { "branch": "master", "commit": "dcdb40ea48f9c7b67a5576f6bb2e5f63ec15f2c0" },
|
||||
"neotest-go": { "branch": "main", "commit": "d29d20d912aca81a07c50022d880cc66f0d26542" },
|
||||
"neotest": { "branch": "master", "commit": "73043d666780e35185a77589e01bec96a52db910" },
|
||||
"neotest-go": { "branch": "main", "commit": "22513619bcb156939c22ea7cd1a99f754fcb1fde" },
|
||||
"neotest-jest": { "branch": "main", "commit": "a394106cf053eef86d65ae04c4b93a1a7bd60aef" },
|
||||
"neotest-python": { "branch": "master", "commit": "2e83d2bc00acbcc1fd529dbf0a0e677cabfe6b50" },
|
||||
"neotest-vitest": { "branch": "main", "commit": "87e91bfd9419a8c74bf0d105e2ae31b9692daf0b" },
|
||||
|
@ -51,50 +51,50 @@
|
|||
"noice.nvim": { "branch": "main", "commit": "bf67d70bd7265d075191e7812d8eb42b9791f737" },
|
||||
"nui.nvim": { "branch": "main", "commit": "35da9ca1de0fc4dda96c2e214d93d363c145f418" },
|
||||
"nvim-cmp": { "branch": "main", "commit": "538e37ba87284942c1d76ed38dd497e54e65b891" },
|
||||
"nvim-cokeline": { "branch": "main", "commit": "a62eaff75c59da2ca261fefc2992e1cac04bd30e" },
|
||||
"nvim-cokeline": { "branch": "main", "commit": "7310f192af74c6912ca7a40ae1b16253aa95e50e" },
|
||||
"nvim-coverage": { "branch": "main", "commit": "cf4b5c61dfac977026a51a2bcad9173c272986ce" },
|
||||
"nvim-dap": { "branch": "master", "commit": "9adbfdca13afbe646d09a8d7a86d5d031fb9c5a5" },
|
||||
"nvim-dap-repl-highlights": { "branch": "master", "commit": "902d533b2682c26d6be4f8a4d1dfd895cbba4840" },
|
||||
"nvim-dap-ui": { "branch": "master", "commit": "d845ebd798ad1cf30aa4abd4c4eff795cdcfdd4f" },
|
||||
"nvim-dap-virtual-text": { "branch": "master", "commit": "d4542ac257d3c7ee4131350db6179ae6340ce40b" },
|
||||
"nvim-lint": { "branch": "master", "commit": "2cf9ad095130755d7d87f1730bcf33c91ee822e4" },
|
||||
"nvim-lspconfig": { "branch": "master", "commit": "8917d2c830e04bf944a699b8c41f097621283828" },
|
||||
"nvim-lint": { "branch": "master", "commit": "8e5920f9ce9f24c283a2e64be5fe58d1d37d1744" },
|
||||
"nvim-lspconfig": { "branch": "master", "commit": "021906284dcfb938bc236f8295af2650c60cb807" },
|
||||
"nvim-navic": { "branch": "master", "commit": "8649f694d3e76ee10c19255dece6411c29206a54" },
|
||||
"nvim-notify": { "branch": "master", "commit": "80b67b265530632505193553d05127ae7fe09ddd" },
|
||||
"nvim-scrollbar": { "branch": "main", "commit": "35f99d559041c7c0eff3a41f9093581ceea534e8" },
|
||||
"nvim-spectre": { "branch": "master", "commit": "d8906855f1949ac97b1e77aaf8d3fe12ed158ddc" },
|
||||
"nvim-treesitter": { "branch": "master", "commit": "177a775fd8b2a9de97011a43f13c74ad8d3739c8" },
|
||||
"nvim-treesitter-context": { "branch": "master", "commit": "85cf977181fb8e816e47ac05df7f756e9cb72caf" },
|
||||
"nvim-spectre": { "branch": "master", "commit": "d958cc3ea8b3fb2f0922dff6177630a40751a3a9" },
|
||||
"nvim-treesitter": { "branch": "master", "commit": "5f950cdcb82d2cf74e6b30338897b3a4897f52b3" },
|
||||
"nvim-treesitter-context": { "branch": "master", "commit": "9c06b115abc57c99cf0aa81dc29490f5001f57a1" },
|
||||
"nvim-treesitter-textobjects": { "branch": "master", "commit": "19a91a38b02c1c28c14e0ba468d20ae1423c39b2" },
|
||||
"nvim-ts-autotag": { "branch": "main", "commit": "8515e48a277a2f4947d91004d9aa92c29fdc5e18" },
|
||||
"nvim-ts-autotag": { "branch": "main", "commit": "a65b202cfd08e0e69e531eab737205ff5bc082a4" },
|
||||
"nvim-ts-context-commentstring": { "branch": "main", "commit": "1277b4a1f451b0f18c0790e1a7f12e1e5fdebfee" },
|
||||
"nvim-web-devicons": { "branch": "master", "commit": "140edfcf25093e8b321d13e154cbce89ee868ca0" },
|
||||
"nvim-web-devicons": { "branch": "master", "commit": "aaec87dbdaa776bfa0a13c8694bec9bcb7454719" },
|
||||
"nvim-window-picker": { "branch": "main", "commit": "41cfaa428577c53552200a404ae9b3a0b5719706" },
|
||||
"oil.nvim": { "branch": "master", "commit": "bf753c3e3f8736939ad5597f92329dfe7b1df4f5" },
|
||||
"orgmode": { "branch": "master", "commit": "651078a2fe60b12c93903e3a2b655491c951bf9d" },
|
||||
"orgmode": { "branch": "master", "commit": "ab045e3084d5987e8939d25d69b09baaf762278c" },
|
||||
"overseer.nvim": { "branch": "master", "commit": "68a2d344cea4a2e11acfb5690dc8ecd1a1ec0ce0" },
|
||||
"pantran.nvim": { "branch": "main", "commit": "461799624948bfb66f73b20b6fffa7e4c8ca6d08" },
|
||||
"parinfer-rust": { "branch": "master", "commit": "0e4d52e712641ad351a1bfe6cee3d34d63ed087b" },
|
||||
"persistence.nvim": { "branch": "main", "commit": "4982499c1636eac254b72923ab826ee7827b3084" },
|
||||
"plenary.nvim": { "branch": "master", "commit": "663246936325062427597964d81d30eaa42ab1e4" },
|
||||
"plenary.nvim": { "branch": "master", "commit": "4f71c0c4a196ceb656c824a70792f3df3ce6bb6d" },
|
||||
"project.nvim": { "branch": "main", "commit": "8c6bad7d22eef1b71144b401c9f74ed01526a4fb" },
|
||||
"rainbow-delimiters.nvim": { "branch": "master", "commit": "35530b4ad48f01bdaa852da34e4de9930fb54c89" },
|
||||
"rest.nvim": { "branch": "main", "commit": "84e81a19ab24ccf05c9233d34d4dfce61c233abe" },
|
||||
"rainbow-delimiters.nvim": { "branch": "master", "commit": "c84eeb689e4cc86808e823c11eac4239c75292ce" },
|
||||
"rest.nvim": { "branch": "main", "commit": "2d7bd3d398940ce2692941e6cd052c072207b9f9" },
|
||||
"scope.nvim": { "branch": "main", "commit": "cd27af77ad61a7199af5c28d27013fb956eb0e3e" },
|
||||
"sniprun": { "branch": "master", "commit": "0079f9c4675a6825f84e108bbff866f67dd8762f" },
|
||||
"ssr.nvim": { "branch": "main", "commit": "bb323ba621ac647b4ac5638b47666e3ef3c279e1" },
|
||||
"stickybuf.nvim": { "branch": "master", "commit": "2160fcd536d81f5fa43f7167dba6634e814e3154" },
|
||||
"telescope-file-browser.nvim": { "branch": "master", "commit": "6f735a63dc24b9aed527cd505a31864223c8a6d8" },
|
||||
"telescope-file-browser.nvim": { "branch": "master", "commit": "6dd6522bc1a4cbe5883eb0272f5cc7a54ae3858b" },
|
||||
"telescope-fzf-native.nvim": { "branch": "main", "commit": "6c921ca12321edaa773e324ef64ea301a1d0da62" },
|
||||
"telescope-symbols.nvim": { "branch": "master", "commit": "a6d0127a53d39b9fc2af75bd169d288166118aec" },
|
||||
"telescope-tabs": { "branch": "master", "commit": "c3572358e60817f40f0de31bc01906af0993d4c4" },
|
||||
"telescope.nvim": { "branch": "master", "commit": "36dce6261ae3660bb57ba942361067b2028aec31" },
|
||||
"telescope.nvim": { "branch": "master", "commit": "e54fbf4ab2b64640b639b75c006c23b4bc51c86f" },
|
||||
"todo-comments.nvim": { "branch": "main", "commit": "833d8dd8b07eeda37a09e99460f72a02616935cb" },
|
||||
"toggleterm.nvim": { "branch": "main", "commit": "b49df5cdce67a8964d1b027dae94bde212092b51" },
|
||||
"treesj": { "branch": "main", "commit": "14808da3cddd62fc86ede53a5ea1fd1635897e75" },
|
||||
"trouble.nvim": { "branch": "main", "commit": "f1168feada93c0154ede4d1fe9183bf69bac54ea" },
|
||||
"twilight.nvim": { "branch": "main", "commit": "8b7b50c0cb2dc781b2f4262a5ddd57571556d1e4" },
|
||||
"undotree": { "branch": "master", "commit": "d9c8b4ef872e078e8c4080812e5a3ed56d151c00" },
|
||||
"undotree": { "branch": "master", "commit": "a1758ba9990b7189f601a3a5acdfc8ca3907a700" },
|
||||
"venn.nvim": { "branch": "main", "commit": "e4d68341a73dd56c64955058821a58295fb337b1" },
|
||||
"vim-log-highlighting": { "branch": "master", "commit": "1037e26f3120e6a6a2c0c33b14a84336dee2a78f" },
|
||||
"vim-matchup": { "branch": "master", "commit": "e2cca1747ab175b8d839a5d28679427564643a57" },
|
||||
|
|
|
@ -25,8 +25,8 @@ local function get_binary_paths(binaries)
|
|||
return table.concat(paths, ',')
|
||||
end
|
||||
|
||||
local function node_root_dir(fname)
|
||||
return lsputil.root_pattern('tsconfig.json', 'jsconfig.json', 'package.json')(fname)
|
||||
local function deno_root_dir(fname)
|
||||
return lsputil.root_pattern('deno.json', 'deno.jsonc')(fname)
|
||||
end
|
||||
|
||||
return {
|
||||
|
@ -67,11 +67,7 @@ return {
|
|||
-- Ref: https://docs.deno.com/runtime/manual/advanced/language_server/overview
|
||||
denols = {
|
||||
-- Ensure `tsserver` and `denols` aren't attached to a single buffer at the same time
|
||||
root_dir = function(fname)
|
||||
if node_root_dir(fname) == nil then
|
||||
return lsputil.root_pattern('deno.json', 'deno.jsonc', '.git')(fname)
|
||||
end
|
||||
end,
|
||||
root_dir = deno_root_dir,
|
||||
init_options = { enable = true, lint = true },
|
||||
settings = {
|
||||
deno = {
|
||||
|
@ -104,15 +100,16 @@ return {
|
|||
|
||||
gleam = {},
|
||||
|
||||
-- this uses a project's local instance of glint-language-server (`pnpm add -D @glint/core`)
|
||||
glint = {
|
||||
filetypes = {
|
||||
'handlebars',
|
||||
'html.handlebars',
|
||||
'typescript.glimmer',
|
||||
'javascript.glimmer',
|
||||
},
|
||||
},
|
||||
-- this uses a project's local instance of glint-language-server
|
||||
-- Ref: https://typed-ember.gitbook.io/glint/getting-started
|
||||
-- glint = {
|
||||
-- filetypes = {
|
||||
-- 'handlebars',
|
||||
-- 'html.handlebars',
|
||||
-- 'typescript.glimmer',
|
||||
-- 'javascript.glimmer',
|
||||
-- },
|
||||
-- },
|
||||
|
||||
-- NOTE: for Bazel setup (GOPACKAGESDRIVER), use neoconf.nvim
|
||||
-- Ref: https://github.com/bazelbuild/rules_go/wiki/Editor-setup
|
||||
|
@ -298,7 +295,11 @@ return {
|
|||
|
||||
tsserver = {
|
||||
cmd = { servers_path .. '/tsserver/node_modules/.bin/typescript-language-server', '--stdio' },
|
||||
root_dir = node_root_dir,
|
||||
root_dir = function(fname)
|
||||
if deno_root_dir(fname) == nil then
|
||||
return lsputil.root_pattern('package.json', 'tsconfig.json', 'jsconfig.json', '.git')(fname)
|
||||
end
|
||||
end,
|
||||
single_file_support = false,
|
||||
},
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ return {
|
|||
changedelete = { text = '-' },
|
||||
untracked = { text = '+' },
|
||||
},
|
||||
attach_to_untracked = true,
|
||||
current_line_blame_opts = { virt_text_pos = 'right_align' },
|
||||
preview_config = { border = require('user.config.vars').border },
|
||||
on_attach = function(bufnr)
|
||||
|
|
|
@ -24,7 +24,7 @@ return {
|
|||
['@string.special'] = { link = 'Special' },
|
||||
['@string.special.symbol'] = { fg = c.purple },
|
||||
['@string.special.url'] = { link = '@markup.link.url' },
|
||||
['@string.special.path'] = { fg = c.fg, underline = true },
|
||||
['@string.special.path'] = { fg = c.green, underline = true },
|
||||
|
||||
['@character'] = { link = 'Character' },
|
||||
['@character.special'] = { link = 'SpecialChar' },
|
||||
|
|
12
mage.go
12
mage.go
|
@ -1,12 +0,0 @@
|
|||
//go:build ignore
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/magefile/mage/mage"
|
||||
)
|
||||
|
||||
func main() { os.Exit(mage.Main()) }
|
321
magefile.go
321
magefile.go
|
@ -1,321 +0,0 @@
|
|||
//go:build mage
|
||||
// +build mage
|
||||
|
||||
package main
|
||||
|
||||
// NOTE: intentionally not handle errors with mage to have nice terminal output via logrus
|
||||
// TODO: run commands with sh.Run instead of exec.Command (when https://github.com/magefile/mage/issues/213 is fixed)
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/goccy/go-yaml"
|
||||
"github.com/magefile/mage/mg"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"mvdan.cc/sh/v3/expand"
|
||||
"mvdan.cc/sh/v3/interp"
|
||||
"mvdan.cc/sh/v3/syntax"
|
||||
)
|
||||
|
||||
type Target struct {
|
||||
Env map[string]string `yaml:"env,omitempty" validate:"excluded_unless=Type custom,omitempty,min=1,dive,keys,min=1,endkeys,required"`
|
||||
Type string `yaml:"type" validate:"required,oneof=python nodejs custom"`
|
||||
Category []string `yaml:"category" validate:"required,min=1,dive,oneof=lsp dap lint"`
|
||||
Pkgs []string `yaml:"pkgs,omitempty" validate:"excluded_if=Type custom,omitempty,min=1,dive,min=1"`
|
||||
Script []string `yaml:"script,omitempty" validate:"required_if=Type custom,omitempty,min=1,dive,min=1"`
|
||||
}
|
||||
|
||||
type Install mg.Namespace
|
||||
|
||||
var Aliases = map[string]any{
|
||||
// Shorter task names to type
|
||||
"i": Install.Pkg,
|
||||
"i:lsp": Install.Lsp,
|
||||
"i:dap": Install.Dap,
|
||||
"i:lint": Install.Linters,
|
||||
"i:all": Install.All,
|
||||
|
||||
// `Install` is already registered as a type, so can't make an original func name of it
|
||||
"install": Install.Pkg,
|
||||
}
|
||||
|
||||
var (
|
||||
validate = validator.New()
|
||||
targets, readErr = readTargets("pkgs.yaml")
|
||||
)
|
||||
|
||||
func init() {
|
||||
logrus.SetFormatter(&logrus.TextFormatter{
|
||||
DisableTimestamp: true,
|
||||
DisableQuote: true,
|
||||
})
|
||||
logrus.SetOutput(os.Stderr)
|
||||
logrus.SetLevel(logrus.InfoLevel)
|
||||
}
|
||||
|
||||
// List lists installable targets
|
||||
func List() {
|
||||
if readErr != nil {
|
||||
logrus.Fatal(readErr)
|
||||
}
|
||||
|
||||
// Categorize the list
|
||||
categories := map[string][]string{
|
||||
"LSP servers": {},
|
||||
"DAP servers": {},
|
||||
"Linters/Formatters": {},
|
||||
}
|
||||
|
||||
for target, spec := range targets {
|
||||
// NOTE: there will be duplications (.e.g elixirls), but it is fine
|
||||
if slices.Contains(spec.Category, "lsp") {
|
||||
categories["LSP servers"] = append(categories["LSP servers"], target)
|
||||
}
|
||||
if slices.Contains(spec.Category, "dap") {
|
||||
categories["DAP servers"] = append(categories["DAP servers"], target)
|
||||
}
|
||||
if slices.Contains(spec.Category, "lint") {
|
||||
categories["Linters/Formatters"] = append(categories["Linters/Formatters"], target)
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate over a list, to make the output stable
|
||||
categoryList := []string{}
|
||||
for name := range categories {
|
||||
categoryList = append(categoryList, name)
|
||||
}
|
||||
sort.Strings(categoryList)
|
||||
|
||||
for _, name := range categoryList {
|
||||
fmt.Printf("* %s:\n", name)
|
||||
sort.Strings(categories[name])
|
||||
for _, target := range categories[name] {
|
||||
fmt.Printf(" - %s\n", target)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pkg installs the specified target(s)
|
||||
func (Install) Pkg(target string) {
|
||||
if readErr != nil {
|
||||
logrus.Fatal(readErr)
|
||||
}
|
||||
|
||||
// Split the input into individual targets
|
||||
t := strings.Split(target, " ")
|
||||
|
||||
if err := installGroup(targets, t); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Lsp installs all LSP servers
|
||||
func (Install) Lsp() {
|
||||
if readErr != nil {
|
||||
logrus.Fatal(readErr)
|
||||
}
|
||||
|
||||
logrus.Warn("Installing LSP servers")
|
||||
if err := installGroup(targets, filterTargets(targets, "lsp")); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Dap installs all DAP servers
|
||||
func (Install) Dap() {
|
||||
if readErr != nil {
|
||||
logrus.Fatal(readErr)
|
||||
}
|
||||
|
||||
logrus.Warn("Installing DAP servers")
|
||||
if err := installGroup(targets, filterTargets(targets, "dap")); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Linters installs all linters and formatters
|
||||
func (Install) Linters() {
|
||||
if readErr != nil {
|
||||
logrus.Fatal(readErr)
|
||||
}
|
||||
|
||||
logrus.Warn("Installing linters and formatters")
|
||||
if err := installGroup(targets, filterTargets(targets, "lint")); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// All installs everything
|
||||
func (Install) All() {
|
||||
if readErr != nil {
|
||||
logrus.Fatal(readErr)
|
||||
}
|
||||
|
||||
logrus.Warn("Installing everything")
|
||||
if err := installGroup(targets, filterTargets(targets, "all")); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// readTargets returns the list of installable targets from YAML input file
|
||||
func readTargets(file string) (map[string]Target, error) {
|
||||
input, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
targets := map[string]Target{}
|
||||
err = yaml.Unmarshal(input, &targets)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Validate the received input before return it
|
||||
for target, spec := range targets {
|
||||
err = validate.Struct(spec)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("[%s] invalid input: %v", target, err)
|
||||
}
|
||||
}
|
||||
|
||||
return targets, nil
|
||||
}
|
||||
|
||||
// filterTargets returns the list of installable targets with category filter
|
||||
func filterTargets(targets map[string]Target, category string) []string {
|
||||
result := []string{}
|
||||
for name, spec := range targets {
|
||||
// Treat `all` as matching everything
|
||||
if slices.Contains(spec.Category, category) || category == "all" {
|
||||
result = append(result, name)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// installGroup installs a list of targets concurrently if they exist within specified group
|
||||
func installGroup(targets map[string]Target, t []string) error {
|
||||
errGroup := new(errgroup.Group)
|
||||
|
||||
for _, target := range t {
|
||||
target := target
|
||||
errGroup.Go(func() error {
|
||||
return install(targets, target)
|
||||
})
|
||||
}
|
||||
|
||||
return errGroup.Wait()
|
||||
}
|
||||
|
||||
// install installs the specified target if it exists inside the provided target list
|
||||
func install(targets map[string]Target, target string) error {
|
||||
targetLog := logrus.WithField("target", target)
|
||||
|
||||
spec, ok := targets[target]
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid target '%s'", target)
|
||||
}
|
||||
|
||||
targetLog.Warn("Installing target")
|
||||
|
||||
data_dir, ok := os.LookupEnv("XDG_DATA_HOME")
|
||||
if !ok {
|
||||
data_dir = filepath.Join(os.Getenv("HOME"), ".local", "share")
|
||||
}
|
||||
install_dir := filepath.Join(data_dir, "nvim", spec.Category[0], target)
|
||||
|
||||
// Create the parent directory to install packages into (in the case of `python` or `nodejs`).
|
||||
// For `custom` type, the script should make this directory in its own way
|
||||
if spec.Type == "nodejs" || spec.Type == "python" {
|
||||
err := os.MkdirAll(install_dir, 0o755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Use the target's name as its package name, if not specified
|
||||
if len(spec.Pkgs) == 0 {
|
||||
spec.Pkgs = append(spec.Pkgs, target)
|
||||
}
|
||||
}
|
||||
|
||||
switch spec.Type {
|
||||
case "nodejs":
|
||||
for _, pkg := range spec.Pkgs {
|
||||
cmd := [3]string{"pnpm", "add", fmt.Sprintf("%s@latest", pkg)}
|
||||
targetLog.Infof("%s %s %s", cmd[0], cmd[1], cmd[2])
|
||||
|
||||
execCmd := exec.Command(cmd[0], cmd[1:]...)
|
||||
execCmd.Dir = install_dir
|
||||
execCmd.Stdout = os.Stdout
|
||||
execCmd.Stderr = os.Stderr
|
||||
if err := execCmd.Run(); err != nil {
|
||||
return fmt.Errorf("failed to install %s: %v", pkg, err)
|
||||
}
|
||||
}
|
||||
|
||||
case "python":
|
||||
// Always upgrade pip along the way
|
||||
spec.Pkgs = append(spec.Pkgs, "pip")
|
||||
|
||||
// Create a venv directory to install the target's packages into
|
||||
execCmd := exec.Command("python3", "-m", "venv", install_dir)
|
||||
execCmd.Stdout = os.Stdout
|
||||
execCmd.Stderr = os.Stderr
|
||||
if err := execCmd.Run(); err != nil {
|
||||
return fmt.Errorf("failed to create venv: %v", err)
|
||||
}
|
||||
|
||||
for _, pkg := range spec.Pkgs {
|
||||
cmd := [4]string{filepath.Join("bin", "pip3"), "install", "-U", pkg}
|
||||
targetLog.Infof("%s %s %s %s", cmd[0], cmd[1], cmd[2], cmd[3])
|
||||
|
||||
execCmd = exec.Command(cmd[0], cmd[1:]...)
|
||||
execCmd.Dir = install_dir
|
||||
execCmd.Stdout = os.Stdout
|
||||
execCmd.Stderr = os.Stderr
|
||||
if err := execCmd.Run(); err != nil {
|
||||
return fmt.Errorf("failed to install %s: %v", pkg, err)
|
||||
}
|
||||
}
|
||||
|
||||
case "custom":
|
||||
// Always export `PKG_INSTALL_DIR` for convenient usage in script block.
|
||||
// Also inherit from the shell env, to have proper PATH and so on.
|
||||
envs := append(os.Environ(), "PKG_INSTALL_DIR="+install_dir)
|
||||
for k, v := range spec.Env {
|
||||
envs = append(envs, fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
|
||||
runner, err := interp.New(
|
||||
interp.Env(expand.ListEnviron(envs...)),
|
||||
interp.StdIO(nil, os.Stdout, os.Stderr),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx := context.TODO() // just create a dummy context for each custom target
|
||||
for _, line := range spec.Script {
|
||||
targetLog.Info(line)
|
||||
script, err := syntax.NewParser().Parse(strings.NewReader(line), "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = runner.Run(ctx, script)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package main
|
||||
|
||||
import "github.com/neovim/go-client/nvim"
|
||||
|
||||
func findNvimDataDir() (string, error) {
|
||||
var nvim_data_dir string
|
||||
|
||||
vim, err := nvim.NewChildProcess(nvim.ChildProcessArgs("--embed"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := vim.ExecLua("return vim.fn.stdpath(...)", &nvim_data_dir, "data"); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return nvim_data_dir, vim.Close()
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"mvdan.cc/sh/v3/expand"
|
||||
"mvdan.cc/sh/v3/interp"
|
||||
"mvdan.cc/sh/v3/syntax"
|
||||
)
|
||||
|
||||
func installPkgGroup(data_dir string, targets map[string]Target, t []string) error {
|
||||
errGroup := new(errgroup.Group)
|
||||
for _, target := range t {
|
||||
target := target
|
||||
errGroup.Go(func() error {
|
||||
return installPkg(data_dir, targets, target)
|
||||
})
|
||||
}
|
||||
return errGroup.Wait()
|
||||
}
|
||||
|
||||
func installPkg(data_dir string, targets map[string]Target, target string) error {
|
||||
// Verify that the target exists
|
||||
spec, ok := targets[target]
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid target '%s'", target)
|
||||
}
|
||||
|
||||
targetLog := logrus.WithField("target", target)
|
||||
targetLog.Warn("Installing target")
|
||||
|
||||
// Install targets into categorized directories
|
||||
install_dir := filepath.Join(data_dir, spec.Category[0], target)
|
||||
|
||||
// Create the parent directory to install packages into (in the case of `python` or `nodejs`).
|
||||
// For `custom` type, the script should make this directory in its own way
|
||||
if spec.Type == "nodejs" || spec.Type == "python" {
|
||||
err := os.MkdirAll(install_dir, 0o755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Use the target's name as its package name, if not specified
|
||||
if len(spec.Pkgs) == 0 {
|
||||
spec.Pkgs = append(spec.Pkgs, target)
|
||||
}
|
||||
}
|
||||
|
||||
switch spec.Type {
|
||||
case "nodejs":
|
||||
for _, pkg := range spec.Pkgs {
|
||||
cmd := [3]string{"pnpm", "add", fmt.Sprintf("%s@latest", pkg)}
|
||||
targetLog.Infof("%s %s %s", cmd[0], cmd[1], cmd[2])
|
||||
|
||||
execCmd := exec.Command(cmd[0], cmd[1:]...)
|
||||
execCmd.Dir = install_dir
|
||||
execCmd.Stdout = os.Stdout
|
||||
execCmd.Stderr = os.Stderr
|
||||
if err := execCmd.Run(); err != nil {
|
||||
return fmt.Errorf("failed to install %s: %v", pkg, err)
|
||||
}
|
||||
}
|
||||
|
||||
case "python":
|
||||
// Always upgrade pip along the way
|
||||
spec.Pkgs = append(spec.Pkgs, "pip")
|
||||
|
||||
// Create a venv directory to install the target's packages into
|
||||
execCmd := exec.Command("python3", "-m", "venv", install_dir)
|
||||
execCmd.Stdout = os.Stdout
|
||||
execCmd.Stderr = os.Stderr
|
||||
if err := execCmd.Run(); err != nil {
|
||||
return fmt.Errorf("failed to create python venv: %v", err)
|
||||
}
|
||||
|
||||
for _, pkg := range spec.Pkgs {
|
||||
cmd := [4]string{filepath.Join("bin", "pip3"), "install", "-U", pkg}
|
||||
targetLog.Infof("%s %s %s %s", cmd[0], cmd[1], cmd[2], cmd[3])
|
||||
|
||||
execCmd = exec.Command(cmd[0], cmd[1:]...)
|
||||
execCmd.Dir = install_dir
|
||||
execCmd.Stdout = os.Stdout
|
||||
execCmd.Stderr = os.Stderr
|
||||
if err := execCmd.Run(); err != nil {
|
||||
return fmt.Errorf("failed to install %s: %v", pkg, err)
|
||||
}
|
||||
}
|
||||
|
||||
case "custom":
|
||||
// Always export `PKG_INSTALL_DIR` for convenient usage in script block.
|
||||
// Also inherit from the shell env, to have proper PATH and so on.
|
||||
envs := append(os.Environ(), "PKG_INSTALL_DIR="+install_dir)
|
||||
for k, v := range spec.Env {
|
||||
envs = append(envs, fmt.Sprintf("%s=%s", k, v))
|
||||
}
|
||||
|
||||
runner, err := interp.New(
|
||||
interp.Env(expand.ListEnviron(envs...)),
|
||||
interp.StdIO(nil, os.Stdout, os.Stderr),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx := context.TODO() // just create a dummy context for each custom target
|
||||
for _, line := range spec.Script {
|
||||
targetLog.Info(line)
|
||||
script, err := syntax.NewParser().Parse(strings.NewReader(line), "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = runner.Run(ctx, script)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"sort"
|
||||
)
|
||||
|
||||
func listPkgs(targets map[string]Target) error {
|
||||
// Categorize the list
|
||||
categories := map[string][]string{
|
||||
"LSP servers": {},
|
||||
"DAP servers": {},
|
||||
"Linters/Formatters": {},
|
||||
}
|
||||
|
||||
for target, spec := range targets {
|
||||
// NOTE: there will be duplications (items belonging to multiple categories, .e.g elixirls), but it is intentional
|
||||
if slices.Contains(spec.Category, "lsp") {
|
||||
categories["LSP servers"] = append(categories["LSP servers"], target)
|
||||
}
|
||||
if slices.Contains(spec.Category, "dap") {
|
||||
categories["DAP servers"] = append(categories["DAP servers"], target)
|
||||
}
|
||||
if slices.Contains(spec.Category, "lint") {
|
||||
categories["Linters/Formatters"] = append(categories["Linters/Formatters"], target)
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate over a list, to make the output stable
|
||||
categoryList := []string{}
|
||||
for name := range categories {
|
||||
categoryList = append(categoryList, name)
|
||||
}
|
||||
sort.Strings(categoryList)
|
||||
|
||||
for _, name := range categoryList {
|
||||
fmt.Printf("* %s:\n", name)
|
||||
sort.Strings(categories[name])
|
||||
for _, target := range categories[name] {
|
||||
fmt.Printf(" - %s\n", target)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func init() {
|
||||
logrus.SetFormatter(&logrus.TextFormatter{
|
||||
DisableTimestamp: true,
|
||||
DisableQuote: true,
|
||||
})
|
||||
logrus.SetOutput(os.Stderr)
|
||||
logrus.SetLevel(logrus.InfoLevel)
|
||||
}
|
||||
|
||||
func main() {
|
||||
var list, lsp, dap, lint bool
|
||||
|
||||
rootCmd := &cobra.Command{
|
||||
Use: "pkg-install",
|
||||
Short: "A small CLI program to install LSP/DAP servers and various linters/formatters",
|
||||
SilenceUsage: true,
|
||||
SilenceErrors: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
// Just print help output if there is nothing to do
|
||||
if cmd.Flags().NFlag() == 0 && len(args) == 0 {
|
||||
return cmd.Help()
|
||||
}
|
||||
|
||||
targets, err := readTargets()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if list {
|
||||
return listPkgs(targets)
|
||||
}
|
||||
|
||||
nvim_data_dir, err := findNvimDataDir()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// We can install multiple categories at the same time
|
||||
if lsp {
|
||||
logrus.Warn("Installing LSP servers")
|
||||
err := installPkgGroup(nvim_data_dir, targets, filterTargets(targets, "lsp"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if dap {
|
||||
logrus.Warn("Installing DAP servers")
|
||||
err := installPkgGroup(nvim_data_dir, targets, filterTargets(targets, "dap"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if lint {
|
||||
logrus.Warn("Installing linters and formatters")
|
||||
err := installPkgGroup(nvim_data_dir, targets, filterTargets(targets, "lint"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Only install specified targets when no categories are selected
|
||||
if cmd.Flags().NFlag() == 0 {
|
||||
err := installPkgGroup(nvim_data_dir, targets, args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
rootCmd.PersistentFlags().BoolVar(&list, "list", false, "List installable targets")
|
||||
rootCmd.PersistentFlags().BoolVar(&lsp, "lsp", false, "Install all LSP servers")
|
||||
rootCmd.PersistentFlags().BoolVar(&dap, "dap", false, "Install all DAP servers")
|
||||
rootCmd.PersistentFlags().BoolVar(&lint, "lint", false, "Install all linters and formatters")
|
||||
|
||||
err := rootCmd.Execute()
|
||||
if err != nil {
|
||||
logrus.Error(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/goccy/go-yaml"
|
||||
"github.com/neovim/go-client/nvim"
|
||||
)
|
||||
|
||||
type Target struct {
|
||||
Env map[string]string `yaml:"env,omitempty" validate:"excluded_unless=Type custom,omitempty,min=1,dive,keys,min=1,endkeys,required"`
|
||||
Type string `yaml:"type" validate:"required,oneof=python nodejs custom"`
|
||||
Category []string `yaml:"category" validate:"required,min=1,dive,oneof=lsp dap lint"`
|
||||
Pkgs []string `yaml:"pkgs,omitempty" validate:"excluded_if=Type custom,omitempty,min=1,dive,min=1"`
|
||||
Script []string `yaml:"script,omitempty" validate:"required_if=Type custom,omitempty,min=1,dive,min=1"`
|
||||
}
|
||||
|
||||
var validate = validator.New()
|
||||
|
||||
func readTargets() (map[string]Target, error) {
|
||||
var nvim_config_dir string
|
||||
vim, err := nvim.NewChildProcess(nvim.ChildProcessArgs("--embed"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = vim.ExecLua("return vim.fn.stdpath(...)", &nvim_config_dir, "config"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = vim.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
input, err := os.ReadFile(filepath.Join(nvim_config_dir, "pkgs.yaml"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
targets := map[string]Target{}
|
||||
err = yaml.Unmarshal(input, &targets)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Validate the received input before return it
|
||||
for target, spec := range targets {
|
||||
err = validate.Struct(spec)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("[%s] invalid input: %v", target, err)
|
||||
}
|
||||
}
|
||||
|
||||
return targets, nil
|
||||
}
|
||||
|
||||
func filterTargets(targets map[string]Target, category string) []string {
|
||||
result := []string{}
|
||||
for name, spec := range targets {
|
||||
if slices.Contains(spec.Category, category) {
|
||||
result = append(result, name)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
Loading…
Reference in New Issue