Skip to content

Commit

Permalink
Merge pull request #275 from laytan/better-bitset-completion
Browse files Browse the repository at this point in the history
better bitset completion
  • Loading branch information
DanielGavin authored Nov 28, 2023
2 parents c2a8ee7 + ba960e8 commit f0744a6
Showing 1 changed file with 159 additions and 80 deletions.
239 changes: 159 additions & 80 deletions src/server/completion.odin
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -671,11 +705,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,
Expand Down Expand Up @@ -792,114 +846,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 &&
Expand Down Expand Up @@ -1068,6 +1120,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 {
Expand Down

0 comments on commit f0744a6

Please sign in to comment.