どうすれば(emacs lispから)括弧を見つけることができますか?


7

ポイントを囲む括弧のタイプ(つまり、 '('、 '['、または '{')を見つける方法はありますか?例(|ポイントを表すために使用)

{ abc, | df }

'{'を返す必要があります。

{ abc[ | ], 123 }

'['を返す必要があります。理想的には、引用符も処理したいと思います。


誰かが好奇心が強い場合や詳細が必要な場合:私の目的は:、Pythonでelectric-spacingsmart-operatorとも呼ばれます)を使用してスマートな自動間隔を設定することです。問題は、通常(Pythonの場合):はスライス演算子またはfor / if / ...ステートメントの開始であり、スペースで囲まないでください。ただし、ディクショナリ内では代入演算子のようなものなので、スペースで囲む必要があります。私ので、ポイントはdictの(すなわち内部の内側にあるかどうかを確認する方法の必要性{})ではなく、(すなわちない内部その辞書内のスライス操作や文字列の内部[]または"")。


編集:

以下は、abo-aboの回答に基づいて私が作成したヘルパー関数です。

(defun enclosing-paren ()
  "Return the closing parenthesis of the enclosing parens, or nil if not inside any parens."
  (ignore-errors
    (save-excursion
      (up-list)
      (char-before))))

次に、最後の述語は次のとおりです。

(and (not (in-string-p))
     (eq (enclosing-paren) ?\}))

編集2:

上記の関数は遅すぎることがわかりました(a :が入力されたときに顕著な遅延が発生することがよくありました)。今は代わりにStefanの回答を使用しています。


1
完全な答えではありませんが、の特定のケースでは""、組み込みのを使用できますin-string-p
T. Verron、2015年

回答:


10

up-list私がお勧めするの(syntax-ppss)ではなく、これを使用すると、いくつかの解析状態に戻ります。これには、文字列内かコメント内か、最後に開いた「括弧」の位置などに関する情報が含まれます。

たとえば、かっこの種類を見つけることができます

(let ((ppss (syntax-ppss)))
  (when (nth 1 ppss) (char-after (nth 1 ppss))))

それがうまくいけば(チェックすることにより、同様にあなたが引用符を処理させる必要がある(nth 3 ppss)(char-after (nth 8 ppss)))。


5

これを試して:

(save-excursion
  (up-list)
  (char-before))

up-listはスローする可能性があるため、エラーも処理する必要があります。


1
私はこの答えの単純さが好きですが、ポイントが括弧内にない場合、Pythonでは遅くなることがわかりました(Pythonの空白構文で非常に一般的です)。おそらくそれは、この場合バッファ全体を解析してしまうためです。
dshepherd 2015年


0

次の関数は、ポイントが最初または最後の括弧の上に直接ある場合(私の場合は重要でした)を含め、周囲の括弧を返す関数です。

これは言語で機能するため({[]})、たとえばすべてCで機能します。

(defun find-surrounding-brackets (pos)
  "Return a pair of buffer positions for the opening & closing bracket positions.

Or nil when nothing is found."
  (save-excursion
    (goto-char pos)
    (when
      (or
        ;; Check if we're on the opening brace.
        (when
          ;; Note that the following check for opening brace
          ;; can be skipped, however it can cause the entire buffer
          ;; to be scanned for an opening brace causing noticeable lag.
          (and
            ;; Opening brace.
            (eq (syntax-class (syntax-after pos)) 4)
            ;; Not escaped.
            (= (logand (skip-syntax-backward "/\\") 1) 0))
          (forward-char 1)
          (if (and (ignore-errors (backward-up-list arg) t) (eq (point) pos))
            t
            ;; Restore location and fall through to the next check.
            (goto-char pos)
            nil))
        ;; Check if we're on the closing or final brace.
        (ignore-errors (backward-up-list arg) t))
      ;; Upon success, return the pair as a list.
      (list
        (point)
        (progn
          (forward-list)
          (1- (point)))))))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.