Skip to content

Commit

Permalink
add completions_with_replace flag (#1458)
Browse files Browse the repository at this point in the history
  • Loading branch information
almmiko authored Oct 1, 2023
1 parent ee3f9d8 commit de2464a
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 26 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ The following options are currently available.
| `build_runner_path` | `?[]const u8` | `null` | Path to the `build_runner.zig` file provided by zls. null is equivalent to `${executable_directory}/build_runner.zig` |
| `global_cache_path` | `?[]const u8` | `null` | Path to a directory that will be used as zig's cache. null is equivalent to `${KnownFolders.Cache}/zls` |
| `build_runner_global_cache_path` | `?[]const u8` | `null` | Path to a directory that will be used as the global cache path when executing a projects build.zig. null is equivalent to the path shown by `zig env` |
| `completions_with_replace` | `bool` | `true` | Completions confirm behavior. If 'true', replace the text after the cursor |
<!-- DO NOT EDIT -->

### Per-build Configuration Options
Expand Down
5 changes: 5 additions & 0 deletions schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@
"description": "Path to a directory that will be used as the global cache path when executing a projects build.zig. null is equivalent to the path shown by `zig env`",
"type": "string",
"default": "null"
},
"completions_with_replace": {
"description": "Completions confirm behavior. If 'true', replace the text after the cursor",
"type": "boolean",
"default": "true"
}
}
}
3 changes: 3 additions & 0 deletions src/Config.zig
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,7 @@ global_cache_path: ?[]const u8 = null,
/// Path to a directory that will be used as the global cache path when executing a projects build.zig. null is equivalent to the path shown by `zig env`
build_runner_global_cache_path: ?[]const u8 = null,

/// Completions confirm behavior. If 'true', replace the text after the cursor
completions_with_replace: bool = true,

// DO NOT EDIT
8 changes: 7 additions & 1 deletion src/config_gen/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@
"description": "Path to a directory that will be used as the global cache path when executing a projects build.zig. null is equivalent to the path shown by `zig env`",
"type": "?[]const u8",
"default": "null"
},
{
"name": "completions_with_replace",
"description": "Completions confirm behavior. If 'true', replace the text after the cursor",
"type": "bool",
"default": "true"
}
]
}
}
52 changes: 27 additions & 25 deletions src/features/completions.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1455,33 +1455,35 @@ pub fn completionAtIndex(server: *Server, analyser: *Analyser, arena: std.mem.Al

const completions = maybe_completions orelse return null;

// The cursor is in the middle of a word or before a @, so we can replace
// the remaining identifier with the completion instead of just inserting.
// TODO Identify function call/struct init and replace the whole thing.
const lookahead_context = try Analyser.getPositionContext(arena, handle.text, source_index, true);
if (server.client_capabilities.supports_apply_edits and
pos_context != .import_string_literal and
pos_context != .cinclude_string_literal and
pos_context != .embedfile_string_literal and
pos_context.loc() != null and
lookahead_context.loc() != null and
pos_context.loc().?.end != lookahead_context.loc().?.end)
{
var end = lookahead_context.loc().?.end;
while (end < handle.text.len and (std.ascii.isAlphanumeric(handle.text[end]) or handle.text[end] == '"')) {
end += 1;
}
if (server.config.completions_with_replace) {
// The cursor is in the middle of a word or before a @, so we can replace
// the remaining identifier with the completion instead of just inserting.
// TODO Identify function call/struct init and replace the whole thing.
const lookahead_context = try Analyser.getPositionContext(arena, handle.text, source_index, true);
if (server.client_capabilities.supports_apply_edits and
pos_context != .import_string_literal and
pos_context != .cinclude_string_literal and
pos_context != .embedfile_string_literal and
pos_context.loc() != null and
lookahead_context.loc() != null and
pos_context.loc().?.end != lookahead_context.loc().?.end)
{
var end = lookahead_context.loc().?.end;
while (end < handle.text.len and (std.ascii.isAlphanumeric(handle.text[end]) or handle.text[end] == '"')) {
end += 1;
}

const replaceLoc = offsets.Loc{ .start = lookahead_context.loc().?.start, .end = end };
const replaceRange = offsets.locToRange(handle.text, replaceLoc, server.offset_encoding);
const replaceLoc = offsets.Loc{ .start = lookahead_context.loc().?.start, .end = end };
const replaceRange = offsets.locToRange(handle.text, replaceLoc, server.offset_encoding);

for (completions) |*item| {
item.textEdit = .{
.TextEdit = .{
.newText = item.insertText orelse item.label,
.range = replaceRange,
},
};
for (completions) |*item| {
item.textEdit = .{
.TextEdit = .{
.newText = item.insertText orelse item.label,
.range = replaceRange,
},
};
}
}
}

Expand Down

0 comments on commit de2464a

Please sign in to comment.