feat(engine): Report the selected text; remember recently used fonts
type.selectionAttrs reports the start of the selected text on one line (`selectedText`, up to 60 characters), for previews such as the font menu's Selected Text sample. The preferences keep `recentFonts`, the fonts last picked in the font menus. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
d020b4e85d
commit
ef87428481
|
|
@ -253,7 +253,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
|||
has_text_or_frames,
|
||||
break_link
|
||||
),
|
||||
cmd!(query "type.selectionAttrs", "Selection Attributes", [], None, "{} → resolved character/paragraph attributes at the text selection", has_doc, selection_attrs),
|
||||
cmd!(query "type.selectionAttrs", "Selection Attributes", [], None, "{} → resolved character/paragraph attributes at the text selection, and its start as `selectedText` (one line, up to 60 characters)", has_doc, selection_attrs),
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -970,6 +970,9 @@ fn open_type(s: &mut Session, p: &Value) -> Result<Value> {
|
|||
Ok(json!({"features": list, "figures": otf::figures(&list)}))
|
||||
}
|
||||
|
||||
/// How much of the selected text `type.selectionAttrs` reports.
|
||||
const SELECTED_TEXT_CHARS: usize = 60;
|
||||
|
||||
fn selection_attrs(s: &mut Session, _p: &Value) -> Result<Value> {
|
||||
let st = s.doc()?;
|
||||
let targets = format_targets(s);
|
||||
|
|
@ -980,8 +983,17 @@ fn selection_attrs(s: &mut Session, _p: &Value) -> Result<Value> {
|
|||
let (pp, base) = st.doc.styles.resolve_para(pf);
|
||||
let cf = if r.is_empty() { story.char_format_at(r.start) } else { story.format_after(r.start) };
|
||||
let cp = st.doc.styles.resolve_char(&base, cf);
|
||||
// The selected text (its start, on one line), for previews such as the font menu's.
|
||||
let line: String = story
|
||||
.text
|
||||
.get(r.start..r.end)
|
||||
.unwrap_or_default()
|
||||
.chars()
|
||||
.map(|c| if c.is_control() || c == designcraft_doc::OBJECT_MARK { ' ' } else { c })
|
||||
.collect();
|
||||
let selected: String = line.trim_start().chars().take(SELECTED_TEXT_CHARS).collect();
|
||||
Ok(json!({"story": sid.0, "paragraphStyle": pf.style, "characterStyle": cf.style, "para": pp, "chars": cp,
|
||||
"paraOverrides": pf.para.count(), "charOverrides": cf.over.count()}))
|
||||
"paraOverrides": pf.para.count(), "charOverrides": cf.over.count(), "selectedText": selected.trim()}))
|
||||
}
|
||||
|
||||
/// Our own filler text (not Adobe's).
|
||||
|
|
@ -1154,6 +1166,26 @@ mod open_type_tests {
|
|||
s.execute("text.move", &json!({"dir": "right"})).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn selection_attrs_report_the_selected_text() {
|
||||
let mut s = Session::new();
|
||||
s.execute("file.new", &json!({})).unwrap();
|
||||
let r = s
|
||||
.execute(
|
||||
"frame.create",
|
||||
&json!({"rect": [72, 72, 300, 200], "content": "text", "text": "Spring issue
|
||||
What's new in typography this season, and why it matters to every designer"}),
|
||||
)
|
||||
.unwrap();
|
||||
s.execute("text.select", &json!({"story": r["story"], "anchor": 0, "focus": 13})).unwrap();
|
||||
assert_eq!(s.execute("type.selectionAttrs", &json!({})).unwrap()["selectedText"], "Spring issue", "on one line, trimmed");
|
||||
s.execute("text.select", &json!({"story": r["story"], "anchor": 13, "focus": 200})).unwrap();
|
||||
let long = s.execute("type.selectionAttrs", &json!({})).unwrap()["selectedText"].as_str().unwrap().to_string();
|
||||
assert!(long.starts_with("What's new") && (55..=60).contains(&long.chars().count()), "the line break skipped, capped: {long}");
|
||||
s.execute("text.select", &json!({"story": r["story"], "anchor": 3, "focus": 3})).unwrap();
|
||||
assert_eq!(s.execute("type.selectionAttrs", &json!({})).unwrap()["selectedText"], "", "a caret selects nothing");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn open_type_toggles_reach_the_text() {
|
||||
let mut s = Session::new();
|
||||
|
|
|
|||
|
|
@ -179,6 +179,8 @@ pub struct Prefs {
|
|||
pub rich_black_output: bool,
|
||||
/// Font menu favourites (family names).
|
||||
pub favorite_fonts: Vec<String>,
|
||||
/// Fonts picked in the font menus, most recent first (shown at the menus' top).
|
||||
pub recent_fonts: Vec<String>,
|
||||
/// Preferences › Type › Show Font Names in English: the font menus show CJK families by their
|
||||
/// English names instead of their native ones. Documents store the English name either way.
|
||||
pub show_font_names_in_english: bool,
|
||||
|
|
@ -235,6 +237,7 @@ impl Default for Prefs {
|
|||
highlight_substituted_fonts: true,
|
||||
rich_black_output: false,
|
||||
favorite_fonts: Vec::new(),
|
||||
recent_fonts: Vec::new(),
|
||||
show_font_names_in_english: false,
|
||||
smart_text_reflow: true,
|
||||
autocorrect: false,
|
||||
|
|
|
|||
Loading…
Reference in New Issue