มีแพ็คเกจหรือโหมดจัดตำแหน่งอัตโนมัติสำหรับ Emacs หรือไม่


15

มีบางครั้งที่ฉันกำลังแก้ไขไฟล์ (ตัวอย่างหุ่นกระบอก) ที่ฉันต้องการจัดเรียงเนื้อหาบัฟเฟอร์ได้ทันที ตัวอย่างเช่นฉันรู้ว่าฉันสามารถใช้align-regexpหรือalignจัดรหัสเช่นนี้ตราบใดที่ฉันเลือกไว้:

# M-x align-regexp "=>" will line everything up nicely 
file { "/etc/foo":
  ensure => present,
  mode => "0666",
  source => "puppet:///modules/example/foo",
}

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

แก้ไข:ฉันถามเกี่ยวกับ Puppet และ CFEngine เพราะนั่นคือสิ่งที่ฉันรหัสในวันนี้และฉันมีการตั้งค่าที่แข็งแกร่งสำหรับข้อความชิด อย่างไรก็ตามฉันก็อยากรู้อยากเห็น (และไม่ได้แสดงอย่างนี้) ที่จะรู้ว่าการจัดตำแหน่ง on-the-fly เป็นคุณสมบัติที่พบบ่อยในโหมด Emacs (ส่วนใหญ่ในโหมดสำหรับภาษาการเขียนโปรแกรม) หรือถ้าคนส่วนใหญ่จัดเรียงเมื่อบันทึกหรือบาง จุดอื่น ๆ


มีขอบเขตขยายซึ่งมีประโยชน์สำหรับการเลือกขอบเขตที่ใหญ่ขึ้นอย่างต่อเนื่อง
bastibe

1
คุณช่วยอธิบายเพิ่มเติมเกี่ยวกับสิ่งที่คุณมักจะจัดแนวได้หรือไม่ มันเป็นสัญญาณที่เท่ากันและอยู่ในโหมดหุ่นเชิดหรือไม่? คุณสามารถแก้ไขโค้ดในคำตอบของ Emacs SE สำหรับการเยื้องอัตโนมัติโดย @Malabarba เพื่อรับสิ่งที่คุณต้องการ เพียงแทนที่indent-regionด้วยalign-to-equalsและกำหนดฟังก์ชั่นนี้เป็น(defun align-to-equals (begin end) (interactive "r") (align-regexp begin end "\\(\\s-*\\)=" 1 1 nil)); และมีemacs-lisp-mode-hook puppet-mode-hook
Kaushal Modi

คำตอบ:


5

หากคุณต้องการทำเครื่องหมายภูมิภาคสำหรับการจัดตำแหน่งอัตโนมัติอาจเป็นเรื่องยากที่จะทำสิ่งต่อไปนี้:

(require 'cl-lib)

(defvar my--auto-align-overlays nil)
(make-variable-buffer-local 'my--auto-align-overlays)

(defun my-auto-align (beg end regexp)
  (interactive "r\nsRegexp: ")
  (let ((ol (make-overlay beg end)))
    (overlay-put ol 'evaporate t)
    (overlay-put ol 'my--auto-align-regexp regexp)
    (overlay-put ol 'modification-hooks '(my--auto-align-function))
    (push ol my--auto-align-overlays)
    (add-hook 'post-command-hook 'my--auto-align-pch nil t)))

(defun my--auto-align-function (ol &rest _args)
  (cl-pushnew ol my--auto-align-overlays)
  (add-hook 'post-command-hook 'my--auto-align-pch nil t))

(defun my--auto-align-pch ()
  (dolist (ol my--auto-align-overlays)
    (align-regexp (overlay-start ol) (overlay-end ol)
                  (concat "\\(\\s-*\\)" (overlay-get ol 'my--auto-align-regexp))
                  1 align-default-spacing))
  (setq my--auto-align-overlays nil)
  (remove-hook 'post-command-hook 'my--auto-align-pch))

แต่ถ้าคุณต้องการให้มันเป็นแบบอัตโนมัติคุณจะต้องหาวิธีที่จะจำแนกลักษณะภูมิภาคที่คุณต้องการจัดตำแหน่งอัตโนมัติ (และ regexp ใด) ซึ่งยากกว่า ฉันเดาว่าคุณสามารถจัดทำ regexps แล้วสแกนบัฟเฟอร์เพื่อหาบรรทัดต่อเนื่องที่ตรงกับหนึ่งใน regexps เหล่านั้น


ฉันไม่เคยใช้การซ้อนทับมาก่อน แต่คู่มือ Elisp ดูเหมือนว่าพวกเขากำลังเปลี่ยนรูปลักษณ์ - ฉันเข้าใจใช่มั้ย ถ้าเป็นเช่นนั้นนั่นหมายความว่าคำตอบนี้จะเปลี่ยนแปลงลักษณะของบัฟเฟอร์เท่านั้นแทนที่จะเป็นเนื้อหาจริงของไฟล์เมื่อมีการบันทึก? (มันเป็นเรื่องหลังที่ฉันกำลังมองหา แต่รูปลักษณ์ที่เปลี่ยนแปลงจะเป็นตัวเลือกที่น่าสนใจ)
Saint Aardvark the Carpeted

2
@SaintAardvarktheClayeted Overlays มักถูกใช้เพื่อปรับเปลี่ยนลักษณะที่ปรากฏ ในคำตอบนี้ (IIUC) การซ้อนทับจะใช้ในการทำเครื่องหมายภูมิภาคที่จะจัดตำแหน่ง (ดังนั้นบัฟเฟอร์จึงเปลี่ยนไปจริงๆไม่ใช่แค่ลักษณะที่ปรากฏ) ฟังก์ชันmy-auto-alignนี้ใช้เพื่อกำหนดการวางซ้อนเหล่านี้ (ทำเครื่องหมายภูมิภาคที่คุณต้องการจัดตำแหน่ง) เหตุผล (ฉันคิดว่า) Stefan กำลังเผชิญกับปัญหาทั้งหมดนี้คือ (ไม่เหมือนกับการเยื้อง) หากคุณเพียงแค่พยายามจัดแนวบัฟเฟอร์ทั้งหมดคุณจะได้รับผลลัพธ์ที่ไม่พึงประสงค์ดังนั้นคุณต้องจัดตำแหน่งชิ้นส่วนในแต่ละครั้ง
Malabarba

3

โหมดหุ่นpuppet-align-blockให้ คุณสามารถจัดการให้ฟังก์ชันนี้ถูกเรียกโดยอัตโนมัติเช่นโดยการเพิ่มลงpost-command-hookในเครื่อง (ยังไม่ทดลอง):

(defun puppet-auto-align ()
  (unless (puppet-in-string-or-comment-p)
    (puppet-align-block)))

(define-minor-mode puppet-auto-align-mode
  :init-value nil
  :keymap nil
  :lighter "PAl"
  :group 'puppet-lint
  (if puppet-auto-align-mode
      (add-hook 'post-command-hook #'puppet-auto-align nil 'local)
    (remove-hook 'post-command-hook #'puppet-auto-align 'local)))

(add-hook 'puppet-mode-hook #'puppet-auto-align-mode)

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

ดังนั้น - พูดในฐานะผู้ดูแลโหมด Puppet - ฉันแนะนำต่อและเราจะไม่ช่วยคุณหรือยอมรับรายงานข้อผิดพลาดหากคุณใช้รหัสนี้

นอกจากนี้สำหรับบล็อกทรัพยากรขนาดใหญ่อาจช้าดังนั้นคุณอาจต้องการใช้ตัวจับเวลาว่างแทนการใช้post-command-hookโดยตรง

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