Text overwriting (#1495)
* added text overwriting * rewrote `DocView:draw_caret` to not use the order of draws * forgot to delete some old code in `DocView:draw_overlay` also added a temporary solution to overwriting and added the missing arguments in `DocView:draw_ime_decoration` and fixed `DocView:draw_caret` * accidentally broke the `draw_caret` call in `draw_overlay` in the process * multiline * fixed calling `Doc:get_char` as a function that, in turn, crashed the editor because "can't index a number" * move and rename some stuff * remove unneeded extra check I just had to change the `~=` to `<` in the second condition * overwrite disregards pasting text * disregard overwrite on selections; doc only removes selection * Fixed error where `doc` was used, instead of `self`. --------- Co-authored-by: ThaCuber <70547062+ThaCuber@users.noreply.github.com> Co-authored-by: Adam Harrison <adamdharrison@gmail.com>
This commit is contained in:
parent
e95094f0ca
commit
9615ead41b
|
@ -545,6 +545,11 @@ local commands = {
|
||||||
dv.doc.crlf = not dv.doc.crlf
|
dv.doc.crlf = not dv.doc.crlf
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
["doc:toggle-overwrite"] = function(dv)
|
||||||
|
dv.doc.overwrite = not dv.doc.overwrite
|
||||||
|
core.blink_reset() -- to show the cursor has changed edit modes
|
||||||
|
end,
|
||||||
|
|
||||||
["doc:save-as"] = function(dv)
|
["doc:save-as"] = function(dv)
|
||||||
local last_doc = core.last_active_view and core.last_active_view.doc
|
local last_doc = core.last_active_view and core.last_active_view.doc
|
||||||
local text
|
local text
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
local Object = require "core.object"
|
local Object = require "core.object"
|
||||||
local Highlighter = require "core.doc.highlighter"
|
local Highlighter = require "core.doc.highlighter"
|
||||||
|
local translate = require "core.doc.translate"
|
||||||
local core = require "core"
|
local core = require "core"
|
||||||
local syntax = require "core.syntax"
|
local syntax = require "core.syntax"
|
||||||
local config = require "core.config"
|
local config = require "core.config"
|
||||||
|
@ -29,7 +30,6 @@ function Doc:new(filename, abs_filename, new_file)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:reset()
|
function Doc:reset()
|
||||||
self.lines = { "\n" }
|
self.lines = { "\n" }
|
||||||
self.selections = { 1, 1, 1, 1 }
|
self.selections = { 1, 1, 1, 1 }
|
||||||
|
@ -38,10 +38,10 @@ function Doc:reset()
|
||||||
self.redo_stack = { idx = 1 }
|
self.redo_stack = { idx = 1 }
|
||||||
self.clean_change_id = 1
|
self.clean_change_id = 1
|
||||||
self.highlighter = Highlighter(self)
|
self.highlighter = Highlighter(self)
|
||||||
|
self.overwrite = false
|
||||||
self:reset_syntax()
|
self:reset_syntax()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:reset_syntax()
|
function Doc:reset_syntax()
|
||||||
local header = self:get_text(1, 1, self:position_offset(1, 1, 128))
|
local header = self:get_text(1, 1, self:position_offset(1, 1, 128))
|
||||||
local path = self.abs_filename
|
local path = self.abs_filename
|
||||||
|
@ -56,16 +56,14 @@ function Doc:reset_syntax()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:set_filename(filename, abs_filename)
|
function Doc:set_filename(filename, abs_filename)
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.abs_filename = abs_filename
|
self.abs_filename = abs_filename
|
||||||
self:reset_syntax()
|
self:reset_syntax()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:load(filename)
|
function Doc:load(filename)
|
||||||
local fp = assert( io.open(filename, "rb") )
|
local fp = assert(io.open(filename, "rb"))
|
||||||
self:reset()
|
self:reset()
|
||||||
self.lines = {}
|
self.lines = {}
|
||||||
local i = 1
|
local i = 1
|
||||||
|
@ -85,7 +83,6 @@ function Doc:load(filename)
|
||||||
self:reset_syntax()
|
self:reset_syntax()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:reload()
|
function Doc:reload()
|
||||||
if self.filename then
|
if self.filename then
|
||||||
local sel = { self:get_selection() }
|
local sel = { self:get_selection() }
|
||||||
|
@ -95,7 +92,6 @@ function Doc:reload()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:save(filename, abs_filename)
|
function Doc:save(filename, abs_filename)
|
||||||
if not filename then
|
if not filename then
|
||||||
assert(self.filename, "no filename set to default to")
|
assert(self.filename, "no filename set to default to")
|
||||||
|
@ -104,7 +100,7 @@ function Doc:save(filename, abs_filename)
|
||||||
else
|
else
|
||||||
assert(self.filename or abs_filename, "calling save on unnamed doc without absolute path")
|
assert(self.filename or abs_filename, "calling save on unnamed doc without absolute path")
|
||||||
end
|
end
|
||||||
local fp = assert( io.open(filename, "wb") )
|
local fp = assert(io.open(filename, "wb"))
|
||||||
for _, line in ipairs(self.lines) do
|
for _, line in ipairs(self.lines) do
|
||||||
if self.crlf then line = line:gsub("\n", "\r\n") end
|
if self.crlf then line = line:gsub("\n", "\r\n") end
|
||||||
fp:write(line)
|
fp:write(line)
|
||||||
|
@ -115,12 +111,10 @@ function Doc:save(filename, abs_filename)
|
||||||
self:clean()
|
self:clean()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:get_name()
|
function Doc:get_name()
|
||||||
return self.filename or "unsaved"
|
return self.filename or "unsaved"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:is_dirty()
|
function Doc:is_dirty()
|
||||||
if self.new_file then
|
if self.new_file then
|
||||||
if self.filename then return true end
|
if self.filename then return true end
|
||||||
|
@ -130,20 +124,17 @@ function Doc:is_dirty()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:clean()
|
function Doc:clean()
|
||||||
self.clean_change_id = self:get_change_id()
|
self.clean_change_id = self:get_change_id()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:get_indent_info()
|
function Doc:get_indent_info()
|
||||||
if not self.indent_info then return config.tab_type, config.indent_size, false end
|
if not self.indent_info then return config.tab_type, config.indent_size, false end
|
||||||
return self.indent_info.type or config.tab_type,
|
return self.indent_info.type or config.tab_type,
|
||||||
self.indent_info.size or config.indent_size,
|
self.indent_info.size or config.indent_size,
|
||||||
self.indent_info.confirmed
|
self.indent_info.confirmed
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:get_change_id()
|
function Doc:get_change_id()
|
||||||
return self.undo_stack.idx
|
return self.undo_stack.idx
|
||||||
end
|
end
|
||||||
|
@ -167,13 +158,14 @@ function Doc:get_selection(sort)
|
||||||
return line1, col1, line2, col2, swap
|
return line1, col1, line2, col2, swap
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
---Get the selection specified by `idx`
|
---Get the selection specified by `idx`
|
||||||
---@param idx integer @the index of the selection to retrieve
|
---@param idx integer @the index of the selection to retrieve
|
||||||
---@param sort? boolean @whether to sort the selection returned
|
---@param sort? boolean @whether to sort the selection returned
|
||||||
---@return integer,integer,integer,integer,boolean? @line1, col1, line2, col2, was the selection sorted
|
---@return integer,integer,integer,integer,boolean? @line1, col1, line2, col2, was the selection sorted
|
||||||
function Doc:get_selection_idx(idx, sort)
|
function Doc:get_selection_idx(idx, sort)
|
||||||
local line1, col1, line2, col2 = self.selections[idx*4-3], self.selections[idx*4-2], self.selections[idx*4-1], self.selections[idx*4]
|
local line1, col1, line2, col2 = self.selections[idx * 4 - 3], self.selections[idx * 4 - 2],
|
||||||
|
self.selections[idx * 4 - 1],
|
||||||
|
self.selections[idx * 4]
|
||||||
if line1 and sort then
|
if line1 and sort then
|
||||||
return sort_positions(line1, col1, line2, col2)
|
return sort_positions(line1, col1, line2, col2)
|
||||||
else
|
else
|
||||||
|
@ -217,7 +209,7 @@ function Doc:set_selections(idx, line1, col1, line2, col2, swap, rm)
|
||||||
if swap then line1, col1, line2, col2 = line2, col2, line1, col1 end
|
if swap then line1, col1, line2, col2 = line2, col2, line1, col1 end
|
||||||
line1, col1 = self:sanitize_position(line1, col1)
|
line1, col1 = self:sanitize_position(line1, col1)
|
||||||
line2, col2 = self:sanitize_position(line2 or line1, col2 or col1)
|
line2, col2 = self:sanitize_position(line2 or line1, col2 or col1)
|
||||||
common.splice(self.selections, (idx - 1)*4 + 1, rm == nil and 4 or rm, { line1, col1, line2, col2 })
|
common.splice(self.selections, (idx - 1) * 4 + 1, rm == nil and 4 or rm, { line1, col1, line2, col2 })
|
||||||
end
|
end
|
||||||
|
|
||||||
function Doc:add_selection(line1, col1, line2, col2, swap)
|
function Doc:add_selection(line1, col1, line2, col2, swap)
|
||||||
|
@ -233,7 +225,6 @@ function Doc:add_selection(line1, col1, line2, col2, swap)
|
||||||
self.last_selection = target
|
self.last_selection = target
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:remove_selection(idx)
|
function Doc:remove_selection(idx)
|
||||||
if self.last_selection >= idx then
|
if self.last_selection >= idx then
|
||||||
self.last_selection = self.last_selection - 1
|
self.last_selection = self.last_selection - 1
|
||||||
|
@ -241,7 +232,6 @@ function Doc:remove_selection(idx)
|
||||||
common.splice(self.selections, (idx - 1) * 4 + 1, 4)
|
common.splice(self.selections, (idx - 1) * 4 + 1, 4)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:set_selection(line1, col1, line2, col2, swap)
|
function Doc:set_selection(line1, col1, line2, col2, swap)
|
||||||
self.selections = {}
|
self.selections = {}
|
||||||
self:set_selections(1, line1, col1, line2, col2, swap)
|
self:set_selections(1, line1, col1, line2, col2, swap)
|
||||||
|
@ -252,24 +242,24 @@ function Doc:merge_cursors(idx)
|
||||||
for i = (idx or (#self.selections - 3)), (idx or 5), -4 do
|
for i = (idx or (#self.selections - 3)), (idx or 5), -4 do
|
||||||
for j = 1, i - 4, 4 do
|
for j = 1, i - 4, 4 do
|
||||||
if self.selections[i] == self.selections[j] and
|
if self.selections[i] == self.selections[j] and
|
||||||
self.selections[i+1] == self.selections[j+1] then
|
self.selections[i + 1] == self.selections[j + 1] then
|
||||||
common.splice(self.selections, i, 4)
|
common.splice(self.selections, i, 4)
|
||||||
if self.last_selection >= (i+3)/4 then
|
if self.last_selection >= (i + 3) / 4 then
|
||||||
self.last_selection = self.last_selection - 1
|
self.last_selection = self.last_selection - 1
|
||||||
end
|
end
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function selection_iterator(invariant, idx)
|
local function selection_iterator(invariant, idx)
|
||||||
local target = invariant[3] and (idx*4 - 7) or (idx*4 + 1)
|
local target = invariant[3] and (idx * 4 - 7) or (idx * 4 + 1)
|
||||||
if target > #invariant[1] or target <= 0 or (type(invariant[3]) == "number" and invariant[3] ~= idx - 1) then return end
|
if target > #invariant[1] or target <= 0 or (type(invariant[3]) == "number" and invariant[3] ~= idx - 1) then return end
|
||||||
if invariant[2] then
|
if invariant[2] then
|
||||||
return idx+(invariant[3] and -1 or 1), sort_positions(table.unpack(invariant[1], target, target+4))
|
return idx + (invariant[3] and -1 or 1), sort_positions(table.unpack(invariant[1], target, target + 4))
|
||||||
else
|
else
|
||||||
return idx+(invariant[3] and -1 or 1), table.unpack(invariant[1], target, target+4)
|
return idx + (invariant[3] and -1 or 1), table.unpack(invariant[1], target, target + 4)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -277,8 +267,9 @@ end
|
||||||
-- If a number, runs for exactly that iteration.
|
-- If a number, runs for exactly that iteration.
|
||||||
function Doc:get_selections(sort_intra, idx_reverse)
|
function Doc:get_selections(sort_intra, idx_reverse)
|
||||||
return selection_iterator, { self.selections, sort_intra, idx_reverse },
|
return selection_iterator, { self.selections, sort_intra, idx_reverse },
|
||||||
idx_reverse == true and ((#self.selections / 4) + 1) or ((idx_reverse or -1)+1)
|
idx_reverse == true and ((#self.selections / 4) + 1) or ((idx_reverse or -1) + 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- End of cursor seciton.
|
-- End of cursor seciton.
|
||||||
|
|
||||||
function Doc:sanitize_position(line, col)
|
function Doc:sanitize_position(line, col)
|
||||||
|
@ -291,7 +282,6 @@ function Doc:sanitize_position(line, col)
|
||||||
return line, common.clamp(col, 1, #self.lines[line])
|
return line, common.clamp(col, 1, #self.lines[line])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function position_offset_func(self, line, col, fn, ...)
|
local function position_offset_func(self, line, col, fn, ...)
|
||||||
line, col = self:sanitize_position(line, col)
|
line, col = self:sanitize_position(line, col)
|
||||||
return fn(self, line, col, ...)
|
return fn(self, line, col, ...)
|
||||||
|
@ -330,7 +320,6 @@ function Doc:position_offset(line, col, ...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:get_text(line1, col1, line2, col2)
|
function Doc:get_text(line1, col1, line2, col2)
|
||||||
line1, col1 = self:sanitize_position(line1, col1)
|
line1, col1 = self:sanitize_position(line1, col1)
|
||||||
line2, col2 = self:sanitize_position(line2, col2)
|
line2, col2 = self:sanitize_position(line2, col2)
|
||||||
|
@ -346,13 +335,11 @@ function Doc:get_text(line1, col1, line2, col2)
|
||||||
return table.concat(lines)
|
return table.concat(lines)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:get_char(line, col)
|
function Doc:get_char(line, col)
|
||||||
line, col = self:sanitize_position(line, col)
|
line, col = self:sanitize_position(line, col)
|
||||||
return self.lines[line]:sub(col, col)
|
return self.lines[line]:sub(col, col)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function push_undo(undo_stack, time, type, ...)
|
local function push_undo(undo_stack, time, type, ...)
|
||||||
undo_stack[undo_stack.idx] = { type = type, time = time, ... }
|
undo_stack[undo_stack.idx] = { type = type, time = time, ... }
|
||||||
undo_stack[undo_stack.idx - config.max_undos] = nil
|
undo_stack[undo_stack.idx - config.max_undos] = nil
|
||||||
|
@ -413,7 +400,8 @@ function Doc:raw_insert(line, col, text, undo_stack, time)
|
||||||
if cline1 < line then break end
|
if cline1 < line then break end
|
||||||
local line_addition = (line < cline1 or col < ccol1) and #lines - 1 or 0
|
local line_addition = (line < cline1 or col < ccol1) and #lines - 1 or 0
|
||||||
local column_addition = line == cline1 and ccol1 > col and len or 0
|
local column_addition = line == cline1 and ccol1 > col and len or 0
|
||||||
self:set_selections(idx, cline1 + line_addition, ccol1 + column_addition, cline2 + line_addition, ccol2 + column_addition)
|
self:set_selections(idx, cline1 + line_addition, ccol1 + column_addition, cline2 + line_addition,
|
||||||
|
ccol2 + column_addition)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- push undo
|
-- push undo
|
||||||
|
@ -426,7 +414,6 @@ function Doc:raw_insert(line, col, text, undo_stack, time)
|
||||||
self:sanitize_selection()
|
self:sanitize_selection()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:raw_remove(line1, col1, line2, col2, undo_stack, time)
|
function Doc:raw_remove(line1, col1, line2, col2, undo_stack, time)
|
||||||
-- push undo
|
-- push undo
|
||||||
local text = self:get_text(line1, col1, line2, col2)
|
local text = self:get_text(line1, col1, line2, col2)
|
||||||
|
@ -485,7 +472,6 @@ function Doc:raw_remove(line1, col1, line2, col2, undo_stack, time)
|
||||||
self:sanitize_selection()
|
self:sanitize_selection()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:insert(line, col, text)
|
function Doc:insert(line, col, text)
|
||||||
self.redo_stack = { idx = 1 }
|
self.redo_stack = { idx = 1 }
|
||||||
-- Reset the clean id when we're pushing something new before it
|
-- Reset the clean id when we're pushing something new before it
|
||||||
|
@ -497,7 +483,6 @@ function Doc:insert(line, col, text)
|
||||||
self:on_text_change("insert")
|
self:on_text_change("insert")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:remove(line1, col1, line2, col2)
|
function Doc:remove(line1, col1, line2, col2)
|
||||||
self.redo_stack = { idx = 1 }
|
self.redo_stack = { idx = 1 }
|
||||||
line1, col1 = self:sanitize_position(line1, col1)
|
line1, col1 = self:sanitize_position(line1, col1)
|
||||||
|
@ -507,28 +492,34 @@ function Doc:remove(line1, col1, line2, col2)
|
||||||
self:on_text_change("remove")
|
self:on_text_change("remove")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:undo()
|
function Doc:undo()
|
||||||
pop_undo(self, self.undo_stack, self.redo_stack, false)
|
pop_undo(self, self.undo_stack, self.redo_stack, false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:redo()
|
function Doc:redo()
|
||||||
pop_undo(self, self.redo_stack, self.undo_stack, false)
|
pop_undo(self, self.redo_stack, self.undo_stack, false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:text_input(text, idx)
|
function Doc:text_input(text, idx)
|
||||||
for sidx, line1, col1, line2, col2 in self:get_selections(true, idx or true) do
|
for sidx, line1, col1, line2, col2 in self:get_selections(true, idx or true) do
|
||||||
|
local had_selection = false
|
||||||
if line1 ~= line2 or col1 ~= col2 then
|
if line1 ~= line2 or col1 ~= col2 then
|
||||||
self:delete_to_cursor(sidx)
|
self:delete_to_cursor(sidx)
|
||||||
|
had_selection = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if self.overwrite
|
||||||
|
and not had_selection
|
||||||
|
and col1 < #self.lines[line1]
|
||||||
|
and text:ulen() == 1 then
|
||||||
|
self:remove(line1, col1, translate.next_char(self, line1, col1))
|
||||||
|
end
|
||||||
|
|
||||||
self:insert(line1, col1, text)
|
self:insert(line1, col1, text)
|
||||||
self:move_to_cursor(sidx, #text)
|
self:move_to_cursor(sidx, #text)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:ime_text_editing(text, start, length, idx)
|
function Doc:ime_text_editing(text, start, length, idx)
|
||||||
for sidx, line1, col1, line2, col2 in self:get_selections(true, idx or true) do
|
for sidx, line1, col1, line2, col2 in self:get_selections(true, idx or true) do
|
||||||
if line1 ~= line2 or col1 ~= col2 then
|
if line1 ~= line2 or col1 ~= col2 then
|
||||||
|
@ -539,7 +530,6 @@ function Doc:ime_text_editing(text, start, length, idx)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:replace_cursor(idx, line1, col1, line2, col2, fn)
|
function Doc:replace_cursor(idx, line1, col1, line2, col2, fn)
|
||||||
local old_text = self:get_text(line1, col1, line2, col2)
|
local old_text = self:get_text(line1, col1, line2, col2)
|
||||||
local new_text, res = fn(old_text)
|
local new_text, res = fn(old_text)
|
||||||
|
@ -555,7 +545,7 @@ function Doc:replace_cursor(idx, line1, col1, line2, col2, fn)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Doc:replace(fn)
|
function Doc:replace(fn)
|
||||||
local has_selection, results = false, { }
|
local has_selection, results = false, {}
|
||||||
for idx, line1, col1, line2, col2 in self:get_selections(true) do
|
for idx, line1, col1, line2, col2 in self:get_selections(true) do
|
||||||
if line1 ~= line2 or col1 ~= col2 then
|
if line1 ~= line2 or col1 ~= col2 then
|
||||||
results[idx] = self:replace_cursor(idx, line1, col1, line2, col2, fn)
|
results[idx] = self:replace_cursor(idx, line1, col1, line2, col2, fn)
|
||||||
|
@ -569,7 +559,6 @@ function Doc:replace(fn)
|
||||||
return results
|
return results
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function Doc:delete_to_cursor(idx, ...)
|
function Doc:delete_to_cursor(idx, ...)
|
||||||
for sidx, line1, col1, line2, col2 in self:get_selections(true, idx) do
|
for sidx, line1, col1, line2, col2 in self:get_selections(true, idx) do
|
||||||
if line1 ~= line2 or col1 ~= col2 then
|
if line1 ~= line2 or col1 ~= col2 then
|
||||||
|
@ -583,6 +572,7 @@ function Doc:delete_to_cursor(idx, ...)
|
||||||
end
|
end
|
||||||
self:merge_cursors(idx)
|
self:merge_cursors(idx)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Doc:delete_to(...) return self:delete_to_cursor(nil, ...) end
|
function Doc:delete_to(...) return self:delete_to_cursor(nil, ...) end
|
||||||
|
|
||||||
function Doc:move_to_cursor(idx, ...)
|
function Doc:move_to_cursor(idx, ...)
|
||||||
|
@ -591,8 +581,8 @@ function Doc:move_to_cursor(idx, ...)
|
||||||
end
|
end
|
||||||
self:merge_cursors(idx)
|
self:merge_cursors(idx)
|
||||||
end
|
end
|
||||||
function Doc:move_to(...) return self:move_to_cursor(nil, ...) end
|
|
||||||
|
|
||||||
|
function Doc:move_to(...) return self:move_to_cursor(nil, ...) end
|
||||||
|
|
||||||
function Doc:select_to_cursor(idx, ...)
|
function Doc:select_to_cursor(idx, ...)
|
||||||
for sidx, line, col, line2, col2 in self:get_selections(false, idx) do
|
for sidx, line, col, line2, col2 in self:get_selections(false, idx) do
|
||||||
|
@ -601,8 +591,8 @@ function Doc:select_to_cursor(idx, ...)
|
||||||
end
|
end
|
||||||
self:merge_cursors(idx)
|
self:merge_cursors(idx)
|
||||||
end
|
end
|
||||||
function Doc:select_to(...) return self:select_to_cursor(nil, ...) end
|
|
||||||
|
|
||||||
|
function Doc:select_to(...) return self:select_to_cursor(nil, ...) end
|
||||||
|
|
||||||
function Doc:get_indent_string()
|
function Doc:get_indent_string()
|
||||||
local indent_type, indent_size = self:get_indent_info()
|
local indent_type, indent_size = self:get_indent_info()
|
||||||
|
@ -625,7 +615,7 @@ function Doc:get_line_indent(line, rnd_up)
|
||||||
local indent = e and line:sub(1, e):gsub("\t", soft_tab) or ""
|
local indent = e and line:sub(1, e):gsub("\t", soft_tab) or ""
|
||||||
local number = #indent / #soft_tab
|
local number = #indent / #soft_tab
|
||||||
return e, indent:sub(1,
|
return e, indent:sub(1,
|
||||||
(rnd_up and math.ceil(number) or math.floor(number))*#soft_tab)
|
(rnd_up and math.ceil(number) or math.floor(number)) * #soft_tab)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -674,5 +664,4 @@ function Doc:on_close()
|
||||||
core.log_quiet("Closed doc \"%s\"", self:get_name())
|
core.log_quiet("Closed doc \"%s\"", self:get_name())
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
return Doc
|
return Doc
|
||||||
|
|
|
@ -460,9 +460,14 @@ function DocView:draw_line_text(line, x, y)
|
||||||
return self:get_line_height()
|
return self:get_line_height()
|
||||||
end
|
end
|
||||||
|
|
||||||
function DocView:draw_caret(x, y)
|
function DocView:draw_caret(x, y, line, col)
|
||||||
local lh = self:get_line_height()
|
local lh = self:get_line_height()
|
||||||
|
if self.doc.overwrite then
|
||||||
|
local w = self:get_font():get_width(self.doc:get_char(line, col))
|
||||||
|
renderer.draw_rect(x, y + lh, w, style.caret_width * 2, style.caret)
|
||||||
|
else
|
||||||
renderer.draw_rect(x, y, style.caret_width, lh, style.caret)
|
renderer.draw_rect(x, y, style.caret_width, lh, style.caret)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function DocView:draw_line_body(line, x, y)
|
function DocView:draw_line_body(line, x, y)
|
||||||
|
@ -542,7 +547,7 @@ function DocView:draw_ime_decoration(line1, col1, line2, col2)
|
||||||
line_size = style.caret_width
|
line_size = style.caret_width
|
||||||
renderer.draw_rect(x + math.min(x1, x2), y + lh - line_size, math.abs(x1 - x2), line_size, style.caret)
|
renderer.draw_rect(x + math.min(x1, x2), y + lh - line_size, math.abs(x1 - x2), line_size, style.caret)
|
||||||
end
|
end
|
||||||
self:draw_caret(x + x1, y)
|
self:draw_caret(x + x1, y, line1, col)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -559,7 +564,8 @@ function DocView:draw_overlay()
|
||||||
else
|
else
|
||||||
if config.disable_blink
|
if config.disable_blink
|
||||||
or (core.blink_timer - core.blink_start) % T < T / 2 then
|
or (core.blink_timer - core.blink_start) % T < T / 2 then
|
||||||
self:draw_caret(self:get_line_screen_position(line1, col1))
|
local x, y = self:get_line_screen_position(line1, col1)
|
||||||
|
self:draw_caret(x, y, line1, col1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -341,6 +341,7 @@ keymap.add_direct {
|
||||||
["ctrl+x"] = "doc:cut",
|
["ctrl+x"] = "doc:cut",
|
||||||
["ctrl+c"] = "doc:copy",
|
["ctrl+c"] = "doc:copy",
|
||||||
["ctrl+v"] = "doc:paste",
|
["ctrl+v"] = "doc:paste",
|
||||||
|
["insert"] = "doc:toggle-overwrite",
|
||||||
["ctrl+insert"] = "doc:copy",
|
["ctrl+insert"] = "doc:copy",
|
||||||
["shift+insert"] = "doc:paste",
|
["shift+insert"] = "doc:paste",
|
||||||
["escape"] = { "command:escape", "doc:select-none", "dialog:select-no" },
|
["escape"] = { "command:escape", "doc:select-none", "dialog:select-no" },
|
||||||
|
|
|
@ -319,6 +319,19 @@ function StatusView:register_docview_items()
|
||||||
end,
|
end,
|
||||||
command = "doc:toggle-line-ending"
|
command = "doc:toggle-line-ending"
|
||||||
})
|
})
|
||||||
|
|
||||||
|
self:add_item {
|
||||||
|
predicate = predicate_docview,
|
||||||
|
name = "doc:overwrite-mode",
|
||||||
|
alignment = StatusView.Item.RIGHT,
|
||||||
|
get_item = function()
|
||||||
|
return {
|
||||||
|
style.text, core.active_view.doc.overwrite and "OVR" or "INS"
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
command = "doc:toggle-overwrite",
|
||||||
|
separator = StatusView.separator2
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue