Implement vim visual mode
This commit is contained in:
parent
ee040b5785
commit
4584f98a23
|
@ -176,7 +176,15 @@ command.add(nil, {
|
||||||
core.vim_mode = not core.vim_mode
|
core.vim_mode = not core.vim_mode
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
["core:set-command-mode"] = function()
|
||||||
|
core.set_editing_mode(core.active_view, 'command')
|
||||||
|
end,
|
||||||
|
|
||||||
["core:set-insert-mode"] = function()
|
["core:set-insert-mode"] = function()
|
||||||
core.set_editing_mode(core.active_view, 'insert')
|
core.set_editing_mode(core.active_view, 'insert')
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
["core:set-visual-mode"] = function()
|
||||||
|
core.set_editing_mode(core.active_view, 'visual')
|
||||||
|
end,
|
||||||
})
|
})
|
||||||
|
|
|
@ -376,4 +376,14 @@ commands["doc:move-to-next-char"] = function()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
commands["doc:move-to-end-of-selection"] = function()
|
||||||
|
local _, _, line, col = doc():get_selection(true)
|
||||||
|
doc():set_selection(line, col)
|
||||||
|
end
|
||||||
|
|
||||||
|
commands["doc:move-to-start-of-selection"] = function()
|
||||||
|
local line, col = doc():get_selection(true)
|
||||||
|
doc():set_selection(line, col)
|
||||||
|
end
|
||||||
|
|
||||||
command.add("core.docview", commands)
|
command.add("core.docview", commands)
|
||||||
|
|
|
@ -25,7 +25,9 @@ local function table_find(t, e)
|
||||||
end
|
end
|
||||||
|
|
||||||
local verbs_obj = {'c', 'd'}
|
local verbs_obj = {'c', 'd'}
|
||||||
local verbs_imm = {'a', 'h', 'i', 'j', 'k', 'l', 'o', 'p', 'u', 'x', 'y', 'O', 'left', 'right', 'up', 'down'}
|
local verbs_imm = {'a', 'h', 'i', 'j', 'k', 'l', 'o', 'p', 'u', 'v', 'x', 'y', 'O',
|
||||||
|
'left', 'right', 'up', 'down', 'escape'}
|
||||||
|
|
||||||
local vim_objects = {'b', 'd', 'e', 'w', '^', '0', '$'}
|
local vim_objects = {'b', 'd', 'e', 'w', '^', '0', '$'}
|
||||||
|
|
||||||
local vim_object_map = {
|
local vim_object_map = {
|
||||||
|
@ -37,45 +39,53 @@ local vim_object_map = {
|
||||||
['0'] = 'start-of-line',
|
['0'] = 'start-of-line',
|
||||||
}
|
}
|
||||||
|
|
||||||
local function vim_execute(verb, mult, object)
|
local function doc_command(action, command)
|
||||||
|
return 'doc:' .. action .. '-' .. command
|
||||||
|
end
|
||||||
|
|
||||||
|
local function vim_execute(mode, verb, mult, object)
|
||||||
|
local action = (mode == 'command' and 'move-to' or 'select-to')
|
||||||
if verb == '.' then
|
if verb == '.' then
|
||||||
if object == '$' then
|
if object == '$' then
|
||||||
command.perform_many(mult - 1, 'doc:move-to-next-line')
|
command.perform_many(mult - 1, doc_command(action, 'next-line'))
|
||||||
command.perform('doc:move-to-end-of-line')
|
command.perform(doc_command(action, 'end-of-line'))
|
||||||
else
|
else
|
||||||
if object == 'e' then
|
if object == 'e' then
|
||||||
command.perform('doc:move-to-next-char')
|
command.perform(doc_command(action, 'next-char'))
|
||||||
end
|
end
|
||||||
command.perform_many(mult, 'doc:move-to-' .. vim_object_map[object])
|
command.perform_many(mult, doc_command(action, vim_object_map[object]))
|
||||||
if object == 'e' then
|
if object == 'e' then
|
||||||
command.perform('doc:move-to-previous-char')
|
command.perform(doc.command(action, 'previous-char'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif verb == 'd' then
|
elseif verb == 'd' then
|
||||||
if object == '$' then
|
if mode == 'command' then
|
||||||
command.perform_many(mult - 1, 'doc:select-to-next-line')
|
if object == '$' then
|
||||||
command.perform('doc:select-to-end-of-line')
|
command.perform_many(mult - 1, 'doc:select-to-next-line')
|
||||||
elseif object == 'd' then
|
command.perform('doc:select-to-end-of-line')
|
||||||
command.perform('doc:move-to-start-of-line')
|
elseif object == 'd' then
|
||||||
command.perform_many(mult, 'doc:select-to-next-line')
|
command.perform('doc:move-to-start-of-line')
|
||||||
else
|
command.perform_many(mult, 'doc:select-to-next-line')
|
||||||
command.perform_many(mult, 'doc:select-to-' .. vim_object_map[object])
|
else
|
||||||
|
command.perform_many(mult, 'doc:select-to-' .. vim_object_map[object])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
command.perform('doc:copy')
|
command.perform('doc:copy')
|
||||||
command.perform('doc:cut')
|
command.perform('doc:cut')
|
||||||
|
command.perform('core:set-command-mode')
|
||||||
elseif verb == 'c' then
|
elseif verb == 'c' then
|
||||||
command.perform_many(mult, 'doc:select-to-' .. vim_object_map[object])
|
command.perform_many(mult, 'doc:select-to-' .. vim_object_map[object])
|
||||||
command.perform('doc:copy')
|
command.perform('doc:copy')
|
||||||
command.perform('doc:cut')
|
command.perform('doc:cut')
|
||||||
command.perform('core:set-insert-mode')
|
command.perform('core:set-insert-mode')
|
||||||
elseif verb == 'h' or verb == 'left' then
|
elseif verb == 'h' or verb == 'left' then
|
||||||
command.perform_many(mult, 'doc:move-to-previous-char')
|
command.perform_many(mult, doc_command(action, 'previous-char'))
|
||||||
elseif verb == 'j' or verb == 'down' then
|
elseif verb == 'j' or verb == 'down' then
|
||||||
command.perform_many(mult, 'doc:move-to-next-line')
|
command.perform_many(mult, doc_command(action, 'next-line'))
|
||||||
elseif verb == 'k' or verb == 'up' then
|
elseif verb == 'k' or verb == 'up' then
|
||||||
command.perform_many(mult, 'doc:move-to-previous-line')
|
command.perform_many(mult, doc_command(action, 'previous-line'))
|
||||||
elseif verb == 'l' or verb == 'right' then
|
elseif verb == 'l' or verb == 'right' then
|
||||||
command.perform_many(mult, 'doc:move-to-next-char')
|
command.perform_many(mult, doc_command(action, 'next-char'))
|
||||||
elseif verb == 'x' then
|
elseif verb == 'x' then
|
||||||
command.perform_many(mult, 'doc:delete')
|
command.perform_many(mult, 'doc:delete')
|
||||||
elseif verb == 'a' then
|
elseif verb == 'a' then
|
||||||
|
@ -87,7 +97,7 @@ local function vim_execute(verb, mult, object)
|
||||||
command.perform('doc:move-to-end-of-line')
|
command.perform('doc:move-to-end-of-line')
|
||||||
command.perform('doc:newline')
|
command.perform('doc:newline')
|
||||||
command.perform('core:set-insert-mode')
|
command.perform('core:set-insert-mode')
|
||||||
elseif verb == 'O' then -- FIXME: doesn't work
|
elseif verb == 'O' then
|
||||||
command.perform('doc:move-to-start-of-line')
|
command.perform('doc:move-to-start-of-line')
|
||||||
command.perform('doc:newline')
|
command.perform('doc:newline')
|
||||||
command.perform('doc:move-to-previous-line')
|
command.perform('doc:move-to-previous-line')
|
||||||
|
@ -96,6 +106,15 @@ local function vim_execute(verb, mult, object)
|
||||||
command.perform('doc:paste')
|
command.perform('doc:paste')
|
||||||
elseif verb == 'u' then
|
elseif verb == 'u' then
|
||||||
command.perform('doc:undo')
|
command.perform('doc:undo')
|
||||||
|
elseif verb == 'v' then
|
||||||
|
command.perform('core:set-visual-mode')
|
||||||
|
elseif verb == 'y' then
|
||||||
|
command.perform('doc:copy')
|
||||||
|
command.perform('doc:move-to-start-of-selection')
|
||||||
|
command.perform('core:set-command-mode')
|
||||||
|
elseif verb == 'escape' then
|
||||||
|
command.perform('doc:move-to-end-of-selection')
|
||||||
|
command.perform('core:set-command-mode')
|
||||||
else
|
else
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
@ -104,19 +123,24 @@ end
|
||||||
|
|
||||||
function vim.on_text_input(mode, text, stroke)
|
function vim.on_text_input(mode, text, stroke)
|
||||||
text = text or stroke
|
text = text or stroke
|
||||||
if mode == 'command' then
|
if mode == 'command' or mode == 'visual' then
|
||||||
if command_buffer.verb == '.' and table_find(verbs_imm, text) then
|
if command_buffer.verb == '.' and table_find(verbs_imm, text) then
|
||||||
vim_execute(text, command_buffer:mult())
|
vim_execute(mode, text, command_buffer:mult())
|
||||||
command_buffer:reset()
|
command_buffer:reset()
|
||||||
return true
|
return true
|
||||||
elseif command_buffer.verb == '.' and table_find(verbs_obj, text) then
|
elseif command_buffer.verb == '.' and table_find(verbs_obj, text) then
|
||||||
command_buffer.verb = text
|
if mode == 'command' then
|
||||||
|
command_buffer.verb = text
|
||||||
|
else
|
||||||
|
vim_execute(mode, text, command_buffer:mult())
|
||||||
|
command_buffer:reset()
|
||||||
|
end
|
||||||
return true
|
return true
|
||||||
elseif string.byte(text) >= string.byte('0') and string.byte(text) <= string.byte('9') then
|
elseif string.byte(text) >= string.byte('0') and string.byte(text) <= string.byte('9') then
|
||||||
command_buffer:add_mult_char(text)
|
command_buffer:add_mult_char(text)
|
||||||
return true
|
return true
|
||||||
elseif table_find(vim_objects, text) then
|
elseif table_find(vim_objects, text) then
|
||||||
vim_execute(command_buffer.verb, command_buffer:mult(), text)
|
vim_execute(mode, command_buffer.verb, command_buffer:mult(), text)
|
||||||
command_buffer:reset()
|
command_buffer:reset()
|
||||||
return true
|
return true
|
||||||
elseif stroke == 'escape' then
|
elseif stroke == 'escape' then
|
||||||
|
|
Loading…
Reference in New Issue