ฉันจะตรวจสอบได้อย่างไรว่าตัวละครปัจจุบันเป็นตัวอักษรสำหรับโหมดหลักนั้นหรือไม่?


12

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

ตัวอย่าง:

ก่อน

;; comment 1▮
;; comment 2

การเรียกร้อง M-x modi/pull-up-line

หลังจาก

;; comment 1▮comment 2

โปรดทราบว่า;;ตัวละครจะถูกลบออกก่อนหน้าcomment 2นี้

(defun modi/pull-up-line ()
  "Join the following line onto the current one (analogous to `C-e', `C-d') or
`C-u M-^' or `C-u M-x join-line'.

If the current line is a comment and the pulled-up line is also a comment,
remove the comment characters from that line."
  (interactive)
  (join-line -1)
  ;; If the current line is a comment
  (when (nth 4 (syntax-ppss))
    ;; Remove the comment prefix chars from the pulled-up line if present
    (save-excursion
      (forward-char)
      (while (looking-at "/\\|;\\|#")
        (delete-forward-char 1))
      (when (looking-at "\\s-")
        (delete-forward-char 1)))))

ฟังก์ชั่นข้างต้นทำงาน แต่ตอนนี้ไม่คำนึงถึงหลักโหมดก็จะพิจารณา/หรือ;หรือเป็นตัวอักษรแสดงความคิดเห็น:#(looking-at "/\\|;\\|#")

ฉันต้องการทำให้บรรทัดนี้ฉลาดขึ้น โหมดหลักเฉพาะ

วิธีการแก้

ขอบคุณ @ericstokes 'solution ฉันเชื่อว่าตอนนี้จะครอบคลุมกรณีการใช้ของฉันทั้งหมด :)

(defun modi/pull-up-line ()
  "Join the following line onto the current one (analogous to `C-e', `C-d') or
`C-u M-^' or `C-u M-x join-line'.

If the current line is a comment and the pulled-up line is also a comment,
remove the comment characters from that line."
  (interactive)
  (join-line -1)
  ;; If the current line is a comment
  (when (nth 4 (syntax-ppss))
    ;; Remove the comment prefix chars from the pulled-up line if present
    (save-excursion
      (forward-char)
      ;; Delete all comment-start or space characters
      (while (looking-at (concat "\\s<" ; comment-start char as per syntax table
                                 "\\|" (substring comment-start 0 1) ; first char of `comment-start'
                                 "\\|" "\\s-")) ; extra spaces
        (delete-forward-char 1)))))

คุณต้องการให้มันฉลาดพอที่จะรับมือกับความคิดเห็นที่แตกต่างกันทั้งตัวอักษรเริ่มต้นและตัวละครสุดท้ายและความคิดเห็นหลายตัวละคร (เช่นของ C /* ... */) หรือไม่?
erikstokes

ไม่นั่นคือทั้งหมดที่ฉันต้องการ ขอบคุณ!
Kaushal Modi

@erikstokes จากความอยากรู้คุณจะจัดการความคิดเห็นแบบ C อย่างไร
Pradhan

วิธีนี้ใช้ได้กับความคิดเห็นหลายบรรทัดในทันทีไม่จำเป็นต้องทำอะไรเป็นพิเศษเพราะเราไม่จำเป็นต้องลบอักขระใด ๆ เมื่อเข้าร่วมความคิดเห็นหลายบรรทัด
Kaushal Modi

2
@Phanhan มีcomment-startและcomment-endสตริงที่ตั้งค่าเป็น "/ *" และ "* /" ในc-mode(แต่ไม่ใช่c++-mode) และมีc-comment-start-regexpที่ตรงกับสไตล์ทั้งสอง คุณลบอักขระสิ้นสุดจากนั้นเริ่มต้นหลังจากเข้าร่วม แต่ฉันคิดว่าวิธีแก้ปัญหาของฉันuncomment-regionคือjoin-lineการcomment-regionปล่อยให้ Emacs กังวลเกี่ยวกับสิ่งที่ตัวละครแสดงความคิดเห็นคืออะไร
erikstokes

คำตอบ:


12

(looking-at "\\s<")คุณสามารถตรวจสอบว่าตัวละครในปัจจุบันคือความคิดเห็นของตัวละครโดยใช้ตารางไวยากรณ์: regexp \\s<จะจับคู่อักขระใด ๆ กับไวยากรณ์ "ความคิดเห็นเริ่มต้น"; \\s>จะจับคู่กับไวยากรณ์ "ความคิดเห็นท้าย"

ตัวเลือกอื่นคือตัวแปรcomment-startซึ่งเป็นสตริงที่แทรกโดยcomment-dwimและเพื่อน ๆ โดยทั่วไปแล้วมันจะถูกตั้งค่าเป็นตัวอักษรเริ่มต้นความคิดเห็นบวกบางพื้นที่


2

มีวิธีแก้ปัญหาที่ง่ายกว่ามากโปรดศึกษารหัสของฉันที่https://github.com/redguardtoo/evil-nerd-commenter/blob/master/evil-nerd-commenter.el

ฉันจะไม่คัดลอก / วางรหัสทั้งหมดที่นี่ แต่นี่คือประเด็นสำคัญ:

  • ความคิดเห็นมีแบบอักษรของตัวเองค้นหา font-lock-comment-face และ font-lock-comment-delimiter-face ในรหัสของฉัน

  • ใช้ API ของ Emacs เองเพื่อยกเลิกหมายเหตุบรรทัดที่สองจากนั้นเข้าร่วมกับบรรทัดแรก

ควรทำงานกับโหมดหลัก ๆ ที่เหมาะสม

เคล็ดลับนี้ไม่ได้คิดค้นโดยฉัน มันมาจากรหัสของ Emacs (โดยเฉพาะอย่างยิ่ง flyspell) ดังนั้นวิธีการแก้ปัญหาควรสนับสนุนโหมดหลักของ flyspell


3
หากต้องการเน้นสิ่งที่เป็นความคิดเห็นมันต้องมีการตั้งค่าตารางไวยากรณ์อย่างเหมาะสมดังนั้นฉันจึงสงสัยว่านี่ฉลาดกว่าทางเลือกอื่นในการดูไวยากรณ์
wasamasa

ฉันได้เรียนรู้เคล็ดลับนี้โดยการอ่านรหัสของ Emacs (อันที่จริงมันคือ flyspell) ตามที่ฉันบันทึกไว้ในรหัสของฉัน
เฉินปิน

0

หากคุณกำลังมองหาคุณสมบัตินี้สำหรับรหัสเสียงกระเพื่อม (Elisp, Clojure, Scheme และ Common LISP) คุณควรลองlispyฟังก์ชันที่เรียกว่าlispy-fillทำสิ่งนี้

หากคุณกำลังมองหาคุณสมบัตินี้สำหรับภาษาอื่นคุณควรrebox2 (ตรวจสอบแล้วCและPython) ฟังก์ชั่นที่เรียกว่าrebox-fillหรือฟังก์ชั่นอื่นที่เรียกว่าrebox-dwimทำสิ่งนี้

พวกเขาทั้งสองเป็นแพ็คเกจที่ยอดเยี่ยมและพวกเขาไม่ได้ขัดแย้งกันเนื่องจากใช้สำหรับโหมดหลักที่แตกต่างกันและพวกเขาทั้งสอง ( lispy-fillและrebox-dwim) ผูกพันกับM-qค่อนข้างเรียบร้อย

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