ไฟล์เครื่องหมายย่อหน้าเติมที่เปลี่ยนแปลงแม้ว่ามันจะไม่ได้ทำอะไรเลย


11

เมื่อใดก็ตามที่ฉันเรียกfill-paragraphใช้บัฟเฟอร์จะถูกทำเครื่องหมายว่ามีการปรับเปลี่ยนเสมอแม้ว่าคำสั่งจะไม่มีผลกระทบ (เช่นถ้าเติมย่อหน้าแล้ว) มันยังสร้างการกระทำที่ไม่สามารถยกเลิกได้ที่ว่างเปล่า (ตรวจจับได้ง่ายด้วยundo-tree-mode) คำสั่งอื่น ๆ ที่มีศักยภาพในการเปลี่ยนแปลงเช่นคำสั่งเยื้องไม่ได้ทำเครื่องหมายบัฟเฟอร์ว่ามีการแก้ไขหรือสร้างการกระทำที่เลิกทำการได้หากไม่มีการเปลี่ยนแปลงใด ๆ มีวิธีใดในการทำfill-paragraphเครื่องหมายบัฟเฟอร์ที่แก้ไขและสร้างการกระทำที่ยกเลิกไม่ได้เฉพาะเมื่อมันเปลี่ยนบางสิ่งบางอย่างจริง ๆ ?


ฉันไม่คิดว่ามันถูกM-qต้อง - ไม่ทำเครื่องหมายว่าบัฟเฟอร์เปลี่ยนโดยค่าเริ่มต้นอย่างน้อยจากการทดสอบของฉัน คุณกำลังใช้โหมดอะไร ฉันเดาว่าโหมดนั้นเขียนทับไม่fill-paragraphทางใดก็ทางหนึ่ง
shosti

@shosti ฉันใช้โหมดพื้นฐาน ย่อหน้าต้องมีความยาวมากกว่าหนึ่งบรรทัด (เมื่อเติมอย่างเหมาะสม)
Lily Chung

อ่าฉันเห็นมันแล้ว
shosti

คำตอบ:


2

โปรดทราบว่านี่ได้รับการแก้ไขแล้วสำหรับ Emacsen รุ่นใหม่ (v.26 ขึ้นไป)


10

ปัญหาคือfill-paragraph(หรือมากกว่าfill-region-as-paragraph) จะลบและแทรกบรรทัดใหม่ในขณะที่แบ่งย่อหน้าของคุณ มันจะไม่แก้ไขบัฟเฟอร์หากมีเพียงหนึ่งบรรทัด ไม่มีตัวเลือกในรายการยกเลิกคุณเป็นพยานเป็นเพียงfill-paragraphการลบและแทรกขึ้นบรรทัดใหม่

มันไม่สำคัญเลยที่จะหลีกเลี่ยงสิ่งนี้ ต่อไปนี้เป็นแฮ็คที่แย่และไม่มีประสิทธิภาพสูงสำหรับบัฟเฟอร์ขนาดใหญ่ แต่อาจใช้งานได้กับคุณ คำสั่งเลียนแบบfill-paragraph( M-q) ที่มีพฤติกรรมเหมือนกันยกเว้นจะเก็บเนื้อหาของบัฟเฟอร์ก่อนที่จะเรียกมันและหลังจากนั้นถ้าเนื้อหายังคงเหมือนเดิมมันจะคืนค่าสถานะการแก้ไขและเลิกทำรายการก่อนการเปลี่ยนแปลง ในการทำเช่นนี้จำเป็นต้องมีการคัดลอก (สองอัน) ของเนื้อหาบัฟเฟอร์ดังนั้นจริงๆแล้วมันไม่มีประสิทธิภาพเลย :-)

