วิธีรับบัฟเฟอร์ (ไม่ใช่แค่ไฟล์) เพื่อเป็นเกียรติแก่ auto-mode-alist?


13

ถาม:ฉันจะรับบัฟเฟอร์ใหม่เพื่อทำแผนที่ได้auto-mode-alistอย่างไร

เมื่อค้นหาไฟล์ Emacs จะเปรียบเทียบส่วนขยายของไฟล์กับauto-mode-alistเพื่อกำหนดโหมดหลักที่จะใช้สำหรับบัฟเฟอร์ของไฟล์ มีวิธีใช้ข้อมูลในauto-mode-alistการกำหนดโหมดสำหรับบัฟเฟอร์ที่ยังไม่มีไฟล์ที่เกี่ยวข้องหรือไม่

นั่นคือ: ถ้าฉันเปิดบัฟเฟอร์ใหม่ที่ชื่อมีบางอย่างที่ดูเหมือนนามสกุลไฟล์ฉันจะให้มันเปิดโดยอัตโนมัติในโหมดที่คาดไว้ได้ไหม ตัวอย่างเช่นถ้าฉันจะเปิดบัฟเฟอร์ใหม่a-new-buffer.elที่ยังไม่ได้เชื่อมโยงกับไฟล์ฉันต้องการให้เปิดในemacs-lisp-modeแทนที่จะอยู่ในโหมดเริ่มต้น


2
แค่อยากรู้: กรณีการใช้งานคืออะไร? IOW คุณต้องการทำสิ่งนี้ทำไม / เมื่อใด / ในบริบทใด โดยทั่วไปถ้าคุณต้องการบัฟเฟอร์ที่จะเชื่อมโยงกับไฟล์และเพื่อเลือกโหมดจากauto-mode-alistคุณทำบัฟเฟอร์" เยี่ยมชม "ไฟล์ (และที่ดูแลทุกอย่าง)
Drew

5
ตัวอย่างของกรณีการใช้งานทั่วไปสำหรับฉันคือ a) ชั่วคราวorgบัฟเฟอร์การทดสอบฟังก์ชั่นใหม่ที่ผมเขียนเพื่อใช้ในการorg-mode; b) Rบัฟเฟอร์ชั่วคราวเพื่อทำการเปลี่ยนแปลงทางสถิติอย่างรวดเร็วทิ้งไป; c) บัฟเฟอร์ข้อความชั่วคราวเพื่อเขียนอีเมล ในแต่ละกรณีฉันไม่ต้องการสร้างไฟล์เพื่อเยี่ยมชมฉันแค่ต้องการบัฟเฟอร์ทิ้งที่เปิดอย่างไรก็ตามในโหมดที่เหมาะสม
แดน

2
ไฟล์คำสั่งการเยี่ยมชมเช่นC-x C-fไม่ได้ " สร้างไฟล์การมาเยือน " นั่นเป็นความเข้าใจผิดขั้นพื้นฐาน พวกเขาทำสิ่งที่คุณกำลังมองหา เป็นเพียงถ้าและเมื่อคุณพยายามบันทึกบัฟเฟอร์ที่สร้างไฟล์ หากคุณไม่พยายามบันทึกบัฟเฟอร์จะไม่มีการสร้างไฟล์ สิ่งที่คุณต้องการจากสิ่งที่ฉันเข้าใจจนถึงคือการ "เยี่ยมชมไฟล์" (ซึ่งจริงๆหมายถึงการเปิดบัฟเฟอร์ในโหมดที่เหมาะสม)
ดึง

8
เช่นเดียวกับ Dan ฉันสร้างบัฟเฟอร์ชั่วคราวตลอดเวลาที่ฉันไม่ต้องการเชื่อมโยงกับพา ธ ไฟล์จริง การไปที่พา ธ ไฟล์ปลอมจะใช้งานได้ แต่อย่างน้อยก็มีความฝืดเล็กน้อยในการเลือกไดเรคทอรี่ (หรือยอมรับในปัจจุบัน) อาจมีผลข้างเคียงอื่น ๆ ขึ้นอยู่กับการกำหนดค่าที่เหลือของคุณ: พฤติกรรมการบันทึกอัตโนมัติ? กลุ่ม Ibuffer หรือโปรเจคไทล์ที่กำหนดโดยเส้นทาง? การยืนยัน Ido แจ้งเตือน? เนื่องจากบัฟเฟอร์ต้องมีชื่ออยู่แล้วการใช้ชื่อเพื่อตั้งค่าโหมดโดยอัตโนมัติสำหรับบัฟเฟอร์ชั่วคราวทำให้รู้สึกถึงฉัน
ลูกัส

