aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaytan Laats <laytanlaats@hotmail.com>2023-11-28 19:55:16 +0100
committerLaytan Laats <laytanlaats@hotmail.com>2023-11-28 19:55:16 +0100
commitba960e84180a2b3ce8e0b3c4c376f280687e138e (patch)
treeff90fee6b9ef07469c3dc9ff931ea1ab726581b1 /src
parente53da4ddeb79e43d0b2ff18461fd18a8191364c9 (diff)
better bitset completion
Diffstat (limited to 'src')
-rw-r--r--src/server/completion.odin239
1 files changed, 159 insertions, 80 deletions
diff --git a/src/server/completion.odin b/src/server/completion.odin
index 94789e2..493fa4e 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -517,6 +517,40 @@ get_selector_completion :: proc(
append(&items, item)
}
+ case SymbolBitSetValue:
+ list.isIncomplete = false
+
+ enumv, ok := unwrap_bitset(ast_context, selector)
+ if !ok { break }
+
+ range, rok := get_range_from_selection_start_to_dot(position_context)
+ if !rok { break }
+
+ range.end.character -= 1
+
+ variable, vok := position_context.selector.derived_expr.(^ast.Ident)
+ if !vok { break }
+
+ remove_edit := TextEdit {
+ range = {
+ start = range.start,
+ end = range.end,
+ },
+ newText = "",
+ }
+
+ additionalTextEdits := make([]TextEdit, 1, context.temp_allocator)
+ additionalTextEdits[0] = remove_edit
+
+ for name in enumv.names {
+ append(&items, CompletionItem {
+ label = fmt.tprintf(".%s", name),
+ kind = .EnumMember,
+ detail = fmt.tprintf("%s.%s", selector.name, name),
+ additionalTextEdits = additionalTextEdits,
+ })
+ }
+
case SymbolStructValue:
list.isIncomplete = false
@@ -669,11 +703,31 @@ get_implicit_completion :: proc(
//value decl infer a : My_Enum = .*
if position_context.value_decl != nil &&
position_context.value_decl.type != nil {
- if enum_value, ok := unwrap_enum(
+ enum_value: Maybe(SymbolEnumValue)
+
+ if _enum_value, ok := unwrap_enum(
ast_context,
position_context.value_decl.type,
); ok {
- for name in enum_value.names {
+ enum_value = _enum_value
+ }
+
+ if position_context.comp_lit != nil {
+ if bitset_symbol, ok := resolve_type_expression(
+ ast_context,
+ position_context.value_decl.type,
+ ); ok {
+ if _enum_value, ok := unwrap_bitset(
+ ast_context,
+ bitset_symbol,
+ ); ok {
+ enum_value = _enum_value
+ }
+ }
+ }
+
+ if ev, ok := enum_value.?; ok {
+ for name in ev.names {
item := CompletionItem {
label = name,
kind = .EnumMember,
@@ -790,114 +844,112 @@ get_implicit_completion :: proc(
//infer bitset and enums based on the identifier comp_lit, i.e. a := My_Struct { my_ident = . }
if position_context.comp_lit != nil {
- if position_context.parent_comp_lit.type == nil {
- return
- }
-
- field_name: string
+ if position_context.parent_comp_lit.type != nil {
+ field_name: string
- if position_context.field_value != nil {
- if field, ok := position_context.field_value.field.derived.(^ast.Ident);
- ok {
- field_name = field.name
- } else {
- return
+ if position_context.field_value != nil {
+ if field, ok := position_context.field_value.field.derived.(^ast.Ident);
+ ok {
+ field_name = field.name
+ } else {
+ return
+ }
}
- }
- if symbol, ok := resolve_type_expression(
- ast_context,
- position_context.parent_comp_lit.type,
- ); ok {
- if comp_symbol, comp_lit, ok := resolve_type_comp_literal(
+ if symbol, ok := resolve_type_expression(
ast_context,
- position_context,
- symbol,
- position_context.parent_comp_lit,
+ position_context.parent_comp_lit.type,
); ok {
- if s, ok := comp_symbol.value.(SymbolStructValue); ok {
- ast_context.current_package = comp_symbol.pkg
-
- //We can either have the final
- elem_index := -1
-
- for elem, i in comp_lit.elems {
- if position_in_node(elem, position_context.position) {
- elem_index = i
- }
- }
+ if comp_symbol, comp_lit, ok := resolve_type_comp_literal(
+ ast_context,
+ position_context,
+ symbol,
+ position_context.parent_comp_lit,
+ ); ok {
+ if s, ok := comp_symbol.value.(SymbolStructValue); ok {
+ ast_context.current_package = comp_symbol.pkg
- type: ^ast.Expr
+ //We can either have the final
+ elem_index := -1
- for name, i in s.names {
- if name != field_name {
- continue
+ for elem, i in comp_lit.elems {
+ if position_in_node(elem, position_context.position) {
+ elem_index = i
+ }
}
- type = s.types[i]
- break
- }
-
- if type == nil && len(s.types) > elem_index {
- type = s.types[elem_index]
- }
+ type: ^ast.Expr
- if enum_value, ok := unwrap_enum(ast_context, type); ok {
- for enum_name in enum_value.names {
- item := CompletionItem {
- label = enum_name,
- kind = .EnumMember,
- detail = enum_name,
+ for name, i in s.names {
+ if name != field_name {
+ continue
}
- append(&items, item)
+ type = s.types[i]
+ break
}
- list.items = items[:]
- return
- } else if bitset_symbol, ok := resolve_type_expression(
- ast_context,
- type,
- ); ok {
- ast_context.current_package = bitset_symbol.pkg
-
- if value, ok := unwrap_bitset(
- ast_context,
- bitset_symbol,
- ); ok {
- for name in value.names {
+ if type == nil && len(s.types) > elem_index {
+ type = s.types[elem_index]
+ }
+ if enum_value, ok := unwrap_enum(ast_context, type); ok {
+ for enum_name in enum_value.names {
item := CompletionItem {
- label = name,
+ label = enum_name,
kind = .EnumMember,
- detail = name,
+ detail = enum_name,
}
append(&items, item)
}
+
list.items = items[:]
return
+ } else if bitset_symbol, ok := resolve_type_expression(
+ ast_context,
+ type,
+ ); ok {
+ ast_context.current_package = bitset_symbol.pkg
+
+ if value, ok := unwrap_bitset(
+ ast_context,
+ bitset_symbol,
+ ); ok {
+ for name in value.names {
+
+ item := CompletionItem {
+ label = name,
+ kind = .EnumMember,
+ detail = name,
+ }
+
+ append(&items, item)
+ }
+ list.items = items[:]
+ return
+ }
}
- }
- } else if s, ok := unwrap_bitset(ast_context, comp_symbol);
- ok {
- for enum_name in s.names {
- item := CompletionItem {
- label = enum_name,
- kind = .EnumMember,
- detail = enum_name,
+ } else if s, ok := unwrap_bitset(ast_context, comp_symbol);
+ ok {
+ for enum_name in s.names {
+ item := CompletionItem {
+ label = enum_name,
+ kind = .EnumMember,
+ detail = enum_name,
+ }
+
+ append(&items, item)
}
- append(&items, item)
+ list.items = items[:]
+ return
}
-
- list.items = items[:]
- return
}
}
- }
- reset_ast_context(ast_context)
+ reset_ast_context(ast_context)
+ }
}
if position_context.binary != nil &&
@@ -1066,6 +1118,33 @@ get_implicit_completion :: proc(
list.items = items[:]
return
}
+
+ // Bitset comp literal in parameter, eg: `hello({ . })`.
+ if position_context.comp_lit != nil {
+ if bitset_symbol, ok := resolve_type_expression(
+ ast_context,
+ proc_value.arg_types[parameter_index].type,
+ ); ok {
+ if enum_value, ok := unwrap_bitset(
+ ast_context,
+ bitset_symbol,
+ ); ok {
+ for name in enum_value.names {
+ item := CompletionItem {
+ label = name,
+ kind = .EnumMember,
+ detail = name,
+ }
+
+ append(&items, item)
+ }
+
+ list.items = items[:]
+ return
+ }
+ }
+ }
+
} else if enum_value, ok := symbol.value.(SymbolEnumValue);
ok {
for name in enum_value.names {