การปิดวงเล็บที่ค้างอยู่ทั้งหมด


14

เมื่อเขียนรหัส lisp บางครั้งฉันลึกลงไปในนิพจน์ที่ซ้อนกันและทั้งหมดที่ฉันต้องการคือการใส่วงเล็บปิดที่หายไปทั้งหมด ตอนนี้ฉันแค่สอดมันไว้จนกว่าฉันจะได้ paren ที่ไม่ตรงกัน แต่มันไม่ได้มีประสิทธิภาพมาก
มีคำสั่งใด ๆ ที่จะแทรกวงเล็บที่หายไปทั้งหมดหรือไม่?

FYI ฉันใช้ smartparens เพื่อแทรก parens ที่ตรงกันโดยอัตโนมัติ ถึงกระนั้นบางครั้งฉันก็ต้องทำเช่นนี้


2
FWIW, Franz Lisp (ก่อน CL) มีคุณสมบัติที่]ทำหน้าที่เป็น paren ที่ถูกต้องเป็นพิเศษและปิด parens ที่เปิดอยู่ทั้งหมดตามที่คุณร้องขอ
ดึง

2
ฉันเคยใช้วิธีการเดียวกันในอดีต ตั้งแต่นั้นมาฉันเริ่มใช้pareditซึ่งหยุดปัญหาก่อนที่จะเริ่ม ข้อแม้เดียวคือการวางโค้ดไม่ได้รับการรักษาแบบสมดุล
elarson

คำตอบ:


6

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

(defun close-all-parentheses ()
  (interactive "*")
  (let ((closing nil))
    (save-excursion
      (while (condition-case nil
         (progn
           (backward-up-list)
           (let ((syntax (syntax-after (point))))
             (case (car syntax)
               ((4) (setq closing (cons (cdr syntax) closing)))
               ((7 8) (setq closing (cons (char-after (point)) closing)))))
           t)
           ((scan-error) nil))))
    (apply #'insert (nreverse closing))))

IIUC สิ่งนี้ต้องการจุดที่ไม่อยู่ในวงเล็บที่จับคู่กัน ฉันอยู่ภายใต้ความประทับใจ OQ ที่จำเป็นต้องทำงานจากบางอย่างภายในนิพจน์เสียงกระเพื่อมที่วงเล็บที่ทำจะไม่ตรงกัน แต่คนอื่นจะไม่
Malabarba

@Malabarba นี่เป็นการปิดวงเล็บที่เปิดก่อนหน้านี้ทั้งหมดไม่ว่าพวกเขาจะมีวงเล็บปิดอยู่ตรงจุดแล้วหรือยัง นั่นเป็นวิธีที่ฉันเข้าใจคำถาม แต่เป็นที่ยอมรับในจุดนี้ไม่ชัดเจน ภายใต้การตีความของคุณตัวคั่นปิดจะถูกแทรกที่ใด เช่นกับ([-!-foo]คุณแทรก])ที่จุดหรือ)หลังfoo]?
Gilles 'หยุดความชั่วร้าย'

จากความเข้าใจของฉันถ้าคุณมี([-!-foo]ผมจะใส่หลัง) foo]แต่ฉันอาจจะผิดแน่นอน บางที @rlazo สามารถทำอย่างละเอียดได้
Malabarba

สำหรับกรณีการใช้งานของฉัน @Gilles นั้นถูกต้องฉันไม่สนใจว่าตัวคั่นจะปิดหลังจากจุดนั้นหรือไม่ฉันต้องการปิดทุกอย่างก่อนถึงจุด
rlazo

3

ฉันพบว่าหากคุณติดตั้งน้ำเมือกมีคำสั่งให้ทำสิ่งนี้เรียกว่า slime-close-all-parens-in-sexp


อืม ... ดังนั้นนี่จะปิดในบรรทัดปัจจุบัน มันอาจจะดีถ้ามีวิธีการที่ปิด "บล็อกปัจจุบัน" สิ่งนี้สามารถทำได้โดยไปที่จุดสิ้นสุดของไฟล์แล้วย้าย sexp ย้อนหลังจนกว่าจะไม่มีสิ่งใดถูกปิด
Att Righ

1

เป็นวิธีดั้งเดิม (และเกือบผิดอย่างแน่นอน) ในการทำเช่นนั้น

(defun buffer-needs-parens-fixing ()
  (save-excursion
    (condition-case nil
        (check-parens)
      (error (point)))))

(defun buffer-fix-parens ()
  (interactive)
  (while (buffer-needs-parens-fixing)
    (insert ")")))

ท่ามกลางข้อ จำกัด อื่น ๆ มันจะถือว่าวงเล็บทั้งหมดที่ต้องใส่คือ:

  • คนที่ปิด
  • จำเป็นที่ตำแหน่งปัจจุบัน

ฉันเดาว่ามันอาจจะเพียงพอสำหรับการใช้งานเฉพาะของคุณ


สิ่งนี้จะติดอยู่ในการวนซ้ำไม่สิ้นสุดหากคุณมีวงเล็บปิดมากเกินไป
Emil Vikström

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