@ ดึงใช่นั่นเหมาะสมแล้วและจะเป็นคำตอบที่ง่ายที่สุดสำหรับคำถามนี้ - คุณช่วยโพสต์มันเป็นคำตอบได้มั้ย มันสมควรได้รับการอัพเกรด
ด่าน

คำตอบ:


8

คำสั่งการเยี่ยมชมไฟล์เช่นC-x C-f อย่าสร้างไฟล์ที่จะเยี่ยมชม พวกเขาทำสิ่งที่คุณกำลังมองหา

มันเป็นเพียงถ้าและเมื่อคุณพยายามที่จะ บันทึกบัฟเฟอร์ ว่าแฟ้มได้รับการสร้างขึ้น

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


4
จะทำอย่างไรถ้าคุณมีนิ้วซึ่งกระทำมากกว่าปกซึ่งจะบันทึกไฟล์ปัจจุบันทุก ๆ 3 วินาทีโดยไม่คำนึงถึงสิ่งที่คุณต้องการ?
Malabarba

1
@ Malabarba: จริง ๆ แล้วฉันมีนิ้วนั้น! ;-) บางทีพวกเราเก่า ๆ ส่วนใหญ่จะทำเช่นนี้ - นิสัยดีขึ้นเมื่อมีสิ่งผิดพลาดเกิดขึ้นตลอดเวลา แต่อย่างไรก็ตามฉันทำสิ่งที่ฉันแนะนำ: แก้ไขในบัฟเฟอร์การเยี่ยมชมทิ้งไฟล์ หากหน่วยความจำของกล้ามเนื้อไวเกินเข้ามาขวางทางและพยายามบันทึกไม่ว่าจะเป็น: ฉันnจะกดเพื่อไม่บันทึกหรือ (บ่อยครั้ง) ฉันเพิ่งบันทึกบัฟเฟอร์ และหลังจากนั้นฉันจะโยนไฟล์ที่สร้างขึ้น ... หรือไม่)
Drew

1
@Malabarba มันเป็นการป้องกันความยุ่งเหยิงของไฟล์ temp ที่ฉันเริ่มใช้ scratch buffer เฉพาะโหมดหลัก หากไฟล์มีรอยขีดข่วนคุณควรบันทึกไว้เป็นไฟล์เดียวในภายหลัง
Kaushal Modi

1
@kaushalmodi: ไม่มีอะไรกับบัฟเฟอร์โหมดเฉพาะของคุณ แต่เป็น " ความยุ่งเหยิงของไฟล์ temp " คือการทำความสะอาดได้อย่างง่ายดายขึ้นเป็นความยุ่งเหยิงของบัฟเฟอร์ ;-) และนิ้วสมาธิในรอยขีดข่วนโหมดเฉพาะบัฟเฟอร์นำเสนอปัญหาเดียวกันสันนิษฐาน - เช่นเดียวกับมันไม่ใน*scratch*: C-x C-sจะแจ้งให้คุณบันทึกเมื่อนิ้วที่ฮิตโดยอัตโนมัติ
Drew

9

ถ้าใช้Juri Linkovมาหลายปีแล้ว

C-x b test.org C-jฉันจะสร้างบัฟเฟอร์ชั่วคราวกับสิ่งที่ต้องการ จะถูกกำหนดโดยนามสกุลไฟล์ผ่านทางmajor-modeauto-mode-alist

;; http://thread.gmane.org/gmane.emacs.devel/115520/focus=115794
(setq-default major-mode
              (lambda () (if buffer-file-name
                          (fundamental-mode)
                            (let ((buffer-file-name (buffer-name)))
                          (set-auto-mode)))))

เพื่อทดสอบเอฟเฟกต์ที่คุณสามารถลอง(prog1 (and (switch-to-buffer "my-new.org") major-mode) (kill-buffer "my-new.org")) => org-modeได้ ในการทำความสะอาดการทดสอบจะกลับมาemacs -qfundamental-mode


1
มันฉลาดมาก! นอกจากนี้ยังเป็นระเบียบadviceเรียบร้อยกว่าตัวเลือกที่ฉันใช้ ไม่แน่ใจว่าฉันติดตามสิ่งที่(prog1...)มีไว้สำหรับชิ้นส่วนนั้น แต่(setq-default major-mode ...)ส่วนนั้นค่อนข้างดี
ด่าน

