ฉันจะเปลี่ยนโหมดอ่าน / เขียนสำหรับไฟล์โดยใช้ Emacs ได้อย่างไร


126

หากไฟล์ถูกตั้งค่าเป็นโหมดอ่านอย่างเดียวฉันจะเปลี่ยนเป็นโหมดเขียนได้อย่างไรและในทางกลับกันจากภายใน Emacs

คำตอบ:


178

Mx สลับอ่านอย่างเดียว

หรือในเวอร์ชันล่าสุดของ Emacs

โหมดอ่านอย่างเดียว Mx

ในกล่อง Windows ของฉันจำนวนนั้นจะเท่ากับ Alt-x เพื่อเปิดเมตาพรอมต์และพิมพ์ "toggle-read-only" เพื่อเรียกใช้ฟังก์ชัน elisp ที่ถูกต้อง

หากคุณใช้การเชื่อมแป้นพิมพ์เริ่มต้น

Cx Cq

(ซึ่งคุณอ่านออกเสียงว่า "Control-X Control-Q") จะมีผลเช่นเดียวกัน อย่างไรก็ตามโปรดจำไว้ว่าเนื่องจาก emac นั้นสามารถกำหนดค่าใหม่ได้ไม่ จำกัด ระยะทางของคุณอาจแตกต่างกันไป

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

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


5
สวัสดีตามที่ระบุไว้ในคำตอบจาก jfm3 toggle-read-onlyจะสลับสถานะอ่านอย่างเดียวของบัฟเฟอร์ไม่ใช่ของไฟล์ หากคุณต้องการเปลี่ยนโหมดของไฟล์ให้ใช้diredหรือดำเนินการchmod +wเป็นคำสั่งเชลล์บนไฟล์
danielpoe

จริงอยู่ที่คุณจะเปลี่ยนโหมด อย่างไรก็ตามหากคุณสลับโหมดอ่านอย่างเดียวบนบัฟเฟอร์ที่ชี้ไปที่ไฟล์แบบอ่านอย่างเดียวที่คุณเป็นเจ้าของคุณจะสามารถแก้ไขและเขียนการเปลี่ยนแปลงของคุณได้ (แน่นอนว่าจะมีคำถามยืนยัน)
Bob Cross

ติดตามความคิดเห็นด้านบนและเพิ่มข้อความในคำตอบ
Bob Cross

5
ใน Emac เวอร์ชันล่าสุดการสลับอ่านอย่างเดียวจะถูกแทนที่ด้วยโหมดอ่านอย่างเดียว
Ben Key

15

ต้องแน่ใจว่าคุณไม่สับสนกับ 'ไฟล์' กับ 'บัฟเฟอร์' คุณสามารถตั้งค่าบัฟเฟอร์เป็นแบบอ่านอย่างเดียวและย้อนกลับอีกครั้งด้วยC-x C-q( toggle-read-only) หากคุณได้รับอนุญาตให้อ่าน แต่ไม่เขียนไฟล์บัฟเฟอร์ที่คุณได้รับเมื่อคุณเยี่ยมชมไฟล์ ( C-x C-fหรือfind-file) จะถูกทำให้อยู่ในโหมดอ่านอย่างเดียวโดยอัตโนมัติ หากคุณต้องการเปลี่ยนสิทธิ์ของไฟล์ในระบบไฟล์อาจเริ่มต้นด้วยdiredไดเร็กทอรีที่มีไฟล์ เอกสารสำหรับการทำอาหารสามารถพบได้ในข้อมูล C-h i (emacs)dired RET.


inc. สอนผู้ชายตกปลา ...
user234461

12

สิ่งที่พบคือ M-x set-file-modes filename mode

มันทำงานที่กล่อง Windows Vista ของฉัน ตัวอย่างเช่น:M-x set-file-modes <RET> ReadOnlyFile.txt <RET> 0666


ในความคิดของฉันนี่เป็นคำตอบที่ถูกต้องสำหรับคำถามที่ถาม
Mathias Dahl

