Skip to content

Commit bcf918d

Browse files
QuentinLeeWeberLeonMatthesKDABQuentin Weber
authored
Span inspector (#1296)
* WIP: Add Span-Inspector * added expansion of input-code * added span highlighting * Add highlighting at cursor position This highlights all output tokens that share the same span as the text cursor is hovering over. * Improved errorhandling: show expansion errors in textfield Expansion erros are now shown directly in the output textfield. * Fix target-span determination and incorrect highlighting - Fix incorrect calculation of target span - Fix false highlighting caused by Pretty Please code manipulation * Sanitize expanded code in build_html - Prevents issues with special characters like '<' and '>' breaking the output HTML * refactor: replaced get_span_data() with map * add loading indicator to span inspector * Add "{" and "}" to parsing filter These tokens are now ignored during parsing because prettyplease inserts them automatically in certain situations. * span-inspector: make output scrollable, improve theme support, fix refresh bug - Make output text area scrollable - Adjust text color to match the theme - Fix edge case where text change did not trigger refresh if cursor position stayed the same * span_inspector: add indication for synthesized tokens * chore: add license headers and fix rustfmt formatting * fix: update Cargo.lock to fix test failure with --locked - Before tests were failing due to an outdated Cargo.lock * fix: update Cargo.lock to fix test failure with --locked - Tests were failing due to an outdated Cargo.lock * fix: cargo test for span-inspector * chore(clippy): apply Clippy suggestions to improve code quality * fix: update Cargo.lock * fix: update Cargo.lock * chore(span-inspector): optimize crate features of cxx-qt-lib * chore: reorder line in Cargo.toml for clarity * chore(span_inspector): changed uri of qml_module * chore(span-inspector): removed unnecessary threadspawn * chore(span-inspector): removed unnecessary mutex for cursor_position * refactor(span-inspector): moved pretty-please filter into a universal function * refactor(span-inspector): replaced vec<(bool, bool)> with TokenFlag struct * feat(span-inspector): ensure only the last spawned thread can write to output * fix(span-inspector) THREAD_COUNT - thread_count is no longer a static atomic type, so multiple span-inspectors can be used without interferrring their selfs * refactor(span-inspector): thread_count is now a simple u32 * chore(span-inspector): removed unnecessary use * Update build.rs after merge --------- Co-authored-by: Leon Matthes <[email protected]> Co-authored-by: Quentin Weber <[email protected]>
1 parent f88253b commit bcf918d

File tree

7 files changed

+459
-0
lines changed

7 files changed

+459
-0
lines changed

Cargo.lock

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ members = [
2121
"examples/qml_multi_crates/rust/main",
2222
"examples/qml_multi_crates/rust/sub1",
2323
"examples/qml_multi_crates/rust/sub2",
24+
"examples/span-inspector",
2425

2526
"tests/basic_cxx_only/rust",
2627
"tests/basic_cxx_qt/rust",

examples/span-inspector/Cargo.toml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# SPDX-FileCopyrightText: 2022 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
2+
# SPDX-FileContributor: Leon Matthes <[email protected]>
3+
# SPDX-FileContributor: Quentin Weber <[email protected]>
4+
#
5+
# SPDX-License-Identifier: MIT OR Apache-2.0
6+
7+
[package]
8+
name = "span-inspector"
9+
edition.workspace = true
10+
license.workspace = true
11+
repository.workspace = true
12+
version.workspace = true
13+
rust-version.workspace = true
14+
15+
[dependencies]
16+
cxx.workspace = true
17+
cxx-qt.workspace = true
18+
cxx-qt-lib = { workspace = true, features = ["qt_full"] }
19+
cxx-qt-macro = { workspace = true }
20+
cxx-qt-gen = { workspace = true }
21+
proc-macro2.workspace = true
22+
prettyplease = { version = "0.2", features = ["verbatim"] }
23+
syn.workspace = true
24+
25+
[build-dependencies]
26+
cxx-qt-build = { workspace = true, features = ["link_qt_object_files"] }
27+
28+
[lints]
29+
workspace = true

examples/span-inspector/build.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// SPDX-FileCopyrightText: 2025 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
2+
// SPDX-FileContributor: Leon Matthes <[email protected]>
3+
//
4+
// SPDX-License-Identifier: MIT OR Apache-2.0
5+
6+
use cxx_qt_build::{CxxQtBuilder, QmlModule};
7+
8+
fn main() {
9+
let qml_module = QmlModule::new("com.kdab.cxx_qt.span_inspector").qml_file("qml/main.qml");
10+
CxxQtBuilder::new_qml_module(qml_module)
11+
// Link Qt's Network library
12+
// - Qt Core is always linked
13+
// - Qt Gui is linked by enabling the qt_gui Cargo feature of cxx-qt-lib.
14+
// - Qt Qml is linked by enabling the qt_qml Cargo feature of cxx-qt-lib.
15+
// - Qt Qml requires linking Qt Network on macOS
16+
.qt_module("Network")
17+
.qt_module("Quick")
18+
.file("src/inspector.rs")
19+
.build();
20+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// SPDX-FileCopyrightText: 2025 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
2+
// SPDX-FileContributor: Leon Matthes <[email protected]>
3+
//
4+
// SPDX-License-Identifier: MIT OR Apache-2.0
5+
6+
import QtQuick
7+
import QtQuick.Controls
8+
import QtQuick.Window
9+
import QtQuick.Layouts
10+
11+
import com.kdab.cxx_qt.span_inspector 1.0
12+
13+
ApplicationWindow {
14+
id: appWindow
15+
color: palette.window
16+
property color textColor: color.lightness < 128 * "black", "white"
17+
height: 480
18+
title: qsTr("Span Inspector")
19+
visible: true
20+
width: 640
21+
22+
SpanInspector {
23+
id: inspector
24+
}
25+
26+
SplitView {
27+
anchors.fill: parent
28+
Item {
29+
SplitView.preferredWidth: parent.width / 2
30+
TextArea {
31+
id: inputEdit
32+
SplitView.preferredWidth: parent.width / 2
33+
wrapMode: TextArea.Wrap
34+
anchors.fill: parent
35+
clip: true
36+
color: appWindow.textColor
37+
Component.onCompleted: {
38+
inspector.input = textDocument;
39+
inspector.rebuildOutput(cursorPosition);
40+
}
41+
42+
onCursorPositionChanged: {
43+
inspector.rebuildOutput(cursorPosition);
44+
}
45+
46+
onTextChanged: {
47+
inspector.rebuildOutput(cursorPosition);
48+
}
49+
}
50+
}
51+
52+
ScrollView {
53+
SplitView.preferredWidth: parent.width / 2
54+
TextEdit {
55+
clip: true
56+
color: appWindow.textColor
57+
text: "Hello World"
58+
readOnly: true
59+
Component.onCompleted: inspector.output = textDocument
60+
}
61+
}
62+
}
63+
}

0 commit comments

Comments
 (0)