1
รู้สึกอิสระที่จะตรวจสอบเว็บไซต์ของ Emacs Juri การprog1ทดสอบแสดงให้เห็นว่าคุณได้รับความคาดหวังmajor-modeเมื่อเปลี่ยนเป็นบัฟเฟอร์ Eval setq-defaultส่วนและเรียกใช้การทดสอบ มันจะกลับมาorg-mode โดยไม่ต้องมันก็จะกลับมาsetq-default fundamental-mode
rasmus

นี่เป็นวิธีที่สวยงามกว่า buffer-list-update-hook ของฉัน ขอบคุณ!
ลูกัส

นี้ควรจะเป็นคำตอบที่ได้รับการยอมรับเพราะมันจริงตอบคำถามมากกว่าบอกเราว่าทำไมเราจะไม่ถูกต้องสำหรับการขอมัน :)
Shlomi

6

หาวิธีตามคำแนะนำโดยใช้แนวคิดที่มาจากความคิดเห็นของ @ Drew และคำตอบของ @ glucas ที่ฉันจะบันทึกที่นี่ในกรณีที่พวกเขามีประโยชน์สำหรับทุกคน

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

สำหรับido-switch-bufferและวานิลลาswitch-to-bufferคำแนะนำสองประการคือ:

(defadvice ido-switch-buffer (after set-mode activate)
  (unless buffer-file-name
    (let ((buffer-file-name (buffer-name)))
      (set-auto-mode t))))

(defadvice switch-to-buffer (after set-mode activate)
  (unless buffer-file-name
    (let ((buffer-file-name (buffer-name)))
      (set-auto-mode t))))

ฉันพบตัวเลือกนี้เป็นประโยชน์ด้านบนของfind-fileจุดนั้น @Drew ยกเพราะมือของฉันจะได้รับไปข้างหน้าของสมองของฉัน: หน่วยความจำของกล้ามเนื้อมักจะได้รับฉันเข้าไปในดินแดนสวิทช์การบัฟเฟอร์ก่อนที่มันจะเกิดขึ้นอย่างเต็มที่กับผมว่าfind-fileจะทำสิ่งที่ฉันต้องการ ตอนนี้มีให้เลือกทั้งสองแบบ

อัปเดต:ข้อบกพร่องเล็ก ๆ แต่อาจเกิดการระคายเคืองในรหัสด้านบน: มันจะเรียกใช้โหมดฮุกอีกครั้งบนบัฟเฟอร์ในแต่ละครั้งที่คุณเปลี่ยนมาใช้ ต่อไปนี้ให้ชื่อไฟล์จริงนอก/tmpไดเรกทอรีและหลีกเลี่ยงปัญหานั้น:

(defadvice ido-switch-buffer (after set-mode activate)
  (unless buffer-file-name
    (setq buffer-file-name (concat "/tmp/" (buffer-name)))
    (set-auto-mode t)))

ดูดีและทำความสะอาดคราบน้ำมันที่คำตอบของฉันได้สะสมซ้ำสองรอบ :-) ฉันจะทำซ้ำที่นี่ว่าถ้าคุณไม่ต้องการตั้งค่าเส้นทางไฟล์จริงด้วยเหตุผลบางอย่างคุณสามารถใช้ตัวแปร buffer-local เพื่อหลีกเลี่ยงการตั้งค่าโหมดหลายครั้ง
ลูกัส

5

set-auto-modeฟังก์ชั่นชุดโหมดบนพื้นฐานของไฟล์ที่เกี่ยวข้องกับกันชน นี่คือฟังก์ชั่นที่ตั้งค่าชั่วคราวbuffer-file-nameจากชื่อบัฟเฟอร์เพื่อตั้งโหมด:

