mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-08-03 09:52:27 +00:00
feat: support font arguments
This commit is contained in:
parent
0be0fe07c2
commit
1c825607b2
12 changed files with 2623 additions and 33 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -3589,7 +3589,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tinymist"
|
||||
version = "0.11.0"
|
||||
version = "0.10.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
|
@ -3627,7 +3627,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tinymist-query"
|
||||
version = "0.11.0"
|
||||
version = "0.10.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"comemo 0.4.0",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[workspace.package]
|
||||
description = "An integrated language service for Typst."
|
||||
authors = ["Myriad-Dreamin <camiyoru@gmail.com>", "Nathan Varner"]
|
||||
version = "0.11.0"
|
||||
version = "0.10.0"
|
||||
edition = "2021"
|
||||
readme = "README.md"
|
||||
license = "Apache-2.0"
|
||||
|
|
|
@ -41,10 +41,9 @@ impl TypstLanguageServer {
|
|||
|
||||
let opts = CompileOpts {
|
||||
root_dir,
|
||||
// todo: font paths
|
||||
// font_paths: arguments.font_paths.clone(),
|
||||
// todo: additional inputs
|
||||
with_embedded_fonts: typst_assets::fonts().map(Cow::Borrowed).collect(),
|
||||
..CompileOpts::default()
|
||||
..self.compile_opts.clone()
|
||||
};
|
||||
create_server(
|
||||
name,
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
#[cfg(feature = "clap")]
|
||||
const ENV_PATH_SEP: char = if cfg!(windows) { ';' } else { ':' };
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[cfg_attr(feature = "clap", derive(clap::Parser))]
|
||||
#[cfg_attr(feature = "clap", clap(name = "tinymist", author, version, about, long_version(LONG_VERSION.as_str())))]
|
||||
|
@ -16,6 +21,18 @@ pub struct CliArguments {
|
|||
/// Replay input from the file
|
||||
#[cfg_attr(feature = "clap", clap(long, default_value = "", value_name = "FILE"))]
|
||||
pub replay: String,
|
||||
/// Font paths, which doesn't allow for dynamic configuration
|
||||
#[cfg_attr(feature = "clap", clap(
|
||||
long = "font-path",
|
||||
value_name = "DIR",
|
||||
action = clap::ArgAction::Append,
|
||||
env = "TYPST_FONT_PATHS",
|
||||
value_delimiter = ENV_PATH_SEP
|
||||
))]
|
||||
pub font_paths: Vec<PathBuf>,
|
||||
/// Exclude system fonts
|
||||
#[cfg_attr(feature = "clap", clap(long, default_value = "false"))]
|
||||
pub no_system_fonts: bool,
|
||||
}
|
||||
|
||||
pub static LONG_VERSION: Lazy<String> = Lazy::new(|| {
|
||||
|
|
|
@ -9,9 +9,10 @@ use serde::Deserialize;
|
|||
use serde_json::{Map, Value as JsonValue};
|
||||
use tinymist_query::{get_semantic_tokens_options, PositionEncoding};
|
||||
use tokio::sync::mpsc;
|
||||
use typst_ts_core::config::CompileOpts;
|
||||
|
||||
use crate::actor::cluster::CompileClusterActor;
|
||||
use crate::{invalid_params, LspHost, LspResult, TypstLanguageServer};
|
||||
use crate::{invalid_params, LspHost, LspResult, TypstLanguageServer, TypstLanguageServerArgs};
|
||||
|
||||
trait InitializeParamsExt {
|
||||
fn position_encodings(&self) -> &[PositionEncodingKind];
|
||||
|
@ -335,6 +336,7 @@ impl From<&InitializeParams> for ConstConfig {
|
|||
|
||||
pub struct Init {
|
||||
pub host: LspHost,
|
||||
pub compile_opts: CompileOpts,
|
||||
}
|
||||
|
||||
impl Init {
|
||||
|
@ -371,8 +373,13 @@ impl Init {
|
|||
// Bootstrap server
|
||||
let (diag_tx, diag_rx) = mpsc::unbounded_channel();
|
||||
|
||||
let mut service =
|
||||
TypstLanguageServer::new(self.host.clone(), params.root_paths(), cc, diag_tx);
|
||||
let mut service = TypstLanguageServer::new(TypstLanguageServerArgs {
|
||||
client: self.host.clone(),
|
||||
compile_opts: self.compile_opts,
|
||||
roots: params.root_paths(),
|
||||
const_config: cc,
|
||||
diag_tx,
|
||||
});
|
||||
|
||||
if let Some(init) = ¶ms.initialization_options {
|
||||
if let Err(err) = config
|
||||
|
|
|
@ -59,6 +59,7 @@ use tinymist_query::{
|
|||
};
|
||||
use tokio::sync::mpsc;
|
||||
use typst::util::Deferred;
|
||||
use typst_ts_core::config::CompileOpts;
|
||||
|
||||
pub type MaySyncResult<'a> = Result<JsonValue, BoxFuture<'a, JsonValue>>;
|
||||
|
||||
|
@ -256,6 +257,14 @@ fn as_path_pos(inp: TextDocumentPositionParams) -> (PathBuf, Position) {
|
|||
(as_path(inp.text_document), inp.position)
|
||||
}
|
||||
|
||||
pub struct TypstLanguageServerArgs {
|
||||
pub client: LspHost,
|
||||
pub compile_opts: CompileOpts,
|
||||
pub roots: Vec<PathBuf>,
|
||||
pub const_config: ConstConfig,
|
||||
pub diag_tx: mpsc::UnboundedSender<(String, Option<DiagnosticsMap>)>,
|
||||
}
|
||||
|
||||
/// The object providing the language server functionality.
|
||||
pub struct TypstLanguageServer {
|
||||
/// The language server client.
|
||||
|
@ -273,6 +282,8 @@ pub struct TypstLanguageServer {
|
|||
/// Const configuration initialized at the start of the session.
|
||||
/// For example, the position encoding.
|
||||
pub const_config: ConstConfig,
|
||||
/// The default opts for the compiler.
|
||||
pub compile_opts: CompileOpts,
|
||||
|
||||
diag_tx: mpsc::UnboundedSender<(String, Option<DiagnosticsMap>)>,
|
||||
roots: Vec<PathBuf>,
|
||||
|
@ -285,23 +296,19 @@ pub struct TypstLanguageServer {
|
|||
/// Getters and the main loop.
|
||||
impl TypstLanguageServer {
|
||||
/// Create a new language server.
|
||||
pub fn new(
|
||||
client: LspHost,
|
||||
roots: Vec<PathBuf>,
|
||||
const_config: ConstConfig,
|
||||
diag_tx: mpsc::UnboundedSender<(String, Option<DiagnosticsMap>)>,
|
||||
) -> Self {
|
||||
pub fn new(args: TypstLanguageServerArgs) -> Self {
|
||||
Self {
|
||||
client: client.clone(),
|
||||
client: args.client.clone(),
|
||||
shutdown_requested: false,
|
||||
config: Default::default(),
|
||||
const_config,
|
||||
const_config: args.const_config,
|
||||
compile_opts: args.compile_opts,
|
||||
exec_cmds: Self::get_exec_commands(),
|
||||
regular_cmds: Self::get_regular_cmds(),
|
||||
notify_cmds: Self::get_notify_cmds(),
|
||||
|
||||
diag_tx,
|
||||
roots,
|
||||
diag_tx: args.diag_tx,
|
||||
roots: args.roots,
|
||||
memory_changes: RwLock::new(HashMap::new()),
|
||||
primary: OnceCell::new(),
|
||||
main: Arc::new(Mutex::new(None)),
|
||||
|
|
|
@ -9,6 +9,7 @@ use log::{info, trace, warn};
|
|||
use lsp_types::{InitializeParams, InitializedParams};
|
||||
use serde::de::DeserializeOwned;
|
||||
use tinymist::{init::Init, transport::io_transport, LspHost};
|
||||
use typst_ts_core::config::CompileOpts;
|
||||
|
||||
use crate::args::CliArguments;
|
||||
|
||||
|
@ -111,8 +112,15 @@ async fn main() -> anyhow::Result<()> {
|
|||
|
||||
let initialize_params = from_json::<InitializeParams>("InitializeParams", &initialize_params)?;
|
||||
|
||||
let (mut service, initialize_result) =
|
||||
Init { host: host.clone() }.initialize(initialize_params.clone());
|
||||
let (mut service, initialize_result) = Init {
|
||||
host: host.clone(),
|
||||
compile_opts: CompileOpts {
|
||||
font_paths: args.font_paths,
|
||||
no_system_fonts: args.no_system_fonts,
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
.initialize(initialize_params.clone());
|
||||
|
||||
host.respond(match initialize_result {
|
||||
Ok(cap) => Response::new_ok(initialize_id, Some(cap)),
|
||||
|
@ -159,16 +167,6 @@ async fn main() -> anyhow::Result<()> {
|
|||
|
||||
service.initialized(InitializedParams {});
|
||||
|
||||
// // Set up LSP server
|
||||
// let (inner, socket) = LspService::new();
|
||||
// let service = LogService {
|
||||
// inner,
|
||||
// show_time: true,
|
||||
// };
|
||||
|
||||
// // Handle requests
|
||||
// Server::new(stdin, stdout, socket).serve(service).await;
|
||||
|
||||
service.main_loop(connection.receiver)?;
|
||||
|
||||
io_threads.join()?;
|
||||
|
|
1
editors/vscode/.gitignore
vendored
1
editors/vscode/.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
tinymist-*.vsix
|
||||
*.log
|
|
@ -13,7 +13,7 @@
|
|||
],
|
||||
"publisher": "myriad-dreamin",
|
||||
"license": "Apache-2.0",
|
||||
"version": "0.11.0",
|
||||
"version": "0.10.0",
|
||||
"engines": {
|
||||
"vscode": "^1.71.0"
|
||||
},
|
||||
|
@ -72,6 +72,24 @@
|
|||
"Do not use semantic tokens for syntax highlighting"
|
||||
]
|
||||
},
|
||||
"tinymist.noSystemFonts": {
|
||||
"title": "whether to load system fonts for Typst compiler",
|
||||
"description": "A flag that determines whether to load system fonts for Typst compiler, which is useful for ensuring reproducible compilation. If set to null or not set, the extension will use the default behavior of the Typst compiler.",
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"tinymist.fontPaths": {
|
||||
"title": "Font paths for Typst compiler",
|
||||
"description": "Font paths, which doesn't allow for dynamic configuration",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"tinymist.serverPath": {
|
||||
"title": "Path to server executable",
|
||||
"description": "The extension can use a local tinymist executable instead of the one bundled with the extension. This setting controls the path to the executable.",
|
||||
|
@ -338,7 +356,8 @@
|
|||
"test": ""
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-languageclient": "^9.0.1"
|
||||
"vscode-languageclient": "^9.0.1",
|
||||
"vscode-variables": "^0.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.8.10",
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
TextEditor,
|
||||
ExtensionMode,
|
||||
} from "vscode";
|
||||
import * as vscode from "vscode";
|
||||
import * as path from "path";
|
||||
import * as child_process from "child_process";
|
||||
|
||||
|
@ -17,6 +18,7 @@ import {
|
|||
type LanguageClientOptions,
|
||||
type ServerOptions,
|
||||
} from "vscode-languageclient/node";
|
||||
import vscodeVariables from "vscode-variables";
|
||||
|
||||
let client: LanguageClient | undefined = undefined;
|
||||
|
||||
|
@ -30,6 +32,9 @@ export function activate(context: ExtensionContext): Promise<void> {
|
|||
async function startClient(context: ExtensionContext): Promise<void> {
|
||||
const config = workspace.getConfiguration("tinymist");
|
||||
const serverCommand = getServer(config);
|
||||
const fontPaths = vscode.workspace.getConfiguration().get<string[]>("tinymist.fontPaths");
|
||||
const noSystemFonts =
|
||||
vscode.workspace.getConfiguration().get<boolean | null>("tinymist.noSystemFonts") === true;
|
||||
const run = {
|
||||
command: serverCommand,
|
||||
args: [
|
||||
|
@ -38,6 +43,8 @@ async function startClient(context: ExtensionContext): Promise<void> {
|
|||
...(context.extensionMode != ExtensionMode.Production
|
||||
? ["--mirror", "tinymist-lsp.log"]
|
||||
: []),
|
||||
...(fontPaths ?? []).flatMap((fontPath) => ["--font-path", vscodeVariables(fontPath)]),
|
||||
...(noSystemFonts ? ["--no-system-fonts"] : []),
|
||||
],
|
||||
options: { env: Object.assign({}, process.env, { RUST_BACKTRACE: "1" }) },
|
||||
};
|
||||
|
@ -166,6 +173,7 @@ async function commandShowPdf(): Promise<void> {
|
|||
return;
|
||||
}
|
||||
|
||||
// todo: this is wrong
|
||||
const uri = activeEditor.document.uri;
|
||||
// change the file extension to `.pdf` as we want to open the pdf file
|
||||
// and not the currently opened `.typ` file.
|
||||
|
|
3
editors/vscode/src/vscode-variables.d.ts
vendored
Normal file
3
editors/vscode/src/vscode-variables.d.ts
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
declare module "vscode-variables" {
|
||||
export default function vscodeVariables<T>(arg: T): T;
|
||||
}
|
2531
editors/vscode/yarn.lock
Normal file
2531
editors/vscode/yarn.lock
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue