Как сделать, чтобы область заполнения / абзац идентифицировала префикс абзаца?

11

Допустим, у меня есть следующий буфер.

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

Попадание M-qсюда во время text-modeприводит к следующему.

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

С другой стороны, если я активирую markdown-mode, я получаю следующее (Markdown - просто пример, вы видите похожее поведение в различных режимах).

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

Как мне настроить текстовый режим для этого?

Я полагаю, что это может быть достигнуто путем написания специального fill-paragraph-function, но эта переменная просто установлена nilв markdown-mode, так что, вероятно, есть более простой способ.

Malabarba
источник

Ответы:

6

Я долгое время был счастливым пользователем filladapt-mode, который прекрасно справляется с подобными вещами. Для получения информации см.

http://emacswiki.org/emacs/FillAdapt

С этой страницы:

Filladapt от KyleJones расширяет функции заполнения Emacs, угадывая префикс заполнения, такой как последовательность комментариев в программном коде, и обрабатывая точки с маркерами, такие как «1.» или же "*".

Например, это может превратить это

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

в

* Pretend I'm a really super
  long line.
* And the window's narrow.
Крис
источник
Хорошо, отредактировано для решения этой проблемы.
Крис
чтобы включить этот режим в сочетании с другим режимом, добавьте что-то вроде (add-hook 'org-mode-hook 'turn-on-filladapt-mode)своего конфигурационного файла (эта информация не доступна напрямую на связанной странице вики).
Марк
Прекрасно работает, чтобы заставить fill-paragraphсебя вести себя в кавычках в markdown-mode.
Радон Росборо
2 года прошло с момента ответа. Ссылка для скачивания wonderworks.com/download/filladapt.el больше не доступна.
Танкист 六四
Ссылка у меня работает прямо сейчас. Возможно была временная проблема с сайтом.
Крис
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-modeпредположительно устанавливает fill-paragraph-functionдля nilтого , чтобы функция использует , fill-prefixчтобы сделать начинку.

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

Полный пример:

(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 "
Шон Оллред
источник
1
msgstr "markdown-mode, по-видимому, устанавливает для fill-para-function значение nil, чтобы функция использовала fill-prefix для выполнения заполнения." Это не может быть целой историей. Когда я нажимаю M-q, fill-paragraphвызывается напрямую (вокруг него нет привязки). Хотя возможно, что fill-prefixв конечном итоге используется для этой цели, должна быть некоторая переменная конфигурации, которая позволяет автоматически обнаруживать ее.
Малабарба
1
@Malabarba Похоже, что на markdown-modeсамом деле это делается с помощью определений абзацев: gist.github.com/vermiculus/88759fd9f8368adbf663
Шон Оллред
Да, это больше похоже на это.
Малабарба
2

Суть Шона указала мне правильное направление, и вот фрагмент, который решил это.

(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
источник