(defun my/set-buffer-mode (buffer &optional again)
  "Set the mode for BUFFER from the name.  
When called repeatedly for the same buffer only set the mode the first
time, unless the optional argument AGAIN is specified.
Does nothing if the buffer is associated with a file."

  (with-current-buffer buffer
    (when again (kill-local-variable 'my/buffer-mode-set))
    (unless (or buffer-file-name 
            (local-variable-p 'my/buffer-mode-set))
      (let ((buffer-file-name (buffer-name)))
        (set-auto-mode t)
        (setq-local my/buffer-mode-set t)))))

คุณสามารถเรียกใช้เมื่อบัฟเฟอร์ถูกเปลี่ยนชื่อโดยใช้คำแนะนำ:

(defadvice rename-buffer (after my/rename-update-mode activate)
  (my/set-buffer-mode (current-buffer) 'again))

ฉันไม่แน่ใจเกี่ยวกับสถานที่ที่ดีที่สุดในการเชื่อมต่อกับบัฟเฟอร์ใหม่ ที่นี่ฉันใช้buffer-list-update-hookแต่ได้รับการเรียกในกรณีมากกว่าที่เราต้องการ

(add-hook 'buffer-list-update-hook
      '(lambda ()
         (my/set-buffer-mode (car (buffer-list)))))

คำตอบข้างต้นได้รับการแก้ไขเพื่อจัดการกับปัญหาบางอย่าง โดยเฉพาะฉันกลับไปใช้buffer-list-update-hookเนื่องจากchange-major-mode-hookไม่มีการเรียกด้วยบัฟเฟอร์ปัจจุบันที่คาดไว้ สำหรับเร็กคอร์ดมันอาจเหมาะสมกว่าที่จะแนะนำฟังก์ชั่นบัฟเฟอร์บัฟเฟอร์ของคุณตามที่ @Dan ทำในคำตอบของเขา
ลูกัส

3

คุณสามารถใช้ * scratch * บัฟเฟอร์เพื่อสร้างบัฟเฟอร์ชั่วคราวที่มีโหมดหลักเหมือนกับไฟล์ที่คุณอาจใช้งาน

นี่คือคำตอบของ emacs SE ที่อาจแก้ปัญหาของคุณ:

ฉันจะสลับอย่างรวดเร็วระหว่างไฟล์และบัฟเฟอร์ * scratch * ที่มีโหมดหลักเดียวกันได้อย่างไร

ทั้งคำถามและคำตอบที่อ้างอิงนั้นโพสต์โดยฉัน คำตอบในฟังก์ชั่นทำดังต่อไปนี้:

  • หากคุณกำลังทำงานในโหมด X major ในไฟล์การเรียกใช้ฟังก์ชั่นนี้จะสร้างบัฟเฟอร์ใหม่ที่เรียกว่า*scratch-X-mode*ถ้าไม่มีอยู่แล้วและสลับไปที่บัฟเฟอร์ที่สร้างขึ้นใหม่นี้
  • หาก*scratch-X-mode*มีอยู่แล้วมันจะสลับไปที่บัฟเฟอร์นั้น
  • เรียกใช้ฟังก์ชันนี้อีกครั้งในขณะที่ในบัฟเฟอร์รอยขีดข่วนนั้นจะนำคุณกลับไปยังบัฟเฟอร์ไฟล์ที่คุณกำลังทำงานอยู่

0

มีคำตอบที่ดีที่นี่ แต่ฉันต้องการเพิ่มอีกหนึ่งสิ่ง Emacs มีฟีเจอร์มากมายและมักจะมีหลายวิธีในการทำบางสิ่ง คุณสามารถเพิ่มแท็กที่ด้านบนของไฟล์ใด ๆ ที่บอก emacs ประเภทใดโดยไม่คำนึงถึงนามสกุล ตัวอย่างเช่นการเพิ่มสิ่งนี้:

# -*-Python-*-

ที่ด้านบนของไฟล์จะทำให้ emacs รู้ว่าเป็นไฟล์ Python แม้จะไม่มี.pyนามสกุลก็ตาม โปรดทราบว่า#ที่จุดเริ่มต้นของบรรทัดเป็นความคิดเห็นสไตล์งูหลาม สำหรับประเภทไฟล์ที่แตกต่างกันคุณสามารถใช้ความคิดเห็นที่แตกต่างกัน ตัวอย่างเช่นเพื่อระบุไฟล์ Lisp ที่คุณใช้;เพื่อเริ่มบรรทัดความคิดเห็นและตั้งค่าโหมดเป็น emacs ดังนี้:

; -*- mode: Lisp;-*-

ดูการระบุตัวแปรไฟล์และเลือกโหมดไฟล์


ใช่ แต่คำถามที่นี่โดยเฉพาะเกี่ยวกับการสร้างบัฟเฟอร์ใหม่ชั่วคราว (เช่นกับswitch-buffer) fundamental-modeและมีโหมดตั้งค่าโดยอัตโนมัติอย่างอื่นที่ไม่ใช่
ลูกัส
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.