วิธีเพิ่มการเน้นไวยากรณ์ที่ซับซ้อนในโหมดรองได้อย่างไร


10

ฉันต้องการไฮไลต์โค้ดด้วยใบหน้าต่างๆในโหมดรอง

นี่คือภาพหน้าจอที่ใกล้เคียงกับสิ่งที่ฉันต้องการ:

หลามไวยากรณ์ไฮไลท์

สิ่งหนึ่งที่ฉันหายไปจะมีตัวอักษรแสดงความคิดเห็นใน# font-lock-comment-faceแนวคิดคือมีความคิดเห็นที่ "เป็น" ของโครงร่างที่เน้นเป็นข้อความธรรมดาดังนั้นจึงง่ายต่อการอ่าน ในขณะที่มีความเห็นปกติกับใบหน้าที่โดดเด่นน้อยกว่าปกติของพวกเขา

นี่คือรหัสที่ฉันใช้:

(setq-local font-lock-defaults
            '(python-font-lock-keywords
              nil nil nil nil
              (font-lock-syntactic-face-function
               . lpy-font-lock-syntactic-face-function)))

(defun lpy-font-lock-syntactic-face-function (state)
  "Return syntactic face given STATE.
Returns 'defalt face for comments that belong to an outline."
  (cond ((nth 3 state)
         (if (python-info-docstring-p state)
             font-lock-doc-face
           font-lock-string-face))
        ((save-excursion
           (while (and (> (point) (point-min))
                       (progn (move-beginning-of-line 0)
                              (eq (char-after) ?\#))))
           (forward-line 1)
           (looking-at "#\\*+ "))
         'default)
        (t
         font-lock-comment-face)))

สิ่งคือฉันไม่มีเงื่อนงำเกี่ยวกับอินเทอร์เฟซที่ font-lock-syntactic-face-functionทำงานนอกเหนือจากที่ได้รับโครงสร้างข้อมูลที่ซับซ้อนstateมีสถานะจุดที่แตกต่างกันและส่งกลับใบหน้า

มีคนอธิบายอินเตอร์เฟซนี้ได้ไหม อาจมีสิ่งที่ดีกว่าหรือไม่?

คำตอบ:


6

font-lock-syntactic-face-functionเป็นตัวแปรปกติจาก Font Lock โดยเฉพาะอย่างยิ่งจากขั้นตอนการล็อคแบบอักษรของ Syntactic (เหมืองที่เน้น):

หากตัวแปรนี้ไม่ใช่ศูนย์มันควรจะเป็นฟังก์ชั่นเพื่อกำหนดใบหน้าที่จะใช้สำหรับองค์ประกอบวากยสัมพันธ์ที่กำหนด (สตริงหรือความคิดเห็น) โดยปกติค่าจะถูกตั้งค่าผ่านอิลิเมนต์ other-vars ใน font-lock-defaults

ฟังก์ชั่นเรียกว่ามีหนึ่งอาร์กิวเมนต์รัฐแจงที่จุดกลับโดยparse-partial-sexpและควรกลับใบหน้า ค่าเริ่มต้นส่งคืน font-lock-comment-face สำหรับความคิดเห็นและ font-lock-string-face สำหรับสตริง (ดูที่ Faces for Font Lock)

parse-partial-sexpในทางกลับกันส่งกลับรายการซึ่งอธิบายสถานะ syntactic ปัจจุบันของ Emacs ซึ่งเป็นผลมาจากการใช้ตารางไวยากรณ์ไปยังบัฟเฟอร์ปัจจุบัน รายการค่อนข้างซับซ้อนดังนั้นฉันจะสำรองไว้ที่นี่ คุณสามารถดูอ้างอิงที่สมบูรณ์ใน docstring parse-partial-sexpของ วัตถุประสงค์ของฟังก์ชั่นนี้คือการเปลี่ยนใบหน้าที่ใช้กับองค์ประกอบประโยคภายใต้กฎบางอย่าง จุดเริ่มต้นของฟังก์ชั่นของคุณแสดงให้เห็นถึงสิ่งนี้: ถ้าสตริงปัจจุบันเป็น docstring ให้ใช้ใบหน้าที่แตกต่างกัน

อย่างไรก็ตามใบหน้าใช้กับองค์ประกอบประโยคทั้งหมดเช่นสตริงทั้งหมดหรือความคิดเห็น คุณไม่สามารถเน้นชิ้นส่วนแต่ละชิ้นด้วยฟังก์ชั่นนี้ได้และคุณควรดูเฉพาะสิ่งที่กำหนดstateเพื่อจุดประสงค์นี้ - เช่นเดียวกับ(python-info-docstring-p state)ในรหัสของคุณ อย่าได้ใช้จุดที่สถานที่นี้ ฉันไม่แน่ใจด้วยซ้ำว่าการกำหนดค่าของการpointล็อคแบบอักษรในขั้นตอนนี้ถูกต้องหรือไม่


การนำชิ้นส่วนต่างๆมารวมกันคุณกำลังใช้ฟังก์ชั่นที่ไม่ถูกต้องเพื่อจุดประสงค์ของคุณซึ่งเป็นสาเหตุที่คุณไม่สามารถใช้งานได้

ฉันไม่ได้พยายามที่จะใช้ไฮไลต์ที่คุณต้องการ แต่ฉันคิดว่าคุณขุดวิธีลึกเกินไปสำหรับวัตถุประสงค์ของคุณ หากฉันเข้าใจสิ่งต่าง ๆ ที่ถูกต้องคุณก็แค่ต้องการไฮไลต์โครงร่างในความคิดเห็น

ถ้าฉันถูกคุณก็แค่ต้องการfont-lock-keywordsวิธีพิเศษคือ:

(my/find-outline-in-comment-p 0 'outline-face t)

ที่outline-faceเป็นใบหน้าที่คุณต้องการที่จะนำไปใช้กับพาดหัวtหมายถึงการแทนที่ตัวอักษรใด ๆ ล็อคก่อนที่สถานที่นี้และmy/find-outline-in-commentเป็นฟังก์ชั่นการจับคู่ (ดู docstring ของfont-lock-defaults) ซึ่งจะมีตำแหน่งและค้นหาร่างแรกในการแสดงความคิดเห็น ระหว่าง(point)และตำแหน่งนั้นให้ส่งคืนขอบเขตของเค้าร่างเพื่อเน้นในข้อมูลการจับคู่

ในการค้นหาโครงร่างคุณจะสแกนความเห็นล่วงหน้า (โดยใช้font-lock-comment-faceหรือสถานะวากยสัมพันธ์) จากนั้นใช้looking-atเพื่อตรวจสอบว่าความคิดเห็นนั้นมีเค้าโครงหรือไม่


1

พิจารณากำหนดfont-lock-syntactic-face-functionเช่นนั้น:

(setq font-lock-syntactic-face-function
      (lambda (state)
    (cond ((nth 3 state)
           font-lock-string-face)
          ((and (nth 4 state)(nth 8 state))
            MY-COMMENT-FACE
          (t  font-lock-comment-face))))

สิ่งนี้ทดสอบกับ python-mode.el โดยปล่อยส่วนที่ขึ้นต้นด้วย "# *" โดยไม่ต้องแสดงความคิดเห็น:

(setq py--font-lock-syntactic-face-function
      (lambda (state)
    (cond ((nth 3 state)
           font-lock-string-face)
          ((and (nth 4 state)(nth 8 state)
            (progn (save-excursion
                 (goto-char (nth 8 state))
                 (looking-at (concat comment-start (regexp-quote "*"))))))
           nil)
          (t font-lock-comment-face))))

ขณะที่จัดการกับโหมด:

(font-lock-syntactic-face-function
                    . py--font-lock-syntactic-face-function)

แทนที่จะnilใบหน้าที่ถูกต้องควรจะทำงาน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.