refactor(docmodel): share strict block motion scan
- commit
- 830f50b8082c6de1176ffa914de35bc1c76fb71d
- author
- brice · · 2026-08-14 07:01 UTC
- parent
- d596066
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
1 file · +10 -24
M internal/domain/docmodel/motions.go +10 -24
| @@ -31,29 +31,9 @@ func (d Document) PreviousBlockOfKind(from Cursor, kind BlockKind, count int) (C | |||
| 31 | 31 | } | |
| 32 | 32 | ||
| 33 | 33 | func (d Document) headingMotion(from Cursor, count, direction int, levels []int) (Cursor, bool) { | |
| 34 | - | start, ok := d.indexByID[from.BlockID] | |
| 35 | - | if !ok { | |
| 36 | - | return Cursor{}, false | |
| 37 | - | } | |
| 38 | - | ||
| 39 | - | if count <= 0 { | |
| 40 | - | count = 1 | |
| 41 | - | } | |
| 42 | - | ||
| 43 | - | remaining := count | |
| 44 | - | for i := start + direction; i >= 0 && i < len(d.blocks); i += direction { | |
| 45 | - | block := d.blocks[i] | |
| 46 | - | if !block.IsHeading() || !headingLevelMatches(block.HeadingLevel, levels) { | |
| 47 | - | continue | |
| 48 | - | } | |
| 49 | - | ||
| 50 | - | remaining-- | |
| 51 | - | if remaining == 0 { | |
| 52 | - | return Cursor{BlockID: block.ID}, true | |
| 53 | - | } | |
| 54 | - | } | |
| 55 | - | ||
| 56 | - | return Cursor{}, false | |
| 34 | + | return d.matchingBlockMotion(from, count, direction, func(block Block) bool { | |
| 35 | + | return block.IsHeading() && headingLevelMatches(block.HeadingLevel, levels) | |
| 36 | + | }) | |
| 57 | 37 | } | |
| 58 | 38 | ||
| 59 | 39 | func (d Document) blockKindMotion(from Cursor, kind BlockKind, count, direction int) (Cursor, bool) { | |
| @@ -61,6 +41,12 @@ func (d Document) blockKindMotion(from Cursor, kind BlockKind, count, direction | |||
| 61 | 41 | return Cursor{}, false | |
| 62 | 42 | } | |
| 63 | 43 | ||
| 44 | + | return d.matchingBlockMotion(from, count, direction, func(block Block) bool { | |
| 45 | + | return block.Kind == kind | |
| 46 | + | }) | |
| 47 | + | } | |
| 48 | + | ||
| 49 | + | func (d Document) matchingBlockMotion(from Cursor, count, direction int, matches func(Block) bool) (Cursor, bool) { | |
| 64 | 50 | start, ok := d.indexByID[from.BlockID] | |
| 65 | 51 | if !ok { | |
| 66 | 52 | return Cursor{}, false | |
| @@ -73,7 +59,7 @@ func (d Document) blockKindMotion(from Cursor, kind BlockKind, count, direction | |||
| 73 | 59 | remaining := count | |
| 74 | 60 | for i := start + direction; i >= 0 && i < len(d.blocks); i += direction { | |
| 75 | 61 | block := d.blocks[i] | |
| 76 | - | if block.Kind != kind { | |
| 62 | + | if !matches(block) { | |
| 77 | 63 | continue | |
| 78 | 64 | } | |
| 79 | 65 | ||
| @@ -31,29 +31,9 @@ func (d Document) PreviousBlockOfKind(from Cursor, kind BlockKind, count int) (C | |||||
| 31 | } | 31 | } | ||
| 32 | 32 | ||||
| 33 | func (d Document) headingMotion(from Cursor, count, direction int, levels []int) (Cursor, bool) { | 33 | func (d Document) headingMotion(from Cursor, count, direction int, levels []int) (Cursor, bool) { | ||
| 34 | - | start, ok := d.indexByID[from.BlockID] | 34 | + | return d.matchingBlockMotion(from, count, direction, func(block Block) bool { |
| 35 | - | if !ok { | 35 | + | return block.IsHeading() && headingLevelMatches(block.HeadingLevel, levels) |
| 36 | - | return Cursor{}, false | 36 | + | }) |
| 37 | - | } | |||
| 38 | - | ||||
| 39 | - | if count <= 0 { | |||
| 40 | - | count = 1 | |||
| 41 | - | } | |||
| 42 | - | ||||
| 43 | - | remaining := count | |||
| 44 | - | for i := start + direction; i >= 0 && i < len(d.blocks); i += direction { | |||
| 45 | - | block := d.blocks[i] | |||
| 46 | - | if !block.IsHeading() || !headingLevelMatches(block.HeadingLevel, levels) { | |||
| 47 | - | continue | |||
| 48 | - | } | |||
| 49 | - | ||||
| 50 | - | remaining-- | |||
| 51 | - | if remaining == 0 { | |||
| 52 | - | return Cursor{BlockID: block.ID}, true | |||
| 53 | - | } | |||
| 54 | - | } | |||
| 55 | - | ||||
| 56 | - | return Cursor{}, false | |||
| 57 | } | 37 | } | ||
| 58 | 38 | ||||
| 59 | func (d Document) blockKindMotion(from Cursor, kind BlockKind, count, direction int) (Cursor, bool) { | 39 | func (d Document) blockKindMotion(from Cursor, kind BlockKind, count, direction int) (Cursor, bool) { | ||
| @@ -61,6 +41,12 @@ func (d Document) blockKindMotion(from Cursor, kind BlockKind, count, direction | |||||
| 61 | return Cursor{}, false | 41 | return Cursor{}, false | ||
| 62 | } | 42 | } | ||
| 63 | 43 | ||||
| 44 | + | return d.matchingBlockMotion(from, count, direction, func(block Block) bool { | |||
| 45 | + | return block.Kind == kind | |||
| 46 | + | }) | |||
| 47 | + | } | |||
| 48 | + | ||||
| 49 | + | func (d Document) matchingBlockMotion(from Cursor, count, direction int, matches func(Block) bool) (Cursor, bool) { | |||
| 64 | start, ok := d.indexByID[from.BlockID] | 50 | start, ok := d.indexByID[from.BlockID] | ||
| 65 | if !ok { | 51 | if !ok { | ||
| 66 | return Cursor{}, false | 52 | return Cursor{}, false | ||
| @@ -73,7 +59,7 @@ func (d Document) blockKindMotion(from Cursor, kind BlockKind, count, direction | |||||
| 73 | remaining := count | 59 | remaining := count | ||
| 74 | for i := start + direction; i >= 0 && i < len(d.blocks); i += direction { | 60 | for i := start + direction; i >= 0 && i < len(d.blocks); i += direction { | ||
| 75 | block := d.blocks[i] | 61 | block := d.blocks[i] | ||
| 76 | - | if block.Kind != kind { | 62 | + | if !matches(block) { |
| 77 | continue | 63 | continue | ||
| 78 | } | 64 | } | ||
| 79 | 65 | ||||