現在の文字がそのメジャーモードのコメント文字かどうかを検出するにはどうすればよいですか?


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好奇心から、Cスタイルのコメントをどのように処理しますか?
プラダン

このソリューションは複数行のコメントでもすぐに機能します。複数行のコメントを結合するときに文字を削除する必要がないため、特別な作業は必要ありません。
カウ

2
あり@Pradhan comment-startcomment-endに設定されている文字列「/ *」と「* /」でc-mode(なくc++-mode)。そしてc-comment-start-regexp、両方のスタイルに一致するものがあります。終了文字を削除してから、結合後に開始文字を削除します。しかし、私は私の解決策は、になるだろうと思うuncomment-region、とコメント文字が何であるかについてEmacsの心配をしましょう。join-linecomment-region
エリクスト

回答:


12

構文テーブルを使用して、現在の文字がコメント文字かどうかを確認できます(looking-at "\\s<")。正規表現\\s<は、「コメント開始」構文の任意の文字と一致します。\\s>「コメント終了」構文と一致します。

もう1つのオプションは変数ですcomment-start。これは、comment-dwim友人が挿入した文字列です。通常、コメント開始文字とスペースが設定されます。


2

もっと簡単な解決策があります。https://github.com/redguardtoo/evil-nerd-commenter/blob/master/evil-nerd-commenter.elで私のコードを調べてください。

ここではすべてのコードをコピー/貼り付けません。しかし、ここにキーポイントがあります:

  • コメントには、独自のフォントフェース、検索コードでfont-lock-comment-faceおよびfont-lock-comment-delimiter-faceが含まれています

  • Emacs独自のAPIを使用して2行目のコメントを解除し、1行目に結合します

賢明なメジャーモードで動作するはずです。

このトリックは私が発明したものではありません。実際には、Emacs独自のコード(より具体的にはflyspell)からのものです。そのため、このソリューションは、メジャーモードのflyspellサポートをサポートする必要があります。


3
コメントとして何かを強調するには、構文テーブルを適切に設定する必要があります。そのため、これは構文を見る代替案よりも賢明ではないでしょう。
wasamasa

私は自分のコードで文書化したように、Emacs自身のコード(実際にはflyspell)を読むことでこのトリックを学びました。
チェンビン

0

この機能をlispコード(Elisp、Clojure、Scheme、Common Lisp)で探している場合は、lispyを試してくださいlispy-fill。呼び出される関数はこのようなことを行います。

あなたが他の言語のために、この機能を探しているなら、あなたがすべきrebox2(のための検証CPython)、呼び出された関数rebox-fillまたは他の関数が呼ばれるrebox-dwimこの種のものを行います。

彼らは両方の偉大なパッケージであり、彼らは別のメジャーモードのために使用されているので、互いに競合していない、と彼らは両方(あるlispy-fillrebox-dwim)に結合しているM-qかなりきちんと、。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.