Manual merge of into .

This commit is contained in:
Adam Harrison
2021-11-23 15:57:22 -05:00
44 changed files with 2789 additions and 311 deletions
+12 -4
View File
@@ -1,4 +1,5 @@
local core = require "core"
local common = require "core.common"
local config = require "core.config"
local tokenizer = require "core.tokenizer"
local Object = require "core.object"
@@ -40,6 +41,13 @@ end
function Highlighter:reset()
self.lines = {}
self:soft_reset()
end
function Highlighter:soft_reset()
for i=1,#self.lines do
self.lines[i] = false
end
self.first_invalid_line = 1
self.max_wanted_line = 0
end
@@ -51,16 +59,16 @@ end
function Highlighter:insert_notify(line, n)
self:invalidate(line)
local blanks = { }
for i = 1, n do
table.insert(self.lines, line, nil)
blanks[i] = false
end
common.splice(self.lines, line, 0, blanks)
end
function Highlighter:remove_notify(line, n)
self:invalidate(line)
for i = 1, n do
table.remove(self.lines, line)
end
common.splice(self.lines, line, n)
end
+5 -1
View File
@@ -47,7 +47,7 @@ function Doc:reset_syntax()
local syn = syntax.get(self.filename or "", header)
if self.syntax ~= syn then
self.syntax = syn
self.highlighter:reset()
self.highlighter:soft_reset()
end
end
@@ -62,12 +62,15 @@ function Doc:load(filename)
local fp = assert( io.open(filename, "rb") )
self:reset()
self.lines = {}
local i = 1
for line in fp:lines() do
if line:byte(-1) == 13 then
line = line:sub(1, -2)
self.crlf = true
end
table.insert(self.lines, line .. "\n")
self.highlighter.lines[i] = false
i = i + 1
end
if #self.lines == 0 then
table.insert(self.lines, "\n")
@@ -306,6 +309,7 @@ local function pop_undo(self, undo_stack, redo_stack, modified)
self:raw_remove(line1, col1, line2, col2, redo_stack, cmd.time)
elseif cmd.type == "selection" then
self.selections = { table.unpack(cmd) }
self:sanitize_selection()
end
modified = modified or (cmd.type ~= "selection")
+46 -21
View File
@@ -22,37 +22,62 @@ local function init_args(doc, line, col, text, opt)
return doc, line, col, text, opt
end
-- This function is needed to uniform the behavior of
-- `regex:cmatch` and `string.find`.
local function regex_func(text, re, index, _)
local s, e = re:cmatch(text, index)
return s, e and e - 1
end
local function rfind(func, text, pattern, index, plain)
local s, e = func(text, pattern, 1, plain)
local last_s, last_e
if index < 0 then index = #text - index + 1 end
while e and e <= index do
last_s, last_e = s, e
s, e = func(text, pattern, s + 1, plain)
end
return last_s, last_e
end
function search.find(doc, line, col, text, opt)
doc, line, col, text, opt = init_args(doc, line, col, text, opt)
local re
local plain = not opt.pattern
local pattern = text
local search_func = string.find
if opt.regex then
re = regex.compile(text, opt.no_case and "i" or "")
pattern = regex.compile(text, opt.no_case and "i" or "")
search_func = regex_func
end
for line = line, #doc.lines do
local start, finish, step = line, #doc.lines, 1
if opt.reverse then
start, finish, step = line, 1, -1
end
for line = start, finish, step do
local line_text = doc.lines[line]
if opt.regex then
local s, e = re:cmatch(line_text, col)
if s then
return line, s, line, e
end
col = 1
else
if opt.no_case then
line_text = line_text:lower()
end
local s, e = line_text:find(text, col, true)
if s then
return line, s, line, e + 1
end
col = 1
if opt.no_case and not opt.regex then
line_text = line_text:lower()
end
local s, e
if opt.reverse then
s, e = rfind(search_func, line_text, pattern, col - 1, plain)
else
s, e = search_func(line_text, pattern, col, plain)
end
if s then
return line, s, line, e + 1
end
col = opt.reverse and -1 or 1
end
if opt.wrap then
opt = { no_case = opt.no_case, regex = opt.regex }
return search.find(doc, 1, 1, text, opt)
opt = { no_case = opt.no_case, regex = opt.regex, reverse = opt.reverse }
if opt.reverse then
return search.find(doc, #doc.lines, #doc.lines[#doc.lines], text, opt)
else
return search.find(doc, 1, 1, text, opt)
end
end
end