Skip to content

Commit 5da0915

Browse files
committed
Fix expression editor string parsing bug
1 parent 4253f7b commit 5da0915

9 files changed

Lines changed: 48 additions & 20 deletions

File tree

rust/perspective-viewer/src/rust/components/column_settings_sidebar/sidebar.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ impl Component for ColumnSettingsSidebar {
192192
let session_sub = ctx
193193
.props()
194194
.renderer
195-
.session_changed
195+
.render_limits_changed
196196
.add_listener(session_cb);
197197

198198
let mut this = Self {

rust/perspective-viewer/src/rust/components/viewer.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,10 @@ impl Component for PerspectiveViewer {
198198
]
199199
}
200200
});
201-
ctx.props().renderer.session_changed.add_listener(callback)
201+
ctx.props()
202+
.renderer
203+
.render_limits_changed
204+
.add_listener(callback)
202205
};
203206

204207
let on_close_column_settings =

rust/perspective-viewer/src/rust/exprtk/tokenize.rs

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use nom::bytes::complete::{is_a, is_not};
2020
use nom::character::complete::{line_ending, space1};
2121
use nom::combinator::map;
2222
use nom::multi::many0;
23+
use nom::IResult;
2324
use yew::prelude::*;
2425

2526
use self::comment::*;
@@ -86,24 +87,37 @@ impl<'a> Token<'a> {
8687
}
8788
}
8889

90+
#[allow(clippy::redundant_closure)]
91+
fn parse_multiline_string<'a>(
92+
sep: char,
93+
lit: impl Fn(&'a str) -> Token<'a>,
94+
) -> impl FnMut(&'a str) -> IResult<&'a str, Vec<Token<'a>>> {
95+
map(parse_string_literal(sep), move |x| {
96+
x.into_iter()
97+
.map(|x| lit(x))
98+
.intersperse(Token::Break("\n"))
99+
.collect()
100+
})
101+
}
102+
89103
/// Parse a string representing an ExprTK Expression Column into `Token`s. A
90104
/// token list is sufficient for syntax-highlighting purposes, faster than a
91105
/// full parser and much easier to write a renderer for.
92106
pub fn tokenize(input: &str) -> Vec<Token<'_>> {
93-
let comment = map(parse_comment, Token::Comment);
94-
let string = map(parse_string_literal('"'), Token::Literal);
95-
let column = map(parse_string_literal('\''), Token::Column);
96-
let symbol = map(parse_symbol_literal, Token::Symbol);
97-
let number = map(parse_number_literal, Token::Literal);
98-
let whitespace = map(space1, Token::Whitespace);
99-
let linebreak = map(line_ending, Token::Break);
100-
let ops = map(is_a("+-/*^%&|=:;,.(){}[]"), Token::Operator);
101-
let unknown = map(is_not(" \t\n\r"), Token::Unknown);
102-
103-
let mut expr = many0(alt((
107+
let comment = map(parse_comment, |x| vec![Token::Comment(x)]);
108+
let string = parse_multiline_string('\'', Token::Literal);
109+
let column = parse_multiline_string('"', Token::Column);
110+
let symbol = map(parse_symbol_literal, |x| vec![Token::Symbol(x)]);
111+
let number = map(parse_number_literal, |x| vec![Token::Literal(x)]);
112+
let whitespace = map(space1, |x| vec![Token::Whitespace(x)]);
113+
let linebreak = map(line_ending, |x| vec![Token::Break(x)]);
114+
let ops = map(is_a("+-/*^%&|=:;,.(){}[]"), |x| vec![Token::Operator(x)]);
115+
let unknown = map(is_not(" \t\n\r"), |x| vec![Token::Unknown(x)]);
116+
let token = alt((
104117
comment, string, column, symbol, number, whitespace, linebreak, ops, unknown,
105-
)));
118+
));
106119

120+
let mut expr = map(many0(token), |x| x.into_iter().flatten().collect());
107121
let (rest, mut tokens) = expr(input).unwrap_or_else(|_| (input, vec![]));
108122
if !rest.is_empty() {
109123
tracing::warn!(

rust/perspective-viewer/src/rust/exprtk/tokenize/string.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,18 @@ fn parse_fragment(sep: char, input: &str) -> IResult<&str, StringFragment> {
8181
))(input)
8282
}
8383

