Skip to content

Commit 567348c

Browse files
authored
Merge pull request #7 from wflixu/dev
[feat] add compile error tip
2 parents 08cdbef + e7fe0af commit 567348c

33 files changed

+208
-152
lines changed

.github/workflows/build-pkg.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ name: "build pkg"
22

33
on:
44
push:
5-
tags:
6-
- "v*"
5+
-branches:
6+
- release
77

88
jobs:
99
publish-tauri:

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
![typster](./public/imgs/app-icon.png)
1+
![typster](./app-icon.png)
22

33
# [WIP] typster
44

app-icon.png

-138 Bytes
Loading

src-tauri/icons/128x128.png

-221 Bytes
Loading

src-tauri/icons/128x128@2x.png

-91 Bytes
Loading

src-tauri/icons/32x32.png

-68 Bytes
Loading

src-tauri/icons/Square107x107Logo.png

-114 Bytes
Loading

src-tauri/icons/Square142x142Logo.png

-142 Bytes
Loading

src-tauri/icons/Square150x150Logo.png

-190 Bytes
Loading

src-tauri/icons/Square284x284Logo.png

-393 Bytes
Loading

src-tauri/icons/Square30x30Logo.png

-54 Bytes
Loading

src-tauri/icons/Square310x310Logo.png

-326 Bytes
Loading

src-tauri/icons/Square44x44Logo.png

-38 Bytes
Loading

src-tauri/icons/Square71x71Logo.png

-67 Bytes
Loading

src-tauri/icons/Square89x89Logo.png

-132 Bytes
Loading

src-tauri/icons/StoreLogo.png

-45 Bytes
Loading

src-tauri/icons/icon.icns

-6.54 KB
Binary file not shown.

src-tauri/icons/icon.ico

-756 Bytes
Binary file not shown.

src-tauri/icons/icon.png

-1.19 KB
Loading

src-tauri/src/ipc/commands/typst.rs

