Make chat windows read only

This commit is contained in:
Jonas Widen 2025-03-16 20:57:04 +01:00
parent 4db184f29b
commit 6efac64319

@ -22,6 +22,7 @@ local function setup_chat_highlighting(bufnr)
end
local function setup_buffer_options(bufnr)
-- Set strict buffer options
local options = {
buftype = 'nofile',
filetype = 'markdown',
@ -30,52 +31,90 @@ local function setup_buffer_options(bufnr)
bufhidden = 'wipe',
modifiable = false,
readonly = true,
undolevels = -1, -- Disable undo
list = false, -- Disable list mode
number = false, -- Disable line numbers
undolevels = -1,
list = false,
number = false,
relativenumber = false,
modifiable = false,
modified = false,
foldmethod = 'manual',
foldlevel = 99,
textwidth = 0,
wrapmargin = 0,
expandtab = true,
autoindent = false,
smartindent = false,
}
for option, value in pairs(options) do
vim.api.nvim_buf_set_option(bufnr, option, value)
end
-- Clear buffer name to prevent file operations
vim.api.nvim_buf_set_name(bufnr, '')
end
local function setup_buffer_autocmds(bufnr)
local augroup = vim.api.nvim_create_augroup('GeminiChatBuffer', { clear = true })
-- Block ALL file operations and buffer modifications
-- Block ALL buffer events that could load files
local blocked_events = {
'BufReadCmd', 'FileReadCmd', 'BufWriteCmd', 'FileWriteCmd',
'BufReadPre', 'BufReadPost', 'BufWrite', 'BufWritePre', 'BufWritePost',
'FileReadPre', 'FileReadPost', 'FileWritePre', 'FileWritePost',
'BufAdd', 'BufCreate', 'BufDelete', 'BufWipeout'
'BufAdd', 'BufCreate', 'BufDelete', 'BufWipeout',
'BufNew', 'BufNewFile', 'BufRead', 'BufEnter', 'BufLeave',
'FileType', 'BufFilePre', 'BufFilePost',
'FileChangedShell', 'FileChangedShellPost',
'FileChangedRO', 'FileAppendCmd', 'FileAppendPre', 'FileAppendPost',
'FilterReadPre', 'FilterReadPost', 'FocusGained', 'FocusLost'
}
vim.api.nvim_create_autocmd(blocked_events, {
group = augroup,
buffer = bufnr,
callback = function()
vim.notify('File operations are not allowed in the chat window', vim.log.levels.WARN)
return true
end
})
for _, event in ipairs(blocked_events) do
vim.api.nvim_create_autocmd(event, {
group = augroup,
buffer = bufnr,
callback = function()
vim.notify('File operations are not allowed in the chat window', vim.log.levels.WARN)
return true -- Prevent the default handler
end
})
end
-- Prevent dropping files into the buffer
-- Override buffer behavior
vim.api.nvim_create_autocmd('BufEnter', {
group = augroup,
buffer = bufnr,
callback = function()
-- Force buffer settings on every enter
vim.opt_local.modifiable = false
vim.opt_local.readonly = true
-- Disable file-related options
vim.opt_local.swapfile = false
vim.opt_local.buftype = 'nofile'
vim.opt_local.buflisted = false
-- Disable file loading capabilities
vim.bo[bufnr].buftype = 'nofile'
vim.bo[bufnr].filetype = 'markdown'
-- Clear file name to prevent file operations
vim.api.nvim_buf_set_name(bufnr, '')
-- Return true to prevent default BufEnter handling
return true
end
})
-- Prevent any attempt to change buffer settings
vim.api.nvim_create_autocmd('OptionSet', {
group = augroup,
buffer = bufnr,
callback = function()
vim.schedule(function()
vim.opt_local.modifiable = false
vim.opt_local.readonly = true
vim.opt_local.buftype = 'nofile'
end)
return true
end
})
end
@ -83,46 +122,28 @@ end
local function setup_buffer_keymaps(bufnr)
local opts = { buffer = bufnr, nowait = true, silent = true }
-- Block ALL commands that could manipulate files or buffers
local blocked_cmds = {
'e', 'edit', 'ene', 'enew', 'fin', 'find',
'w', 'write', 'wa', 'wall',
'sp', 'split', 'vs', 'vsplit',
'new', 'vnew', 'tabnew',
'read', 'r', 'file', 'f',
'saveas', 'w', 'wq', 'wqa',
'q', 'quit', 'qa', 'qall',
'bn', 'bnext', 'bp', 'bprevious',
'bd', 'bdelete', 'bw', 'bwipeout',
'o', 'open', 'browse'
}
-- Block all command variations
for _, cmd in ipairs(blocked_cmds) do
vim.keymap.set('n', ':' .. cmd, function()
vim.notify('Command not allowed in chat window', vim.log.levels.WARN)
end, opts)
vim.keymap.set('n', ':' .. cmd .. '!', function()
vim.notify('Command not allowed in chat window', vim.log.levels.WARN)
end, opts)
end
-- Disable command-line completely
-- Disable ALL commands
vim.keymap.set('n', ':', function()
vim.notify('Command mode disabled in chat window', vim.log.levels.WARN)
vim.notify('Commands are disabled in chat window', vim.log.levels.WARN)
return '<Esc>'
end, opts)
-- Block common file operation key combinations
-- Block ALL normal mode key combinations that could manipulate files
local blocked_keys = {
'ZZ', 'ZQ', 'gf', '<C-w>f', '<C-w>gf',
'<C-w>v', '<C-w>s', '<C-w>n'
'ZZ', 'ZQ', 'gf', '<C-w>f', '<C-w>gf', '<C-w>F',
'<C-w>v', '<C-w>s', '<C-w>n', '<C-^>', '<C-6>',
'<C-w>^', '<C-w>6', 'gF', '<C-w>gF',
'<C-w>o', '<C-w>T', '<C-w>H', '<C-w>J', '<C-w>K', '<C-w>L'
}
for _, key in ipairs(blocked_keys) do
vim.keymap.set('n', key, '<Nop>', opts)
vim.keymap.set({'n', 'v', 'i'}, key, function()
vim.notify('Operation not allowed in chat window', vim.log.levels.WARN)
return '<Esc>'
end, opts)
end
-- Set chat-specific keymaps
-- Only allow specific keymaps for chat functionality
local mappings = config.options.mappings
vim.keymap.set('n', mappings.close, function()
vim.api.nvim_win_close(state.winnr, true)
@ -136,6 +157,12 @@ local function setup_buffer_keymaps(bufnr)
vim.keymap.set('n', mappings.new_query, function()
require("gemini").prompt_query(state.current_context)
end, opts)
-- Allow basic navigation
local allowed_keys = {'j', 'k', '<C-d>', '<C-u>', '<C-f>', '<C-b>', 'G', 'gg'}
for _, key in ipairs(allowed_keys) do
vim.keymap.set('n', key, key, opts)
end
end
function M.create_window()