feat: export text in range as ansi highlighted code (#526)

* feat: export text in range as ansi highlighted code

* dev: update snapshot
This commit is contained in:
Myriad-Dreamin 2024-08-12 11:25:55 +08:00 committed by GitHub
parent 190b09d4b5
commit 6b8380ade7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 105 additions and 3 deletions

View file

@ -75,6 +75,8 @@ pin-project-lite.workspace = true
base64.workspace = true
rayon.workspace = true
typst-ansi-hl = "0.2.0"
[features]
default = ["cli", "embed-fonts", "no-content-hint", "preview"]

View file

@ -38,6 +38,12 @@ struct QueryOpts {
one: Option<bool>,
}
#[derive(Debug, Clone, Default, Deserialize)]
#[serde(rename_all = "camelCase")]
struct HiglightRangeOpts {
range: Option<Range>,
}
/// Here are implemented the handlers for each command.
impl LanguageState {
/// Export the current document as PDF file(s).
@ -122,6 +128,42 @@ impl LanguageState {
run_query!(req_id, self.OnExport(path, kind))
}
/// Export a range of the current document as Ansi highlighted text.
pub fn export_ansi_hl(&mut self, mut args: Vec<JsonValue>) -> AnySchedulableResponse {
let path = get_arg!(args[0] as PathBuf);
let opts = get_arg_or_default!(args[1] as HiglightRangeOpts);
let s = self
.query_source(path.into(), Ok)
.map_err(|e| internal_error(format!("cannot find source: {e}")))?;
// todo: cannot select syntax-sensitive data well
// let node = LinkedNode::new(s.root());
let range = opts
.range
.map(|r| {
tinymist_query::lsp_to_typst::range(r, self.const_config().position_encoding, &s)
.ok_or_else(|| internal_error("cannoet convert range"))
})
.transpose()?;
let mut text_in_range = s.text();
if let Some(range) = range {
text_in_range = text_in_range
.get(range)
.ok_or_else(|| internal_error("cannot get text in range"))?;
}
let output = typst_ansi_hl::Highlighter::default()
.for_discord()
.with_soft_limit(2000)
.highlight(text_in_range)
.map_err(|e| internal_error(format!("cannot highlight: {e}")))?;
just_ok(JsonValue::String(output))
}
/// Clear all cached resources.
pub fn clear_cache(&mut self, _arguments: Vec<JsonValue>) -> AnySchedulableResponse {
comemo::evict(0);

View file

@ -248,6 +248,7 @@ impl LanguageState {
.with_command_("tinymist.exportHtml", State::export_html)
.with_command_("tinymist.exportMarkdown", State::export_markdown)
.with_command_("tinymist.exportQuery", State::export_query)
.with_command("tinymist.exportAnsiHighlight", State::export_ansi_hl)
.with_command("tinymist.doClearCache", State::clear_cache)
.with_command("tinymist.pinMain", State::pin_document)
.with_command("tinymist.focusMain", State::focus_document)