mirror of
https://github.com/hyzendust/KickestEnd.nvim.git
synced 2026-02-15 06:21:13 +01:00
Fix: Save as fix.
This commit is contained in:
128
lua/keymaps.lua
128
lua/keymaps.lua
@@ -136,6 +136,28 @@ end, { desc = 'New buffer in vertical split (right)' })
|
|||||||
|
|
||||||
-- [[ Save buffer ]]
|
-- [[ Save buffer ]]
|
||||||
local sudo_password_cache = nil -- store sudo password for session
|
local sudo_password_cache = nil -- store sudo password for session
|
||||||
|
-- Helper to write file with sudo permissions
|
||||||
|
local function write_with_sudo(filename, content)
|
||||||
|
-- Prompt for password once per session
|
||||||
|
if not sudo_password_cache then
|
||||||
|
local pass = vim.fn.inputsecret 'sudo password: '
|
||||||
|
if pass == '' or pass == nil then
|
||||||
|
vim.notify('Sudo password required, save cancelled', vim.log.levels.WARN)
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
sudo_password_cache = pass
|
||||||
|
end
|
||||||
|
-- Write buffer content to sudo tee
|
||||||
|
local sudo_cmd = string.format('sudo -S tee %s > /dev/null', vim.fn.fnameescape(filename))
|
||||||
|
local ok = vim.fn.system(sudo_cmd, sudo_password_cache .. '\n' .. content)
|
||||||
|
if vim.v.shell_error ~= 0 then
|
||||||
|
vim.notify('Failed to write with sudo: ' .. ok, vim.log.levels.ERROR)
|
||||||
|
-- clear cached password to allow retry next time
|
||||||
|
sudo_password_cache = nil
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
local function smart_save(force_save_as)
|
local function smart_save(force_save_as)
|
||||||
local current_path = vim.api.nvim_buf_get_name(0)
|
local current_path = vim.api.nvim_buf_get_name(0)
|
||||||
-- Compute default input (prefill directory + filename)
|
-- Compute default input (prefill directory + filename)
|
||||||
@@ -150,8 +172,8 @@ local function smart_save(force_save_as)
|
|||||||
local default_name = current_path ~= '' and vim.fn.fnamemodify(current_path, ':t') or ''
|
local default_name = current_path ~= '' and vim.fn.fnamemodify(current_path, ':t') or ''
|
||||||
local default_input = default_dir .. default_name
|
local default_input = default_dir .. default_name
|
||||||
-- Decide whether to ask for filename
|
-- Decide whether to ask for filename
|
||||||
local filename = current_path
|
|
||||||
if current_path == '' or force_save_as then
|
if current_path == '' or force_save_as then
|
||||||
|
local filename
|
||||||
local overwrite = false
|
local overwrite = false
|
||||||
while true do
|
while true do
|
||||||
-- Ask user for filename
|
-- Ask user for filename
|
||||||
@@ -175,42 +197,82 @@ local function smart_save(force_save_as)
|
|||||||
break -- file doesn't exist, safe to write
|
break -- file doesn't exist, safe to write
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
-- If Save As filename is same as current file, just write and return
|
||||||
-- Read buffer content
|
if filename == current_path then
|
||||||
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, true)
|
local write_cmd = overwrite and 'write!' or 'write'
|
||||||
local content = table.concat(lines, '\n')
|
local ok = pcall(function()
|
||||||
-- Determine if the file is writable
|
vim.cmd(write_cmd)
|
||||||
local writable = vim.fn.filereadable(filename) == 1 and vim.fn.filewritable(filename) == 1
|
end)
|
||||||
if writable then
|
if not ok then
|
||||||
-- Normal writable file
|
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, true)
|
||||||
if current_path == '' or force_save_as then
|
local content = table.concat(lines, '\n')
|
||||||
vim.cmd('write ' .. vim.fn.fnameescape(filename))
|
if not write_with_sudo(filename, content) then
|
||||||
else
|
return
|
||||||
vim.cmd 'write'
|
end
|
||||||
end
|
|
||||||
else
|
|
||||||
-- File requires sudo
|
|
||||||
-- Prompt for password once per session
|
|
||||||
if not sudo_password_cache then
|
|
||||||
local pass = vim.fn.inputsecret 'sudo password: '
|
|
||||||
if pass == '' or pass == nil then
|
|
||||||
vim.notify('Sudo password required, save cancelled', vim.log.levels.WARN)
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
sudo_password_cache = pass
|
print('Saved ' .. filename)
|
||||||
end
|
|
||||||
-- Write buffer content to sudo tee
|
|
||||||
local sudo_cmd = string.format('sudo -S tee %s > /dev/null', vim.fn.fnameescape(filename))
|
|
||||||
local ok = vim.fn.system(sudo_cmd, sudo_password_cache .. '\n' .. content)
|
|
||||||
if vim.v.shell_error ~= 0 then
|
|
||||||
vim.notify('Failed to write with sudo: ' .. ok, vim.log.levels.ERROR)
|
|
||||||
-- clear cached password to allow retry next time
|
|
||||||
sudo_password_cache = nil
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
-- For no-name buffers or Save As, write and set buffer name
|
||||||
|
if current_path == '' then
|
||||||
|
-- No-name buffer: set name first
|
||||||
|
vim.api.nvim_buf_set_name(0, filename)
|
||||||
|
-- Force overwrite if file exists
|
||||||
|
local write_cmd = 'write!'
|
||||||
|
local ok = pcall(function()
|
||||||
|
vim.cmd(write_cmd)
|
||||||
|
end)
|
||||||
|
if not ok then
|
||||||
|
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, true)
|
||||||
|
local content = table.concat(lines, '\n')
|
||||||
|
if not write_with_sudo(filename, content) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Clear modified flag so future saves work correctly
|
||||||
|
vim.api.nvim_buf_set_option(0, 'modified', false)
|
||||||
|
else
|
||||||
|
-- Named buffer: normal Save As logic
|
||||||
|
local write_cmd = overwrite and 'write!' or 'write'
|
||||||
|
local ok = pcall(function()
|
||||||
|
vim.cmd(write_cmd .. ' ' .. vim.fn.fnameescape(filename))
|
||||||
|
end)
|
||||||
|
if not ok then
|
||||||
|
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, true)
|
||||||
|
local content = table.concat(lines, '\n')
|
||||||
|
if not write_with_sudo(filename, content) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Preserve cursor position and undo history
|
||||||
|
local old_buf = vim.api.nvim_get_current_buf()
|
||||||
|
local cursor_pos = vim.api.nvim_win_get_cursor(0)
|
||||||
|
local undo_history = vim.fn.getbufinfo(old_buf)[1].changedtick
|
||||||
|
-- Open the new file in a fresh buffer
|
||||||
|
vim.cmd('edit ' .. vim.fn.fnameescape(filename))
|
||||||
|
-- Restore cursor
|
||||||
|
vim.api.nvim_win_set_cursor(0, cursor_pos)
|
||||||
|
-- Restore undo history
|
||||||
|
vim.cmd 'undojoin'
|
||||||
|
-- Delete the old buffer without saving
|
||||||
|
vim.api.nvim_buf_delete(old_buf, { force = true })
|
||||||
|
end
|
||||||
|
print('Saved as ' .. filename)
|
||||||
|
else
|
||||||
|
-- Buffer already has a name, just save it
|
||||||
|
local ok = pcall(function()
|
||||||
|
vim.cmd 'w'
|
||||||
|
end)
|
||||||
|
if not ok then
|
||||||
|
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, true)
|
||||||
|
local content = table.concat(lines, '\n')
|
||||||
|
if not write_with_sudo(current_path, content) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
vim.api.nvim_buf_set_option(0, 'modified', false)
|
||||||
|
print('Saved ' .. current_path)
|
||||||
end
|
end
|
||||||
vim.api.nvim_buf_set_option(0, 'modified', false)
|
|
||||||
print('Saved ' .. filename)
|
|
||||||
end
|
end
|
||||||
-- Save current buffer
|
-- Save current buffer
|
||||||
vim.keymap.set('n', '<leader>w', function()
|
vim.keymap.set('n', '<leader>w', function()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
return {
|
return {
|
||||||
'mbbill/undotree',
|
'mbbill/undotree',
|
||||||
|
lazy = false,
|
||||||
keys = {
|
keys = {
|
||||||
{ '<leader>u', vim.cmd.UndotreeToggle, desc = 'Toggle UndoTree' },
|
{ '<leader>u', vim.cmd.UndotreeToggle, desc = 'Toggle UndoTree' },
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user