Como altero o modo de leitura / gravação de um arquivo usando o Emacs?

126

Se um arquivo está definido para o modo somente leitura, como faço para alterá-lo para o modo de gravação e vice-versa no Emacs?

Raio
fonte

Respostas:

178

Mx alternar somente leitura

ou em versões mais recentes do Emacs

Mx modo somente leitura

Na minha caixa do Windows, isso significa Alt-x para exibir o meta prompt e digitar "toggle-read-only" para chamar a função elisp correta.

Se você estiver usando as ligações de teclado padrão,

Cx Cq

(que você lê em voz alta como "Control-X Control-Q") terá o mesmo efeito. Lembre-se, no entanto, considerando que o emacs é essencialmente infinitamente reconfigurável, sua milhagem pode variar.

Seguindo o comentário: observe que o status gravável do buffer não altera a permissão gravável do arquivo. Se você tentar gravar em um arquivo somente leitura , verá uma mensagem de confirmação. No entanto, se você possuir o arquivo, poderá gravar suas alterações sem alterar as permissões no arquivo.

Isso é muito conveniente se você deseja fazer uma alteração rápida em um arquivo sem precisar executar as várias etapas de adicionar permissão de gravação, gravar alterações e remover a permissão de gravação. Costumo esquecer esse último passo, deixando arquivos potencialmente críticos abertos para alterações acidentais mais tarde.

Bob Cross
fonte
5
Olá, conforme declarado na resposta do jfm3, toggle-read-onlyapenas alterna o estado somente leitura do buffer que não está no arquivo. Se você deseja alterar o modo do arquivo, use diredou execute chmod +wcomo um comando shell no arquivo.
30909 danielpoe
É verdade que é assim que você mudaria o modo. No entanto, se você alternar o modo somente leitura em um buffer que aponte para um arquivo somente leitura que você possui, você poderá editá-lo e escrever suas alterações (haverá uma pergunta de confirmação, é claro).
Bob transversal
Acompanhou os comentários acima e adicionou texto à resposta.
22612 Bob Cross
5
Nas versões recentes do Emacs, a alternância somente leitura foi substituída pelo modo somente leitura.
Ben Key
15

Certifique-se de não confundir 'arquivo' com 'buffer'. Você pode definir buffers como somente leitura e vice-versa com C-x C-q( toggle-read-only). Se você tiver permissão para ler, mas não gravar, um arquivo, o buffer que você obtém quando o visita ( C-x C-fou find-file) será colocado no modo somente leitura automaticamente. Se você deseja alterar as permissões em um arquivo no sistema de arquivos, talvez comece diredno diretório que contém o arquivo. A documentação para dired pode ser encontrada em info; C-h i (emacs)dired RET.

jfm3
fonte
inc. O que você quer
tocar hoje?
12

O que eu achei é M-x set-file-modes filename mode

Funcionou na minha caixa do Windows Vista. Por exemplo:M-x set-file-modes <RET> ReadOnlyFile.txt <RET> 0666

Dmytro Kuznetsov
fonte
Na minha opinião, esta é a resposta certa para a pergunta exata feita.
Mathias Dahl
1
No elisp, isso funcionou: (set-file-modes FILE 438)(onde 438 é o equivalente decimal de 2#0110110110ou 666).
Kaushal Modi
7

Como mencionado por outra pessoa: o Mx toggle-read-only- iria funcionar.

No entanto, isso agora está obsoleto e o modo somente leitura Mx é a maneira atual de fazê-lo, que está definido como Cx Cq keybinding.

Borja Tarraso
fonte
7

CTRL + X + CTRL + Q     

anjanb
fonte
Explicação? OP disse que o arquivo, não buf.
user234461 21/07
6

Se apenas o buffer (e não o arquivo) for somente leitura, você poderá usar o toggle-read-onlyqual normalmente está vinculado C-x C-q.

Se o próprio arquivo for somente leitura, você poderá encontrar a seguinte função útil:

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

A função depende unix-outpute 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))

Coloque as funções no seu ~/.emacs.el, avalie-as (ou reinicie o emacs). Você pode tornar o arquivo no buffer atual gravável com M-x set-buffer-file-writable.

Vebjorn Ljosa
fonte
Quando tento compilar meu .emacs com esse código, recebo a mensagem "Aviso: excursão salva derrotada pelo conjunto de buffer".
Alan
1
@ Alan, editado para colocar o set-bufferfora do save-excursion.
Vebjorn Ljosa
obrigado por essa alteração, que eliminou o aviso. No entanto, há outro: "Aviso: Função` subseq 'do pacote cl chamada em tempo de execução. " Eu não conseguia me livrar disso, mesmo quando adicionei (eval-when-compile (require 'cl)) ao meu .emacs.
Alan
Veja este tópico . Eu editei o código e o substitui subseqpor substringagora. Isso deve evitar o aviso.
Vebjorn Ljosa 6/03/2013
Agora que fui para o Emacs 24, recebo a mensagem "Atenção: não se sabe que a função` decf 'está definida ".
Alan
3

Se você estiver procurando em um diretório de arquivos (direcionado), poderá usar Shift + Mum nome de arquivo e inserir modespecos mesmos atributos usados ​​no chmodcomando.
M modespec <RET>

Veja os outros comandos úteis nos arquivos em uma lista de diretórios em http://www.gnu.org/s/libtool/manual/emacs/Operating-on-Files.html

Louis Roehrs
fonte
0

Tentei a solução de Vebjorn Ljosa e, pelo menos no meu Emacs (22.3.1), não existe a função 'trim-right', que é usada para remover uma nova linha inútil no final da saída do chmod.

A remoção da chamada para 'aparar à direita' ajudou, mas fez com que a linha de status "retornasse" por causa da nova linha extra.


fonte
Esqueceu de incluí-lo ... adicionado agora.
Vebjorn Ljosa
0

C-x C-qé inútil. Porque você também precisa da permissão para salvar um arquivo.

Eu uso Spacemacs . Dá-me uma função conveniente para resolver esta questão. O código está seguindo.

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

Eu chamo spacemacs/sudo-editpara abrir um arquivo no emacs e insiro minha senha, posso alterar o arquivo sem o modo somente leitura.

Você pode escrever uma nova função como spacemacs/sudo-edit.

Li Tianyi
fonte