Bagaimana cara mengubah mode baca / tulis untuk file menggunakan Emacs?

126

Jika file diatur ke mode hanya baca, bagaimana cara mengubahnya ke mode tulis dan sebaliknya dari dalam Emacs?

sinar
sumber

Jawaban:

178

Mx beralih-hanya-baca

atau dalam versi terbaru dari Emacs

Mx read-only-mode

Pada kotak Windows saya, itu berjumlah Alt-x untuk memunculkan meta prompt dan mengetikkan "toggle-read-only" untuk memanggil fungsi elisp yang benar.

Jika Anda menggunakan binding keyboard default,

Cx Cq

(yang Anda baca dengan keras sebagai "Control-X Control-Q") akan memiliki efek yang sama. Ingat, bagaimanapun, mengingat emacs pada dasarnya sangat tidak dapat dikonfigurasi ulang, jarak tempuh Anda mungkin bervariasi.

Tindak lanjut dari komentar: Anda harus mencatat bahwa status buffer yang dapat ditulisi tidak mengubah izin file yang dapat ditulisi. Jika Anda mencoba menulis ke file hanya baca , Anda akan melihat pesan konfirmasi. Namun, jika Anda memiliki file tersebut, Anda dapat menuliskan perubahan Anda tanpa mengubah izin pada file tersebut.

Ini sangat nyaman jika Anda ingin membuat perubahan cepat ke file tanpa harus melalui beberapa langkah menambahkan izin menulis, menulis perubahan, menghapus izin menulis. Saya cenderung melupakan langkah terakhir itu, membiarkan file-file penting yang berpotensi terbuka untuk perubahan yang tidak disengaja di kemudian hari.

Bob Cross
sumber
5
Hai, seperti yang dinyatakan dalam jawaban dari jfm3 toggle-read-onlyhanya mengaktifkan status read only dari buffer bukan dari file. Jika Anda ingin mengubah mode penggunaan file diredatau jalankan chmod +wsebagai perintah shell pada file.
danielpoe
Benar, itulah bagaimana Anda akan mengubah mode. Namun, jika Anda mengaktifkan mode read-only pada buffer yang mengarah ke file read-only yang Anda miliki, Anda akan dapat mengeditnya dan menuliskan perubahan Anda (tentu saja akan ada pertanyaan konfirmasi).
Bob Cross
Tindak lanjuti komentar di atas dan menambahkan teks ke jawabannya.
Bob Cross
5
Di versi terbaru Emacs, toggle-read-only telah diganti dengan mode read-only-only.
Ben Key
15

Pastikan Anda tidak membingungkan 'file' dengan 'buffer'. Anda dapat mengatur buffer menjadi hanya-baca dan kembali lagi dengan C-x C-q( toggle-read-only). Jika Anda memiliki izin untuk membaca, tetapi tidak menulis, file, buffer yang Anda dapatkan ketika Anda mengunjungi file ( C-x C-fatau find-file) akan dimasukkan ke mode read-only secara otomatis. Jika Anda ingin mengubah izin pada file di sistem file, mungkin mulai dengan diredpada direktori yang berisi file. Dokumentasi untuk dired dapat ditemukan di info; C-h i (emacs)dired RET.

jfm3
sumber
inc. Ajari pria memancing ...
user234461
12

Apa yang saya temukan adalah M-x set-file-modes filename mode

Ini bekerja di kotak Windows Vista saya. Sebagai contoh:M-x set-file-modes <RET> ReadOnlyFile.txt <RET> 0666

Dmytro Kuznetsov
sumber
Menurut pendapat saya, ini adalah jawaban yang tepat untuk pertanyaan yang diajukan.
Mathias Dahl
1
Dalam elisp, ini berhasil: (set-file-modes FILE 438)(di mana 438 adalah setara dengan desimal 2#0110110110atau 666).
Kaushal Modi
7

Seperti yang disebutkan di atas oleh orang lain: Mx toggle-read-only akan bekerja.

Namun, ini sekarang sudah usang dan mode baca-saja-Mx adalah cara saat ini untuk melakukannya, bahwa itu diatur ke Cx Cq keybinding.

Borja Tarraso
sumber
7

CTRL + X + CTRL + Q     

anjanb
sumber
Penjelasan? OP mengatakan file, bukan buf.
user234461
6

Jika hanya buffer (dan bukan file) read-only, Anda dapat menggunakan toggle-read-only, yang biasanya terikat C-x C-q.

Namun, jika file itu sendiri hanya-baca, Anda mungkin menemukan fungsi berikut berguna:

(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)))))

Fungsi tergantung pada unix-outputdan 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))

Tempatkan fungsi di Anda ~/.emacs.el, evaluasi mereka (atau restart emacs). Anda kemudian dapat membuat file dalam buffer saat ini dapat ditulis dengan M-x set-buffer-file-writable.

Vebjorn Ljosa
sumber
Ketika saya mencoba untuk mengkompilasi .emacs saya dengan kode ini, saya mendapatkan pesan "Peringatan: save-excursion dikalahkan oleh set-buffer".
Alan
1
@Lan, diedit untuk meletakkan di set-bufferluar save-excursion.
Vebjorn Ljosa
terima kasih untuk perubahan itu, yang menghilangkan peringatan itu. Namun, ada satu lagi: "Peringatan: Fungsi` subseq 'dari paket cl yang disebut saat runtime. " Saya tidak bisa menyingkirkan itu bahkan ketika saya menambahkan (eval-when-compile (memerlukan 'cl)) ke .emacs saya.
Alan
Lihat utas ini . Saya telah mengedit kode dan diganti subseqdengan substringsekarang. Itu harus menghindari peringatan.
Vebjorn Ljosa
Sekarang saya telah pergi ke Emacs 24, saya mendapatkan pesan "Peringatan: fungsi` decf 'tidak diketahui didefinisikan. "
Alan
0

Saya mencoba solusi Vebjorn Ljosa, dan ternyata setidaknya di Emacs saya (22.3.1) tidak ada fungsi seperti 'trim-right', yang digunakan untuk menghapus baris baru yang tidak berguna di akhir output chmod.

Menghapus panggilan ke 'trim-kanan' membantu, tetapi membuat baris status "terpental" karena baris baru tambahan.


sumber
Lupa untuk memasukkannya ... ditambahkan sekarang.
Vebjorn Ljosa
0

C-x C-qtidak berguna. Karena Anda juga memerlukan izin untuk menyimpan file.

Saya menggunakan Spacemacs . Ini memberi saya fungsi yang nyaman untuk menyelesaikan pertanyaan ini. Kode berikut.

(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))))

Saya menelepon spacemacs/sudo-edit untuk membuka file di emacs dan memasukkan kata sandi saya, saya dapat mengubah file tanpa mode read-only.

Anda dapat menulis fungsi baru seperti spacemacs/sudo-edit.

Li Tianyi
sumber