Как предотвратить попадание лиц на окружающие участки буфера?

20

В: Как я могу предотвратить org-modeперетекание граней ссылок в ...символы выборочного отображения в конце сложенного заголовка?

Это визуальный тик, который сводит меня с ума. Когда org-modeссылка является самой последней вещью в строке, лицевая сторона ссылки перетекает в то, ...что указывает на то, что заголовок свернут. Если, скажем, после ссылки есть пробел, кровотечения нет.

Скриншот, который я разместил, демонстрирует проблему. Третья строка - проблемная строка без символов между концом ссылки и концом строки, а четвертая строка показывает ссылку, за которой следует пробел:

странное поведение лица ссылки

Прежде всего, почему это происходит? Во-вторых, и, что более важно, как мне остановить это?

ОБНОВЛЕНИЕ 1: Согласно комментариям, ниже выложены скриншоты буфера с закрытыми и открытыми заголовками. Я открыл Emacs без файла инициализации (то есть emacs -Q), required org-mode и открыл этот файл примера. Итак: это не кажется чем-то странным в моей настройке.

Все заголовки закрыты: странная ссылка закрыта

Все заголовки открыты: странная ссылка открыта

Темой, которую я использовал выше, является чернильница, хотя у меня возникает та же проблема при использовании соляризованной темы, а также темы по умолчанию (как на новых скриншотах).

Версия Emacs - 24.3.1. Я получаю те же результаты, когда использую версию org 7.9.3f (то есть ту, что связана с этой версией Emacs), а также 8.3beta.

ОБНОВЛЕНИЕ 2: вот минимальный рабочий пример в ответ на запрос комментария:

* here's a header with a [[~/somefile.txt][link at the end]]

  - This one's a problem
  - Interesting note:
    + put the cursor immediately *after* the *d* in "end" with the
      header closed/folded
      * the face no longer bleeds over into the dots
    + move the cursor anywhere else
      * the face bleeds over into the dots again

* here's another [[~/someotherfile.txt][go at it]]
  DEADLINE: <2014-10-26 Sun>

  - This one's also a problem

* here's another header with a [[~/anotherfile.txt][link followed by a space]] 

  - No bleed-over onto the dots with this one
Дэн
источник
1
Мне трудно воспроизвести его на Emacs 24.3.1 и в режиме org, который идет с ним. Даже с упомянутыми вами шагами воспроизведения. Не могли бы вы показать необработанный буфер режима орг? (Тем не менее, я предполагаю, что это ошибка в режиме org. Помогает ли добавление дополнительного символа новой строки?)
aerique
Так же, как @aerique, я не вижу этого здесь. Так что, возможно, это зависит от версии Emacs или некоторых деталей буфера режима Org.
Стефан
@ Дэн, из любопытства, какую тему ты используешь?
Лука
1
@ Не могли бы вы предоставить пример файла org для тестирования?
Уилфред Хьюз
2
@ Дан Я могу воспроизвести это на Emacs 24.4 с файлом, который вы предоставили.
'16

Ответы:

10

Это выглядит как ошибка вызвана org-mode«S org-activate-bracket-linksфункции.

Вот как выглядит эта функция:

