Bring the fancy Neovim prompt back
This commit is contained in:
@@ -24,6 +24,7 @@ function! s:OutputErrorMessage(message) abort
|
||||
|
||||
try
|
||||
for l:line in l:lines
|
||||
" FIXME: This can cause "Press Enter to continue..."
|
||||
" no-custom-checks
|
||||
echomsg l:line
|
||||
endfor
|
||||
@@ -79,6 +80,7 @@ function! s:HandleOutputEnd(buffer, job_data, exit_code) abort
|
||||
else
|
||||
" Signal Neural is done for plugin integration.
|
||||
silent doautocmd <nomodeline> User NeuralWritePost
|
||||
" FIXME: This can cause "Press Enter to continue..."
|
||||
" no-custom-checks
|
||||
echomsg 'Neural is done!'
|
||||
endif
|
||||
@@ -112,7 +114,36 @@ function! neural#Escape(str) abort
|
||||
return shellescape (a:str)
|
||||
endfunction
|
||||
|
||||
function! neural#ComplainNoPromptText() abort
|
||||
call s:OutputErrorMessage('No prompt text!')
|
||||
endfunction
|
||||
|
||||
function! neural#OpenPrompt() abort
|
||||
if has('nvim')
|
||||
" In Neovim, try to use the fancy prompt UI, if we can.
|
||||
lua require('neural').prompt()
|
||||
else
|
||||
call feedkeys(':NeuralPrompt ')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! neural#ComplainNoPromptText() abort
|
||||
call s:OutputErrorMessage('No prompt text!')
|
||||
endfunction
|
||||
|
||||
function! neural#Prompt(prompt_text) abort
|
||||
if empty(a:prompt_text)
|
||||
if has('nvim')
|
||||
" FIXME: The prompt in Neovim can keep opening again and again
|
||||
" if the UI plugin is not installed.
|
||||
call neural#OpenPrompt()
|
||||
else
|
||||
call s:OutputErrorMessage('No prompt text!')
|
||||
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
" TODO: Print a message if the function cannot be loaded.
|
||||
let l:GetDatasource = function(
|
||||
\ 'neural#datasource#'
|
||||
@@ -175,6 +206,8 @@ function! neural#Prompt(prompt_text) abort
|
||||
" it print the results live. Maybe users will want to disable
|
||||
" the 'cool' printing of messages in any case.
|
||||
"
|
||||
" FIXME: This can cause "Press Enter to continue..."
|
||||
"
|
||||
" no-custom-checks
|
||||
echomsg 'Neural is working, please wait...'
|
||||
endfunction
|
||||
|
||||
@@ -66,6 +66,11 @@ NeuralPrompt *NeuralPrompt*
|
||||
|
||||
Prompt Neural for a response. e.g. `:NeuralPrompt say hello`
|
||||
|
||||
If the command is run with no text input and `nui.vim` is installed, a fancy
|
||||
UI for entering the prompt will be shown.
|
||||
|
||||
See https://github.com/MunifTanjim/nui.nvim for installation instructions.
|
||||
|
||||
A plug mapping `<Plug>(neural_prompt)` is defined for this command.
|
||||
|
||||
A |NeuralWritePost| event will be fired whenever Neural successfully
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
std = "min"
|
||||
ignore = {"211", "542"}
|
||||
globals = {"vim", "unpack"}
|
||||
@@ -0,0 +1,40 @@
|
||||
local next = next
|
||||
local Config = require('neural.config')
|
||||
|
||||
-- External dependencies
|
||||
local has_nui, _ = pcall(require, 'nui.input')
|
||||
local UI = {}
|
||||
|
||||
if has_nui then
|
||||
UI = require('neural.ui')
|
||||
end
|
||||
|
||||
local Neural = {}
|
||||
|
||||
function Neural.setup(options)
|
||||
Config.setup(options)
|
||||
end
|
||||
|
||||
function Neural.prompt()
|
||||
-- Set up the default config if not otherwise configured.
|
||||
if next(Config.options) == nil then
|
||||
Config.setup({})
|
||||
end
|
||||
|
||||
if has_nui and Config.options.ui.use_prompt then
|
||||
UI.prompt(
|
||||
' Neural ',
|
||||
function(value)
|
||||
if value == nil or value == '' then
|
||||
vim.fn['neural#ComplainNoPromptText']()
|
||||
else
|
||||
vim.fn['neural#Prompt'](value)
|
||||
end
|
||||
end
|
||||
)
|
||||
else
|
||||
vim.fn.feedkeys(':NeuralPrompt ')
|
||||
end
|
||||
end
|
||||
|
||||
return Neural
|
||||
@@ -0,0 +1,38 @@
|
||||
local Config = {}
|
||||
|
||||
Config.namespace = vim.api.nvim_create_namespace('Neural')
|
||||
|
||||
local defaults = {
|
||||
mappings = {
|
||||
swift = '<C-n>', -- Code complete with no prompt
|
||||
prompt = '<C-space>',
|
||||
},
|
||||
-- OpenAI settings
|
||||
open_ai = {
|
||||
temperature = 0.0,
|
||||
presence_penalty = 0.3,
|
||||
frequency_penalty = 0.3,
|
||||
max_tokens = 2048,
|
||||
context_lines = 16, -- Surrounding lines for swift completion
|
||||
api_key = '...', -- Add your Open API secret key on setup (DO NOT COMMIT)
|
||||
},
|
||||
-- Visual settings
|
||||
ui = {
|
||||
use_prompt = true, -- Use visual floating Input
|
||||
use_animated_sign = true, -- Use animated sign mark
|
||||
show_hl = true,
|
||||
show_icon = true,
|
||||
icon = '🗲', -- Prompt/Static sign icon
|
||||
icon_color = '#ffe030', -- Sign icon color
|
||||
hl_color = '#4D4839', -- Line highlighting on output
|
||||
prompt_border_color = '#E5C07B',
|
||||
},
|
||||
}
|
||||
|
||||
Config.options = {}
|
||||
|
||||
function Config.setup(options)
|
||||
Config.options = vim.tbl_deep_extend("force", {}, defaults, options or {})
|
||||
end
|
||||
|
||||
return Config
|
||||
@@ -0,0 +1,75 @@
|
||||
-- UI module for creating the nui.nvim input popup
|
||||
|
||||
local Input = require('nui.input')
|
||||
local Event = require('nui.utils.autocmd').event
|
||||
local Config = require('neural.config')
|
||||
|
||||
local UI = {}
|
||||
|
||||
-- Prompts the user for input.
|
||||
--- @param title string The title of the prompt.
|
||||
--- @param on_submit function The function to call when the user submits the prompt.
|
||||
function UI.prompt(title, on_submit)
|
||||
|
||||
-- TODO: Make escape keys configurable.
|
||||
local exit_keys = {
|
||||
{'n', 'q',
|
||||
function(_)
|
||||
vim.api.nvim_command(':q')
|
||||
end, {noremap = true},
|
||||
},
|
||||
{'n', '<ESC>',
|
||||
function(_)
|
||||
vim.api.nvim_command(':q')
|
||||
end, {noremap = true},
|
||||
},
|
||||
{'i', '<ESC>',
|
||||
function(_)
|
||||
vim.api.nvim_command(':q')
|
||||
end, {noremap = true},
|
||||
},
|
||||
{'i', '<C-c>',
|
||||
function(_)
|
||||
vim.api.nvim_command(':q')
|
||||
end, {noremap = true},
|
||||
},
|
||||
}
|
||||
|
||||
-- TODO: Make prompt more configurable.
|
||||
local input = Input({
|
||||
position = {row = '85.2%', col = '50%'},
|
||||
size = {
|
||||
width = '51.8%',
|
||||
height = '20%',
|
||||
},
|
||||
relative = 'editor',
|
||||
border = {
|
||||
highlight = 'NeuralPromptBorder',
|
||||
style = 'rounded',
|
||||
text = {
|
||||
top = title,
|
||||
top_align = 'center',
|
||||
},
|
||||
},
|
||||
win_options = {
|
||||
winblend = 10,
|
||||
winhighlight = 'Normal:Normal',
|
||||
},
|
||||
}, {
|
||||
prompt = Config.options.ui.icon .. ' ',
|
||||
default_value = '',
|
||||
on_close = function() end,
|
||||
on_submit = function(value)
|
||||
on_submit(value)
|
||||
end,
|
||||
})
|
||||
input:mount()
|
||||
input:on(Event.BufLeave, function()
|
||||
input:unmount()
|
||||
end)
|
||||
for _, v in ipairs(exit_keys) do
|
||||
input:map(unpack(v))
|
||||
end
|
||||
end
|
||||
|
||||
return UI
|
||||
+2
-2
@@ -37,7 +37,7 @@ let g:neural_selected_datasource = get(g:, 'neural_selected_datasource', 'openai
|
||||
" Configure machine learning datasources, such as: {'openai': {'api_key': ...}}
|
||||
let g:neural_datasource_config = get(g:, 'neural_datasource_config', {})
|
||||
|
||||
command! -nargs=1 NeuralPrompt :call neural#Prompt(<q-args>)
|
||||
command! -nargs=? NeuralPrompt :call neural#Prompt(<q-args>)
|
||||
|
||||
" <Plug> mappings for commands
|
||||
nnoremap <Plug>(neural_prompt) :NeuralPrompt<Space>
|
||||
nnoremap <Plug>(neural_prompt) :call neural#OpenPrompt()<Return>
|
||||
|
||||
Reference in New Issue
Block a user