Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions src/docs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use std::{collections::HashMap, sync::LazyLock};

macro_rules! docmap_builtin {
($name:literal) => {
($name, include_str!(concat!("docs/builtin/", $name, ".md")))
};
}

macro_rules! docmap_wellknown {
($name:literal) => {
(
concat!("google.protobuf.", $name),
include_str!(concat!("docs/wellknown/", $name, ".md")),
)
};
}

pub static BUITIN: LazyLock<HashMap<&'static str, &'static str>> = LazyLock::new(|| {
HashMap::from([
docmap_builtin!("int32"),
docmap_builtin!("int64"),
docmap_builtin!("uint32"),
docmap_builtin!("uint64"),
docmap_builtin!("sint32"),
docmap_builtin!("sint64"),
docmap_builtin!("fixed32"),
docmap_builtin!("fixed64"),
docmap_builtin!("sfixed32"),
docmap_builtin!("sfixed64"),
docmap_builtin!("float"),
docmap_builtin!("double"),
docmap_builtin!("string"),
docmap_builtin!("bytes"),
docmap_builtin!("bool"),
docmap_builtin!("default"),
])
});

pub static WELLKNOWN: LazyLock<HashMap<&'static str, &'static str>> = LazyLock::new(|| {
HashMap::from([
docmap_wellknown!("Any"),
docmap_wellknown!("Api"),
docmap_wellknown!("BoolValue"),
docmap_wellknown!("BytesValue"),
docmap_wellknown!("DoubleValue"),
docmap_wellknown!("Duration"),
docmap_wellknown!("Empty"),
docmap_wellknown!("Enum"),
docmap_wellknown!("EnumValue"),
docmap_wellknown!("Field"),
docmap_wellknown!("Field.Cardinality"),
docmap_wellknown!("Field.Kind"),
docmap_wellknown!("FieldMask"),
docmap_wellknown!("FloatValue"),
docmap_wellknown!("Int32Value"),
docmap_wellknown!("Int64Value"),
docmap_wellknown!("ListValue"),
docmap_wellknown!("Method"),
docmap_wellknown!("Mixin"),
docmap_wellknown!("NullValue"),
docmap_wellknown!("Option"),
docmap_wellknown!("SourceContext"),
docmap_wellknown!("StringValue"),
docmap_wellknown!("Struct"),
docmap_wellknown!("Syntax"),
docmap_wellknown!("Timestamp"),
docmap_wellknown!("Type"),
docmap_wellknown!("UInt32Value"),
docmap_wellknown!("UInt64Value"),
docmap_wellknown!("Value"),
])
});
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
41 changes: 31 additions & 10 deletions src/lsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,20 @@ use async_lsp::lsp_types::{
CreateFilesParams, DeleteFilesParams, DidChangeConfigurationParams,
DidChangeTextDocumentParams, DidChangeWorkspaceFoldersParams, DidCloseTextDocumentParams,
DidOpenTextDocumentParams, DidSaveTextDocumentParams, DocumentFormattingParams,
DocumentRangeFormattingParams, DocumentSymbolParams, DocumentSymbolResponse,
DocumentRangeFormattingParams, DocumentSymbolParams, DocumentSymbolResponse, Documentation,
FileOperationFilter, FileOperationPattern, FileOperationPatternKind,
FileOperationRegistrationOptions, GotoDefinitionParams, GotoDefinitionResponse, Hover,
HoverContents, HoverParams, HoverProviderCapability, InitializeParams, InitializeResult,
Location, OneOf, PrepareRenameResponse, ReferenceParams, RenameFilesParams, RenameOptions,
RenameParams, ServerCapabilities, ServerInfo, TextDocumentPositionParams,
TextDocumentSyncCapability, TextDocumentSyncKind, TextEdit, Url, WorkspaceEdit,
WorkspaceFileOperationsServerCapabilities, WorkspaceFoldersServerCapabilities,
Location, MarkupContent, MarkupKind, OneOf, PrepareRenameResponse, ReferenceParams,
RenameFilesParams, RenameOptions, RenameParams, ServerCapabilities, ServerInfo,
TextDocumentPositionParams, TextDocumentSyncCapability, TextDocumentSyncKind, TextEdit, Url,
WorkspaceEdit, WorkspaceFileOperationsServerCapabilities, WorkspaceFoldersServerCapabilities,
WorkspaceServerCapabilities,
};
use async_lsp::{LanguageClient, LanguageServer, ResponseError};
use futures::future::BoxFuture;

use crate::docs;
use crate::formatter::ProtoFormatter;
use crate::server::ProtoLanguageServer;

Expand Down Expand Up @@ -159,20 +160,40 @@ impl LanguageServer for ProtoLanguageServer {
) -> BoxFuture<'static, Result<Option<CompletionResponse>, Self::Error>> {
let uri = params.text_document_position.text_document.uri;

// All keywords in the language
let keywords = vec![
"syntax", "package", "option", "import", "service", "rpc", "returns", "message",
"enum", "oneof", "repeated", "reserved", "to",
];

