yasnippet: làm thế nào để mở rộng một đoạn trích từ một chuỗi và có các trường được công nhận?


7

H: làm cách nào để tôi yasnippetmở rộng chuỗi văn bản một cách chính xác (nhận ra các trường đoạn mã) từ bên trong mã elisp?

Một đoạn rất đơn giản chỉ là một chuỗi các ký tự với một số ký tự điều khiển xen kẽ. Chúng tôi cũng có thể sử dụng các hình thức elisp để tạo các đoạn mã phong phú hơn, nhưng tôi không rõ làm thế nào để mở rộng chúng một cách thích hợp.

Đây là một ví dụ đơn giản nắm bắt được vấn đề. Tôi đang tạo một org-modeđoạn mã để chèn một bộ xương liên kết, trông giống như vậy [[source][description]]. Đoạn mã đơn giản sau đây tạo ra hành vi mong muốn "bắt đầu trong trường nguồn, kết thúc trong trường mô tả":

[[$1][$0]]

Chúng ta có thể xen kẽ mã elisp trong đoạn trích (được gói trong `s). Tôi đã nghĩ rằng những điều sau đây sẽ tạo ra chính xác hành vi tương tự như phiên bản đơn giản hơn, bởi vì ý ifchí đơn giản sẽ đánh giá thành [[$1][$0]]một chuỗi:

`(if t "[[$1][$0]]")`

Nó không làm như vậy, tuy nhiên. Thay vào đó, nó hoạt động như thể $0$1các trường không phải là các trường, kết thúc đoạn mã và đặt điểm sau trận chung kết ]. Vậy: làm thế nào để có được hành vi mong muốn khi một hình thức elisp đánh giá một chuỗi văn bản với yasnippetcác trường được nhúng trong chuỗi đó?

EDIT: theo yêu cầu, đây là trường hợp sử dụng cụ thể đã truyền cảm hứng cho câu hỏi. Nếu bảng tạm X chứa liên kết url, tôi muốn nó điền vào trường nguồn trong liên kết org ([[ nguồn ] [mô tả]]) và để tôi trong trường đích. Nó sử dụng hàm trợ giúp ( dan-xclipboard-link-p) trả về url nếu nó tồn tại hoặc nếu không nil. Dường như với tôi rằng tôi sẽ có thể làm một cái gì đó như thế này:

`(let ((link (dan-xclipboard-link-p)))
   (if link
       (concat "[[" link "][$0]]")
     "[[$1][$0]]"))`

Trong thực tế, với một phiên bản trước đó của yasnippet, một phiên bản của mã này đã hoạt động như tôi dự định.

EDIT 2: Thật thú vị, đoạn trích này hoạt động khi có một liên kết trên bảng tạm X, nhưng không thành công khi không (nghĩa là nó không nhận ra $1là một trường:

[[`(or (dan-xclipboard-link-p) "$1")`][$0]]

Thế còn (if t (yas-insert-snippet))? Bạn có thể đưa ra một điều kiện thực tế hơn để chúng ta có thể hiểu trường hợp sử dụng thực tế? Đây có thể là một vấn đề XY với các giải pháp thanh lịch hơn.
Vamsi

Tôi không thấy cách yas-insert-snippetáp dụng ở đây. Ở bất kỳ giá nào, một trường hợp sử dụng thực tế (được sử dụng để làm việc) hiện đang được đặt ra.
Dân

@Dan Nó không hoạt động vì hình thức elisp được đánh giá khi đang được mở rộng , tại thời điểm đó yasnippet đã đọc đoạn trích. Tôi đoán những gì bạn muốn làm là tạo khuôn mẫu cho chính nó, không chắc điều đó có thể xảy ra với yasnippet tại thời điểm này
Iqbal Ansari

@IqbalAnsari Tôi có một cách thô thiển trong việc tạo khuôn mẫu cho các đoạn trích. Xem giải pháp lâu hơn của tôi. Cảm ơn.
Vamsi

Câu trả lời:


11

GIẢI PHÁP NGẮN

Nếu bạn không phiền khi TABnhấn phím bổ sung , hãy xác định đoạn mã của bạn như dưới đây sẽ hoạt động.

 [[${1:`(dan-xclipboard-link-p)`}][$0]]

Lisp nhúng trả về url từ bảng ghi tạm nếu nó tồn tại và đặt nó thành văn bản mặc định trong trường $1. Bạn có thể gõ qua liên kết để thay đổi nó hoặc chỉ TAB (yas-next-field)để di chuyển điểm đến $0.

GIẢI PHÁP TÍNH NĂNG ĐẦY ĐỦ

Tôi đã có ý tưởng dựa trên nhận xét của @ IqbalAnsari sau khi viết giải pháp ngắn hơn. Bạn có thể sử dụng vị từ điều kiện để chọn đoạn mở rộng nào. Chẳng hạn, xác định hai đoạn mã có cùng kích hoạt

SNIPPET 1

  # -*- mode: snippet; require-final-newline: nil -*-
  # name: org-link
  # key: [[
  # binding: direct-keybinding
  # type: snippet
  # condition: (not (dan-xclipboard-link-p))
  # --
  [[$1][$0]]

SNIPPET 2

  # -*- mode: snippet; require-final-newline: nil -*-
  # name: org-link-with-default-paste
  # key: [[
  # binding: direct-keybinding
  # type: snippet
  # condition: (dan-xclipboard-link-p)
  # --
  [[`(dan-xclipboard-link-p)`][$0]]

Cả hai đoạn mã có cùng một kích hoạt, nhưng có các vị từ đảo ngược được biểu thị bởi condition:. Như vậy, chỉ một trong số các đoạn sẽ được mở rộng tùy thuộc vào giá trị được trả về (dan-xclipboard-link-p). Bằng cách này bạn có thể định vị điểm $0trực tiếp.

Để trả lời câu hỏi chung, yasnippet không thể nhận ra các trường trong elisp vì nó phân tích các khối elisp nhúng riêng biệt mà không cần quan tâm đến cú pháp khuôn mẫu thông thường. Tôi không chắc chắn làm thế nào các phiên bản trước làm việc mặc dù.


Tuyệt vời, tôi đã nghĩ về một cái gì đó dọc theo cùng một dòng. Mặc dù tôi sẽ thích 'tab' hơn là viết hai đoạn. +1
Iqbal Ansari

Cảm ơn những suy nghĩ. Nhân tiện, tôi đã đưa ra một cái gì đó tương tự như giải pháp ngắn và sửa lỗi chính tả với dấu ngoặc để tham khảo trong tương lai. Các đoạn có điều kiện là một liên lạc tốt đẹp.
Dan
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.