1
ใน elisp สิ่งนี้ได้ผล: (set-file-modes FILE 438)(โดยที่ 438 เท่ากับทศนิยมของ2#0110110110หรือ666)
Kaushal Modi

7

ดังที่ใครบางคนกล่าวถึงที่นั่น: Mx toggle-read-onlyจะทำงาน

อย่างไรก็ตามตอนนี้เลิกใช้แล้วและโหมดอ่านอย่างเดียว Mxเป็นวิธีการในปัจจุบันที่ตั้งค่าเป็นCx Cq keybinding



6

หากเฉพาะบัฟเฟอร์ (ไม่ใช่ไฟล์) เท่านั้นที่เป็นแบบอ่านอย่างเดียวคุณสามารถใช้ได้toggle-read-onlyซึ่งโดยปกติจะถูกผูกไว้กับC-x C-qซึ่งมักจะถูกผูกไว้กับ

อย่างไรก็ตามหากไฟล์เป็นแบบอ่านอย่างเดียวคุณอาจพบว่าฟังก์ชันต่อไปนี้มีประโยชน์:

(defun set-buffer-file-writable ()
  "Make the file shown in the current buffer writable.
Make the buffer writable as well."
  (interactive)
  (unix-output "chmod" "+w" (buffer-file-name))
  (toggle-read-only nil)
  (message (trim-right '(?\n) (unix-output "ls" "-l" (buffer-file-name)))))

ฟังก์ชันขึ้นอยู่กับunix-outputและtrim-right:

(defun unix-output (command &rest args)
  "Run a unix command and, if it returns 0, return the output as a string.
Otherwise, signal an error.  The error message is the first line of the output."
  (let ((output-buffer (generate-new-buffer "*stdout*")))
    (unwind-protect
     (let ((return-value (apply 'call-process command nil
                    output-buffer nil args)))
       (set-buffer output-buffer)
       (save-excursion 
         (unless (= return-value 0)
           (goto-char (point-min))
           (end-of-line)
           (if (= (point-min) (point))
           (error "Command failed: %s%s" command
              (with-output-to-string
                  (dolist (arg args)
                (princ " ")
                (princ arg))))
           (error "%s" (buffer-substring-no-properties (point-min) 
                                   (point)))))
         (buffer-substring-no-properties (point-min) (point-max))))
      (kill-buffer output-buffer))))

(defun trim-right (bag string &optional start end)
  (setq bag (if (eq bag t) '(?\  ?\n ?\t ?\v ?\r ?\f) bag)
    start (or start 0)
    end (or end (length string)))
  (while (and (> end 0)
          (member (aref string (1- end)) bag))
    (decf end))
  (substring string start end))

วางฟังก์ชันในของคุณ~/.emacs.elประเมิน (หรือรีสตาร์ท emacs) จากนั้นคุณสามารถทำให้ไฟล์ในบัฟเฟอร์ปัจจุบันสามารถเขียนได้ด้วยM-x set-buffer-file-writable.


เมื่อฉันพยายามรวบรวม. emac ของฉันด้วยรหัสนี้ฉันได้รับข้อความ "คำเตือน: บันทึกการเดินทางพ่ายแพ้โดย set-buffer"
Alan

1
@Alan แก้ไขเพื่อใส่set-bufferด้านนอกsave-excursion.
Vebjorn Ljosa

ขอบคุณสำหรับการเปลี่ยนแปลงที่ยกเลิกคำเตือน อย่างไรก็ตามยังมีอีกอย่างหนึ่ง: "คำเตือน: ฟังก์ชัน` `subseq '' จากแพ็คเกจ cl ที่เรียกว่ารันไทม์" ฉันไม่สามารถกำจัดสิ่งนั้นได้แม้ว่าฉันจะเพิ่ม (eval-when-compile (ต้องใช้ 'cl)) ใน. emac ของฉัน
Alan

ดูกระทู้นี้ครับ ฉันได้แก้ไขรหัสและแทนที่subseqด้วยsubstringตอนนี้ ที่ควรหลีกเลี่ยงคำเตือน
Vebjorn Ljosa

ตอนนี้ฉันได้ไปที่ Emacs 24 แล้วฉันได้รับข้อความ "คำเตือน: ไม่ทราบว่าจะกำหนดฟังก์ชัน` `decf '"
Alan

3

หากคุณกำลังดูไดเร็กทอรีของไฟล์ (dired) คุณสามารถใช้Shift + Mกับชื่อไฟล์และป้อนmodespecแอ็ตทริบิวต์เดียวกับที่ใช้ในchmodคำสั่ง
M modespec <RET>

ดูคำสั่งที่มีประโยชน์อื่น ๆ บนไฟล์ในรายการไดเร็กทอรีที่ http://www.gnu.org/s/libtool/manual/emacs/Operating-on-Files.html


0

ฉันลองใช้โซลูชันของ Vebjorn Ljosa และปรากฎว่าอย่างน้อยใน Emacs (22.3.1) ของฉันไม่มีฟังก์ชันเช่น 'trim-right' ซึ่งใช้สำหรับการลบบรรทัดใหม่ที่ไร้ประโยชน์เมื่อสิ้นสุดเอาต์พุต chmod

การลบการเรียก "ตัดด้านขวา" ช่วยได้ แต่ทำให้แถวสถานะ "ตีกลับ" เนื่องจากขึ้นบรรทัดใหม่


ลืมใส่…เพิ่มแล้ว
Vebjorn Ljosa

0

C-x C-qไม่มีประโยชน์ เนื่องจากคุณต้องได้รับอนุญาตในการบันทึกไฟล์ด้วย

ผมใช้Spacemacs มันทำให้ฉันมีฟังก์ชันที่สะดวกในการแก้ปัญหานี้ รหัสดังต่อไปนี้

(defun spacemacs/sudo-edit (&optional arg)
  (interactive "p")
  (if (or arg (not buffer-file-name))
      (find-file (concat "/sudo:root@localhost:" (ido-read-file-name "File: ")))
    (find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name))))

ฉันโทร spacemacs/sudo-editให้เปิดไฟล์ใน emacs และป้อนรหัสผ่านของฉันฉันสามารถเปลี่ยนไฟล์ได้โดยไม่ต้องใช้โหมดอ่านอย่างเดียว

คุณสามารถเขียนฟังก์ชันใหม่เช่นspacemacs/sudo-edit.

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