let mut completions: Vec<CompletionItem> = keywords
.into_iter()
.map(|w| CompletionItem {
label: w.to_string(),
kind: Some(CompletionItemKind::KEYWORD),
// Build completion item from builtins as fields
let mut completions: Vec<CompletionItem> = docs::BUITIN
.iter()
.map(|(k, v)| {
(
k,
MarkupContent {
kind: MarkupKind::Markdown,
value: v.to_string(),
},
)
})
.map(|(k, v)| CompletionItem {
label: k.to_string(),
kind: Some(CompletionItemKind::FIELD),
documentation: Some(Documentation::MarkupContent(v)),
..CompletionItem::default()
})
.collect();

// Build completion item from keywords
completions.extend(keywords.into_iter().map(|w| CompletionItem {
label: w.to_string(),
kind: Some(CompletionItemKind::KEYWORD),
..CompletionItem::default()
}));

// Build completion item from the current tree
if let Some(tree) = self.state.get_tree(&uri) {
let content = self.state.get_content(&uri);
if let Some(package_name) = tree.get_package_name(content.as_bytes()) {
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use tracing::Level;

mod config;
mod context;
mod docs;
mod formatter;
mod lsp;
mod nodekind;
Expand Down
65 changes: 5 additions & 60 deletions src/workspace/hover.rs
Original file line number Diff line number Diff line change
@@ -1,67 +1,12 @@
use std::{collections::HashMap, path::PathBuf, sync::LazyLock};
use std::path::PathBuf;

use async_lsp::lsp_types::{MarkupContent, MarkupKind};

use crate::{
context::hoverable::Hoverables, state::ProtoLanguageState, utils::split_identifier_package,
context::hoverable::Hoverables, docs, state::ProtoLanguageState,
utils::split_identifier_package,
};

static BUITIN_DOCS: LazyLock<HashMap<&'static str, &'static str>> = LazyLock::new(|| {
HashMap::from([
("int32", include_str!("docs/builtin/int32.md")),
("int64", include_str!("docs/builtin/int64.md")),
("uint32", include_str!("docs/builtin/uint32.md")),
("uint64", include_str!("docs/builtin/uint64.md")),
("sint32", include_str!("docs/builtin/sint32.md")),
("sint64", include_str!("docs/builtin/sint64.md")),
("fixed32", include_str!("docs/builtin/fixed32.md")),
("fixed64", include_str!("docs/builtin/fixed64.md")),
("sfixed32", include_str!("docs/builtin/sfixed32.md")),
("sfixed64", include_str!("docs/builtin/sfixed64.md")),
("float", include_str!("docs/builtin/float.md")),
("double", include_str!("docs/builtin/double.md")),
("string", include_str!("docs/builtin/string.md")),
("bytes", include_str!("docs/builtin/bytes.md")),
("bool", include_str!("docs/builtin/bool.md")),
("default", include_str!("docs/builtin/default.md")),
])
});

static WELLKNOWN_DOCS: LazyLock<HashMap<&'static str, &'static str>> = LazyLock::new(|| {
HashMap::from([
("google.protobuf.Any", include_str!("docs/wellknown/Any.md")),
("google.protobuf.Api", include_str!("docs/wellknown/Api.md")),
("google.protobuf.BoolValue", include_str!("docs/wellknown/BoolValue.md")),
("google.protobuf.BytesValue", include_str!("docs/wellknown/BytesValue.md")),
("google.protobuf.DoubleValue", include_str!("docs/wellknown/DoubleValue.md")),
("google.protobuf.Duration", include_str!("docs/wellknown/Duration.md")),
("google.protobuf.Empty", include_str!("docs/wellknown/Empty.md")),
("google.protobuf.Enum", include_str!("docs/wellknown/Enum.md")),
("google.protobuf.EnumValue", include_str!("docs/wellknown/EnumValue.md")),
("google.protobuf.Field", include_str!("docs/wellknown/Field.md")),
("google.protobuf.Field.Cardinality", include_str!("docs/wellknown/Field.Cardinality.md")),
("google.protobuf.Field.Kind", include_str!("docs/wellknown/Field.Kind.md")),
("google.protobuf.FieldMask", include_str!("docs/wellknown/FieldMask.md")),
("google.protobuf.FloatValue", include_str!("docs/wellknown/FloatValue.md")),
("google.protobuf.Int32Value", include_str!("docs/wellknown/Int32Value.md")),
("google.protobuf.Int64Value", include_str!("docs/wellknown/Int64Value.md")),
("google.protobuf.ListValue", include_str!("docs/wellknown/ListValue.md")),
("google.protobuf.Method", include_str!("docs/wellknown/Method.md")),
("google.protobuf.Mixin", include_str!("docs/wellknown/Mixin.md")),
("google.protobuf.NullValue", include_str!("docs/wellknown/NullValue.md")),
("google.protobuf.Option", include_str!("docs/wellknown/Option.md")),
("google.protobuf.SourceContext", include_str!("docs/wellknown/SourceContext.md")),
("google.protobuf.StringValue", include_str!("docs/wellknown/StringValue.md")),
("google.protobuf.Struct", include_str!("docs/wellknown/Struct.md")),
("google.protobuf.Syntax", include_str!("docs/wellknown/Syntax.md")),
("google.protobuf.Timestamp", include_str!("docs/wellknown/Timestamp.md")),
("google.protobuf.Type", include_str!("docs/wellknown/Type.md")),
("google.protobuf.UInt32Value", include_str!("docs/wellknown/UInt32Value.md")),
("google.protobuf.UInt64Value", include_str!("docs/wellknown/UInt64Value.md")),
("google.protobuf.Value", include_str!("docs/wellknown/Value.md")),
])
});

impl ProtoLanguageState {
pub fn hover(
&self,
Expand All @@ -72,7 +17,7 @@ impl ProtoLanguageState {
let v = match hv {
Hoverables::FieldType(field) => {
// Type is a builtin
match BUITIN_DOCS.get(field.as_str()) {
match docs::BUITIN.get(field.as_str()) {
Some(docs) => docs.to_string(),
_ => String::new(),
}
Expand All @@ -97,7 +42,7 @@ Included from {}"#,

// Node is user defined type or well known type
// If user defined,
let mut result = WELLKNOWN_DOCS
let mut result = docs::WELLKNOWN
.get(format!("{package}.{identifier}").as_str())
.map(|&s| s.to_string())
.unwrap_or_default();
Expand Down