Làm thế nào tôi có thể tìm thấy dấu ngoặc đơn xung quanh (từ emacs lisp)?


7

Có cách nào để tìm ra loại dấu ngoặc đơn xung quanh (nghĩa là '(', '[' hoặc '{') quanh điểm không? Ví dụ (sử dụng |để biểu thị điểm)

{ abc, | df }

nên trả về '{' và

{ abc[ | ], 123 }

nên trả lại '['. Lý tưởng nhất là tôi muốn nó để xử lý dấu ngoặc kép là tốt.


Trong trường hợp bất kỳ ai cũng tò mò hoặc cần thêm chi tiết: mục đích của tôi là thiết lập khoảng cách tự động thông minh xung quanh :trong python bằng cách sử dụng khoảng cách điện (còn được gọi là toán tử thông minh ). Vấn đề là thông thường (trong python) :là toán tử lát hoặc bắt đầu câu lệnh for / if / ..., không nên được bao quanh bởi khoảng trắng. Tuy nhiên, trong từ điển, nó giống như một toán tử gán, và do đó, nó phải được bao quanh bởi các khoảng trắng. Vì vậy, tôi có một cách cần kiểm tra xem điểm có nằm trong một dict (tức là bên trong {}) không, nhưng không phải bên trong một hoạt động lát hoặc chuỗi trong dict đó (tức là không bên trong []hoặc "").


Biên tập:

Đây là chức năng trợ giúp tôi đã viết, dựa trên câu trả lời của 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))))

Sau đó, vị ngữ cuối cùng là:

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

Chỉnh sửa 2:

Các chức năng trên hóa ra quá chậm (nó thường gây ra độ trễ đáng chú ý khi :gõ). Bây giờ tôi đang sử dụng câu trả lời của Stefan, dường như nhanh hơn nhiều.


1
Không phải là một câu trả lời đầy đủ, nhưng đối với trường hợp cụ thể "", bạn có thể sử dụng tích hợp sẵn in-string-p.
T. Verron 30/03/2015

Câu trả lời:


10

Thay vì up-listtôi khuyên bạn nên sử dụng (syntax-ppss), nó sẽ trả về cho bạn một số trạng thái phân tích cú pháp. Điều này sẽ bao gồm thông tin về việc bạn đang ở trong một chuỗi hoặc một nhận xét, vị trí của "paren" mở cuối cùng, v.v ...

Ví dụ, bạn có thể tìm thấy loại paren với

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

và hy vọng nó cũng sẽ cho phép bạn xử lý dấu ngoặc kép (bằng cách kiểm tra (nth 3 ppss)(char-after (nth 8 ppss))).


5

Thử cái này:

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

Lưu ý rằng up-listcó thể ném, vì vậy bạn cũng cần phải xử lý lỗi.


1
Tôi thích sự đơn giản của câu trả lời này nhưng hóa ra là quá chậm trong python khi điểm không nằm trong bất kỳ parens nào (rất phổ biến với cú pháp khoảng trắng của python). Có lẽ đó là vì nó kết thúc phân tích toàn bộ bộ đệm trong trường hợp này.
dshepherd

1

Mặc dù câu trả lời thích hợp hơn IMO được đưa ra bởi Stefan, đây là một ví dụ bao gồm một giải pháp không dựa vào các dấu phân cách WRT của bảng cú pháp: Nó sử dụng một cái gì đó như

 (skip-chars-backward "^{\(\[\]\)}")

và một chồng. Xem nguồn tại đây

https://github.com/emacs-berlin/general-close


0

Đây là một hàm trả về dấu ngoặc đơn xung quanh, bao gồm cả trường hợp khi điểm nằm trực tiếp trên dấu ngoặc đơn đầu tiên hoặc cuối cùng (điều này rất quan trọng trong trường hợp của tôi).

Điều này hoạt động với ngôn ngữ, vì vậy ({[]})tất cả làm việc trong C chẳng hạn.

(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)))))))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.