Jak zmienić tryb odczytu / zapisu dla pliku przy użyciu Emacsa?

126

Jeśli plik jest ustawiony w trybie tylko do odczytu, jak zmienić go na tryb zapisu i odwrotnie z poziomu Emacsa?

Promień
źródło

Odpowiedzi:

178

MX przełączanie tylko do odczytu

lub w nowszych wersjach Emacsa

Tryb tylko do odczytu Mx

W moim Windowsie oznacza to Alt-x, aby wywołać znak zachęty meta i wpisanie „toggle-read-only”, aby wywołać poprawną funkcję elisp.

Jeśli używasz domyślnych powiązań klawiatury,

Cx Cq

(co czytasz na głos jako „Control-X Control-Q”) da ten sam efekt. Pamiętaj jednak, że biorąc pod uwagę, że emacs jest zasadniczo konfigurowalny w nieskończoność, Twój przebieg może się różnić.

W związku z komentarzem: należy zauważyć, że stan bufora do zapisu nie zmienia prawa zapisu pliku. Jeśli spróbujesz napisać do pliku tylko do odczytu , zobaczysz komunikat z potwierdzeniem. Jeśli jednak jesteś właścicielem pliku, możesz zapisać swoje zmiany bez zmiany uprawnień do pliku.

Jest to bardzo wygodne, jeśli chcesz dokonać szybkiej zmiany w pliku bez konieczności przechodzenia przez wiele kroków dodawania uprawnień do zapisu, wypisywania zmian, usuwania uprawnień do zapisu. Zwykle zapominam o tym ostatnim kroku, pozostawiając później potencjalnie krytyczne pliki otwarte na przypadkowe zmiany.

Bob Cross
źródło
5
Cześć, jak stwierdzono w odpowiedzi z jfm3 toggle-read-onlytylko przełącza stan bufora tylko do odczytu, a nie pliku. Jeśli chcesz zmienić tryb pliku, użyj diredlub wykonaj chmod +wjako polecenie powłoki na pliku.
danielpoe
To prawda, tak byś zmienił tryb. Jeśli jednak przełączysz tryb tylko do odczytu w buforze, który wskazuje plik tylko do odczytu, który posiadasz, będziesz mógł go edytować i zapisać zmiany (oczywiście będzie pytanie potwierdzające).
Bob Cross
Kontynuacja komentarzy powyżej i dodanie tekstu do odpowiedzi.
Bob Cross
5
W ostatnich wersjach Emacsa opcja przełączania tylko do odczytu została zastąpiona trybem tylko do odczytu.
Ben Key
15

Upewnij się, że nie mylisz „pliku” z „buforem”. Możesz ustawić bufory na tylko do odczytu i z powrotem za pomocą C-x C-q( toggle-read-only). Jeśli masz uprawnienia do odczytu, ale nie do zapisu pliku, bufor, który otrzymasz, gdy odwiedzasz plik ( C-x C-flub find-file), zostanie automatycznie przełączony w tryb tylko do odczytu. Jeśli chcesz zmienić uprawnienia do pliku w systemie plików, być może zacznij diredod katalogu zawierającego plik. Dokumentację do dired można znaleźć w info; C-h i (emacs)dired RET.

jfm3
źródło
inc. Naucz człowieka łowić ryby ...
user234461
12

To, co znalazłem, to M-x set-file-modes filename mode

To działało na moim pudełku z Windows Vista. Na przykład:M-x set-file-modes <RET> ReadOnlyFile.txt <RET> 0666

Dmytro Kuznetsov
źródło
Moim zdaniem jest to właściwa odpowiedź na zadane pytanie.
Mathias Dahl
1
W elisp to zadziałało: (set-file-modes FILE 438)(gdzie 438 jest dziesiętnym odpowiednikiem 2#0110110110lub 666).
Kaushal Modi
7

Jak wspomniano tam przez kogoś innego: Mx toggle-read-only będzie działać.

Jednak jest to obecnie przestarzałe, a tryb Mx tylko do odczytu jest aktualnym sposobem na to, że jest ustawiony na Cx Cq keybinding.

Borja Tarraso
źródło
7

CTRL + X + CTRL + Q     

anjanb
źródło
Wyjaśnienie? OP wspomniany plik, a nie buf.
user234461
6

Jeśli tylko bufor (a nie plik) jest tylko do odczytu, możesz użyć toggle-read-only, który zwykle jest powiązany z C-x C-q.

Jeśli jednak sam plik jest tylko do odczytu, przydatna może być następująca funkcja:

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

Funkcja zależy od unix-outputi 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))

Umieść funkcje w swoim ~/.emacs.el, oceń je (lub zrestartuj emacsa). Następnie możesz udostępnić plik w bieżącym buforze do zapisu za pomocą M-x set-buffer-file-writable.

Vebjorn Ljosa
źródło
Kiedy próbuję skompilować plik .emacs z tym kodem, otrzymuję komunikat „Ostrzeżenie: wycieczka zapisywania pokonana przez set-buffer”.
Alan
1
@Alan, edytowany, aby umieścić set-bufferzewnętrzny plik save-excursion.
Vebjorn Ljosa
dzięki za tę zmianę, która wyeliminowała ostrzeżenie. Jest jednak jeszcze jeden: „Ostrzeżenie: funkcja` subseq 'z pakietu cl wywołana w czasie wykonywania ”. Nie mogłem się tego pozbyć, nawet gdy dodałem (eval-when-compile (require 'cl)) do mojego .emacs.
Alan
Zobacz ten wątek . Wyedytowałem kod i zastąpiłem subseqgo substringteraz. To powinno uniknąć ostrzeżenia.
Vebjorn Ljosa
Teraz, gdy przeszedłem do Emacs 24, otrzymałem komunikat „Ostrzeżenie: nie wiadomo, czy funkcja decf” jest zdefiniowana.
Alan
0

Wypróbowałem rozwiązanie Vebjorna Ljosy i okazało się, że przynajmniej w moim Emacsie (22.3.1) nie ma takiej funkcji jak „trim-right”, która służy do usuwania bezużytecznego znaku nowej linii na końcu wyjścia chmod.

Usunięcie wywołania „trim-right” pomogło, ale wiersz stanu „odrzucił” z powodu dodatkowego znaku nowej linii.


źródło
Zapomniałem go dołączyć… dodano teraz.
Vebjorn Ljosa
0

C-x C-qjest bezużyteczna. Ponieważ potrzebujesz również pozwolenia na zapisanie pliku.

Używam Spacemacs . Daje mi wygodną funkcję rozwiązania tego pytania. Kod jest następujący.

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

Dzwonię, spacemacs/sudo-editaby otworzyć plik w emacsie i wpisać hasło, mogę zmienić plik bez trybu tylko do odczytu.

Możesz napisać nową funkcję, taką jak spacemacs/sudo-edit.

Li Tianyi
źródło