|
1 | 1 | use std::fs; |
2 | | -use std::path::PathBuf; |
| 2 | +use std::path::{Path, PathBuf}; |
3 | 3 | use std::process::{Child, Command, Stdio}; |
4 | 4 | use std::sync::Mutex; |
5 | 5 | use std::time::Duration; |
@@ -347,6 +347,68 @@ fn bundled_font_dir(app: &AppHandle) -> Option<PathBuf> { |
347 | 347 | None |
348 | 348 | } |
349 | 349 |
|
| 350 | +// 同梱した tinymist sidecar バイナリの絶対パスを返す。 |
| 351 | +// |
| 352 | +// 解決順: |
| 353 | +// 1. リリース: main 実行ファイルと同じディレクトリの `tinymist`(Windows は `.exe`)。 |
| 354 | +// `tauri.conf.json` の `bundle.externalBin` で Tauri が target triple サフィクスを |
| 355 | +// 剥がして配置する位置。.deb なら `/usr/lib/yuhitsu/`、.msi なら exe の隣。 |
| 356 | +// 2. dev: `<CARGO_MANIFEST_DIR>/binaries/tinymist-<host-triple>` を直接参照 |
| 357 | +// (`scripts/fetch-tinymist.sh` が DL する)。`pnpm tauri dev` 中はこちらが使われる。 |
| 358 | +// 3. 上記いずれも見つからない場合は PATH ルックアップにフォールバック。 |
| 359 | +// バンドル前の旧来動作 / 開発者が手元で `cargo install tinymist` 済の救済用。 |
| 360 | +fn tinymist_path() -> PathBuf { |
| 361 | + let bin_name = if cfg!(windows) { "tinymist.exe" } else { "tinymist" }; |
| 362 | + |
| 363 | + // 1. リリース配置 |
| 364 | + if let Ok(exe) = std::env::current_exe() { |
| 365 | + if let Some(dir) = exe.parent() { |
| 366 | + let p = dir.join(bin_name); |
| 367 | + if p.exists() { |
| 368 | + return p; |
| 369 | + } |
| 370 | + } |
| 371 | + } |
| 372 | + |
| 373 | + // 2. dev 配置 |
| 374 | + let triple = host_target_triple(); |
| 375 | + let dev_name = if cfg!(windows) { |
| 376 | + format!("tinymist-{}.exe", triple) |
| 377 | + } else { |
| 378 | + format!("tinymist-{}", triple) |
| 379 | + }; |
| 380 | + let dev_path = Path::new(env!("CARGO_MANIFEST_DIR")) |
| 381 | + .join("binaries") |
| 382 | + .join(&dev_name); |
| 383 | + if dev_path.exists() { |
| 384 | + return dev_path; |
| 385 | + } |
| 386 | + |
| 387 | + // 3. PATH フォールバック |
| 388 | + PathBuf::from("tinymist") |
| 389 | +} |
| 390 | + |
| 391 | +// Tauri の externalBin が target triple サフィクスで管理しているため、 |
| 392 | +// dev 時のサイドカー解決にホストのトリプルが必要。cfg! の組み合わせで |
| 393 | +// 静的に決定する(クロスコンパイル時もビルド対象側のトリプルになる)。 |
| 394 | +fn host_target_triple() -> &'static str { |
| 395 | + if cfg!(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu")) { |
| 396 | + "x86_64-unknown-linux-gnu" |
| 397 | + } else if cfg!(all(target_arch = "aarch64", target_os = "linux", target_env = "gnu")) { |
| 398 | + "aarch64-unknown-linux-gnu" |
| 399 | + } else if cfg!(all(target_arch = "x86_64", target_os = "windows", target_env = "msvc")) { |
| 400 | + "x86_64-pc-windows-msvc" |
| 401 | + } else if cfg!(all(target_arch = "aarch64", target_os = "windows", target_env = "msvc")) { |
| 402 | + "aarch64-pc-windows-msvc" |
| 403 | + } else if cfg!(all(target_arch = "aarch64", target_os = "macos")) { |
| 404 | + "aarch64-apple-darwin" |
| 405 | + } else if cfg!(all(target_arch = "x86_64", target_os = "macos")) { |
| 406 | + "x86_64-apple-darwin" |
| 407 | + } else { |
| 408 | + "unknown-target" |
| 409 | + } |
| 410 | +} |
| 411 | + |
350 | 412 | // Typst の `--root` に渡すプロジェクトルート。 |
351 | 413 | // Linux/macOS は `/`、Windows は入力パスのドライブ。tinymist は cwd を |
352 | 414 | // 起点に root を相対化することがあり、cwd と root が食い違うと "entry |
@@ -532,7 +594,7 @@ async fn start_preview( |
532 | 594 | // ルートを root として渡す(セキュリティモデルは緩むが、ユーザ自身のファイルを |
533 | 595 | // 自分のエディタで読むだけなので許容)。Windows は入力パスのドライブを起点に。 |
534 | 596 | let root = filesystem_root_for(&path); |
535 | | - let mut cmd = Command::new("tinymist"); |
| 597 | + let mut cmd = Command::new(tinymist_path()); |
536 | 598 | cmd.current_dir(&root) |
537 | 599 | .args([ |
538 | 600 | "preview", |
@@ -630,7 +692,7 @@ fn export_pdf(app: AppHandle, input: String, output: String) -> Result<(), Strin |
630 | 692 | // preview と同じく filesystem ルートを `--root` に渡す。文書外の絶対パスを |
631 | 693 | // 読みたい(例: ホーム配下のスクショ画像)用途に合わせる。 |
632 | 694 | let root = filesystem_root_for(&input); |
633 | | - let mut cmd = Command::new("tinymist"); |
| 695 | + let mut cmd = Command::new(tinymist_path()); |
634 | 696 | cmd.current_dir(&root) |
635 | 697 | .args(["compile", "--root", &root]); |
636 | 698 | if let Some(fonts) = bundled_font_dir(&app) { |
@@ -680,7 +742,7 @@ impl LspState { |
680 | 742 | async fn lsp_start(app: AppHandle, state: State<'_, LspState>) -> Result<(), String> { |
681 | 743 | state.kill_existing().await; |
682 | 744 |
|
683 | | - let mut cmd = TokioCommand::new("tinymist"); |
| 745 | + let mut cmd = TokioCommand::new(tinymist_path()); |
684 | 746 | cmd.arg("lsp"); |
685 | 747 | if let Some(fonts) = bundled_font_dir(&app) { |
686 | 748 | cmd.args(["--font-path", &fonts.to_string_lossy()]); |
|
0 commit comments