gleam: Add /gleam-docs (#13721)

This PR adds a `/gleam-docs` slash command to the Gleam extension, which
can be used to fetch docs from HexDocs.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2024-07-01 17:58:21 -04:00 committed by GitHub
parent 0eb26d29ee
commit ecd9422d11
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 71 additions and 4 deletions

17
Cargo.lock generated
View file

@ -388,7 +388,7 @@ dependencies = [
"fuzzy",
"gpui",
"heed",
"html_to_markdown",
"html_to_markdown 0.1.0",
"http 0.1.0",
"indoc",
"language",
@ -5237,6 +5237,18 @@ dependencies = [
"regex",
]
[[package]]
name = "html_to_markdown"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e608e8dd0939bfb6b516d96a5919751b835297a02230aecb88d2fc84ebebaa8a"
dependencies = [
"anyhow",
"html5ever",
"markup5ever_rcdom",
"regex",
]
[[package]]
name = "http"
version = "0.1.0"
@ -9019,7 +9031,7 @@ dependencies = [
"fuzzy",
"gpui",
"heed",
"html_to_markdown",
"html_to_markdown 0.1.0",
"http 0.1.0",
"indexmap 1.9.3",
"indoc",
@ -13779,6 +13791,7 @@ dependencies = [
name = "zed_gleam"
version = "0.1.3"
dependencies = [
"html_to_markdown 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zed_extension_api 0.0.7",
]

View file

@ -13,4 +13,5 @@ path = "src/gleam.rs"
crate-type = ["cdylib"]
[dependencies]
html_to_markdown = "0.1.0"
zed_extension_api = { path = "../../crates/extension_api" }

View file

@ -18,3 +18,8 @@ commit = "8432ffe32ccd360534837256747beb5b1c82fca1"
description = "Returns information about the current Gleam project."
requires_argument = false
tooltip_text = "Insert Gleam project data"
[slash_commands.gleam-docs]
description = "Returns Gleam docs."
requires_argument = true
tooltip_text = "Insert Gleam docs"

View file

@ -1,10 +1,13 @@
use html_to_markdown::{convert_html_to_markdown, TagHandler};
use std::cell::RefCell;
use std::fs;
use std::rc::Rc;
use zed::lsp::CompletionKind;
use zed::{
CodeLabel, CodeLabelSpan, LanguageServerId, SlashCommand, SlashCommandOutput,
SlashCommandOutputSection,
};
use zed_extension_api::{self as zed, Result};
use zed_extension_api::{self as zed, fetch, HttpRequest, Result};
struct GleamExtension {
cached_binary_path: Option<String>,
@ -164,10 +167,55 @@ impl zed::Extension for GleamExtension {
fn run_slash_command(
&self,
command: SlashCommand,
_argument: Option<String>,
argument: Option<String>,
worktree: &zed::Worktree,
) -> Result<SlashCommandOutput, String> {
match command.name.as_str() {
"gleam-docs" => {
let argument = argument.ok_or_else(|| "missing argument".to_string())?;
let mut components = argument.split('/');
let package_name = components
.next()
.ok_or_else(|| "missing package name".to_string())?;
let module_path = components.map(ToString::to_string).collect::<Vec<_>>();
let response = fetch(&HttpRequest {
url: format!(
"https://hexdocs.pm/{package_name}{maybe_path}",
maybe_path = if !module_path.is_empty() {
format!("/{}.html", module_path.join("/"))
} else {
String::new()
}
),
})?;
let mut handlers: Vec<TagHandler> = vec![
Rc::new(RefCell::new(
html_to_markdown::markdown::WebpageChromeRemover,
)),
Rc::new(RefCell::new(html_to_markdown::markdown::ParagraphHandler)),
Rc::new(RefCell::new(html_to_markdown::markdown::HeadingHandler)),
Rc::new(RefCell::new(html_to_markdown::markdown::ListHandler)),
Rc::new(RefCell::new(html_to_markdown::markdown::TableHandler::new())),
Rc::new(RefCell::new(html_to_markdown::markdown::StyledTextHandler)),
];
let markdown = convert_html_to_markdown(response.body.as_bytes(), &mut handlers)
.map_err(|err| format!("failed to convert docs to Markdown {err}"))?;
let mut text = String::new();
text.push_str(&markdown);
Ok(SlashCommandOutput {
sections: vec![SlashCommandOutputSection {
range: (0..text.len()).into(),
label: format!("gleam-docs: {package_name} {}", module_path.join("/")),
}],
text,
})
}
"gleam-project" => {
let mut text = String::new();
text.push_str("You are in a Gleam project.\n");