diff options
| author | Brad Lewis <22850972+BradLewis@users.noreply.github.com> | 2025-08-24 11:17:18 -0400 |
|---|---|---|
| committer | Brad Lewis <22850972+BradLewis@users.noreply.github.com> | 2025-08-24 16:59:25 -0400 |
| commit | f4b044d228f18856fa0ae3fbfc9513aaf26d0db6 (patch) | |
| tree | 7c155e8fcea164a2ebb93825cb367dcc3dd2d9da /src/server | |
| parent | 7e9d53239f6e8ebff7cf8444d7b97458020317d5 (diff) | |
Add completion and hover information for builtin types
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/completion.odin | 68 | ||||
| -rw-r--r-- | src/server/documentation.odin | 198 | ||||
| -rw-r--r-- | src/server/hover.odin | 24 | ||||
| -rw-r--r-- | src/server/type_definition.odin | 6 |
4 files changed, 120 insertions, 176 deletions
diff --git a/src/server/completion.odin b/src/server/completion.odin index 617ffca..bfbc094 100644 --- a/src/server/completion.odin +++ b/src/server/completion.odin @@ -1524,25 +1524,15 @@ get_identifier_completion :: proc( } } - for keyword, _ in keyword_map { - symbol := Symbol { - name = keyword, - type = .Keyword, - } - - if score, ok := common.fuzzy_match(matcher, keyword); ok == 1 { - append(results, CompletionResult{score = score, symbol = symbol}) - } - } - - for keyword, _ in language_keywords { - symbol := Symbol { - name = keyword, - type = .Keyword, + for keyword, docs in keywords_docs { + item := CompletionItem { + label = keyword, + kind = .Keyword, + documentation = docs, } if score, ok := common.fuzzy_match(matcher, keyword); ok == 1 { - append(results, CompletionResult{score = score * 1.1, symbol = symbol}) + append(results, CompletionResult{score = score * 1.1, completion_item = item}) } } @@ -2202,52 +2192,6 @@ is_bitset_assignment_operator :: proc(op: string) -> bool { return op in bitset_assignment_operators } -language_keywords: []string = { - "align_of", - "case", - "defer", - "enum", - "import", - "proc", - "transmute", - "when", - "auto_cast", - "cast", - "distinct", - "fallthrough", - "in", - "not_in", - "return", - "type_of", - "bit_field", - "const", - "do", - "for", - "inline", - "offset_of", - "size_of", - "typeid", - "bit_set", - "context", - "dynamic", - "foreign", - "opaque", - "struct", - "union", - "break", - "continue", - "else", - "if", - "map", - "package", - "switch", - "using", - "or_return", - "or_else", - "or_continue", - "or_break", -} - swizzle_color_map: map[u8]struct{} = { 'r' = {}, 'g' = {}, diff --git a/src/server/documentation.odin b/src/server/documentation.odin index ac1227f..5615e6c 100644 --- a/src/server/documentation.odin +++ b/src/server/documentation.odin @@ -7,103 +7,109 @@ import "core:odin/ast" import path "core:path/slashpath" import "core:strings" -keywords_docs: map[string]struct{} = { - "typeid" = {}, - "string" = {}, - "cstring" = {}, - "int" = {}, - "uint" = {}, - "u8" = {}, - "i8" = {}, - "u16" = {}, - "i16" = {}, - "u32" = {}, - "i32" = {}, - "u64" = {}, - "i64" = {}, - "u128" = {}, - "i128" = {}, - "f16" = {}, - "f32" = {}, - "f64" = {}, - "bool" = {}, - "rawptr" = {}, - "any" = {}, - "b8" = {}, - "b16" = {}, - "b32" = {}, - "b64" = {}, - "true" = {}, - "false" = {}, - "nil" = {}, - "byte" = {}, - "rune" = {}, - "f16be" = {}, - "f16le" = {}, - "f32be" = {}, - "f32le" = {}, - "f64be" = {}, - "f64le" = {}, - "i16be" = {}, - "i16le" = {}, - "i32be" = {}, - "i32le" = {}, - "i64be" = {}, - "i64le" = {}, - "u16be" = {}, - "u16le" = {}, - "u32be" = {}, - "u32le" = {}, - "u64be" = {}, - "u64le" = {}, - "i128be" = {}, - "i128le" = {}, - "u128be" = {}, - "u128le" = {}, - "complex32" = {}, - "complex64" = {}, - "complex128" = {}, - "quaternion64" = {}, - "quaternion128" = {}, - "quaternion256" = {}, - "uintptr" = {}, +// Docs taken from https://pkg.odin-lang.org/base/builtin +keywords_docs: map[string]string = { + "typeid" = "```odin\ntypeid :: typeid\n```\n`typeid` is a unique identifier for an Odin type at runtime. It can be mapped to relevant type information through `type_info_of`.", + "string" = "```odin\nstring :: string\n```\n`string` is the set of all strings of 8-bit bytes, conventionally but not necessarily representing UTF-8 encoding text. A `string` may be empty but not `nil`. Elements of `string` type are immutable and indexable.", + "cstring" = "```odin\ncstring :: cstring\n```\n`cstring` is the set of all strings of 8-bit bytes terminated with a NUL (0) byte, conventionally but not necessarily representing UTF-8 encoding text. A `cstring` may be empty or `nil`. Elements of `cstring` type are immutable but not indexable.", + "int" = "```odin\nint :: int\n```\n`int` is a signed integer type that is at least 32 bits in size. It is a distinct type, however, and not an alias for say, `i32`.", + "uint" = "```odin\nuint :: uint\n```\n`uint` is an unsigned integer type that is at least 32 bits in size. It is a distinct type, however, and not an alias for say, `u32`.", + "u8" = "```odin\nu8 :: u8\n```\n`u8` is the set of all unsigned 8-bit integers. Range 0 through 255.", + "i8" = "```odin\ni8 :: i8\n```\n`i8` is the set of all signed 8-bit integers. Range -128 through 127.", + "u16" = "```odin\nu16 :: u16\n```\n`u16` is the set of all unsigned 16-bit integers with native endianness. Range 0 through 65535.", + "i16" = "```odin\ni16 :: i16\n```\n`i16` is the set of all signed 16-bit integers with native endianness. Range -32768 through 32767.", + "u32" = "```odin\nu32 :: u32\n```\n`u32` is the set of all unsigned 32-bit integers with native endianness. Range 0 through 4294967295.", + "i32" = "```odin\ni32 :: i32\n```\n`i32` is the set of all signed 32-bit integers with native endianness. Range -2147483648 through 2147483647.", + "u64" = "```odin\nu64 :: u64\n```\n`u64` is the set of all unsigned 64-bit integers with native endianness. Range 0 through 18446744073709551615.", + "i64" = "```odin\ni64 :: i64\n```\n`i64` is the set of all signed 64-bit integers with native endianness. Range -9223372036854775808 through 9223372036854775807.", + "u128" = "```odin\nu128 :: u128\n```\n`u128` is the set of all unsigned 128-bit integers with native endianness. Range 0 through 340282366920938463463374607431768211455.", + "i128" = "```odin\ni128 :: i128\n```\n`i128` is the set of all signed 128-bit integers with native endianness. Range -170141183460469231731687303715884105728 through 170141183460469231731687303715884105727.", + "f16" = "```odin\nf16 :: f16\n```\n`f16` is the set of all IEEE-754 16-bit floating-point numbers with native endianness.", + "f32" = "```odin\nf32 :: f32\n```\n`f32` is the set of all IEEE-754 32-bit floating-point numbers with native endianness.", + "f64" = "```odin\nf64 :: f64\n```\n`f64` is the set of all IEEE-754 64-bit floating-point numbers with native endianness.", + "bool" = "```odin\nbool :: bool :: bool\n`bool` is ```\n`bool` is the set of boolean values, `false` and `true`. This is distinct to `b8`. `bool` has a size of 1 byte (8 bits).", + "any" = "```odin\nany :: any\n```\n`any` is reference any data type at runtime. Internally it contains a pointer to the underlying data and its relevant `typeid`. This is a very useful construct in order to have a runtime type safe printing procedure.\n\nNote: The `any` value is only valid for as long as the underlying data is still valid. Passing a literal to an `any` will allocate the literal in the current stack frame.\n\nNote: It is highly recommend that you do not use this unless you know what you are doing. Its primary use is for printing procedures.", + "b8" = "```odin\nb8 :: b8\n```\n`b8` is the set of boolean values, `false` and `true`. This is distinct to `bool`. `b8` has a size of 1 byte (8 bits).", + "b16" = "```odin\nb16 :: b16\n```\n`b16` is the set of boolean values, `false` and `true`. `b16` has a size of 2 bytes (16 bits).", + "b32" = "```odin\nb32 :: b32\n```\n`b32` is the set of boolean values, `false` and `true`. `b32` has a size of 4 bytes (32 bits).", + "b64" = "```odin\nb64 :: b64\n```\n`b64` is the set of boolean values, `false` and `true`. `b64` has a size of 8 bytes (64 bits).", + "true" = "```odin\ntrue :: 0 == 0 // untyped boolean\n```", + "false" = "```odin\nfalse :: 0 != 0 // untyped boolean\n```", + "nil" = "```odin\nnil :: ... // untyped nil \n```\n`nil` is a predeclared identifier representing the zero value for a pointer, multi-pointer, enum, bit_set, slice, dynamic array, map, procedure, any, typeid, cstring, union, #soa array, #soa pointer, #relative type.", + "byte" = "```odin\nbyte :: u8\n```\n`byte` is an alias for `u8` and is equivalent to `u8` in all ways. It is used as a convention to distinguish values from 8-bit unsigned integer values.", + "rune" = "```odin\nrune :: rune\n```\n`rune` is the set of all Unicode code points. It is internally the same as i32 but distinct.", + "f16be" = "```odin\nf16be :: f16be\n```\n`f16be` is the set of all IEEE-754 16-bit floating-point numbers with big endianness.", + "f16le" = "```odin\nf16le :: f16le\n```\n`f16le` is the set of all IEEE-754 16-bit floating-point numbers with little endianness.", + "f32be" = "```odin\nf32be :: f32be\n```\n`f32be` is the set of all IEEE-754 32-bit floating-point numbers with big endianness.", + "f32le" = "```odin\nf32le :: f32le\n```\n`f32le` is the set of all IEEE-754 32-bit floating-point numbers with little endianness.", + "f64be" = "```odin\nf64be :: f64be\n```\n`f64be` is the set of all IEEE-754 64-bit floating-point numbers with big endianness.", + "f64le" = "```odin\nf64le :: f64le\n```\n`f64le` is the set of all IEEE-754 64-bit floating-point numbers with little endianness.", + "i16be" = "```odin\ni16be :: i16be\n```\n`i16be` is the set of all signed 16-bit integers with big endianness. Range -32768 through 32767.", + "i16le" = "```odin\ni16le :: i16le\n```\n`i16le` is the set of all signed 16-bit integers with little endianness. Range -32768 through 32767.", + "i32be" = "```odin\ni32be :: i32be\n```\n`i32be` is the set of all signed 32-bit integers with big endianness. Range -2147483648 through 2147483647.", + "i32le" = "```odin\ni32le :: i32le\n```\n`i32le` is the set of all signed 32-bit integers with little endianness. Range -2147483648 through 2147483647.", + "i64be" = "```odin\ni64be :: i64be\n```\n`i64be` is the set of all signed 64-bit integers with big endianness. Range -9223372036854775808 through 9223372036854775807.", + "i64le" = "```odin\ni64le :: i64le\n```\n`i64le` is the set of all signed 64-bit integers with little endianness. Range -9223372036854775808 through 9223372036854775807.", + "u16be" = "```odin\nu16be :: u16be\n```\n`u16be` is the set of all unsigned 16-bit integers with big endianness. Range 0 through 65535.", + "u16le" = "```odin\nu16le :: u16le\n```\n`u16le` is the set of all unsigned 16-bit integers with little endianness. Range 0 through 65535.", + "u32be" = "```odin\nu32be :: u32be\n```\n`u32be` is the set of all unsigned 32-bit integers with big endianness. Range 0 through 4294967295.", + "u32le" = "```odin\nu32le :: u32le\n```\n`u32le` is the set of all unsigned 32-bit integers with little endianness. Range 0 through 4294967295.", + "u64be" = "```odin\nu64be :: u64be\n```\n`u64be` is the set of all unsigned 64-bit integers with big endianness. Range 0 through 18446744073709551615.", + "u64le" = "```odin\nu64le :: u64le\n```\n`u64le` is the set of all unsigned 64-bit integers with little endianness. Range 0 through 18446744073709551615.", + "i128be" = "```odin\ni128be :: i128be\n```\n`i128be` is the set of all signed 128-bit integers with big endianness. Range -170141183460469231731687303715884105728 through 170141183460469231731687303715884105727.", + "i128le" = "```odin\ni128le :: i128le\n```\n`i128le` is the set of all signed 128-bit integers with little endianness. Range -170141183460469231731687303715884105728 through 170141183460469231731687303715884105727.", + "u128be" = "```odin\nu128be :: u128be\n```\n`u128be` is the set of all unsigned 128-bit integers with big endianness. Range 0 through 340282366920938463463374607431768211455.", + "u128le" = "```odin\nu128le :: u128le\n```\n`u128le` is the set of all unsigned 128-bit integers with little endianness. Range 0 through 340282366920938463463374607431768211455.", + "complex32" = "```odin\ncomplex32 :: complex32\n```\n`complex32` is the set of all complex numbers with `f16` real and imaginary parts.", + "complex64" = "```odin\ncomplex64 :: complex64\n```\n`complex64` is the set of all complex numbers with `f32` real and imaginary parts.", + "complex128" = "```odin\ncomplex128 :: complex128\n```\n`complex128` is the set of all complex numbers with `f64` real and imaginary parts.", + "quaternion64" = "```odin\nquaternion64 :: quaternion64\n```\n`quaternion64` is the set of all complex numbers with `f16` real and imaginary (i, j, & k) parts.", + "quaternion128" = "```odin\nquaternion128 :: quaternion128\n```\n`quaternion128` is the set of all complex numbers with `f32` real and imaginary (i, j, & k) parts.", + "quaternion256" = "```odin\nquaternion256 :: quaternion256\n```\n`quaternion256` is the set of all complex numbers with `f64` real and imaginary (i, j, & k) parts.", + "uintptr" = "```odin\nuintptr :: uintptr\n```\n`uintptr` is an unsigned integer type that is large enough to hold the bit pattern of any pointer.", + "rawptr" = "```odin\nrawptr :: rawptr\n```\n`rawptr` is a pointer to an arbitrary type. It is equivalent to void * in C.", // taken from https://github.com/odin-lang/Odin/wiki/Keywords-and-Operators - "asm" = {}, - "auto_cast" = {}, - "bit_field" = {}, - "bit_set" = {}, - "break" = {}, - "case" = {}, - "cast" = {}, - "context" = {}, - "continue" = {}, - "defer" = {}, - "distinct" = {}, - "do" = {}, - "dynamic" = {}, - "else" = {}, - "enum" = {}, - "fallthrough" = {}, - "for" = {}, - "foreign" = {}, - "if" = {}, - "import" = {}, - "in" = {}, - "map" = {}, - "not_in" = {}, - "or_else" = {}, - "or_return" = {}, - "package" = {}, - "proc" = {}, - "return" = {}, - "struct" = {}, - "switch" = {}, - "transmute" = {}, - "typeid" = {}, - "union" = {}, - "using" = {}, - "when" = {}, - "where" = {}, + "asm" = "", + "auto_cast" = "```odin\nauto_cast v```\nAutomatically casts an expression `v` to the destination’s type if possible.", + "bit_field" = "", + "bit_set" = "", + "break" = "", + "case" = "", + "cast" = "```odin\ncast(T)v\n```\nConverts the value `v` to the type `T`.", + "const" = "", + "context" = "```odin\nruntime.context: Context\n```\nThe context variable is local to each scope. It is copy-on-write and is implicitly passed by pointer to any procedure call in that scope (if the procedure has the Odin calling convention).", + "continue" = "", + "defer" = "", + "distinct" = "```odin\ndistinct T\n```\nCreate a new type with the same underlying semantics as `T`", + "do" = "", + "dynamic" = "", + "else" = "", + "enum" = "", + "fallthrough" = "", + "for" = "", + "foreign" = "", + "if" = "", + "import" = "", + "in" = "", + "inline" = "", + "map" = "", + "not_in" = "", + "or_break" = "", + "or_continue" = "", + "or_else" = "", + "or_return" = "", + "opaque" = "", + "package" = "", + "proc" = "", + "return" = "", + "struct" = "", + "switch" = "", + "transmute" = "```odin\ntransmute(T)v\n```\nBitwise cast between 2 types of the same size.", + "typeid" = "", + "union" = "", + "using" = "", + "when" = "", + "where" = "", } // Adds signature and docs information to the provided symbol diff --git a/src/server/hover.odin b/src/server/hover.odin index 86fd6a8..d0eb0f3 100644 --- a/src/server/hover.odin +++ b/src/server/hover.odin @@ -47,11 +47,6 @@ write_hover_content :: proc(ast_context: ^AstContext, symbol: Symbol) -> MarkupC return content } -builtin_identifier_hover: map[string]string = { - "context" = "```odin\nruntime.context: Context\n```\nThis context variable is local to each scope and is implicitly passed by pointer to any procedure call in that scope (if the procedure has the Odin calling convention).", -} - - get_hover_information :: proc(document: ^Document, position: common.Position) -> (Hover, bool, bool) { hover := Hover { contents = {kind = "plaintext"}, @@ -83,15 +78,18 @@ get_hover_information :: proc(document: ^Document, position: common.Position) -> return {}, false, true } + if position_context.type_cast != nil { + if str, ok := keywords_docs[position_context.type_cast.tok.text]; ok { + hover.contents.kind = "markdown" + hover.contents.value = str + hover.range = common.get_token_range(position_context.type_cast, ast_context.file.src) + return hover, true, true + } + } + if position_context.identifier != nil { if ident, ok := position_context.identifier.derived.(^ast.Ident); ok { - if _, ok := keyword_map[ident.name]; ok { - hover.contents.kind = "plaintext" - hover.range = common.get_token_range(position_context.identifier^, ast_context.file.src) - return hover, true, true - } - - if str, ok := builtin_identifier_hover[ident.name]; ok { + if str, ok := keywords_docs[ident.name]; ok { hover.contents.kind = "markdown" hover.contents.value = str hover.range = common.get_token_range(position_context.identifier^, ast_context.file.src) @@ -101,7 +99,7 @@ get_hover_information :: proc(document: ^Document, position: common.Position) -> } if position_context.implicit_context != nil { - if str, ok := builtin_identifier_hover[position_context.implicit_context.tok.text]; ok { + if str, ok := keywords_docs[position_context.implicit_context.tok.text]; ok { hover.contents.kind = "markdown" hover.contents.value = str hover.range = common.get_token_range(position_context.implicit_context^, ast_context.file.src) diff --git a/src/server/type_definition.odin b/src/server/type_definition.odin index 7ad9c26..84d1f1a 100644 --- a/src/server/type_definition.odin +++ b/src/server/type_definition.odin @@ -56,11 +56,7 @@ get_type_definition_locations :: proc(document: ^Document, position: common.Posi if position_context.identifier != nil { if ident, ok := position_context.identifier.derived.(^ast.Ident); ok { - if _, ok := keyword_map[ident.name]; ok { - return {}, false - } - - if str, ok := builtin_identifier_hover[ident.name]; ok { + if _, ok := keywords_docs[ident.name]; ok { return {}, false } } |