【问题标题】:How do I change read/write mode for a file using Emacs?如何使用 Emacs 更改文件的读/写模式?
【发布时间】:2010-09-15 21:44:09
【问题描述】:

如果文件设置为只读模式,我如何在 Emacs 中将其更改为写入模式,反之亦然?

【问题讨论】:

    标签: emacs file file-permissions


    【解决方案1】:

    M-x 只读模式

    在非常旧的 Emacs 版本中,命令是:

    M-x 切换只读

    在我的 Windows 机器上,这相当于 Alt-x 调出元提示并键入“只读模式”来调用正确的 elisp 函数。

    如果您使用的是默认键盘绑定,

    C-x C-q

    (您大声读为“Control-X Control-Q”)将具有相同的效果。但是请记住,鉴于 emacs 本质上是无限可重新配置的,您的使用范围可能会有所不同。

    从评论跟进:您应该注意缓冲区的可写状态不会改变文件的可写权限。如果您尝试写入只读文件,您将看到一条确认消息。但是,如果您拥有该文件,则可以写出您的更改而不更改文件的权限。

    如果您想快速更改文件,而无需执行添加写入权限、写出更改、删除写入权限等多个步骤,这将非常方便。我往往会忘记最后一步,留下潜在的关键文件以供以后意外更改。

    【讨论】:

    • 嗨,正如 jfm3 toggle-read-only 的回答中所述,仅切换缓冲区的只读状态而不是文件的只读状态。如果要更改文件的模式,请使用dired 或在文件上执行chmod +w 作为shell 命令。
    • 没错,这就是您更改模式的方式。但是,如果您在指向您拥有的只读文件的缓冲区上切换只读模式,您将能够编辑它并写出您的更改(当然会有一个确认问题)。跨度>
    • 跟进上面的 cmets 并在答案中添加了文本。
    • 在最近的 Emacs 版本中,toggle-read-only 已被 read-only-mode 取代。
    【解决方案2】:

    请确保您没有将“文件”与“缓冲区”混淆。您可以使用C-x C-q (toggle-read-only) 将缓冲区设置为只读并再次返回。如果您有权读取但不能写入文件,则访问文件时获得的缓冲区(C-x C-ffind-file)将自动进入只读模式。如果您想更改文件系统中某个文件的权限,或许可以在包含该文件的目录上以dired 开头。 dired 的文档可以在 info 中找到; C-h i (emacs)dired RET.

    【讨论】:

      【解决方案3】:

      我找到的是M-x set-file-modes filename mode

      它在我的 Windows Vista 机器上工作。 例如:M-x set-file-modes <RET> ReadOnlyFile.txt <RET> 0666

      【讨论】:

      • 在我看来,这是对所提出的确切问题的正确答案。
      • 在 elisp 中,这行得通:(set-file-modes FILE 438)(其中 438 是 2#0110110110666 的十进制等效值)。
      【解决方案4】:

      正如其他人在上面提到的那样:M-x toggle-read-only 可以工作。

      但是,现在已弃用,Mx 只读模式 是当前的方法,它设置为 Cx Cq 键绑定。

      【讨论】:

        【解决方案5】:

        CTRL + X + CTRL + Q     

        【讨论】:

        • 解释? OP 说的是文件,不是 buf。
        【解决方案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-outputtrim-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 击败”。
        • @Alan,编辑后将set-buffer 放在save-excursion 之外。
        • 感谢您的更改,它消除了警告。但是,还有另一个:“警告:运行时调用 cl 包中的函数 `subseq'。”即使我将 (eval-when-compile (require 'cl)) 添加到我的 .emacs 中,我也无法摆脱它。
        • this thread。我已经编辑了代码,现在用substring 替换了subseq。那应该避免警告。
        • 现在我已经转到 Emacs 24,我收到消息“警告:函数 `decf' 未知被定义。”
        【解决方案7】:

        如果您正在查看文件目录(dired),则可以在文件名上使用Shift + M,然后输入modespec,与chmod 命令中使用的属性相同。
        M modespec <RET>

        在目录列表中查看其他有用的文件命令 http://www.gnu.org/s/libtool/manual/emacs/Operating-on-Files.html

        【讨论】:

          【解决方案8】:

          我尝试了 Vebjorn Ljosa 的解决方案,结果发现至少在我的 Emacs (22.3.1) 中没有“trim-right”这样的功能,它用于在末尾删除无用的换行符chmod 输出。

          删除对 'trim-right' 的调用有所帮助,但由于额外的换行符而使状态行“反弹”。

          【讨论】:

          • 忘记包含了……现在添加。
          【解决方案9】:

          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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-09-21
            • 1970-01-01
            • 1970-01-01
            • 2019-11-17
            • 1970-01-01
            相关资源
            最近更新 更多