#954: macOS ⌘←/⌘→ go to the line's start and end (#972)

On macOS, Cmd+Left/Right were bound to Word Left/Right (same as Option+arrows).
Bind them to Line Start/End there, as in Word for Mac and every Mac text field;
Option+arrows still move by word. Windows/Linux keys are unchanged.

Co-authored-by: justinjohn0306 <babyjjbabyjj549@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
This commit is contained in:
authored and GitHub committed 2026-10-15 01:35:42 -04:00
1 parent b3b6c451e3
commit fd0bb2fb1e
3 files changed
+19 -5

No files matched your search

+12 -5
View File
@@ -14,17 +14,24 @@ pub fn specs() -> Vec<CommandSpec> {
CommandSpec::new("caret.right", "Right", "Navigation", |s, v| lr(s, v, false)).key("Right").params(EXTEND).pure(),
CommandSpec::new("caret.up", "Up", "Navigation", |s, v| vert(s, v, -1)).key("Up").params(EXTEND).pure(),
CommandSpec::new("caret.down", "Down", "Navigation", |s, v| vert(s, v, 1)).key("Down").params(EXTEND).pure(),
// In a right-to-left paragraph the word to the left is the next one.
// In a right-to-left paragraph the word to the left is the next one. On macOS ⌘←/⌘→ go
// to the line's start and end, as in Word for Mac and every Mac text field (#954).
CommandSpec::new("caret.wordLeft", "Word Left", "Navigation", |s, v| mv(s, v, if rtl_para(s) { word_right } else { word_left }))
.key("Mod+Left / Alt+Left")
.key(super::mac_or("Alt+Left", "Mod+Left / Alt+Left"))
.params(EXTEND)
.pure(),
CommandSpec::new("caret.wordRight", "Word Right", "Navigation", |s, v| mv(s, v, if rtl_para(s) { word_left } else { word_right }))
.key("Mod+Right / Alt+Right")
.key(super::mac_or("Alt+Right", "Mod+Right / Alt+Right"))
.params(EXTEND)
.pure(),
CommandSpec::new("caret.home", "Line Start", "Navigation", |s, v| line(s, v, true))
.key(super::mac_or("Home / Mod+Left", "Home"))
.params(EXTEND)
.pure(),
CommandSpec::new("caret.end", "Line End", "Navigation", |s, v| line(s, v, false))
.key(super::mac_or("End / Mod+Right", "End"))
.params(EXTEND)
.pure(),
CommandSpec::new("caret.home", "Line Start", "Navigation", |s, v| line(s, v, true)).key("Home").params(EXTEND).pure(),
CommandSpec::new("caret.end", "Line End", "Navigation", |s, v| line(s, v, false)).key("End").params(EXTEND).pure(),
CommandSpec::new("caret.paraUp", "Paragraph Up", "Navigation", |s, v| mv(s, v, para_up)).key("Mod+Up / Alt+Up").params(EXTEND).pure(),
CommandSpec::new("caret.paraDown", "Paragraph Down", "Navigation", |s, v| mv(s, v, para_down))
.key("Mod+Down / Alt+Down")
+5
View File
@@ -122,6 +122,11 @@ fn word_default_shortcuts_resolve() {
assert_eq!(id(cmd::mac_or("Ctrl+Q", "Mod+Q")), Some("para.reset"));
assert_eq!(id(cmd::mac_or("Ctrl+Space", "Mod+Space")), Some("format.resetChar"));
assert_eq!(id(cmd::mac_or("Ctrl+Shift+D", "Alt+Shift+D")), Some("insert.dateField"));
// Option+arrows move by word everywhere; ⌘←/⌘→ go to the line's ends on macOS (#954).
assert_eq!(id("Alt+Left"), Some("caret.wordLeft"));
assert_eq!(id("Alt+Right"), Some("caret.wordRight"));
assert_eq!(id("Mod+Left"), Some(cmd::mac_or("caret.home", "caret.wordLeft")));
assert_eq!(id("Mod+Right"), Some(cmd::mac_or("caret.end", "caret.wordRight")));
assert_eq!(id("Shift+F1"), Some("styles.inspector"));
assert_eq!(id("Alt+F8"), Some("tools.macros"));
assert_eq!(id("Mod+Shift+X"), Some("format.strikethrough"));
+2
View File
@@ -74,6 +74,7 @@ Windows/Linux keys are given first, macOS second.
| Alt+Shift+Left / Right (⌃⇧← / ⌃⇧→) | Promote / Demote: a heading goes up or down one level (Heading 1 and Heading 9 are the ends); promoted body text becomes a heading at the level of the heading before it; a list item changes level like Shift+Tab / Tab | `alt_shift_left_and_right_promote_and_demote_headings_and_list_items` |
| Outline view: Alt+Shift+Up / Down, Left / Right | as above, but a collapsed heading takes what is hidden under it along: moving passes whole shown paragraphs with their hidden content; promote/demote shifts the hidden subheadings too | `outline_collapse_hides_descendants_and_expand_restores` |
| Outline view: Alt+Shift+Plus / Minus, Alt+Shift+1–9, Alt+Shift+A | Expand / Collapse the heading (one level at a time); Show Level 1–9; show all levels. The caret never stays in hidden text: it moves on to the next shown paragraph | `outline_show_level_filters_paragraphs` |
| Ctrl+Left / Right (⌥← / ⌥→); Home / End (⌘← / ⌘→) | one word left / right; the start / end of the line. On macOS ⌘← / ⌘→ go to the line's ends, as in every Mac text field, and ⌥ moves by word (#954); Shift extends the selection | `word_default_shortcuts_resolve` |
| Shift+F5 | Go Back: the caret cycles through the last four places edited, most recent first | `shift_f5_goes_back_through_the_last_edits` |
| Alt+X (no macOS default) | the hex code before the caret (up to six digits, `U+` optional) or the selected code becomes its character; otherwise the character before the caret becomes its code (`é` ↔ `00E9`); one undo step | `alt_x_toggles_between_a_character_and_its_code` |
| Shift+Backspace / Shift+Delete | Shift+Backspace erases like Backspace (#707). Shift+Delete cuts the selection to the clipboard and does nothing without one (Word for Windows, observed 2026-10-14). Windows delivers Shift+Delete as a Cut; macOS and Linux deliver the key, which did nothing (#1669) | `shift_delete_cuts_the_selection_and_shift_backspace_erases` |
@@ -205,6 +206,7 @@ Word.
| 2026-10-14 | trivial | Track Changes: empty tables are removed under tracking; Delete Columns leaves merged cells that keep a column; repeated Change Case reads only live text (#1329 review) |
| 2026-10-14 | trivial | Track Changes: table deletes mark the cells' text deleted and keep the table; Change Case is a tracked delete+insert (differs from Word's hidden formatting revision); Unlink Fields stays untracked; all three refuse locked content controls (#1329) |
| 2026-10-12 | trivial | Track Changes: Accept All after a tracked delete from a paragraph end keeps the next paragraph; Reject All after typing into an empty paragraph keeps it (#864) |
| 2026-10-12 | trivial | macOS: ⌘← / ⌘→ go to the line's start and end instead of moving by word (#954) |
| 2026-10-12 | minor | AutoCorrect: Correct TWo INitial CApitals, accidental cAPS LOCK, capitalize first letter of table cells (#544) |
| 2026-10-12 | trivial | Editing keys: Shift+Right at the end of a cell's text selects the cell first, then the next cell with it (#971) |
| 2026-10-11 | minor | Text direction: right-to-left letters typed into an empty paragraph make it right-to-left; existing paragraphs keep theirs (#713) |