(defun org-activate-bracket-links (limit)
  "Run through the buffer and add overlays to bracketed links."
  (if (and (re-search-forward org-bracket-link-regexp limit t)
       (not (org-in-src-block-p)))
      (let* ((hl (org-match-string-no-properties 1))
         (help (concat "LINK: " (save-match-data (org-link-unescape hl))))
         (ip (org-maybe-intangible
          (list 'invisible 'org-link
            'keymap org-mouse-map 'mouse-face 'highlight
            'font-lock-multiline t 'help-echo help
            'htmlize-link `(:uri ,hl))))
         (Vp (list 'keymap org-mouse-map 'mouse-face 'highlight
               'font-lock-multiline t 'help-echo help
               'htmlize-link `(:uri ,hl))))
    ;; We need to remove the invisible property here.  Table narrowing
    ;; may have made some of this invisible.
    (org-remove-flyspell-overlays-in (match-beginning 0) (match-end 0))
    (remove-text-properties (match-beginning 0) (match-end 0)
                '(invisible nil))
    (if (match-end 3)
        (progn
          (add-text-properties (match-beginning 0) (match-beginning 3) ip)
          (org-rear-nonsticky-at (match-beginning 3))
          (add-text-properties (match-beginning 3) (match-end 3) vp)
          (org-rear-nonsticky-at (match-end 3))
          (add-text-properties (match-end 3) (match-end 0) ip)
          (org-rear-nonsticky-at (match-end 0)))
      (add-text-properties (match-beginning 0) (match-beginning 1) ip)
      (org-rear-nonsticky-at (match-beginning 1))
      (add-text-properties (match-beginning 1) (match-end 1) vp)
      (org-rear-nonsticky-at (match-end 1))
      (add-text-properties (match-end 1) (match-end 0) ip)
      (org-rear-nonsticky-at (match-end 0)))
    t)))

Он ищет совпадение для ссылки в квадратных скобках (например [[target][label]], скрывает [[target][деталь, добавляя ipк текстовым свойствам, затем связывает label, добавляя vpк текстовым свойствам, и, наконец, удаляет завершающий элемент, снова ]]добавляя ipк текстовым свойствам.

Это все выглядит правильно. org-rear-nonsticky-atследует позаботиться о собственности кровотечение.

Это поведение вызвано тем (add-text-properties (match-end 3) (match-end 0) ip), что скрывает трейлинг ]]. Только 'invisible 'org-linkсвойство вызывает это поведение, остальные свойства кажутся невинными.

Вы можете переписать так org-activate-bracket-links, чтобы ipбольше не устанавливалось, 'invisibleно 'display "", что имеет тот же эффект:

(defun org-activate-bracket-links (limit)
  "Run through the buffer and add overlays to bracketed links."
  (if (and (re-search-forward org-bracket-link-regexp limit t)
       (not (org-in-src-block-p)))
      (let* ((hl (org-match-string-no-properties 1))
         (help (concat "LINK: " (save-match-data (org-link-unescape hl))))
         (ip (org-maybe-intangible
          (list 'display ""
            'keymap org-mouse-map 'mouse-face 'highlight
            'font-lock-multiline t 'help-echo help
            'htmlize-link `(:uri ,hl))))
         (Vp (list 'keymap org-mouse-map 'mouse-face 'highlight
               'font-lock-multiline t 'help-echo help
               'htmlize-link `(:uri ,hl))))
    ;; We need to remove the invisible property here.  Table narrowing
    ;; may have made some of this invisible.
    (org-remove-flyspell-overlays-in (match-beginning 0) (match-end 0))
    (remove-text-properties (match-beginning 0) (match-end 0)
                '(invisible nil))
    (if (match-end 3)
        (progn
          (add-text-properties (match-beginning 0) (match-beginning 3) ip)
          (org-rear-nonsticky-at (match-beginning 3))
          (add-text-properties (match-beginning 3) (match-end 3) vp)
          (org-rear-nonsticky-at (match-end 3))
          (add-text-properties (match-end 3) (match-end 0) ip)
          (org-rear-nonsticky-at (match-end 0)))
      (add-text-properties (match-beginning 0) (match-beginning 1) ip)
      (org-rear-nonsticky-at (match-beginning 1))
      (add-text-properties (match-beginning 1) (match-end 1) vp)
      (org-rear-nonsticky-at (match-end 1))
      (add-text-properties (match-end 1) (match-end 0) ip)
      (org-rear-nonsticky-at (match-end 0)))
    t)))

Понятно, что это безобразный хак. Но это работает для меня и может работать для вас. Я все еще рекомендую подать отчет об ошибке.

rekado
источник
Спасибо за усилия (+1 за это!), Но это решение не работает для меня. Вместо того, чтобы использовать его [[~/somefile.txt][link label]]как link label(где курсивом обозначено стандартное лицо для ссылки), оно становится link label]](без изменения лица). Я отправлю отчет об ошибке.
Дан
Хм, странно. Единственное изменение в моем определении org-activate-bracket-links- это замена 'invisible non-nilна 'display "", поэтому он должен по-прежнему применять лицо ссылки, как и раньше. Это, конечно, работает для меня в Emacs 24.4, но я думаю, что энергия лучше тратится на отчет об ошибках, чем на попытки взлома ... :)
rekado