Як я можу визначити, чи є поточний персонаж символом коментаря для цього основного режиму?


12

Я працюю над цією маленькою функцією, яка підтягує наступний рядок до поточного рядка. Я хочу додати функціональність, так що якщо поточний рядок - це коментар до рядка, а наступний - також коментар до рядка, то символи коментарів видаляються після дії "підтягування".

Приклад:

До цього

;; comment 1▮
;; comment 2

Дзвінок M-x modi/pull-up-line

Після

;; comment 1▮comment 2

Зауважте, що ;;символи видалено, які були раніше comment 2.

(defun modi/pull-up-line ()
  "Join the following line onto the current one (analogous to `C-e', `C-d') or
`C-u M-^' or `C-u M-x join-line'.

If the current line is a comment and the pulled-up line is also a comment,
remove the comment characters from that line."
  (interactive)
  (join-line -1)
  ;; If the current line is a comment
  (when (nth 4 (syntax-ppss))
    ;; Remove the comment prefix chars from the pulled-up line if present
    (save-excursion
      (forward-char)
      (while (looking-at "/\\|;\\|#")
        (delete-forward-char 1))
      (when (looking-at "\\s-")
        (delete-forward-char 1)))))

Вище функція працює , але на даний момент, незалежно від основного режиму, він буде розглядати /або ;або #як символ коментаря: (looking-at "/\\|;\\|#").

Я хотів би зробити цю лінію більш розумною; специфічний для основного режиму.

Рішення

Завдяки рішенню @ericstokes я вважаю, що наведене нижче охоплює всі мої випадки використання :)

(defun modi/pull-up-line ()
  "Join the following line onto the current one (analogous to `C-e', `C-d') or
`C-u M-^' or `C-u M-x join-line'.

If the current line is a comment and the pulled-up line is also a comment,
remove the comment characters from that line."
  (interactive)
  (join-line -1)
  ;; If the current line is a comment
  (when (nth 4 (syntax-ppss))
    ;; Remove the comment prefix chars from the pulled-up line if present
    (save-excursion
      (forward-char)
      ;; Delete all comment-start or space characters
      (while (looking-at (concat "\\s<" ; comment-start char as per syntax table
                                 "\\|" (substring comment-start 0 1) ; first char of `comment-start'
                                 "\\|" "\\s-")) ; extra spaces
        (delete-forward-char 1)))))

Ви хочете, щоб це було досить розумним, щоб обробляти різні символи початку та кінця коментарів та коментарі з кількома символами (наприклад, C /* ... */)?
erikstokes

Ні, це було все, що мені було потрібно. Дякую!
Каушал Моді

@erikstokes З цікавості, як би ви поводилися з коментарями у стилі C?
Прадхан

Це рішення працює з багаторядковими коментарями теж відразу, нічого особливого не потрібно робити, оскільки нам не потрібно видаляти жодних символів під час приєднання до багаторядкових коментарів.
Каушал Моді

2
@Pradhan Є comment-startі comment-endрядки, які встановлені «/ *» і «* /» в c-mode(але не c++-mode). І є, c-comment-start-regexpщо відповідає обом стилям. Ви видаляєте кінцеві символи та початок після приєднання. Але я думаю , що моє рішення було б uncomment-region, і нехай Emacs турбуватися про те, що символ коментаря до чого. join-linecomment-region
erikstokes

Відповіді:


12

Ви можете перевірити , якщо поточний символ є символом коментаря за допомогою таблиці синтаксису: (looking-at "\\s<"). Регепс \\s<відповідатиме будь-якому символу із синтаксисом «запуск коментарів»; \\s>відповідатиме тим, хто має синтаксис "кінець коментаря".

Інший варіант - це змінна comment-start, яка є рядком, вставленим comment-dwimі друзями. Зазвичай він встановлюється символом початку коментаря плюс деяким місцем.


2

Є набагато простіше рішення , будь ласка, вивчіть мій код на https://github.com/redguardtoo/evil-nerd-commenter/blob/master/evil-nerd-commenter.el

Я не копіюю / вставляю тут весь код. але ось ключові моменти:

  • коментар має власне обличчя шрифту, шукайте шрифт-блокування-коментар-обличчя та шрифт-замок-коментар-роздільник обличчя в моєму коді

  • використовуйте власний API Emacs, щоб коментувати другий рядок, а потім приєднайте його до першого рядка

Він повинен працювати на будь-яких розумних основних режимах.

Ця хитрість не вигадана мною. Це насправді з власного коду Emacs (точніше, flyspell). Таким чином, рішення повинно підтримувати будь-які підтримуючі мухоспеціальні режими основних режимів


3
Щоб виділити щось як коментар, він вимагає відповідної настройки синтаксичної таблиці, тому я сумніваюся, що це розумніше, ніж альтернатива погляду на синтаксис.
wasamasa

Цю хитрість я навчився, читаючи власний код Emacs (насправді це flyspell), як я документально підтвердив свій код.
Чень бен

0

Якщо ви шукаєте цю функцію для коду lisp (Elisp, Clojure, Scheme та Common Lisp), тоді вам слід спробувати lispy , функція під назвою lispy-fillробить подібне.

Якщо ви шукаєте цю функцію для іншої мови, вам слід rebox2 (підтверджено для Cі Python), функцію, що називається, rebox-fillабо іншу функцію під назвою rebox-dwimзробити подібний вигляд.

Вони обидва чудові пакети, і вони не конфліктують між собою, оскільки вони використовуються для різних основних режимів, і вони обоє ( lispy-fillі rebox-dwim) пов'язані M-q, досить акуратно.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.