Commit f71bf44f5c
Verified · cmc
Layout: unified · split
Sources/OrgCore/Commands/Fill.swift +17 −13
| @@ -302,8 +302,9 @@ extension EmacsBuffer { | ||
| 302 | 302 | } |
| 303 | 303 | } |
| 304 | 304 | |
| 305 | /// `fill-region-as-paragraph` with left justification and adaptive fill. | |
| 306 | func fillRegionAsParagraph(_ fromOffset: Int, _ toOffset: Int, prefix fixedPrefix: String? = nil) { | |
| 305 | /// `fill-region-as-paragraph` with left justification and adaptive fill. With `nosqueeze`, | |
| 306 | /// spaces between words and at the end stay. | |
| 307 | func fillRegionAsParagraph(_ fromOffset: Int, _ toOffset: Int, prefix fixedPrefix: String? = nil, nosqueeze: Bool = false) { | |
| 307 | 308 | point = min(fromOffset, toOffset) |
| 308 | 309 | let to = max(fromOffset, toOffset) |
| 309 | 310 | skipForward(Self.whitespace) |
| @@ -349,13 +350,15 @@ extension EmacsBuffer { | ||
| 349 | 350 | if character(at: at) == 10 { replace(at..<(at + 1), with: " ") } |
| 350 | 351 | at += 1 |
| 351 | 352 | } |
| 352 | point = from | |
| 353 | skipForward(Self.blanks) | |
| 354 | canonicallySpace(point, toMarker.position) | |
| 355 | point = toMarker.position | |
| 356 | let end = point | |
| 357 | skipBackward(Self.blanks) | |
| 358 | if point < end { deleteRegion(point, end) } | |
| 353 | if !nosqueeze { | |
| 354 | point = from | |
| 355 | skipForward(Self.blanks) | |
| 356 | canonicallySpace(point, toMarker.position) | |
| 357 | point = toMarker.position | |
| 358 | let end = point | |
| 359 | skipBackward(Self.blanks) | |
| 360 | if point < end { deleteRegion(point, end) } | |
| 361 | } | |
| 359 | 362 | point = from |
| 360 | 363 | while point < toMarker.position { |
| 361 | 364 | let lineBegin = point |
| @@ -469,7 +472,7 @@ extension EmacsBuffer { | ||
| 469 | 472 | |
| 470 | 473 | /// `fill-region` over whole lines: each paragraph's part of `from..<to` filled as a |
| 471 | 474 | /// paragraph. Other elements stay. |
| 472 | func fillRegion(_ from: Int, _ to: Int) { | |
| 475 | func fillRegion(_ from: Int, _ to: Int, nosqueeze: Bool = false) { | |
| 473 | 476 | var spans: [Range<Int>] = [] |
| 474 | 477 | var line = lineStart(from) |
| 475 | 478 | while line < to, line < length { |
| @@ -486,7 +489,7 @@ extension EmacsBuffer { | ||
| 486 | 489 | line = next |
| 487 | 490 | } |
| 488 | 491 | // Back to front, so the spans before stay where they are. |
| 489 | for span in spans.reversed() { fillRegionAsParagraph(span.lowerBound, span.upperBound) } | |
| 492 | for span in spans.reversed() { fillRegionAsParagraph(span.lowerBound, span.upperBound, nosqueeze: nosqueeze) } | |
| 490 | 493 | } |
| 491 | 494 | |
| 492 | 495 | /// Where a paragraph's text starts: past affiliated keywords, and for a paragraph that |
| @@ -507,7 +510,8 @@ public struct FillParagraph: OrgCommand { | ||
| 507 | 510 | |
| 508 | 511 | /// evil's `gq` and `gw` operators: the paragraphs in `range`'s lines filled, as `fill-region`. |
| 509 | 512 | /// With `keep` (`gw`) the caret stays there; without (`gq`) it goes to the first non-blank |
| 510 | /// of the range's last line. | |
| 513 | /// of the range's last line. Spaces are not squeezed, as Doom's `+evil--no-squeeze-on-fill-a` | |
| 514 | /// has it. | |
| 511 | 515 | public struct FillRegion: OrgCommand { |
| 512 | 516 | public let range: Range<Int> |
| 513 | 517 | public let keep: Int? |
| @@ -524,7 +528,7 @@ public struct FillRegion: OrgCommand { | ||
| 524 | 528 | commitBuffer(context) { buffer in |
| 525 | 529 | let target = buffer.marker(keep ?? max(range.lowerBound, range.upperBound - 1)) |
| 526 | 530 | defer { buffer.release(target) } |
| 527 | buffer.fillRegion(range.lowerBound, range.upperBound) | |
| 531 | buffer.fillRegion(range.lowerBound, range.upperBound, nosqueeze: true) | |
| 528 | 532 | buffer.point = target.position |
| 529 | 533 | if keep == nil { |
| 530 | 534 | buffer.beginningOfLine() |
Tests/OrgCoreTests/VimExtrasTests.swift +8
| @@ -165,6 +165,8 @@ struct VimExtrasTests { | ||
| 165 | 165 | ("a\nb\nc\nd\n", 2, "g q j"), |
| 166 | 166 | ("a\nb\nc\n", 0, "V j g q"), |
| 167 | 167 | ("a\nb\n\nc\nd\n", 0, "g q j j ."), |
| 168 | ("one two three\nfour five \nsix\n", 0, "g q G"), | |
| 169 | ("End. Next word, " + long + " \nmore\n", 3, "g w j"), | |
| 168 | 170 | ] |
| 169 | 171 | }() |
| 170 | 172 | |
| @@ -201,6 +203,12 @@ struct VimExtrasTests { | ||
| 201 | 203 | (dolist (d '("evil" "goto-chg" "evil-surround" "evil-org-mode")) (add-to-list 'load-path (concat \(lispString(repos.path)) "/" d))) |
| 202 | 204 | (require 'evil) |
| 203 | 205 | (require 'evil-surround) |
| 206 | (defun oracle-no-squeeze (fn &rest args) | |
| 207 | (cl-letf* ((fill (symbol-function 'fill-region)) | |
| 208 | ((symbol-function 'fill-region) (lambda (from to &optional justify _nosqueeze to-eop) (funcall fill from to justify t to-eop)))) | |
| 209 | (apply fn args))) | |
| 210 | (advice-add 'evil-fill :around #'oracle-no-squeeze) | |
| 211 | (advice-add 'evil-fill-and-move :around #'oracle-no-squeeze) | |
| 204 | 212 | (setq kill-ring nil) |
| 205 | 213 | (switch-to-buffer (current-buffer)) |
| 206 | 214 | \(org ? "(org-mode) (require 'evil-org) (evil-org-set-key-theme '(textobjects navigation)) (evil-org-mode 1)" : "") |