LINUX.ORG.RU

fill-paragraph в emacs 26.3 удаляет нужные пробелы

 


0

1

Емаксеры, как пофиксить такое поведение. Допустим, есть строка

Здесь очень много текста. Отдельных слов и сокращ. которые нужны в тексте и т. д., а емакс их съедает.

Ошибка намеренно допущена для примера. После применения fill-paragraph в зависимости от установленной переменной fill-column форматирует строку по разному, но удалит пробелы т. д., текста. Отдельных, сокращ. которые, т. е. пробелы после различных знаков пунктуации, при этом в auto-fill-mode такого поведения не наблюдаю, но только им пользоватся, увы, не получается. Иногда нужно поправить ошибки и подкорректировать предложение. Тогда приходится вручную применять fill-paragraph, что приводит к указанным последствиям. В описании функции никаких хаков для изменения поведения не увидел. Есть способы избежать удаления нужных пробелов?

Для проверки сказал Alt+x fill-paragraph на предложенной строке и никаких лишних пробелов удалено не было (хотя т.д. лучше писать без пробела или ставить очень маленький пробел).

Evgueni ★★★★★ ()
Ответ на: комментарий от Evgueni

хотя т.д. лучше писать без пробела или ставить очень маленький пробел

Я составляю заметки в org-mode, там или пробел, или ничего.

Взял абзац

Для проверки сказал Alt+x fill-paragraph на предложенной строке. Никаких лишних пробелов удалено не было. Сокращения т. д. лучше писать без пробела или ставить очень маленький пробел.

После fill-paragraph он превратился в

Для проверки сказал Alt+x fill-paragraph на предложенной строке.Никаких лишних пробелов удалено не было.Сокращения т.д.лучше писать без пробела или ставить очень маленький пробел.

GNU Emacs 26.3.

sunnandt ()
Ответ на: комментарий от sunnandt

Сделал тоже самое при включённом org-mode. Результат остался прежним.

GNU Emacs 24.5.1

Возможно регрессия.

Evgueni ★★★★★ ()
Последнее исправление: Evgueni (всего исправлений: 1)
Ответ на: комментарий от Evgueni

Попробовал на всякий случай с чистым профилем без дополнений и моего конфига - результат тот же. Поищу в релиз нотсах, вдруг что-то меняли в функции. Можешь код функции сюда разместить? Хочу сравнить с тем, что в моей поставке.

