Skip to content

Commit 2927954

Browse files
authored
feat: golang (#34)
1 parent 3d69ddd commit 2927954

File tree

10 files changed

+206
-7
lines changed

10 files changed

+206
-7
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ After:
7878

7979
- **ecmascript**: object, array, params, arguments
8080
- **lua**: table, params, arguments, variable_lists
81+
- **html**: tags, attributes
8182
- **css**: rules (blocks)
83+
- **go**: parameter lists, structs, return lists, arguments, slices, etc
8284

8385
[vmp]: https://github.com/t9md/atom-vim-mode-plus
8486
[sjv]: https://github.com/AndrewRadev/splitjoin.vim

lua/splitjoin.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ local Splitjoin = {}
2525
local function get_operable_node_under_cursor(bufnr, winnr)
2626
local row, col = unpack(vim.api.nvim_win_get_cursor(winnr))
2727
local cursor_range = { row - 1, col, row - 1, col }
28-
-- TODO: cache a reference per bufnr
2928
local tsparser = get_parser(bufnr)
29+
if tsparser == nil then return end
3030
tsparser:parse()
3131
local langtree = tsparser:language_for_range(cursor_range);
3232
local tstree = langtree:tree_for_range(cursor_range, { ignore_injections = false }) or langtree:trees()[1]
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
local Node = require'splitjoin.util.node'
2+
local Go = require'splitjoin.languages.go.functions'
3+
4+
---@type SplitjoinLanguageConfig
5+
return {
6+
default_indent = ' ',
7+
nodes = {
8+
-- Go struct fields
9+
field_declaration_list = {
10+
surround = { '{', '}' },
11+
split = Go.split_struct,
12+
join = Go.join_struct,
13+
},
14+
15+
-- Go function parameters and return lists
16+
parameter_list = {
17+
surround = { '(', ')' },
18+
separator = ',',
19+
split = Node.split,
20+
join = Node.join,
21+
trailing_separator = true,
22+
},
23+
24+
-- Go function call arguments
25+
argument_list = {
26+
surround = { '(', ')' },
27+
separator = ',',
28+
split = Node.split,
29+
join = Node.join,
30+
},
31+
32+
-- Go slice, map, and composite literals
33+
literal_value = {
34+
surround = { '{', '}' },
35+
separator = ',',
36+
split = Node.split,
37+
join = Node.join,
38+
}
39+
}
40+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
local Node = require("splitjoin.util.node")
2+
3+
local M = {}
4+
5+
---@param node TSNode
6+
---@param options SplitjoinLanguageOptions
7+
function M.split_struct(node, options)
8+
local indent = options.default_indent or " "
9+
local open, close = unpack(options.surround or {})
10+
local lines = {}
11+
12+
table.insert(lines, open .. "\n")
13+
14+
for child in node:iter_children() do
15+
if child:type() == "field_declaration" then
16+
local text = vim.trim(Node.get_text(child))
17+
table.insert(lines, indent .. text .. "\n")
18+
end
19+
end
20+
21+
table.insert(lines, close)
22+
Node.replace(node, table.concat(lines, ""))
23+
Node.goto_node(node)
24+
end
25+
26+
---@param node TSNode
27+
---@param options SplitjoinLanguageOptions
28+
function M.join_struct(node, options)
29+
local open, close = unpack(options.surround or {})
30+
local padding = options.padding or ""
31+
local parts = {}
32+
33+
for child in node:iter_children() do
34+
if child:type() == "field_declaration" then
35+
local text = vim.trim(Node.get_text(child))
36+
if text:match(".*,%s*$") then
37+
text = text:gsub(",%s*$", "")
38+
end
39+
table.insert(parts, text)
40+
end
41+
end
42+
43+
local final_string = open .. padding .. " " .. table.concat(parts, "; ") .. " " .. padding .. close
44+
Node.replace(node, final_string)
45+
Node.goto_node(node)
46+
end
47+
48+
return M

lua/splitjoin/util/options.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ local function get_defaults()
2222
json = require'splitjoin.languages.json.defaults',
2323
html = require'splitjoin.languages.html.defaults',
2424
css = require'splitjoin.languages.css.defaults',
25+
go = require'splitjoin.languages.go.defaults',
2526
},
2627
}
2728
for name, mod in pairs(defaults.languages) do

