¿Cómo cambio el modo de lectura / escritura para un archivo usando Emacs?

126

Si un archivo está configurado en modo de solo lectura, ¿cómo lo cambio a modo de escritura y viceversa desde Emacs?

Rayo
fuente

Respuestas:

178

Mx alternar-solo lectura

o en versiones más recientes de Emacs

Mx modo de solo lectura

En mi cuadro de Windows, eso equivale a Alt-x para que aparezca el indicador de meta y escriba "alternar-solo lectura" para llamar a la función elisp correcta.

Si está utilizando los enlaces de teclado predeterminados,

Cx Cq

(que lees en voz alta como "Control-X Control-Q") tendrá el mismo efecto. Sin embargo, recuerde que dado que emacs es esencialmente infinitamente reconfigurable, su kilometraje puede variar.

Seguimiento del comentario: debe tener en cuenta que el estado de escritura del búfer no cambia el permiso de escritura del archivo. Si intenta escribir en un archivo de solo lectura , verá un mensaje de confirmación. Sin embargo, si posee el archivo, puede escribir sus cambios sin cambiar los permisos del archivo.

Esto es muy conveniente si desea realizar un cambio rápido en un archivo sin tener que pasar por los múltiples pasos de agregar permiso de escritura, escribir cambios, eliminar el permiso de escritura. Tiendo a olvidar ese último paso, dejando los archivos potencialmente críticos abiertos para cambios accidentales más adelante.

Bob Cross
fuente
55
Hola, como se indica en la respuesta de jfm3 toggle-read-onlysolo alterna el estado de solo lectura del búfer no del archivo. Si desea cambiar el modo del archivo, use diredo ejecute chmod +wcomo un comando de shell en el archivo.
danielpoe
Es cierto, así es como cambiarías el modo. Sin embargo, si alterna el modo de solo lectura en un búfer que apunta a un archivo de solo lectura de su propiedad, podrá editarlo y escribir sus cambios (por supuesto, habrá una pregunta de confirmación).
Bob Cross
Haga un seguimiento de los comentarios anteriores y agregue texto a la respuesta.
Bob Cross
55
En versiones recientes de Emacs, toggle-read-only ha sido reemplazado por modo de solo lectura.
Ben Key
15

Asegúrese de no confundir 'archivo' con 'búfer'. Puede configurar los búferes como de solo lectura y de nuevo con C-x C-q( toggle-read-only). Si tiene permiso para leer, pero no escribir, un archivo, el búfer que obtiene cuando visita el archivo ( C-x C-fo find-file) se pondrá en modo de solo lectura automáticamente. Si desea cambiar los permisos de un archivo en el sistema de archivos, quizás comience con diredel directorio que contiene el archivo. La documentación para dired se puede encontrar en info; C-h i (emacs)dired RET.

jfm3
fuente
inc. Enseñar a un hombre a pescar ...
user234461
12

Lo que encontré es M-x set-file-modes filename mode

Funcionó en mi caja de Windows Vista. Por ejemplo:M-x set-file-modes <RET> ReadOnlyFile.txt <RET> 0666

Dmytro Kuznetsov
fuente
En mi opinión, esta es la respuesta correcta a la pregunta exacta formulada.
Mathias Dahl
1
En elisp, esto funcionó: (set-file-modes FILE 438)(donde 438 es el equivalente decimal de 2#0110110110o 666).
Kaushal Modi
7

Como lo mencionó alguien más: Mx toggle-read-only funcionaría.

Sin embargo, esto ahora está en desuso y el modo de solo lectura Mx es la forma actual de hacerlo, que se establece en la combinación de teclas Cx Cq.

Borja Tarraso
fuente
7

CTRL + X + CTRL + Q     

anjanb
fuente
¿Explicación? OP dicho archivo, no buf.
user234461
6

Si solo el búfer (y no el archivo) es de solo lectura, puede usarlo toggle-read-only, que generalmente está vinculado C-x C-q.

Sin embargo, si el archivo en sí es de solo lectura, puede encontrar útil la siguiente función:

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

La función depende de unix-outputy 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 las funciones en su ~/.emacs.el, evalúelas (o reinicie emacs). Luego puede hacer que el archivo en el búfer actual se pueda escribir con M-x set-buffer-file-writable.

Vebjorn Ljosa
fuente
Cuando intento compilar mis .emacs con este código, aparece el mensaje "Advertencia: save-excursion derrotado por set-buffer".
Alan
1
@ Alan, editado para poner el set-bufferexterior del save-excursion.
Vebjorn Ljosa
gracias por ese cambio, que eliminó la advertencia. Sin embargo, hay otro: "Advertencia: Función` subseq 'del paquete cl llamada en tiempo de ejecución ". No pude deshacerme de eso incluso cuando agregué (eval-when-compile (require 'cl)) a mis .emacs.
Alan
Ver este hilo . He editado el código y reemplazado subseqpor substringahora. Eso debería evitar la advertencia.
Vebjorn Ljosa
Ahora que he pasado a Emacs 24, aparece el mensaje "Advertencia: no se sabe que la función 'decf' esté definida".
Alan
0

Probé la solución de Vebjorn Ljosa, y resultó que al menos en mi Emacs (22.3.1) no existe tal función como 'trim-right', que se usa para eliminar una nueva línea inútil al final de la salida de chmod.

La eliminación de la llamada a 'trim-right' ayudó, pero hizo que la fila de estado "rebotara" debido a la nueva línea adicional.


fuente
Olvidé incluirlo ... agregado ahora.
Vebjorn Ljosa
0

C-x C-qes inútil Porque también necesita el permiso para guardar un archivo.

Yo uso Spacemacs . Me da una función conveniente para resolver esta pregunta. El código está siguiendo.

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

Llamo spacemacs/sudo-editpara abrir un archivo en emacs e ingresar mi contraseña, puedo cambiar el archivo sin el modo de solo lectura.

Puedes escribir una nueva función como spacemacs/sudo-edit.

Li Tianyi
fuente