Làm thế nào để làm nổi bật các từ khóa cụ thể bên trong chuỗi / trích dẫn?


7

Tôi có một cú pháp tô sáng khác cho các từ khóa SQL bên trong các chuỗi (bên trong dấu ngoặc kép) trong VIM. Nó trông như thế này:

nhập mô tả hình ảnh ở đây

Sau đó, trong Emacs với chế độ PHP, mọi thứ giữa dấu ngoặc kép ( ') sẽ được coi là một chuỗi bởi khóa phông chữ:

nhập mô tả hình ảnh ở đây

Như bạn có thể thấy, ví dụ đầu tiên với các thuộc tính khuôn mặt phông chữ khác (không có từ khóa khó hiểu) rõ ràng hơn. Các từ khóa dễ phân biệt hơn nhiều.

Khi tôi nhìn vào font facetài sản của mình :

 (font-lock-string-face ((t (:foreground "#536991" :slant italic)))) 

Sau đó, tôi đang tự hỏi làm thế nào tôi có thể nói rằng có một khuôn mặt bên trong một font-lock-string-facenên được áp dụng, nếu nó matchs các từ khóa cụ thể.

Bất kỳ đề nghị sẽ được đánh giá cao.


Một lần nữa chế độ PHP như trong emacs.stackexchange.com/questions/19002/ cấp ? Và bạn có hack từ câu trả lời đang chạy không? Bạn nên thêm một lưu ý về chế độ chính hiện tại trong câu hỏi.
Tobias

@Tobias StackExchange không thông báo cho tôi rằng tôi đã nhận được phản hồi từ bạn! Rất xin lỗi vì phản hồi muộn màng của tôi sau đó, xem liên kết cho câu trả lời của tôi. Và bạn nói đúng, tôi đã thêm chế độ PHP. Nhưng tôi tin rằng giải pháp có thể không liên quan đến chế độ chính, vì nó chỉ nhắm mục tiêu trên các mặt phông chữ.
ReneFroger

Câu trả lời:


11

Các đoạn elisp sau đây nên làm. Các chi tiết quan trọng là:

  • Các chuỗi được xử lý bằng cách tô sáng cú pháp chứ không phải bằng cách khớp mẫu (nghĩa là tô sáng từ khóa). Điều này có ưu tiên rất cao. Vì vậy, người ta cần ghi đè nó một cách rõ ràng bằng giá trị tcho cờ MATCHER QUÁ HẠN (xem tài liệu của font-lock-keywords).
  • Người ta không thể sử dụng biểu thức chính quy dưới dạng MATCHER vì người ta chỉ phải kiểm tra các từ khóa SQL trong chuỗi. Mã dưới đây cung cấp php-sql-keyword-matchercho mục đích đó. Việc kiểm tra các chuỗi được thực hiện thông qua syntax-ppss(xem tài liệu cho hàm này).

Lưu ý rằng tôi chỉ có một màn hình hiển thị của lớp color. Vì vậy, tôi không thể kiểm tra các lớp khác. Tôi giả sử rằng bạn có một lớp hiển thị khác vì các chuỗi được hiển thị ở mặt in nghiêng trong ví dụ của bạn. Nếu bạn không nhận được kết quả như mong đợi, hãy tùy chỉnh khuôn mặt php-sql-keyword-face.

(require 'sql) ;; for sql-keywords
(require 'php-mode) ;; for php-mode-hook

(defvar php-sql-keywords (concat "\\<" (mapconcat 'car sql-mode-ansi-font-lock-keywords "\\|") "\\>")
  "SQL keywords for php-mode stolen from `sql-mode-ansi-font-lock-keywords'.")

(defun php-sql-keyword-matcher (end)
  "Search for SQl keywords within PHP strings."
  (let (pos (case-fold-search t))
    (while (and (setq pos (re-search-forward php-sql-keywords end t))
                (null (nth 3 (syntax-ppss pos)))))
    (when pos (message "Found keyword at %s" pos))
    pos))

(defface php-sql-keyword-face
  '((((class grayscale))  :slant nil :inherit font-lock-string-face)
    (((class color)) :slant italic :inherit font-lock-string-face)
    (t :slant nil :inherit font-lock-string-face))
  "Face to highlight SQL keywords within PHP strings."
  :group 'php-sql)

(defcustom php-sql-keyword-face 'php-sql-keyword-face
  "Face to highlight SQL keywords within PHP strings."
  :type 'face
  :group 'php-sql)

(defun php-add-sql-keyword-matcher ()
  "Hook to add fontification of sql-keywords in strings."
  (font-lock-add-keywords
   nil
   '((php-sql-keyword-matcher 0 php-sql-keyword-face t))
   'append))

(add-hook 'php-mode-hook 'php-add-sql-keyword-matcher)

Lưu ý: Vui lòng không chỉ chèn hình ảnh của các văn bản cần thiết cho việc xây dựng lại vấn đề. Văn bản ascii có thể giúp giảm bớt sự giúp đỡ tiềm năng trong việc tái cấu trúc vấn đề. Đối với trường hợp người khác có giải pháp tốt hơn, tôi chèn phiên bản ASCII của văn bản vào đây:

$sSql = 'SELECT T05.foo
             T07.bar

         FROM db_pgm_intranet.inttbl_keyuser_proces_keyuser T05

             INNER JOIN db_pgm_intranet.inttbl_keyuser_keyuser T07
             ON    T07.nKkuID = T01.nKpkKeyuserID

             LEFT JOIN db_pgm_intranet.inttbl_keyuser_applicate T07
             ON   T06.nKpaProcesID = T07.nKapID';

Và đây là hình ảnh của văn bản giống như khi tôi tải nó vào emacs với chế độ PHP:

Hình ảnh của tệp php với các từ khóa in nghiêng trong chuỗi sql

Với colorchuỗi lớp hiển thị không phải là chữ nghiêng nhưng có màu khác. Do đó, tôi đã chọn mặt chữ in nghiêng cho các từ khóa SQL trong chuỗi.

Các ý kiến ​​chỉ ra một số khó khăn với câu trả lời này. Nó đã được chỉ ra rằng giải pháp sẽ không hoạt động với phông chữ mặc định được đặt thành Consolas. Tôi vừa mới thử nghiệm và trên hệ thống của tôi, nó cũng hoạt động với phông chữ Consola như mặc định:

Làm nổi bật các từ khóa SQL trong chuỗi php với phông chữ Consolas làm mặc định.

Trong phần trợ giúp font-lock-add-keywordstôi đã tìm thấy đoạn văn sau:

Ví dụ:

(font-lock-add-keywords 'c-mode
  '(("\\<\\(FIXME\\):" 1 'font-lock-warning-face prepend)
    ("\\<\\(and\\|or\\|not\\)\\>" . 'font-lock-keyword-face)))

thêm hai mẫu phông chữ cho chế độ C, để phông chữ các từ 'FIXME:', ngay cả trong các bình luận, và để phông chữ and, orvà các nottừ làm từ khóa.

Trường hợp đầu tiên " FIXME" là trường hợp thú vị. Ở đây họ sử dụng prependnhư cờ ghi đè.


1
Tobias, bạn đã cố gắng giúp tôi một lần nữa. Tôi không biết cảm ơn bạn bao nhiêu cho đủ. Tôi đã nghiên cứu tài liệu về các từ khóa khóa chữ (22.6.2 phông chữ dựa trên tìm kiếm). Có vẻ như tôi cần đặt subexp-highlightercờ ghi đè thành đúng. Nhưng tôi thấy bạn đã làm với (php-sql-keyword-matcher 0 php-sql-keyword-face t). Vì vậy, tôi đã sao chép mã của bạn trong cấu hình Emacs trống chỉ có chế độ PHP trên bo mạch, đánh giá bộ đệm, sau đó tạo bộ đệm mới với văn bản ASCII mà bạn thậm chí đã xây dựng lại! Mặc dù giải thích chi tiết xuất sắc của bạn, tôi không thấy văn bản khó hiểu hoặc văn bản khác, không may.
ReneFroger

Hơn nữa, khi tôi đặt con trỏ vào chuỗi và gọi php-sql-keyword-matcher(tôi đã thêm vào chuỗi (interactive)đó), tôi gặp lỗi, vì vậy tôi cho rằng nó không có ý định cho các cuộc gọi tương tác. Sau khi đánh giá mã của bạn và dán văn bản ASCII vào bộ đệm đầu với chế độ PHP được bật, tôi thấy không có sự khác biệt giữa các từ khóa SQL và phần còn lại của chuỗi. Nếu bạn cần một ảnh chụp màn hình, thông tin gỡ lỗi, tôi rất muốn thêm thông tin vì kiến ​​thức Elisp của tôi chưa đủ. Tôi thực sự đánh giá cao sự giúp đỡ của bạn trong các trường hợp của tôi, và nhân tiện, những lời chúc tốt đẹp nhất cho năm 2016.
ReneFroger

1
Nguồn gốc rất có thể của vấn đề là jit-ocktừ bỏ một số lỗi. jit-lockkhông bảo lãnh cho các lỗi nhưng vô hiệu hóa trình xử lý gây ra lỗi và tiếp tục với công việc của nó. Tuy nhiên, nó để lại một thông báo lỗi trong bộ đệm thông báo. Vì vậy, bắt đầu một emacs mới thử công cụ của bạn và quan sát rất cẩn thận bộ đệm tin nhắn. AFAIK bạn không thể bắt các loại lỗi này thông qua trình gỡ lỗi. Dừng jit-locklỗi có thể có hậu quả có dây như khóa chết. Tôi giả sử nó là một số chức năng bị thiếu. Tôi sẽ thử lại với -Q. Nhân tiện, lời chúc tốt nhất cho bạn quá.
Tobias

1
Tôi có thể xác nhận rằng đoạn mã chạy tốt emacs -Qở đây tại vị trí của tôi với giao diện X11. Tôi sẽ thử lại trong chế độ bảng điều khiển ...
Tobias

Bạn sử dụng phiên bản nào của Emacs? Tôi sử dụng Emacs 25.50 trên Ubuntu và không có chế độ PHP với M-x php-modecấu hình Emacs trống. Đó là lý do tại sao tôi lên chế độ PHP với cấu hình trống hơn nữa.
ReneFroger
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.