queries/css/splitjoin.scm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@
55
(selectors
66
(_
77
(arguments) @splitjoin.css.arguments)))
8+
9+
((arguments) @splitjoin.css.arguments)

queries/go/splitjoin.scm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
(field_declaration_list) @splitjoin.target
2+
(literal_value) @splitjoin.target
3+
(parameter_list) @splitjoin.target
4+
(argument_list) @splitjoin.target

test/go_spec.lua

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
local d = require'plenary.strings'.dedent
2+
local H = require'test.helpers'
3+
4+
local lang = 'go'
5+
6+
describe(lang, function()
7+
H.make_suite(lang, 'struct',
8+
d[[
9+
type User struct { Name string; Age int; Email string }
10+
]],
11+
d[[
12+
type User struct {
13+
Name string
14+
Age int
15+
Email string
16+
}
17+
]],
18+
'{'
19+
)
20+
21+
H.make_suite(lang, 'params',
22+
d[[
23+
func Foo(a int, b string) (int, error) {}
24+
]],
25+
d[[
26+
func Foo(
27+
a int,
28+
b string,
29+
) (int, error) {}
30+
]],
31+
'a'
32+
)
33+
34+
H.make_suite(lang, 'return',
35+
d[[
36+
func Foo(a int, b string) (int, error) {}
37+
]],
38+
d[[
39+
func Foo(a int, b string) (
40+
int,
41+
error,
42+
) {}
43+
]],
44+
'error'
45+
)
46+
47+
H.make_suite(lang, 'args',
48+
d[[
49+
Foo(a, b, c)
50+
]],
51+
d[[
52+
Foo(
53+
a,
54+
b,
55+
c,
56+
)
57+
]],
58+
'a'
59+
)
60+
61+
H.make_suite(lang, 'slice',
62+
d[=[
63+
[]string{"a", "b", "c"}
64+
]=],
65+
d[=[
66+
[]string{
67+
"a",
68+
"b",
69+
"c",
70+
}
71+
]=],
72+
'{'
73+
)
74+
75+
H.make_suite(lang, 'map',
76+
d[=[
77+
map[string]int{"a": 1, "b": 2, "c": 3}
78+
]=],
79+
d[=[
80+
map[string]int{
81+
"a": 1,
82+
"b": 2,
83+
"c": 3,
84+
}
85+
]=],
86+
'{'
87+
)
88+
89+
H.make_suite(lang, 'composite literal',
90+
d[=[
91+
User{Name: "a", Age: 1, Email: "b"}
92+
]=],
93+
d[=[
94+
User{
95+
Name: "a",
96+
Age: 1,
97+
Email: "b",
98+
}
99+
]=],
100+
'{'
101+
)
102+
end)

test/helpers.lua

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,7 @@ local function setup_buffer(content, lang, go_to)
111111

112112
local bufnr = vim.api.nvim_get_current_buf()
113113

114-
local ts_parsers = require('nvim-treesitter.parsers')
115-
local parser = ts_parsers.get_parser(bufnr, lang)
114+
local parser = vim.treesitter.get_parser(bufnr, lang)
116115
if parser then parser:parse() end
117116
vim.wait(100)
118117

test/init.lua

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@ function M.setup()
2525

2626
require'nvim-treesitter.configs'.setup {
2727
ensure_installed = {
28-
'lua',
2928
'css',
30-
'json',
31-
'jsdoc',
29+
'go',
30+
'html',
3231
'javascript',
32+
'jsdoc',
33+
'json',
34+
'lua',
3335
'typescript',
34-
'html',
3536
},
3637
sync_install = true,
3738
}

0 commit comments

Comments
 (0)