84-
pub fn parse_string_literal(sep: char) -> impl for<'a> Fn(&'a str) -> IResult<&'a str, &'a str> {
84+
pub fn parse_string_literal(
85+
sep: char,
86+
) -> impl for<'a> Fn(&'a str) -> IResult<&'a str, Vec<&'a str>> {
8587
move |input| {
8688
let build_string = fold_many0(
8789
|x| parse_fragment(sep, x),
8890
|| 2,
8991
|len, frag| frag.len() + len,
9092
);
93+
9194
let offset = delimited(char(sep), build_string, char(sep));
92-
map(offset, |x| &input[..x])(input)
95+
let (input, lit) = map(offset, |x| &input[..x])(input)?;
96+
Ok((input, lit.split('\n').collect()))
9397
}
9498
}

rust/perspective-viewer/src/rust/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#![feature(lazy_cell)]
1818
#![feature(let_chains)]
1919
#![feature(macro_metavar_expr)]
20+
#![feature(iter_intersperse)]
2021
#![feature(return_position_impl_trait_in_trait)]
2122
#![feature(stmt_expr_attributes)]
2223
#![warn(

rust/perspective-viewer/src/rust/renderer.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub struct RendererData {
5757
plugin_data: RefCell<RendererMutData>,
5858
draw_lock: DebounceMutex,
5959
pub plugin_changed: PubSub<JsPerspectiveViewerPlugin>,
60-
pub session_changed: PubSub<(bool, RenderLimits)>,
60+
pub render_limits_changed: PubSub<(bool, RenderLimits)>,
6161
}
6262

6363
/// Mutable state
@@ -113,7 +113,7 @@ impl Renderer {
113113
}),
114114
draw_lock: Default::default(),
115115
plugin_changed: Default::default(),
116-
session_changed: Default::default(),
116+
render_limits_changed: Default::default(),
117117
}))
118118
}
119119

@@ -286,7 +286,7 @@ impl Renderer {
286286
let plugin = self.get_active_plugin()?;
287287
let meta = self.metadata().clone();
288288
let limits = get_row_and_col_limits(view, &meta).await?;
289-
self.session_changed.emit((is_update, limits));
289+
self.render_limits_changed.emit((is_update, limits));
290290
let viewer_elem = &self.0.borrow().viewer_elem.clone();
291291
if is_update {
292292
let task = plugin.update(view, limits.2, limits.3, false);

rust/perspective-viewer/src/themes/pro-dark.less

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ perspective-string-column-style[theme="Pro Dark"] {
7979
--code-editor-literal--color: #7dc3f0;
8080
--code-editor-operator--color: rgb(23, 166, 123);
8181
--code-editor-comment--color: rgb(204, 120, 48);
82+
--code-editor-column--color: #e18ee1;
83+
// --code-editor-unknown--color: rgb(204, 120, 48);
8284
}
8385

8486
@mixin perspective-viewer-pro-dark--openlayers {

rust/perspective-viewer/src/themes/pro.less

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ perspective-string-column-style[theme="Pro Light"] {
7070
--column_type--width: 25px;
7171

7272
--select--padding: 0px;
73-
--side-panel--padding: 0px 0px 6px 4px;
73+
--side-panel--padding: 0px 0px 0px 4px;
7474
--top-panel--padding: 0px 0px 12px 0px;
7575
--top-panel-row--display: inline-flex;
7676
--button--min-width: 110px;

rust/perspective-viewer/test/js/column_settings.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,12 @@ test.describe("Plugin Styles", () => {
119119
await tabs[0].click();
120120
await sidebar.styleTab.container.waitFor();
121121
});
122+
122123
test("View updates don't re-render sidebar", async ({ page }) => {
123124
await page.evaluate(async () => {
125+
// @ts-ignore
124126
let table = await window.__TEST_WORKER__.table({ x: [0] });
127+
// @ts-ignore
125128
window.__TEST_TABLE__ = table;
126129
let viewer = document.querySelector("perspective-viewer");
127130
viewer?.load(table);
@@ -133,6 +136,7 @@ test.describe("Plugin Styles", () => {
133136
await col.editBtn.click();
134137
await view.columnSettingsSidebar.container.waitFor();
135138
await page.evaluate(() => {
139+
// @ts-ignore
136140
window.__TEST_TABLE__.update({ x: [1] });
137141
});
138142
await page.locator("tbody tr").nth(1).waitFor();

0 commit comments

Comments
 (0)