Elisp สำหรับการใช้คำสั่งกับภูมิภาคที่เลือกเท่านั้น


18

บอกว่าฉันมีรหัสเช่นนี้:

(defun some-function ()
  (interactive)
  ;; do something
  )

ตอนนี้ฉันต้องการsome-functionทำงานเฉพาะในพื้นที่ที่เลือกในบัฟเฟอร์หรือไม่ ฉันจะทำสิ่งนั้นได้อย่างไร นอกจากนี้ยังมีเส้นทางรหัสสองทางแยกสำหรับทำบางสิ่งบางอย่างถ้าฉันเลือกบางภูมิภาคและทำอย่างอื่นถ้าฉันไม่ได้เลือก

คำตอบ:


22
(defun some-function (beginning end)
  (interactive "r")
  (if (use-region-p)
      (message "The region is active, and is from %d to %d" beginning end)
    (message "The region is still there (from % d to %d), but it is inactive" 
             beginning end)))

การใช้(interactive "r")หมายความว่าพารามิเตอร์beginningและendจะรับค่าของจุดเริ่มต้นของภูมิภาคและจุดสิ้นสุดตามลำดับโดยอัตโนมัติเมื่อมีการเรียกใช้ฟังก์ชัน (คุณสามารถรับค่าเหล่านั้นได้ทุกเมื่อโดยใช้ฟังก์ชั่นregion-beginningและregion-endตามลำดับ)

ภูมิภาคนั้นจะมีอยู่เสมอ (หากมีเครื่องหมายในบัฟเฟอร์ปัจจุบัน) แต่คุณอาจไม่คิดว่ามันเป็น พื้นที่ใช้งานได้เมื่อมีการเน้น (เลือกข้อความ) region-active-pคุณสามารถทดสอบว่าพื้นที่นั้นมีการใช้งานโดยใช้คำกริยา แต่โดยปกติแล้วการทดสอบที่ดีกว่านั้นuse-region-pเพราะ (โดยค่าเริ่มต้น) จะส่งกลับค่าจริง (ไม่ใช่ - nil) เฉพาะเมื่อภูมิภาคนั้นมีการใช้งานและไม่ว่าง (จุดและเครื่องหมายจะแตกต่างกัน)

แต่เดิมไม่มีการเน้นถึงภูมิภาค และเป็นเวลานานถึงแม้ว่าการไฮไลต์จะพร้อมใช้งาน แต่ก็ไม่ใช่พฤติกรรมเริ่มต้น เพื่อให้การไฮไลต์เกิดขึ้นคุณต้องtransient-mark-modeเปิดใช้งาน (หรือเปิดอย่างน้อยชั่วคราว) โดยค่าเริ่มต้นtransient-mark-modeจะเปิดใช้งานในเวอร์ชันล่าสุดของ Emacs

การดูนิยามของเพรดิเคตเป็นประโยชน์use-region-p:

(defun use-region-p ()
  (and (region-active-p)
       (or use-empty-active-region
           (> (region-end) (region-beginning)))))

use-empty-active-regionเป็นตัวเลือกผู้ใช้ที่มีค่าเริ่มต้นคือnil(จริง) ซึ่งหมายความว่าโดยค่าเริ่มต้นuse-region-pจะไม่ส่งคืนจริงถ้าภูมิภาคว่างเปล่า ในกรณีนั้นเพื่อให้มันกลับมาจริงจุดสิ้นสุดของภูมิภาคจะต้องมากกว่าจุดเริ่มต้น (พฤติกรรมที่ฉันอธิบายไว้ข้างต้น)

และถ้าเราดูนิยามของregion-active-p:

(defun region-active-p ()
  (and transient-mark-mode
       mark-active
       (mark)))

เราเห็นว่ามันส่งคืนจริง (ไม่ใช่ - nil) เมื่อสิ่งเหล่านี้เป็นจริง:

  • transient-mark-mode เปิดอยู่
  • เครื่องหมายทำงานอยู่ ( mark-active)
  • มีเครื่องหมายในบัฟเฟอร์ปัจจุบัน

เครื่องหมายที่ใช้งานอยู่เป็นสิ่งที่ภูมิภาคกำลังใช้งานอยู่เป็นเรื่องจริง เมื่อมีการใช้งานสมมติว่าtransient-mark-modeเปิดและมีเครื่องหมายในบัฟเฟอร์ปัจจุบันพื้นที่จะถูกเน้น


AFAICS ถ้าเครื่องหมายถูกตั้งไว้ที่จุดเช่นบริเวณนั้นยังไม่ขยายเครื่องหมายที่ใช้งานจะเป็นศูนย์ ดังนั้น Mark-active และ Transient-Mark-Mode จึงเป็นเพียงสิ่งเดียวที่เพิ่มมูลค่าในฟังก์ชั่นการทำงานซ้ำซ้อนเหล่านี้
Andreas Röhler

1
@ AndreasRöhler: ไม่ C-SPC M-: mark-active=> t คุณสามารถมีพื้นที่ว่างที่ยังคงทำงานอยู่
ดึง

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