Skip to content

Commit

Permalink
completion: handle cursor placement
Browse files Browse the repository at this point in the history
Correctly handles cursor placement after a completion when placeholders are disabled but snippets are not.
  • Loading branch information
leecannon committed Jul 14, 2023
1 parent 30f88e0 commit cfd1f98
Showing 1 changed file with 26 additions and 9 deletions.
35 changes: 26 additions & 9 deletions src/features/completions.zig
Original file line number Diff line number Diff line change
Expand Up @@ -181,16 +181,33 @@ fn nodeToCompletion(
const func = tree.fullFnProto(&buf, node).?;
if (func.name_token) |name_token| {
const use_snippets = server.config.enable_snippets and server.client_capabilities.supports_snippets;
const use_placeholders = server.config.enable_argument_placeholders and server.client_capabilities.supports_snippets;
const insert_text = if (use_snippets) blk: {
if (use_placeholders) {
const skip_self_param = !(parent_is_type_val orelse true) and
try server.analyser.hasSelfParam(handle, func);
break :blk try Analyser.getFunctionSnippet(allocator, tree, func, skip_self_param);
} else {
break :blk try std.fmt.allocPrint(allocator, "{s}()", .{tree.tokenSlice(func.name_token.?)});

const insert_text = blk: {
const func_name = tree.tokenSlice(func.name_token.?);

if (!use_snippets) break :blk func_name;

const skip_self_param = !(parent_is_type_val orelse true) and try server.analyser.hasSelfParam(handle, func);

const use_placeholders = server.config.enable_argument_placeholders;
if (use_placeholders) break :blk try Analyser.getFunctionSnippet(allocator, tree, func, skip_self_param);

switch (func.ast.params.len) {
// No arguments, leave cursor at the end
0 => break :blk try std.fmt.allocPrint(allocator, "{s}()", .{func_name}),
1 => {
if (skip_self_param) {
// The one argument is a self parameter, leave cursor at the end
break :blk try try std.fmt.allocPrint(allocator, "{s}()", .{func_name});
}

// Non-self parameter, leave the cursor in the parentheses
break :blk try try std.fmt.allocPrint(allocator, "{s}(${{1:}})", .{func_name});
},
// Atleast one non-self parameter, leave the cursor in the parentheses
else => break :blk try std.fmt.allocPrint(allocator, "{s}(${{1:}})", .{func_name}),
}
} else tree.tokenSlice(func.name_token.?);
};

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

Expand Down

0 comments on commit cfd1f98

Please sign in to comment.