font-lock-add-keywords ไม่ทำงาน

Aug 18 2020

ดังนั้นฉันจึงพยายามเพิ่มการเน้นไวยากรณ์ที่กำหนดเองสำหรับตัวเลขโดยใช้font-lock-add-keywordsและ regex

ฉันได้ดูแหล่งข้อมูลทั้งหมดของ Emacs เพื่อทำสิ่งนี้และในขณะที่ฉันสามารถกำหนดใบหน้าfont-lock-add-keywordsได้สำเร็จ แต่ก็ยังไม่ได้ผลด้วยเหตุผลที่ชัดเจน

ฉันได้คัดลอกตัวอย่างจากแหล่งต่างๆและพยายามให้พวกเขาใช้งานได้โดยตรงโดยไม่ประสบความสำเร็จ ฉันไม่สามารถเข้าใจได้ว่ารหัสของฉันมีอะไรผิดปกติ ฉันไม่ได้รับข้อผิดพลาดใด ๆ แต่เมื่อฉันพยายามประเมินfont-lock-add-keywords(ด้วยC-x C-e) มันจะพิมพ์ลงnilใน*Messages*บัฟเฟอร์

อัปเดต

ฉันรับคำแนะนำของ Gilles และสร้างโหมดรองตั้งเป็นโหมดรองfont-lock-add-keywordsที่กำหนดเองนั้นและใช้คำพูดสำหรับใบหน้า แม้ว่าฉันจะเห็นโหมดรองในบรรทัดโหมดและรู้ว่ามันใช้งานได้ แต่font-lock-add-keywordsก็ดูเหมือนจะไม่ทำงาน นี่คือรหัสที่อัปเดตของฉัน:

(defgroup gio-group nil
  "Group for customization"
  :prefix "gio-")

(defface gio-highlight-numbers-face
  '((t :inherit (default)
       :foreground "#ffff00"))
  "Face for numbers"
  :group 'gio-group )

(define-minor-mode gio-minor-mode
  "Minor mode for customizaion"
  :init-value t
  :lighter " GioMode"
  :global t
  :group 'gio-group)

(font-lock-add-keywords 'gio-minor-mode '(("[0-9]+" . 'gio-highlight-numbers-face)))

ฉันใช้ GNU Emacs 26.3 (build 1, x86_64-w64-mingw32) บน Windows 10 ความช่วยเหลือใด ๆ ที่ได้รับการชื่นชมมาก! ขอบคุณ!

คำตอบ

2 Gyo Aug 19 2020 at 17:00

จากการค้นคว้าเพิ่มเติมและความช่วยเหลือจากความคิดเห็นจาก Gilles และ Lindydancer ฉันพบว่าคุณไม่สามารถเพิ่มคีย์เวิร์ด Font Lock ในโหมดรองได้ แต่คุณต้องเพิ่มและลบคีย์เวิร์ดในโหมดหลักเมื่อโหลดและยกเลิกการโหลดโหมดรอง

นี่คือรหัสการทำงานที่เน้นคำหลักโดยใช้โหมดรอง:

(defgroup gio-group nil
  "Group for customization"
  :prefix "gio-")

(defface gio-highlight-numbers-face
  '((t :inherit (default)
       :foreground "#ffff00"))
  "Face for numbers"
  :group 'gio-group )

(defvar gio-keywords '(("\\(\\b\\|[-]\\)\\([-]?\\([0-9]+\\)\\(\\.?[0-9]\\)*\\)\\b" . 'gio-highlight-numbers-face)) ;; Integers & Decimals
  "Keywords for gio-minor-mode highlighting")

(define-minor-mode gio-minor-mode
  "Minor mode for customization"
  :init-value 1
  :lighter " GioMode"
  :group 'gio-group
  (when (bound-and-true-p gio-minor-mode)
    (font-lock-add-keywords nil gio-keywords)
    (font-lock-fontify-buffer))
  (when (not (bound-and-true-p gio-minor-mode))
    (font-lock-remove-keywords nil gio-keywords)
    (font-lock-fontify-buffer)))

(define-globalized-minor-mode gio-global-minor-mode gio-minor-mode gio-minor-mode :group 'gio-group)
(gio-global-minor-mode 1)
Gilles'SO-stopbeingevil' Aug 19 2020 at 05:18

font-lock-add-keywordsเพิ่มคำหลักสำหรับโหมดหลักเฉพาะเช่นโหมด Lisp หรือโหมด C หรือโหมด HTML เนื่องจากfont-lock-modeไม่ใช่โหมดหลัก(font-lock-add-keywords 'font-lock-mode …)ไม่เคยมีผลใด ๆ

หากคุณต้องการคีย์เวิร์ดล็อกฟอนต์ที่ใช้ในทุกโหมดหลักจริงๆคุณต้องกำหนดโหมดรอง นั่นคือวิธีการทำงานของโหมด Whitespace โหมดช่องว่างจำนวนมากมีความซับซ้อนมากกว่าที่คุณต้องการ คุณอาจเพิ่มการตั้งค่า "ไฮไลต์หลัก" ในโหมดเว้นวรรคได้ แต่การกำหนดโหมดของคุณเองอาจจะง่ายกว่า ฟังก์ชั่นอำนวยความสะดวกdefine-minor-modeช่วย แต่คุณยังคงต้องเพิ่มและลบคำหลักด้วยตนเองเมื่ออยู่ในโหมดที่มีการเปิดหรือปิดโดยการเรียกและ(font-lock-add-keywords nil …) (font-lock-remove-keywords nil …)ดูฉันสามารถเพิ่มการไฮไลต์ในโหมดรองได้หรือไม่ สำหรับคำแนะนำ

นอกจากนี้ยังมี gotcha ในการทำงานของใบหน้า: ชื่อใบหน้าเป็นสัญลักษณ์ที่ไม่ใช่ตัวแปร (MATCHER . FACESPEC)รูปแบบของการfont-lock-keywordsต้องFACESPECจะต้องมีการแสดงออกที่มีค่าระบุใบหน้า custom-faces-highlight-numbers-faceไม่ทำงานเนื่องจากไม่ใช่นิพจน์ที่ถูกต้องเนื่องจากสัญลักษณ์custom-faces-highlight-numbers-faceไม่ถูกผูกไว้ มีสองวิธีแก้ปัญหานี้ วิธีแก้ปัญหาแบบเดิมคือการกำหนดตัวแปรที่มีชื่อเดียวกับใบหน้า นั่นคือวิธีการทำงานสำหรับใบหน้าที่โหมด Font Lock กำหนด แต่

โปรดทราบว่าในโค้ดใหม่ในกรณีส่วนใหญ่ไม่จำเป็นต้องสร้างตัวแปรที่ระบุชื่อใบหน้า เพียงแค่ใช้ใบหน้าโดยตรงก็เพียงพอแล้ว Font-lock ไม่ใช่เทมเพลตที่ต้องทำตามในพื้นที่นี้

วิธีแก้ปัญหาที่แนะนำ แต่ยุ่งยากคือการอ้างสัญลักษณ์

(font-lock-add-keywords 'gyo-highlight-numbers-mode '(("[0-9]+" . 'custom-faces-highlight-numbers-face)))