Skip to content

Commit cfd1f98

Browse files
committed
completion: handle cursor placement
Correctly handles cursor placement after a completion when placeholders are disabled but snippets are not.
1 parent 30f88e0 commit cfd1f98

File tree

1 file changed

+26
-9
lines changed

1 file changed

+26
-9
lines changed

src/features/completions.zig

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,33 @@ fn nodeToCompletion(
181181
const func = tree.fullFnProto(&buf, node).?;
182182
if (func.name_token) |name_token| {
183183
const use_snippets = server.config.enable_snippets and server.client_capabilities.supports_snippets;
184-
const use_placeholders = server.config.enable_argument_placeholders and server.client_capabilities.supports_snippets;
185-
const insert_text = if (use_snippets) blk: {
186-
if (use_placeholders) {
187-
const skip_self_param = !(parent_is_type_val orelse true) and
188-
try server.analyser.hasSelfParam(handle, func);
189-
break :blk try Analyser.getFunctionSnippet(allocator, tree, func, skip_self_param);
190-
} else {
191-
break :blk try std.fmt.allocPrint(allocator, "{s}()", .{tree.tokenSlice(func.name_token.?)});
184+
185+
const insert_text = blk: {
186+
const func_name = tree.tokenSlice(func.name_token.?);
187+
188+
if (!use_snippets) break :blk func_name;
189+
190+
const skip_self_param = !(parent_is_type_val orelse true) and try server.analyser.hasSelfParam(handle, func);
191+
192+
const use_placeholders = server.config.enable_argument_placeholders;
193+
if (use_placeholders) break :blk try Analyser.getFunctionSnippet(allocator, tree, func, skip_self_param);
194+
195+
switch (func.ast.params.len) {
196+
// No arguments, leave cursor at the end
197+
0 => break :blk try std.fmt.allocPrint(allocator, "{s}()", .{func_name}),
198+
1 => {
199+
if (skip_self_param) {
200+
// The one argument is a self parameter, leave cursor at the end
201+
break :blk try try std.fmt.allocPrint(allocator, "{s}()", .{func_name});
202+
}
203+
204+
// Non-self parameter, leave the cursor in the parentheses
205+
break :blk try try std.fmt.allocPrint(allocator, "{s}(${{1:}})", .{func_name});
206+
},
207+
// Atleast one non-self parameter, leave the cursor in the parentheses
208+
else => break :blk try std.fmt.allocPrint(allocator, "{s}(${{1:}})", .{func_name}),
192209
}
193-
} else tree.tokenSlice(func.name_token.?);
210+
};
194211

195212
const is_type_function = Analyser.isTypeFunction(handle.tree, func);
196213

0 commit comments

Comments
 (0)