Jak sprawić, by region / akapit wypełnienia identyfikował prefiks akapitu?

11

Powiedzmy, że mam następujący bufor.

1. lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum

Trafienie M-qtutaj w trakcie text-modeprowadzi do następujących rzeczy.

1. lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem
ipsum lorem ipsum lorem ipsum lorem ipsum

Z drugiej strony, jeśli aktywuję markdown-mode, otrzymam następujące (Markdown to tylko przykład, widzisz podobne zachowanie w różnych trybach).

1. lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem
   ipsum lorem ipsum lorem ipsum lorem ipsum

Jak skonfigurować tryb tekstowy, aby to zrobić?

Wyobrażam sobie ten można osiągnąć poprzez pisanie specjalnego fill-paragraph-function, ale ta zmienna jest po prostu ustawiona na nilIN markdown-mode, więc nie ma chyba łatwiejszy sposób.

Malabarba
źródło

Odpowiedzi:

6

Od dawna jestem szczęśliwym użytkownikiem trybu filladapt, który bardzo ładnie sobie z tym radzi. Aby uzyskać informacje, zobacz

http://emacswiki.org/emacs/FillAdapt

Z tej strony:

Filladapt autorstwa KyleJones poprawia funkcje wypełniania Emacsa poprzez odgadywanie prefiksu wypełnienia, takiego jak sekwencja komentarzy w kodzie programu i obsługa punktów wypunktowanych, takich jak „1”. lub „*”.

Na przykład może to zmienić

* Pretend I'm a really super long line.
* And the window's narrow.

w

* Pretend I'm a really super
  long line.
* And the window's narrow.
Chris
źródło
Ok, edytowane, aby rozwiązać ten problem.
Chris
aby włączyć ten tryb w połączeniu z innym trybem, dodaj coś (add-hook 'org-mode-hook 'turn-on-filladapt-mode)do swojego pliku konfiguracyjnego (te informacje nie są dostępne bezpośrednio na połączonej stronie wiki).
Mark
Działa pięknie, aby fill-paragraphpoprawnie zachowywać się w cudzysłowach w markdown-mode.
Radon Rosborough
Od odpowiedzi minęły 2 lata. Link do pobrania wonderworks.com/download/filladapt.el nie jest już dostępny.
Tankman
Link działa teraz dla mnie. Być może wystąpił tymczasowy problem z witryną.
Chris
3
(fill-paragraph &optional JUSTIFY REGION)

[...]

If `fill-paragraph-function' is non-nil, we call it (passing our
argument to it), and if it returns non-nil, we simply return its value.

If `fill-paragraph-function' is nil, return the `fill-prefix' used for filling.

[...]

markdown-modeprzypuszczalnie ustawia fill-paragraph-functionsię niltak, aby funkcja użyła fill-prefixdo wypełnienia.

(let ((fill-prefix (make-string (length "1. ") ? ))
  (fill-paragraph))

Pełny przykład:

(let* ((num 15)
       (numstr (format "%d. " num))
       (fill-prefix (make-string (length numstr) ? )))
  (with-temp-buffer
    (loop for i from 1 to 15 do
          (insert (format "lorem ipsum (%d) doler sit amet " i)))
    (beginning-of-line)
    (insert numstr)
    (fill-paragraph)
    (buffer-string)))

;; =>

"\
15. lorem ipsum (1) doler sit amet lorem ipsum (2) doler sit amet
    lorem ipsum (3) doler sit amet lorem ipsum (4) doler sit amet
    lorem ipsum (5) doler sit amet lorem ipsum (6) doler sit amet
    lorem ipsum (7) doler sit amet lorem ipsum (8) doler sit amet
    lorem ipsum (9) doler sit amet lorem ipsum (10) doler sit amet
    lorem ipsum (11) doler sit amet lorem ipsum (12) doler sit amet
    lorem ipsum (13) doler sit amet lorem ipsum (14) doler sit amet
    lorem ipsum (15) doler sit amet "
Sean Allred
źródło
1
„tryb markdown przypuszczalnie ustawia funkcję wypełniania akapitu na zero, tak że funkcja używa przedrostka wypełnienia do wypełniania”. To nie może być cała historia. Kiedy uderzę M-q, fill-paragraphjest wywoływany bezpośrednio (nie ma wokół niego let-bind). Chociaż możliwe fill-prefixjest, że zostanie ostatecznie wykorzystane do tego celu, musi istnieć jakaś zmienna konfiguracyjna, która pozwala na automatyczne wykrycie.
Malabarba
1
@Malabarba Wygląda na to, że markdown-modefaktycznie robi to za pomocą definicji akapitów: gist.github.com/vermiculus/88759fd9f8368adbf663
Sean Allred
Tak, to wygląda bardziej jak to.
Malabarba
2

Istota Seana wskazała mi właściwy kierunek, a oto fragment, który ją rozwiązał.

(defun my-adaptive-fill-function ()
  "Return prefix for filling paragraph or nil if not determined."
  (cond
   ;; List item inside blockquote
   ((looking-at "^[ \t]*>[ \t]*\\([0-9]+\\.\\|[*+-]\\)[ \t]+")
    (replace-regexp-in-string
     "[0-9\\.*+-]" " " (match-string-no-properties 0)))
   ;; Blockquote
   ((looking-at "^[ \t]*>[ \t]*")
    (match-string-no-properties 0))
   ;; List items
   ((looking-at "^\\([ \t]*\\)\\([0-9]+\\.\\|[\\*\\+-]\\)\\([ \t]+\\)")
    (match-string-no-properties 0))
   ;; No match
   (t nil)))

;; Paragraph filling in text-mode.
(add-hook 'text-mode-hook
  (lambda ()
    (set (make-local-variable 'paragraph-start)
         "\f\\|[ \t]*$\\|[ \t]*[*+-] \\|[ \t]*[0-9]+\\.[ \t]\\|[ \t]*: ")
    (set (make-local-variable 'paragraph-separate)
         "\\(?:[ \t\f]*\\|.*  \\)$")
    (set (make-local-variable 'adaptive-fill-first-line-regexp)
         "\\`[ \t]*>[ \t]*?\\'")
    (set (make-local-variable 'adaptive-fill-function)
         'my-adaptive-fill-function)))
Malabarba
źródło