+44-133
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::{Error, Result};
22
use crate::ipc::commands::project;
33
use crate::ipc::model::TypstRenderResponse;
44
use crate::ipc::{
5-
TypstCompileEvent, TypstDiagnosticSeverity, TypstDocument, TypstPage, TypstSourceDiagnostic
5+
TypstCompileEvent, TypstDiagnosticSeverity, TypstDocument, TypstPage, TypstSourceDiagnostic,
66
};
77
use crate::project::ProjectManager;
88
use base64::Engine;
@@ -11,6 +11,7 @@ use serde::Serialize;
1111
use serde_repr::Serialize_repr;
1212
use siphasher::sip128::{Hasher128, SipHasher};
1313
use std::hash::Hash;
14+
use std::ops::Range;
1415
use std::path::PathBuf;
1516
use std::sync::Arc;
1617
use std::time::Instant;
@@ -72,7 +73,7 @@ pub async fn typst_slot_update<R: Runtime>(
7273
content: String,
7374
) -> Result<()> {
7475
let project = project(&window, &project_manager)?;
75-
76+
7677
let mut world = project.world.lock().unwrap();
7778
let _ = world
7879
.slot_update(&path, Some(content))
@@ -86,7 +87,7 @@ pub async fn typst_compile_doc<R: Runtime>(
8687
project_manager: tauri::State<'_, Arc<ProjectManager<R>>>,
8788
path: PathBuf,
8889
content: String,
89-
) -> Result<Vec<TypstPage>> {
90+
) -> Result<(Vec<TypstPage>, Vec<TypstSourceDiagnostic>)> {
9091
let project = project(&window, &project_manager)?;
9192

9293
let mut world = project.world.lock().unwrap();
@@ -105,7 +106,8 @@ pub async fn typst_compile_doc<R: Runtime>(
105106
debug!("compiling {:?}: {:?}", path, project);
106107
let now = Instant::now();
107108
let mut tracer = Tracer::new();
108-
let mut res: Vec<TypstPage> = Vec::new();
109+
let mut pages: Vec<TypstPage> = Vec::new();
110+
let mut diags: Vec<TypstSourceDiagnostic> = Vec::new();
109111
match typst::compile(&*world, &mut tracer) {
110112
Ok(doc) => {
111113
let elapsed = now.elapsed();
@@ -114,31 +116,27 @@ pub async fn typst_compile_doc<R: Runtime>(
114116
project,
115117
elapsed.as_millis()
116118
);
117-
let mut idx:u32 = 0;
119+
let mut idx: u32 = 0;
118120
for page in &doc.pages {
119121
let mut hasher = SipHasher::new();
120122
page.frame.hash(&mut hasher);
121123
let hash = hex::encode(hasher.finish128().as_bytes());
122-
let width = page.frame.width().to_pt();
124+
let width = page.frame.width().to_pt();
123125
let height = page.frame.height().to_pt();
124-
idx +=1;
125-
let pag = TypstPage {
126+
idx += 1;
127+
let pag = TypstPage {
126128
num: idx,
127129
width,
128130
height,
129-
hash: hash.clone()
131+
hash: hash.clone(),
130132
};
131-
res.push(pag);
133+
pages.push(pag);
132134
}
133135

134136
project.cache.write().unwrap().document = Some(doc);
135-
136137
}
137138
Err(diagnostics) => {
138-
debug!(
139-
"compilation failed with {:?} diagnostics",
140-
&diagnostics
141-
);
139+
debug!("compilation failed with {:?} diagnostics", &diagnostics);
142140

143141
let source = world.source(source_id);
144142
let diagnostics: Vec<TypstSourceDiagnostic> = match source {
@@ -148,13 +146,11 @@ pub async fn typst_compile_doc<R: Runtime>(
148146
.filter_map(|d| {
149147
let span = source.find(d.span)?;
150148
let range = span.range();
151-
let start = content[..range.start].chars().count();
152-
let size = content[range.start..range.end].chars().count();
153149

154150
let message = d.message.to_string();
155-
info!("############## {}", &message);
156151
Some(TypstSourceDiagnostic {
157-
range: start..start + size,
152+
pos: get_range_position(&content, range.clone()),
153+
range,
158154
severity: match d.severity {
159155
Severity::Error => TypstDiagnosticSeverity::Error,
160156
Severity::Warning => TypstDiagnosticSeverity::Warning,
@@ -167,123 +163,32 @@ pub async fn typst_compile_doc<R: Runtime>(
167163
Err(_) => vec![],
168164
};
169165

170-
info!("############## {:?}", &diagnostics);
171-
166+
diags = diagnostics.clone();
172167

173-
174-
168+
info!("############## {:?}", &diags);
175169
}
176170
}
177171

178-
Ok(res)
172+
Ok((pages, diags))
179173
}
180174

181-
#[tauri::command]
182-
pub async fn typst_compile<R: Runtime>(
183-
window: tauri::Window<R>,
184-
project_manager: tauri::State<'_, Arc<ProjectManager<R>>>,
185-
path: PathBuf,
186-
content: String,
187-
) -> Result<()> {
188-
let project = project(&window, &project_manager)?;
189-
190-
let mut world = project.world.lock().unwrap();
191-
let source_id = world
192-
.slot_update(&path, Some(content.clone()))
193-
.map_err(Into::<Error>::into)?;
194-
195-
if !world.is_main_set() {
196-
let config = project.config.read().unwrap();
197-
if config.apply_main(&project, &mut world).is_err() {
198-
debug!("skipped compilation for {:?} (main not set)", project);
199-
return Ok(());
200-
}
201-
}
202-
203-
debug!("compiling {:?}: {:?}", path, project);
204-
let now = Instant::now();
205-
let mut tracer = Tracer::new();
206-
match typst::compile(&*world, &mut tracer) {
207-
Ok(doc) => {
208-
let elapsed = now.elapsed();
209-
debug!(
210-
"compilation succeeded for {:?} in {:?} ms",
211-
project,
212-
elapsed.as_millis()
213-
);
214-
215-
let pages = doc.pages.len();
216-
217-
let mut hasher = SipHasher::new();
218-
for page in &doc.pages {
219-
page.frame.hash(&mut hasher);
220-
}
221-
let hash = hex::encode(hasher.finish128().as_bytes());
222-
223-
// Assume all pages have the same size
224-
// TODO: Improve this?
225-
let first_page = &doc.pages[0];
226-
let width = first_page.frame.width();
227-
let height = first_page.frame.height();
228-
229-
project.cache.write().unwrap().document = Some(doc);
230-
231-
let _ = window.emit(
232-
"typst_compile",
233-
TypstCompileEvent {
234-
document: Some(TypstDocument {
235-
pages,
236-
hash,
237-
width: width.to_pt(),
238-
height: height.to_pt(),
239-
}),
240-
diagnostics: None,
241-
},
242-
);
175+
pub fn get_range_position(text: &str, rang: Range<usize>) -> (usize, usize) {
176+
let mut ln = 0;
177+
let mut cn = 0;
178+
let mut total: usize = 0;
179+
for line in text.lines() {
180+
181+
ln += 1;
182+
let row = line.chars().count() + 1;
183+
184+
if total <= rang.start && rang.start <= total + row {
185+
cn = rang.start - total;
186+
break;
243187
}
244-
Err(diagnostics) => {
245-
debug!(
246-
"compilation failed with {:?} diagnostics",
247-
diagnostics.len()
248-
);
249-
250-
let source = world.source(source_id);
251-
let diagnostics: Vec<TypstSourceDiagnostic> = match source {
252-
Ok(source) => diagnostics
253-
.iter()
254-
.filter(|d| d.span.id() == Some(source_id))
255-
.filter_map(|d| {
256-
let span = source.find(d.span)?;
257-
let range = span.range();
258-
let start = content[..range.start].chars().count();
259-
let size = content[range.start..range.end].chars().count();
260-
261-
let message = d.message.to_string();
262-
Some(TypstSourceDiagnostic {
263-
range: start..start + size,
264-
severity: match d.severity {
265-
Severity::Error => TypstDiagnosticSeverity::Error,
266-
Severity::Warning => TypstDiagnosticSeverity::Warning,
267-
},
268-
message,
269-
hints: d.hints.iter().map(|hint| hint.to_string()).collect(),
270-
})
271-
})
272-
.collect(),
273-
Err(_) => vec![],
274-
};
275188

276-
let _ = window.emit(
277-
"typst_compile",
278-
TypstCompileEvent {
279-
document: None,
280-
diagnostics: Some(diagnostics),
281-
},
282-
);
283-
}
189+
total += row;
284190
}
285-
286-
Ok(())
191+
return (ln, cn);
287192
}
288193

289194
#[tauri::command]
@@ -294,17 +199,23 @@ pub async fn typst_render<R: Runtime>(
294199
scale: f32,
295200
nonce: u32,
296201
) -> Result<TypstRenderResponse> {
297-
298-
info!("typst_render page:{} scale: {} nonce: {}", page, scale, nonce);
202+
info!(
203+
"typst_render page:{} scale: {} nonce: {}",
204+
page, scale, nonce
205+
);
299206
let project = project_manager
300207
.get_project(&window)
301208
.ok_or(Error::UnknownProject)?;
302-
209+
303210
let cache = project.cache.read().unwrap();
304-
305-
if let Some(p) = cache.document.as_ref().and_then(|doc| doc.pages.get(page-1)) {
211+
212+
if let Some(p) = cache
213+
.document
214+
.as_ref()
215+
.and_then(|doc| doc.pages.get(page - 1))
216+
{
306217
let now = Instant::now();
307-
218+
308219
let bmp = typst_render::render(&p.frame, scale, Color::WHITE);
309220
if let Ok(image) = bmp.encode_png() {
310221
let elapsed = now.elapsed();

src-tauri/src/ipc/model.rs

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ pub struct TypstSourceDiagnostic {
3939
pub severity: TypstDiagnosticSeverity,
4040
pub message: String,
4141
pub hints: Vec<String>,
42+
pub pos:(usize, usize)
4243
}
4344

4445
#[derive(Serialize, Clone, Debug)]

src-tauri/src/main.rs

-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ async fn main() {
4242
ipc::commands::fs_write_file_binary,
4343
ipc::commands::fs_write_file_text,
4444
ipc::commands::load_project_from_path,
45-
ipc::commands::typst_compile,
4645
ipc::commands::typst_compile_doc,
4746
ipc::commands::typst_render,
4847
ipc::commands::typst_autocomplete,

src-tauri/tauri.conf.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,14 @@
8686
"fullscreen": false,
8787
"resizable": true,
8888
"title": "typster",
89+
"center": true,
8990
"hiddenTitle": true,
90-
"titleBarStyle": "Overlay",
91+
"titleBarStyle": "Transparent",
9192
"theme": "Light",
9293
"width": 1200,
93-
"height": 900
94+
"height": 900,
95+
"minWidth": 800,
96+
"minHeight": 400
9497
}
9598
]
9699
}

src-tauri/tauri.macos.conf.json

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"tauri": {
3+
"windows": [
4+
{
5+
"fullscreen": false,
6+
"resizable": true,
7+
"title": "",
8+
"center": true,
9+
"hiddenTitle": false,
10+
"titleBarStyle": "Overlay",
11+
"theme": "Light",
12+
"width": 1200,
13+
"height": 900,
14+
"minWidth": 800,
15+
"minHeight": 400
16+
}
17+
]
18+
}
19+
}

src/components/MonacoEditor.vue

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<script setup lang="ts">
66
import * as monaco from "monaco-editor/esm/vs/editor/editor.api";
77
import { PropType, onMounted, ref, watch } from "vue";
8-
import { TypstPage } from "../pages/typst/interface";
8+
import { TypstCompileResult, TypstPage } from "../pages/typst/interface";
99
import type { editor as editorType } from "monaco-editor";
1010
import { invoke } from "@tauri-apps/api";
1111
import { throttle, debounce, relativePath } from './../shared/util'
@@ -23,7 +23,7 @@ const props = defineProps({
2323
2424
const emit = defineEmits<{
2525
(e: 'change', text: string): void
26-
(e: 'compiled', data: TypstPage[]): void
26+
(e: 'compiled', data: TypstCompileResult): void
2727
}>()
2828
2929
@@ -74,7 +74,7 @@ const handleCompile = async () => {
7474
const content = editorModel.getValue()
7575
const path = relativePath(props.root!, props.path!)
7676
77-
const pages = await invoke<TypstPage[]>('typst_compile_doc', { path, content })
77+
const pages = await invoke<TypstCompileResult>('typst_compile_doc', { path, content })
7878
7979
emit('compiled', pages)
8080
}

src/main.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { createApp } from "vue";
2-
import "./style/styles.css";
32
import "github-markdown-css";
43
import "ant-design-vue/dist/reset.css";
4+
import "./style/styles.css";
55
import "./shared/monaco-hook";
66

77
import Antd from "ant-design-vue";

0 commit comments

Comments
 (0)