Как мне изменить режим чтения / записи для файла с помощью Emacs?

126

Если файл установлен в режим только для чтения, как мне изменить его в режим записи и наоборот из Emacs?

луч
источник

Ответы:

178

Mx toggle-read-only

или в более поздних версиях Emacs

Mx-режим только для чтения

В моем окне Windows это равносильно нажатию Alt-x для вызова мета-приглашения и вводу «toggle-read-only» для вызова правильной функции elisp.

Если вы используете привязки клавиатуры по умолчанию,

Cx Cq

(который вы читаете вслух как «Control-X Control-Q») будет иметь такой же эффект. Помните, однако, что, учитывая, что emacs, по сути, можно бесконечно перенастраивать, ваш пробег может отличаться.

Продолжая комментарий: вы должны отметить, что доступный для записи статус буфера не изменяет права записи для файла. Если вы попытаетесь записать в файл только для чтения , вы увидите подтверждающее сообщение. Однако, если вы являетесь владельцем файла, вы можете записать свои изменения, не меняя права доступа к файлу.

Это очень удобно, если вы хотите быстро внести изменения в файл, не выполняя несколько шагов, таких как добавление разрешения на запись, запись изменений и удаление разрешения на запись. Я часто забываю этот последний шаг, оставляя потенциально важные файлы открытыми для случайных изменений в дальнейшем.

Боб Кросс
источник
5
Привет, как указано в ответе jfm3, toggle-read-onlyпереключает только состояние только для чтения буфера, а не файла. Если вы хотите изменить режим файла, используйте diredили выполните chmod +wкак команду оболочки для файла.
danielpoe
Правда, вот как бы вы изменили режим. Однако, если вы переключите режим только для чтения в буфере, который указывает на файл только для чтения, которым вы владеете, вы сможете редактировать его и записывать свои изменения (конечно, будет вопрос с подтверждением).
Боб Кросс,
Продолжил комментарии выше и добавил текст к ответу.
Боб Кросс
5
В последних версиях Emacs режим переключения только для чтения был заменен режимом только для чтения.
Бен Ки
15

Убедитесь, что вы не путаете «файл» с «буфером». Вы можете установить буферы только для чтения и обратно с помощью C-x C-q( toggle-read-only). Если у вас есть разрешение на чтение, но не на запись файла, буфер, который вы получаете при посещении файла ( C-x C-fили find-file), будет автоматически переведен в режим только для чтения. Если вы хотите изменить разрешения для файла в файловой системе, возможно, начните с diredкаталога, в котором находится файл. Документацию по dired можно найти в info; C-h i (emacs)dired RET,

jfm3
источник
inc, Научите человека ловить рыбу ...
user234461
12

Я нашел M-x set-file-modes filename mode

Это работало на моем компьютере с Windows Vista. Например:M-x set-file-modes <RET> ReadOnlyFile.txt <RET> 0666

Дмитрий Кузнецов
источник
На мой взгляд, это правильный ответ на заданный вопрос.
Матиас Даль
1
В elisp это сработало: (set-file-modes FILE 438)(где 438 - десятичный эквивалент 2#0110110110или 666).
Kaushal Modi
7

Как упоминалось там кем-то другим: Mx toggle-read-only будет работать.

Однако теперь это устарело, и текущий способ сделать это - режим Mx только для чтения , для которого установлено связывание клавиш Cx Cq.

Борха Таррасо
источник
7

CTRL + X + CTRL + Q     

anjanb
источник
Объяснение? OP сказал файл, а не buf.
user234461
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.

Вебьорн Лйоса
источник
Когда я пытаюсь скомпилировать свой .emacs с помощью этого кода, я получаю сообщение «Предупреждение: save-excursion побежден set-buffer».
Алан
1
@Alan, отредактировал, чтобы положить set-bufferвне save-excursion.
Вебьорн Лйоса 05
спасибо за это изменение, которое устранило предупреждение. Однако есть еще один: «Предупреждение: функция` Subq 'из ​​пакета cl вызывается во время выполнения ». Я не мог избавиться от этого, даже когда добавил (eval-when-compile (require 'cl)) в свой .emacs.
Алан
Смотрите эту ветку . Я отредактировал код и заменил его subseqна substringсейчас. Это должно избежать предупреждения.
Вебьорн Лйоса 06
Теперь, когда я перешел на Emacs 24, я получаю сообщение «Предупреждение: известно, что функция` decf 'не определена ».
Алан
3

Если вы просматриваете каталог файлов (dired), вы можете использовать Shift + Mдля имени файла и ввести modespecте же атрибуты, что и в chmodкоманде.
M modespec <RET>

См. Другие полезные команды для файлов в списке каталогов на http://www.gnu.org/s/libtool/manual/emacs/Operating-on-Files.html

Луи Рёрс
источник
0

Я опробовал решение Вебьорна Лйосы, и оказалось, что по крайней мере в моем Emacs (22.3.1) нет такой функции, как 'trim-right', которая используется для удаления бесполезной новой строки в конце вывода chmod.

Удаление вызова 'trim-right' помогло, но сделало строку состояния "подпрыгивающей" из-за дополнительной новой строки.


источник
Забыл включить… добавил сейчас.
Вебьорн Лйоса,
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.

Ли Тяньи
источник