Type: Cmd/Ctrl+Shift+U underlines, and Cmd/Ctrl+Alt+Shift+C and H toggle the line composer and hyphenation

Squashed from #4383 onto main.
This commit is contained in:
dotCooCoo
2026-10-30 00:15:55 +07:00
committed by bflatastic
parent 316d28407f
commit 0ee5fc0a9e
32 changed files with 151 additions and 2 deletions
+1
View File
@@ -3003,6 +3003,7 @@ font-technology Variable Променливи
Single Quotes: Единични кавички:
Single Right Quotation Mark Дясна единична кавичка
Single-line Composer Ред по ред композитор
Toggle Line Composer Превключване на композитора на редове
Sixth Space Шесто разстояние
Size Размер
Size Tile to Art Оразмеряване на плочката според обектите
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -1825,6 +1825,7 @@ lighting Light Světlo
Roman Hanging Punctuation Visící latinková interpunkce
Select a text object to edit its paragraph attributes. Vyberte textový objekt, abyste mohli upravit atributy jeho odstavce.
Single-line Composer Sazba jednoho řádku
Toggle Line Composer Přepnout sazbu řádků
Space After Paragraph Mezera za odstavcem
Space Before Paragraph Mezera před odstavcem
Top-to-Top Leading Proklad od horní k horní
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -1637,6 +1637,7 @@ lighting Light Lys
Roman Hanging Punctuation Romersk hængende tegnsætning
Select a text object to edit its paragraph attributes. Markér et tekstobjekt for at redigere dets afsnitsattributter.
Single-line Composer Enlinjesætter
Toggle Line Composer Skift linjesætter
Space After Paragraph Mellemrum efter afsnit
Space Before Paragraph Mellemrum før afsnit
Top-to-Top Leading Linjeafstand top til top
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -3040,6 +3040,7 @@ mark-style Japanese Japanisch
Single Quotes: Einfache Anführungszeichen:
Single Right Quotation Mark Einfaches schließendes Anführungszeichen
Single-line Composer Einzeilen-Setzer
Toggle Line Composer Zeilensetzer umschalten
Sixth Space Sechstelgeviert-Leerzeichen
Size Größe
Size Tile to Art Kachelgröße an Grafik anpassen
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -3484,6 +3484,7 @@ theme Appearance Εμφάνιση
Single Quotes: Μονά εισαγωγικά:
Single Right Quotation Mark Μονό δεξί εισαγωγικό
Single-line Composer Σύνθεση μονής γραμμής
Toggle Line Composer Εναλλαγή σύνθεσης γραμμών
Sixth Space Διάστημα ενός έκτου
Size Tile to Art Προσαρμογή μεγέθους πλακιδίου στο σχέδιο
Size/Leading Μέγεθος/διάστιχο
Can't render this file because it contains an unexpected character in line 164 and column 5.
+1
View File
@@ -3075,6 +3075,7 @@ font-technology Variable Variables
Single Quotes: Comillas simples:
Single Right Quotation Mark Comilla simple de cierre
Single-line Composer Composición de una línea
Toggle Line Composer Alternar composición de líneas
Sixth Space Sexto de espacio
Size Tamaño
Size Tile to Art Ajustar tamaño del mosaico a la ilustración
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -1787,6 +1787,7 @@ lighting Light Valo
Roman Hanging Punctuation Latinalaiset riippuvat välimerkit
Select a text object to edit its paragraph attributes. Valitse tekstiobjekti, jonka kappalemääritteitä haluat muokata.
Single-line Composer Yhden rivin asettelu
Toggle Line Composer Vaihda rivien asettelu
Space After Paragraph Väli kappaleen jälkeen
Space Before Paragraph Väli ennen kappaletta
Top-to-Top Leading Riviväli yläreunasta yläreunaan
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -3072,6 +3072,7 @@ font-technology Variable Variables
Single Quotes: Guillemets simples :
Single Right Quotation Mark Guillemet simple fermant
Single-line Composer Compositeur ligne par ligne
Toggle Line Composer Basculer le compositeur de lignes
Sixth Space Espace d’un sixième
Size Taille
Size Tile to Art Ajuster le carreau à l’illustration
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -3705,6 +3705,7 @@ mark-style Japanese Japán
Single Quotes: Szimpla idézőjelek:
Single Right Quotation Mark Jobb oldali szimpla idézőjel
Single-line Composer Egysoros tördelő
Toggle Line Composer Sortördelő váltása
Sixth Space Hatodkvirt-szóköz
Size Méret
Size Tile to Art Csempe méretezése a grafikához
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -1637,6 +1637,7 @@ lighting Light Cahaya
Roman Hanging Punctuation Tanda baca gantung Romawi
Select a text object to edit its paragraph attributes. Pilih objek teks untuk mengedit atribut paragrafnya.
Single-line Composer Komposer satu baris
Toggle Line Composer Alihkan komposer baris
Space After Paragraph Spasi setelah paragraf
Space Before Paragraph Spasi sebelum paragraf
Top-to-Top Leading Leading dari atas ke atas
1 # Indonesian (id) catalog. Same format as zh-hant.tsv: context <TAB> source <TAB> translation
1637
1638
1639
1640
1641
1642
1643
+1
View File
@@ -3109,6 +3109,7 @@ mark-style Japanese Giapponese
Single Quotes: Virgolette singole:
Single Right Quotation Mark Virgoletta singola di chiusura
Single-line Composer Composizione su riga singola
Toggle Line Composer Alterna composizione delle righe
Sixth Space Spazio di un sesto
Size Dimensione
Size Tile to Art Adatta tassello alla grafica
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -2905,6 +2905,7 @@ mark-style Japanese 日本式
Simulate Paper 紙色をシミュレート
Single Quotes: 一重引用符:
Single-line Composer 1 行ずつ組む
Toggle Line Composer 行の組版方式を切り替え
Size Tile to Art タイルをアートワークのサイズに合わせる
Size/Leading サイズ/行送り
Size: サイズ:
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -1540,6 +1540,7 @@ lighting Light სინათლე
Roman Hanging Punctuation ლათინური გამოწეული პუნქტუაცია
Select a text object to edit its paragraph attributes. აბზაცის ატრიბუტების რედაქტირებისთვის მონიშნეთ ტექსტური ობიექტი.
Single-line Composer სტრიქონის მიხედვით აწყობა
Toggle Line Composer აწყობის რეჟიმის გადართვა
Space After Paragraph ინტერვალი აბზაცის შემდეგ
Space Before Paragraph ინტერვალი აბზაცის წინ
Top-to-Top Leading სტრიქონთა დაშორება ზედა კიდიდან ზედა კიდემდე
Can't render this file because it is too large.
+1
View File
@@ -2899,6 +2899,7 @@ mark-style Japanese 일본식
Simulate Paper 용지 시뮬레이션
Single Quotes: 작은따옴표:
Single-line Composer 한 줄 조판
Toggle Line Composer 줄 조판 방식 전환
Size Tile to Art 타일을 아트웍 크기에 맞춤
Size/Leading 크기/행간
Size: 크기:
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -1651,6 +1651,7 @@ lighting Light Licht
Roman Hanging Punctuation Romeinse hangende leestekens
Select a text object to edit its paragraph attributes. Selecteer een tekstobject om de alineakenmerken ervan te bewerken.
Single-line Composer Compositie per regel
Toggle Line Composer Compositiemethode wisselen
Space After Paragraph Ruimte na alinea
Space Before Paragraph Ruimte voor alinea
Top-to-Top Leading Regelafstand van boven naar boven
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -1745,6 +1745,7 @@ lighting Light Światło
Roman Hanging Punctuation Wysunięta interpunkcja łacińska
Select a text object to edit its paragraph attributes. Zaznacz obiekt tekstowy, aby edytować atrybuty akapitu.
Single-line Composer Kompozytor jednowierszowy
Toggle Line Composer Przełącz kompozytor wierszy
Space After Paragraph Odstęp po akapicie
Space Before Paragraph Odstęp przed akapitem
Top-to-Top Leading Interlinia od góry do góry
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -2552,6 +2552,7 @@
Single Quotes: Aspas Simples:
Single Right Quotation Mark Aspa Direita Única
Single-line Composer Compositor de Linha Única
Toggle Line Composer Alternar Compositor de Linhas
Sixth Space Espaço de Sexto
Size Tamanho
Size Tile to Art Dimensionar Bloco para a Arte
Can't render this file because it contains an unexpected character in line 6 and column 47.
+1
View File
@@ -3105,6 +3105,7 @@ mark-style Japanese Японский
Single Quotes: Одинарные кавычки:
Single Right Quotation Mark Одинарная закрывающая кавычка
Single-line Composer Однострочный компоновщик
Toggle Line Composer Переключить компоновщик строк
Sixth Space Шестая шпация
Size Размер
Size Tile to Art Подогнать плитку по рисунку
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -3003,6 +3003,7 @@ font-technology Variable Variabla
Single Quotes: Enkla citattecken:
Single Right Quotation Mark Enkelt höger citattecken
Single-line Composer Enradssättare
Toggle Line Composer Växla radsättare
Sixth Space Sjättedelsblanksteg
Size Storlek
Size Tile to Art Anpassa rutans storlek efter grafiken
Can't render this file because it contains an unexpected character in line 5 and column 25.
+1
View File
@@ -2914,6 +2914,7 @@ shape Open Açık
Single Quotes: Tek Alıntılar:
Single Right Quotation Mark Tek Sağ Tırnak İşareti
Single-line Composer Tek Satır Oluşturucu
Toggle Line Composer Satır Oluşturucuyu Değiştir
Sixth Space Altıncı Uzay
Size Boyut
Size Tile to Art Sanata Boyut Döşeme
Can't render this file because it contains an unexpected character in line 5 and column 25.
+1
View File
@@ -3101,6 +3101,7 @@ mark-style Japanese Японський
Single Quotes: Одинарні лапки:
Single Right Quotation Mark Одинарна лапка, що закриває
Single-line Composer Однорядковий компонувальник
Toggle Line Composer Переключити компонувальник рядків
Sixth Space Шоста шпація
Size Розмір
Size Tile to Art Підігнати плитку за малюнком
Can't render this file because it contains an unexpected character in line 178 and column 5.
+1
View File
@@ -3440,6 +3440,7 @@ mark-style Japanese Kiểu Nhật
Single Quotes: Dấu nháy đơn:
Single Right Quotation Mark Dấu nháy đơn đóng
Single-line Composer Soạn thảo một dòng
Toggle Line Composer Chuyển đổi cách soạn dòng
Sixth Space Dấu cách 1/6
Size Kích thước
Size Tile to Art Kích thước ô theo đối tượng
Can't render this file because it contains an unexpected character in line 200 and column 5.
+1
View File
@@ -2940,6 +2940,7 @@ font-script Japanese 汉字
Single Quotes: 单引号:
Single Right Quotation Mark 右单引号
Single-line Composer 单行排版器
Toggle Line Composer 切换行排版器
Sixth Space 六分之一空格
Size 大小
Size Tile to Art 使拼贴适合图稿
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -3907,6 +3907,7 @@ font-script Japanese 漢字
Single Quotes: 單引號:
Single Right Quotation Mark 右單引號
Single-line Composer 單行排版程式
Toggle Line Composer 切換行排版程式
Sixth Space 六分之一空格
Size 大小
Size Tile to Art 拼貼符合圖稿大小
Can't render this file because it contains an unexpected character in line 6 and column 47.
+3
View File
@@ -239,6 +239,9 @@ fn run_ui_part3(app: &mut VectorcraftApp, id: &str, p: &Value) -> Option<Result<
"type.highlightFontName" => crate::panels::character::highlight(app, crate::panels::character::Field::FontName),
"type.highlightKerning" => crate::panels::character::highlight(app, crate::panels::character::Field::Kerning),
"type.highlightTracking" => crate::panels::character::highlight(app, crate::panels::character::Field::Tracking),
"type.underline" => crate::panels::character::toggle_underline(app),
"type.lineComposer" => crate::panels::paragraph::toggle_composer(app),
"type.hyphenate" => crate::panels::paragraph::toggle_hyphenate(app),
id if let Some((_, justify)) = crate::panels::paragraph::ALIGN_COMMANDS.iter().find(|c| c.0 == id) => {
crate::panels::paragraph::align(app, justify)
}
+3 -1
View File
@@ -182,7 +182,9 @@ pub fn enabled(app: &VectorcraftApp, id: &str) -> bool {
match id {
// Save is off for a clean document that already has its own file.
"file.save" => app.session.active().is_some_and(|d| d.path.is_none() || d.converted || d.is_dirty()),
"type.bold" | "type.italic" => crate::panels::character::text_style(app).is_some(),
"type.bold" | "type.italic" | "type.underline" | "type.lineComposer" | "type.hyphenate" => {
crate::panels::character::text_style(app).is_some()
}
id if crate::panels::paragraph::ALIGN_COMMANDS.iter().any(|c| c.0 == id) => crate::panels::character::text_style(app).is_some(),
"type.applyBullets" | "type.applyNumbers" | "type.convertListToText" => crate::panels::character::text_style(app).is_some(),
id if let Some(b) = crate::panels::align::button(id) => enabled(app, b.command()),
+18
View File
@@ -336,6 +336,24 @@ pub const UI_COMMANDS: &[(&str, &str, &str, &str)] = &[
"",
"{} show the Character panel if it is hidden and give its Tracking field the keyboard focus with its value selected: type a value and press Enter → {field: \"tracking\"}. Without selected type (or text the Type tool edits) the panel shows, and the error says to select type first",
),
(
"type.underline",
"Underline",
"Cmd+Shift+U",
"{} the Character panel's Underline button: underline the selected type (or the Type tool's selection), or remove the underline when the text the Character panel shows is underlined (text.setFormat {underline}) → underlined",
),
(
"type.lineComposer",
"Toggle Line Composer",
"Cmd+Alt+Shift+C",
"{} the selected type's paragraphs (or those the Type tool's selection touches) use the Single-line Composer when they all use the Every-line Composer, else the Every-line Composer (text.setFormat {composer}) → \"singleLine\" | \"everyLine\"",
),
(
"type.hyphenate",
"Hyphenate",
"Cmd+Alt+Shift+H",
"{} the Paragraph panel's Hyphenate checkbox: hyphenation off for the selected type's paragraphs (or those the Type tool's selection touches) when they all hyphenate, else on (text.setFormat {hyphenate}) → hyphenate",
),
("effect.last", "Last Effect…", "Cmd+Alt+Shift+E", "{} open the dialog of the last effect applied"),
("view.zoomIn", "Zoom In", "Cmd+=", "{}"),
("view.zoomOut", "Zoom Out", "Cmd+-", "{}"),
+8
View File
@@ -377,6 +377,14 @@ pub(crate) fn highlight(app: &mut VectorcraftApp, field: Field) -> Result<Value,
Ok(json!({ "field": field.name() }))
}
/// `type.underline` (Cmd+Shift+U): what the Underline button does, on the text the panels act on.
/// Returns whether the text is now underlined.
pub(crate) fn toggle_underline(app: &mut VectorcraftApp) -> Result<Value, String> {
let (s, _) = text_style(app).ok_or("select some type first")?;
format(app, json!({"underline": !s.underline}));
Ok(json!(!s.underline))
}
/// `text.setRangeStyle` with `p` on the range the Type tool has selected (the whole text when
/// nothing is selected). Does nothing unless the Type tool edits text.
pub(crate) fn range_style(app: &mut VectorcraftApp, p: Value) {
+19
View File
@@ -50,6 +50,25 @@ pub(crate) fn align(app: &mut VectorcraftApp, justify: &str) -> Result<Value, St
Ok(Value::Null)
}
/// `type.lineComposer` (Cmd+Alt+Shift+C): the Single-line Composer for the paragraphs the panel
/// acts on when they all use the Every-line Composer, else the Every-line Composer. Returns the
/// composer set.
pub(crate) fn toggle_composer(app: &mut VectorcraftApp) -> Result<Value, String> {
text_style(app).ok_or("select some type first")?;
let id = if shared_composer(app) == Some(Composer::EveryLine) { "singleLine" } else { "everyLine" };
format(app, json!({ "composer": id }));
Ok(json!(id))
}
/// `type.hyphenate` (Cmd+Alt+Shift+H): what the Hyphenate checkbox does, on the paragraphs the
/// panel acts on. Returns whether they now hyphenate.
pub(crate) fn toggle_hyphenate(app: &mut VectorcraftApp) -> Result<Value, String> {
text_style(app).ok_or("select some type first")?;
let on = shared_hyphenate(app) != Some(true);
format(app, json!({ "hyphenate": on }));
Ok(json!(on))
}
fn para_cmd(app: &mut VectorcraftApp, cmd: &str, p: Value) {
run_on_paragraphs(app, cmd, p).ok();
}
+64
View File
@@ -384,6 +384,70 @@ fn cmd_shift_x_resets_horizontal_scale() {
assert_eq!(scales(&mut app), [(json!("One "), json!(150.0)), (json!("Two"), json!(100.0))]);
}
/// Cmd+Shift+U underlines the selected type and removes the underline again, Cmd+Alt+Shift+C
/// switches its paragraphs between the Single-line and the Every-line Composer, and
/// Cmd+Alt+Shift+H turns their hyphenation on and off. While the Type tool edits text, they act on
/// its selection and the paragraphs it touches. Smart Guides (Cmd+U), Copy (Cmd+C) and Hide
/// Artboards (Cmd+Shift+H) stay as they are.
#[test]
fn cmd_shift_u_and_cmd_alt_shift_c_and_h_toggle_type_formats() {
use vectorcraft_doc::Composer;
let mut app = VectorcraftApp::new(vectorcraft_engine::Session::new(), Default::default());
app.session.execute("file.new", &json!({"width": 200, "height": 200})).unwrap();
let id = app.session.execute("text.create", &json!({"x": 20, "y": 50, "text": "One\nTwo"})).unwrap()["id"].as_u64().unwrap();
let underlines = |app: &mut VectorcraftApp| {
let r = app.session.execute("text.getRange", &json!({"id": id})).unwrap();
r["runs"].as_array().unwrap().iter().map(|run| (run["text"].clone(), run["style"]["underline"].clone())).collect::<Vec<_>>()
};
let paras = |app: &VectorcraftApp| match &app.session.active().unwrap().doc.node(vectorcraft_doc::NodeId(id)).unwrap().kind {
vectorcraft_doc::NodeKind::Text(t) => (0..t.paragraph_count()).map(|i| (t.para_at(i).composer, t.para_at(i).hyphenate)).collect::<Vec<_>>(),
_ => panic!("text"),
};
let chord =
|key, m: Modifiers| vec![egui::Event::Key { key, physical_key: None, pressed: true, repeat: false, modifiers: Modifiers::COMMAND | m }];
let (shift, alt_shift) = (Modifiers::SHIFT, Modifiers::ALT | Modifiers::SHIFT);
let (guides, artboards) = (app.ui.view.smart_guides, app.ui.view.artboards);
assert!(app.session.clipboard.is_empty());
app.session.execute("select.set", &json!({"ids": [id]})).unwrap();
let hyphenate = paras(&app)[0].1;
frame(&mut app, chord(Key::U, shift));
assert_eq!(underlines(&mut app), [(json!("One\nTwo"), json!(true))]);
frame(&mut app, chord(Key::U, shift));
assert_eq!(underlines(&mut app), [(json!("One\nTwo"), json!(false))]);
frame(&mut app, chord(Key::C, alt_shift));
assert_eq!(paras(&app), [(Composer::SingleLine, hyphenate); 2]);
frame(&mut app, chord(Key::C, alt_shift));
assert_eq!(paras(&app), [(Composer::EveryLine, hyphenate); 2]);
frame(&mut app, chord(Key::H, alt_shift));
assert_eq!(paras(&app), [(Composer::EveryLine, !hyphenate); 2]);
frame(&mut app, chord(Key::H, alt_shift));
assert_eq!(paras(&app), [(Composer::EveryLine, hyphenate); 2]);
assert_eq!((app.ui.view.smart_guides, app.ui.view.artboards, app.session.clipboard.is_empty()), (guides, artboards, true));
// While the Type tool edits: its selected text, and the paragraph that text is in.
app.select_tool("type");
app.session.apply_actions(vec![vectorcraft_tools::Action::Notify("text.editNew".into())]).unwrap();
app.session.set_tool_option("select", &json!({"start": 4, "end": 7}));
assert!(app.session.tool_wants_text());
for (key, m) in [(Key::U, shift), (Key::C, alt_shift), (Key::H, alt_shift)] {
frame(&mut app, chord(key, m));
}
assert_eq!(underlines(&mut app), [(json!("One\n"), json!(false)), (json!("Two"), json!(true))]);
assert_eq!(paras(&app), [(Composer::EveryLine, hyphenate), (Composer::SingleLine, !hyphenate)]);
// Paragraphs with different composers and hyphenation take the Every-line Composer and
// hyphenation, as the Hyphenate checkbox turns it on for them.
app.select_tool("selection");
app.session.execute("select.set", &json!({"ids": [id]})).unwrap();
for (key, m) in [(Key::C, alt_shift), (Key::H, alt_shift)] {
frame(&mut app, chord(key, m));
}
assert_eq!(paras(&app), [(Composer::EveryLine, true); 2]);
// Nothing selected: nothing to change.
app.session.execute("select.none", &json!({})).unwrap();
for id in ["type.underline", "type.lineComposer", "type.hyphenate"] {
assert!(!crate::menus::enabled(&app, id), "{id}");
}
}
/// Tab shows and hides the panels, and in the Type tool it types a tab, without moving the
/// keyboard focus on to a field: the keys after it (a tool letter, the next letter typed) still
/// work.
+11 -1
View File
@@ -3100,6 +3100,10 @@ Pen's second anchor at (150, 431), in line with the square's centre.
give its Kerning or Tracking field the keyboard focus with the value selected, or open its font family menu with the
search field focused; each replies `{field: "kerning" | "tracking" | "fontName"}`. Without selected type or text the
Type tool edits, the panel shows and the command fails.
shows it, in the same text; at a caret it leaves the text as it is. The UI command `type.underline` (Cmd+Shift+U,
in remote mode `press_key {key: "U", mods: {cmd: true, shift: true}}` or `invoke_menu`) does what the Character
panel's Underline button does: it underlines the Type tool's selected text or the selected type objects, or removes
the underline when the text the panel shows is underlined, and returns whether the text is now underlined.
- `missingGlyphProtection` (on by default): `text.setStyle` and `text.setRangeStyle` changing the font leave the
characters the new font has no glyph for in the font that had one.
- `typeSelectionByPathOnly` (off by default): on, the Selection tools (`pointer_gesture` with `selection`, and the
@@ -4542,7 +4546,10 @@ The letter and line counts are rounded, and every value is clamped to its range.
listed word. The options are saved with the paragraph (`hyphenation` in `para`) only when they differ from the
defaults, and paragraph styles carry them (`paraStyle.new {attrs: {hyphenation: {words_longer_than: 8}}}`). One undo
step. `ui.hyphenation` opens the Hyphenation dialog on the values the Paragraph panel shows; OK sends the values that
changed.
changed. The UI command `type.hyphenate` (Cmd+Alt+Shift+H, in remote mode `press_key {key: "H", mods: {cmd: true,
alt: true, shift: true}}` or `invoke_menu`) does what the Hyphenate checkbox does: it turns `hyphenate` off when
every paragraph of the selected type (or every paragraph the Type tool's selection touches) hyphenates, else on, and
returns the new value.
```json
{"name":"run_command","arguments":{"command":"text.setFormat","params":{"hyphenate":true,"wordsLongerThan":8,"hyphenLimit":2}}}
@@ -5493,6 +5500,9 @@ Single-line fills each line as far as it goes. Point type and type on a path hav
give the same result there. A paragraph whose characters differ in line metrics (type size, font, leading or vertical
scale, or an inline graphic taller than the text) is composed with Every-line in rectangular area type, rows and
columns included; in area type of another shape, or with text wrap, it falls back to Single-line.
The UI command `type.lineComposer` (Cmd+Alt+Shift+C, in remote mode `press_key {key: "C", mods: {cmd: true, alt: true,
shift: true}}` or `invoke_menu`) sets `singleLine` when every paragraph of the selected type (or every paragraph the
Type tool's selection touches) uses Every-line, else `everyLine`, and returns the composer it set.
```json
{"name":"run_command","arguments":{"command":"text.setFormat","params":{"ids":[7],"composer":"singleLine"}}}
+1
View File
@@ -622,6 +622,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
- Cmd/Ctrl+Alt+L (`ui.newLayer`) opens Layer Options for a new layer, as an Alt-click on the Layers panel's New Layer button does, on the key the reference app's [Default keyboard shortcuts](https://web.archive.org/web/20260726060015/https://helpx.adobe.com/illustrator/using/default-keyboard-shortcuts.html) page lists for adding a layer through the New Layer dialog box. OK adds the layer above the current layer, and Cancel adds none. Cmd/Ctrl+L still adds a layer without the dialog.
- F8 (`ui.symbolOptions`) opens Symbol Options for a new symbol made from the selection, as the Symbols panel's New Symbol button does, on the key the reference app's [Default keyboard shortcuts](https://web.archive.org/web/20260726060015/https://helpx.adobe.com/illustrator/using/default-keyboard-shortcuts.html) page lists for making a new symbol. OK makes the symbol and puts an instance of it in place of the art, and Cancel makes none. With nothing selected, F8 opens no dialog, and the status bar says that nothing is selected. Shift+F8 and Cmd/Ctrl+F8 still show the Transform and Info panels.
- Cmd/Ctrl+Shift+X (`type.resetHorizontalScale`) sets the horizontal scale of the selected type, or of the text the Type tool has selected, to 100% as the Character panel shows it (the object's own stretch included), in one undo step; at a caret it leaves the text as it is.
- Cmd/Ctrl+Shift+U (`type.underline`) underlines the selected type, or the text the Type tool has selected, and removes the underline again, as the Character panel's Underline button does. Cmd/Ctrl+Alt+Shift+C (`type.lineComposer`) switches the paragraphs between the Single-line and the Every-line Composer, and Cmd/Ctrl+Alt+Shift+H (`type.hyphenate`) turns their hyphenation on and off, as the Hyphenate checkbox does. These are the keys the reference app's [Default keyboard shortcuts](https://web.archive.org/web/20260726060015/https://helpx.adobe.com/illustrator/using/default-keyboard-shortcuts.html) page lists for underlining and for toggling auto-hyphenation, and on Windows for toggling the line composer. The page's macOS key for the line composer ends after Command, and VectorCraft uses C there as well.
- Cmd/Ctrl+Alt+N (`file.newWithoutDialog`) makes a document without opening the New Document dialog, on the key the reference app's [Default keyboard shortcuts](https://web.archive.org/web/20260726060015/https://helpx.adobe.com/illustrator/using/default-keyboard-shortcuts.html) page lists for making a new document with no New Document dialog box. The page does not say which settings the document gets. VectorCraft gives it the settings the dialog opens on (the first Recent entry, or the Print category's Letter while Recent is empty) and the next untitled name.
- Cmd/Ctrl+F6 (`window.nextDocument`) and Cmd/Ctrl+Shift+F6 (`window.previousDocument`) make the next and the previous open document the current one, in tab order and as a click on its tab does, on the keys the reference app's [Default keyboard shortcuts](https://web.archive.org/web/20260726060015/https://helpx.adobe.com/illustrator/using/default-keyboard-shortcuts.html) page lists for navigating to the next and the previous document. After the last document comes the first, and before the first document comes the last. From the Home screen the keys go to the first and the last document. Keyboard Shortcuts lists both under Window.
- Cmd/Ctrl+Alt+Shift+U (`document.switchUnits`) switches the document to the next unit of measurement, in one undo step, on the key the reference app's [Default keyboard shortcuts](https://web.archive.org/web/20260726060015/https://helpx.adobe.com/illustrator/using/default-keyboard-shortcuts.html) page lists for switching units of measurement. The page does not give an order. VectorCraft steps through the units in the order a right-click on a ruler lists them (Points, Picas, Inches, Millimeters, Centimeters, Pixels, Feet & Inches, Meters, Yards, Feet) and goes from Feet back to Points.