Manual merge of into .
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user