aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBradley Lewis <22850972+BradLewis@users.noreply.github.com>2025-08-26 07:56:05 -0400
committerGitHub <noreply@github.com>2025-08-26 07:56:05 -0400
commit4703f8a761bfe70946a3a84db4490a5e66ab9e4c (patch)
tree80acd3d5a2d5f6cfa0bcb45aefa0adc93f16e7cd /src
parenta415dc91e9de80ee066540894e9b385330fad56b (diff)
parentf4b044d228f18856fa0ae3fbfc9513aaf26d0db6 (diff)
Merge pull request #928 from BradLewis/add-docs-keywords
Add completion and hover information for builtin types
Diffstat (limited to 'src')
-rw-r--r--src/server/completion.odin68
-rw-r--r--src/server/documentation.odin198
-rw-r--r--src/server/hover.odin24
-rw-r--r--src/server/type_definition.odin6
4 files changed, 120 insertions, 176 deletions
diff --git a/src/server/completion.odin b/src/server/completion.odin
index d54d03c..60162ec 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -1530,25 +1530,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})
}
}
@@ -2208,52 +2198,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
}
}