(defun my/fill-paragraph (&optional justify region)
  (interactive (progn
                 (barf-if-buffer-read-only)
                 (list (if current-prefix-arg 'full) t)))
  (let ((old-text (buffer-string))
        (old-modified (buffer-modified-p))
        (old-undo-list buffer-undo-list))
    (fill-paragraph justify region)
    (when (equal old-text (buffer-string))
      (setq buffer-undo-list old-undo-list)
      (set-buffer-modified-p old-modified))))

M-qคุณสามารถผูกที่


1
ใช่มันเจ็บปวดมานานแล้ว ;-) ฉันสงสัย (ฉันจำไม่ได้) ว่ามีการร้องขอการแก้ไขนี้มาก่อนหรือไม่ ดูเหมือนว่ามันจะได้รับ
ดึง

อืมม ฉันสงสัยว่ามีวิธีแก้ปัญหาที่ดีกว่าซึ่งไม่ต้องตรวจสอบบัฟเฟอร์ทั้งหมด - อาจตรวจสอบเฉพาะย่อหน้าที่เลือกได้หรือไม่
Lily Chung

fill-paragraphมีความแตกต่างระหว่างกรณีต่าง ๆ บ้างเช่นพฤติกรรมแตกต่างกันไปตามภูมิภาคที่ใช้งานอยู่ฟังก์ชันเติมย่อหน้าที่มีอยู่ ฯลฯ คุณจะต้องจำลองพฤติกรรมนั้นเพื่อให้เข้าใจว่าส่วนใดของบัฟเฟอร์ที่จะเปลี่ยนไป เป็นไปได้ แต่ยุ่งยาก :-)
Jorgen Schäfer

@Drew มีการอภิปรายเกี่ยวกับเรื่องนี้ในรายการส่งเมลเมื่อปีที่แล้ว: ข้อผิดพลาด # 13949: 24.3.50; 'เติมย่อหน้า' ไม่ควรใส่บัฟเฟอร์ตามที่แก้ไขทุกครั้ง
dkim

@dkim: ใช่ฉันจำได้แล้วตอนนี้ และไม่มีอะไรที่เคยออกมาจากมัน ...
ดึง

1

ตอบช้ากว่า แต่นี่เป็นเวอร์ชั่นง่าย ๆ ที่ไม่ได้แก้ไขบัฟเฟอร์หากข้อความไม่เปลี่ยนแปลง

(defun my-fill-paragraph (&optional justify region)
  "Fill paragraph, but don't modify the buffer if filling doesn't
change the text.  See `fill-paragraph' for details."
  (interactive (progn
                 (barf-if-buffer-read-only)
                 (list (if current-prefix-arg 'full) t)))
  (if (buffer-modified-p)
      ;; if modified: use standard fill-paragraph
      (fill-paragraph justify region)
    ;; if unmodified: get a candidate filled version
    (save-excursion
      (let* ((col fill-column)
             (beg (progn (forward-paragraph -1)
                         (skip-syntax-forward " >")
                         (point)))
             (end (progn (forward-paragraph 1)
                         (skip-syntax-backward " >")
                         (point)))
             (old (buffer-substring-no-properties beg end))
             (new (with-temp-buffer
                    (setq fill-column col)
                    (insert old)
                    (fill-paragraph justify region)
                    (buffer-string))))
        ;; don't modify unless the old and new versions differ
        (unless (string-equal old new)
          (delete-region beg end)
          (insert new))))))

มันปรับความคิดบางอย่างในคำตอบของ @ JorgenSchäfer แต่ทำงานได้กับย่อหน้าปัจจุบันเท่านั้นและใช้วิธีแยกช่องว่างอย่างง่าย (ดูความคิดเห็นเกี่ยวกับคำตอบของ @ JorgenSchäferเกี่ยวกับภาวะแทรกซ้อนภายใต้ฝากระโปรง)

นี่เป็นเรื่องเกี่ยวกับกรณีการใช้งานเพียงอย่างเดียวที่เกี่ยวข้องกับวัตถุประสงค์ของตัวเอง (เช่นการใช้งานแบบโต้ตอบกับร้อยแก้ว "ปกติ" ไม่มีภูมิภาคที่ใช้งานอยู่) ดังนั้นฉันจึงโพสต์มันในกรณีที่ใครก็ตามต้องการใช้มันหรือปรับปรุงมัน .

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