sunnandt ()
Ответ на: комментарий от Evgueni
(defun fill-paragraph (&optional justify region)
  "Fill paragraph at or after point.

If JUSTIFY is non-nil (interactively, with prefix argument), justify as well.
If `sentence-end-double-space' is non-nil, then period followed by one
space does not end a sentence, so don't break a line there.
The variable `fill-column' controls the width for filling.

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.

The REGION argument is non-nil if called interactively; in that
case, if Transient Mark mode is enabled and the mark is active,
call `fill-region' to fill each of the paragraphs in the active
region, instead of just filling the current paragraph."
  (interactive (progn
		 (barf-if-buffer-read-only)
		 (list (if current-prefix-arg 'full) t)))
  (or
   ;; 1. Fill the region if it is active when called interactively.
   (and region transient-mark-mode mark-active
	(not (eq (region-beginning) (region-end)))
	(or (fill-region (region-beginning) (region-end) justify) t))
   ;; 2. Try fill-paragraph-function.
   (and (not (eq fill-paragraph-function t))
        (or fill-paragraph-function
            (and (minibufferp (current-buffer))
                 (= 1 (point-min))))
        (let ((function (or fill-paragraph-function
                            ;; In the minibuffer, don't count the width
                            ;; of the prompt.
                            'fill-minibuffer-function))
              ;; If fill-paragraph-function is set, it probably takes care
              ;; of comments and stuff.  If not, it will have to set
              ;; fill-paragraph-handle-comment back to t explicitly or
              ;; return nil.
              (fill-paragraph-handle-comment nil)
              (fill-paragraph-function t))
          (funcall function justify)))
   ;; 3. Try our syntax-aware filling code.
   (and fill-paragraph-handle-comment
        ;; Our code only handles \n-terminated comments right now.
        comment-start (equal comment-end "")
        (let ((fill-paragraph-handle-comment nil))
          (fill-comment-paragraph justify)))
   ;; 4. If it all fails, default to the good ol' text paragraph filling.
   (let ((before (point))
         (paragraph-start paragraph-start)
         ;; Fill prefix used for filling the paragraph.
         fill-pfx)
     ;; Try to prevent code sections and comment sections from being
     ;; filled together.
     (when (and fill-paragraph-handle-comment comment-start-skip)
       (setq paragraph-start
             (concat paragraph-start "\\|[ \t]*\\(?:"
                     comment-start-skip "\\)")))
     (save-excursion
       ;; To make sure the return value of forward-paragraph is meaningful,
       ;; we have to start from the beginning of line, otherwise skipping
       ;; past the last few chars of a paragraph-separator would count as
       ;; a paragraph (and not skipping any chars at EOB would not count
       ;; as a paragraph even if it is).
       (move-to-left-margin)
       (if (not (zerop (fill-forward-paragraph 1)))
           ;; There's no paragraph at or after point: give up.
           (setq fill-pfx "")
         (let ((end (point))
               (beg (progn (fill-forward-paragraph -1) (point))))
           (goto-char before)
           (setq fill-pfx
                 (if use-hard-newlines
                     ;; Can't use fill-region-as-paragraph, since this
                     ;; paragraph may still contain hard newlines.  See
                     ;; fill-region.
                     (fill-region beg end justify)
                   (fill-region-as-paragraph beg end justify))))))
     fill-pfx)))
Evgueni ★★★★★ ()
Ответ на: комментарий от Evgueni

Спасибо. Странно, но я не могу найти в локальных файлах вхождения fill-paragraph

find /usr/share/emacs ~/.emacs.d -type f -exec grep 'defun fill-paragraph` '{}' \; | wc -l
0

find /usr/share/emacs ~/.emacs.d -type f -exec grep 'fill-paragraph` '{}' \; | wc -l
0
sunnandt ()
Ответ на: комментарий от sunnandt

Нашел в портативной версии

(defun fill-paragraph (&optional justify region)
  "Fill paragraph at or after point.

If JUSTIFY is non-nil (interactively, with prefix argument), justify as well.
If `sentence-end-double-space' is non-nil, then period followed by one
space does not end a sentence, so don't break a line there.
The variable `fill-column' controls the width for filling.

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.

The REGION argument is non-nil if called interactively; in that
case, if Transient Mark mode is enabled and the mark is active,
call `fill-region' to fill each of the paragraphs in the active
region, instead of just filling the current paragraph."
  (interactive (progn
		 (barf-if-buffer-read-only)
		 (list (if current-prefix-arg 'full) t)))
  (let ((hash (and (not (buffer-modified-p))
                   (buffer-hash))))
    (prog1
        (or
         ;; 1. Fill the region if it is active when called interactively.
         (and region transient-mark-mode mark-active
              (not (eq (region-beginning) (region-end)))
              (or (fill-region (region-beginning) (region-end) justify) t))
         ;; 2. Try fill-paragraph-function.
         (and (not (eq fill-paragraph-function t))
              (or fill-paragraph-function
                  (and (minibufferp (current-buffer))
                       (= 1 (point-min))))
              (let ((function (or fill-paragraph-function
                                  ;; In the minibuffer, don't count
                                  ;; the width of the prompt.
                                  'fill-minibuffer-function))
                    ;; If fill-paragraph-function is set, it probably
                    ;; takes care of comments and stuff.  If not, it
                    ;; will have to set fill-paragraph-handle-comment
                    ;; back to t explicitly or return nil.
                    (fill-paragraph-handle-comment nil)
                    (fill-paragraph-function t))
                (funcall function justify)))
         ;; 3. Try our syntax-aware filling code.
         (and fill-paragraph-handle-comment
              ;; Our code only handles \n-terminated comments right now.
              comment-start (equal comment-end "")
              (let ((fill-paragraph-handle-comment nil))
                (fill-comment-paragraph justify)))
         ;; 4. If it all fails, default to the good ol' text paragraph filling.
         (let ((before (point))
               (paragraph-start paragraph-start)
               ;; Fill prefix used for filling the paragraph.
               fill-pfx)
           ;; Try to prevent code sections and comment sections from being
           ;; filled together.
           (when (and fill-paragraph-handle-comment comment-start-skip)
             (setq paragraph-start
                   (concat paragraph-start "\\|[ \t]*\\(?:"
                           comment-start-skip "\\)")))
           (save-excursion
             ;; To make sure the return value of forward-paragraph is
             ;; meaningful, we have to start from the beginning of
             ;; line, otherwise skipping past the last few chars of a
             ;; paragraph-separator would count as a paragraph (and
             ;; not skipping any chars at EOB would not count as a
             ;; paragraph even if it is).
             (move-to-left-margin)
             (if (not (zerop (fill-forward-paragraph 1)))
                 ;; There's no paragraph at or after point: give up.
                 (setq fill-pfx "")
               (let ((end (point))
                     (beg (progn (fill-forward-paragraph -1) (point))))
                 (goto-char before)
                 (setq fill-pfx
                       (if use-hard-newlines
                           ;; Can't use fill-region-as-paragraph, since this
                           ;; paragraph may still contain hard newlines.  See
                           ;; fill-region.
                           (fill-region beg end justify)
                         (fill-region-as-paragraph beg end justify))))))
           fill-pfx))
      ;; If we didn't change anything in the buffer (and the buffer
      ;; was previously unmodified), then flip the modification status
      ;; back to "unchanged".
      (when (and hash
                 (equal hash (buffer-hash)))
        (set-buffer-modified-p nil)))))
sunnandt ()
Ответ на: комментарий от Evgueni

Я тоже искал так, но у меня почему-то в справке нет ссылки на файл с исходником.

Создал кастомную функцию из твоего кода и попробовал применить на том же параграфе. Результат не изменился, нужные пробелы удаляет.

sunnandt ()

Проверил в версии 26.1. Код функции такой же, как в 26.3. Проблема присутствует.

sunnandt ()
Ответ на: комментарий от Evgueni

+1. Аналогично ни единого съеденного пробела. GNU/Emacs 26.2

ugoday ★★★★★ ()

Ничего не съедает.

GNU Emacs 26.3 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.24.11) of 2019-09-23, modified by Debian

Может, какой-нибудь minor mode хулиганит?

Nervous ★★★★ ()
Последнее исправление: Nervous (всего исправлений: 1)
Ответ на: комментарий от Nervous

Я пробовал на чистом профиле в простом файле в режиме fundamental без дополнительных конфигураций. Там все так же. Возможно, проблема в каких-то патчах от мейнтенера arch’a или в моих кривых руках. Буду разбираться.

sunnandt ()
Ограничение на отправку комментариев: только для зарегистрированных пользователей