无法将“:w !sudo tee %”与 ranger + nvim 一起使用

问题描述 投票:0回答:1

主要问题

我是一名 arch 用户,正在尝试配置我的环境,以便我可以使用 ranger 和 nvim 无缝编辑文件。

我使用以下命令安装了 Ranger:

make install PREFIX=$HOME/.local

当我尝试在 nvim 中使用

:x
保存文件(假设在 /etc/X11/xorg.conf.d/20-intel.conf 中)时,出现错误:

E45: 'readonly' option is set (add ! to override)

这是预期的,我通常会继续执行

:w !sudo tee %
,并提示输入密码,输入密码,然后保存文件。然而在这种情况下我得到了这个:

:w !sudo tee %
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
sudo: a password is required

shell returned 1

Press ENTER or type command to continue

我尝试使用

:w !sudo -S tee %
选项,但是当我被要求输入密码时,默认通过提示会显示 3 次,然后退出,提示提供了错误的密码。


:w !sudo -S tee %
[sudo] password for boss: Sorry, try again.
[sudo] password for boss: Sorry, try again.
[sudo] password for boss: sudo: 3 incorrect password attempts

shell returned 1

Press ENTER or type command to continue

有什么想法可以解决这个问题吗?

相关环境变量

EDITOR=nvim

版本

ranger --version
ranger version: ranger 1.9.4
Python version: 3.11.8 (main, Feb 12 2024, 14:50:05) [GCC 13.2.1 20230801]

nvim --version
NVIM v0.10.1
Build type: Release
LuaJIT 2.1.1720049189
Run "nvim -V1 -v" for more info

PS 在官方 Ranger README 中建议使用

sudo make install
但我不喜欢使用 sudo 进行用户空间操作。

linux shell sudo neovim
1个回答
0
投票

这是我在 Neovim 中使用 sudo 写入缓冲区的方法,无需安装额外的依赖项。

“ww”被映射到 sudo_write:


local M = {}

function M.info(msg)
    fast_event_aware_notify(msg, vim.log.levels.INFO, {})
end

function M.warn(msg)
    fast_event_aware_notify(msg, vim.log.levels.WARN, {})
end

function M.err(msg)
    fast_event_aware_notify(msg, vim.log.levels.ERROR, {})
end

M.sudo_exec = function(cmd, print_output)
    vim.fn.inputsave()
    local password = vim.fn.inputsecret("Password: ")
    vim.fn.inputrestore()
    if not password or #password == 0 then
        M.warn("Invalid password, sudo aborted")
        return false
    end
    local out = vim.fn.system(string.format("sudo -p '' -S %s", cmd), password)
    if vim.v.shell_error ~= 0 then
        print("\r\n")
        M.err(out)
        return false
    end
    if print_output then
        print("\r\n", out)
    end
    return true
end

M.sudo_write = function(tmpfile, filepath)
    if not tmpfile then
        tmpfile = vim.fn.tempname()
    end
    if not filepath then
        filepath = vim.fn.expand("%")
    end
    if not filepath or #filepath == 0 then
        M.err("E32: No file name")
        return
    end
    -- `bs=1048576` is equivalent to `bs=1M` for GNU dd or `bs=1m` for BSD dd
    -- Both `bs=1M` and `bs=1m` are non-POSIX
    local cmd = string.format("dd if=%s of=%s bs=1048576", vim.fn.shellescape(tmpfile), vim.fn.shellescape(filepath))
    -- no need to check error as this fails the entire function
    vim.api.nvim_exec2(string.format("write! %s", tmpfile), { output = true })
    if M.sudo_exec(cmd) then
        -- refreshes the buffer and prints the "written" message
        vim.cmd.checktime()
        -- exit command mode
        vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes("<Esc>", true, false, true), "n", true)
    end
    vim.fn.delete(tmpfile)
end

vim.keymap.set("c", "ww", M.sudo_write, { silent = true })

作者:ibhagwan (https://github.com/ibhagwan)。您还可以在这里找到原始代码:https://github.com/ibhagwan/nvim-lua/blob/main/lua/utils.lua#L279

© www.soinside.com 2019 - 2024. All rights reserved.