Merge branch master into dev
This commit is contained in:
commit
fbbe6d5dfb
2
LICENSE
2
LICENSE
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2020 rxi
|
Copyright (c) 2020-2021 Francesco Abbate
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
|
|
@ -108,7 +108,7 @@ is meant for people using a unix-like shell and the command line.
|
||||||
Please note that there aren't any hard-coded directories in the executable, so that the
|
Please note that there aren't any hard-coded directories in the executable, so that the
|
||||||
package can be extracted and used in any directory.
|
package can be extracted and used in any directory.
|
||||||
|
|
||||||
Mac OS X is fully supported and a notarized app disk image is provided in the release page.
|
Mac OS X is fully supported and a notarized app disk image is provided in the [release page](https://github.com/franko/lite-xl/releases).
|
||||||
In addition the application can be compiled using the generic instructions given above.
|
In addition the application can be compiled using the generic instructions given above.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
18
changelog.md
18
changelog.md
|
@ -14,6 +14,24 @@ local style = require "core.style"
|
||||||
local italic = renderer.font.load("italic.ttf", 14)
|
local italic = renderer.font.load("italic.ttf", 14)
|
||||||
style.syntax_fonts["comment"] = italic
|
style.syntax_fonts["comment"] = italic
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 1.16.10
|
||||||
|
|
||||||
|
Improved syntax highlight system thanks to @liquidev and @adamharrison.
|
||||||
|
Thanks to the new system we provide more a accurate syntax highlighting for Lua, C and C++.
|
||||||
|
Other syntax improvements contributed by @vincens2005.
|
||||||
|
|
||||||
|
Move to JetBrains Mono and Fira Sans fonts for code and UI respectively.
|
||||||
|
Thet are provided under the SIL Open Font License, Version 1.1.
|
||||||
|
See `doc/licenses.md` for license details.
|
||||||
|
|
||||||
|
Fixed bug with fonts and rencache module.
|
||||||
|
Under very specific situations the application was crashing due to invalid memory access.
|
||||||
|
|
||||||
|
Add documentation for keymap binding, thanks to @Janis-Leuenberger.
|
||||||
|
|
||||||
|
Added a contibutors page in `doc/contributors.md`.
|
||||||
|
|
||||||
### 1.16.9
|
### 1.16.9
|
||||||
|
|
||||||
Fix a bug related to nested panes resizing.
|
Fix a bug related to nested panes resizing.
|
||||||
|
|
|
@ -46,21 +46,14 @@ local function insert_at_start_of_selected_lines(text, skip_empty)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function remove_from_start_of_selected_lines(text, skip_empty)
|
||||||
local function remove_from_start_of_selected_lines(text, skip_empty, remove_partial)
|
|
||||||
local line1, col1, line2, col2, swap = doc_multiline_selection(true)
|
local line1, col1, line2, col2, swap = doc_multiline_selection(true)
|
||||||
for line = line1, line2 do
|
for line = line1, line2 do
|
||||||
local line_text = doc().lines[line]
|
local line_text = doc().lines[line]
|
||||||
for i = #text, 1, -1 do
|
if line_text:sub(1, #text) == text
|
||||||
if line_text:sub(1, i) == text:sub(1, i)
|
and (not skip_empty or line_text:find("%S"))
|
||||||
and (not skip_empty or line_text:find("%S"))
|
then
|
||||||
then
|
doc():remove(line, 1, line, #text + 1)
|
||||||
doc():remove(line, 1, line, i + 1)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
if not remove_partial then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
doc():set_selection(line1, col1 - #text, line2, col2 - #text, swap)
|
doc():set_selection(line1, col1 - #text, line2, col2 - #text, swap)
|
||||||
|
@ -86,6 +79,56 @@ local function save(filename)
|
||||||
core.log("Saved \"%s\"", saved_filename)
|
core.log("Saved \"%s\"", saved_filename)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- returns the size of the original indent, and the indent
|
||||||
|
-- in your config format, rounded either up or down
|
||||||
|
local function get_line_indent(line, rnd_up)
|
||||||
|
local _, e = line:find("^[ \t]+")
|
||||||
|
local soft_tab = string.rep(" ", config.indent_size)
|
||||||
|
if config.tab_type == "hard" then
|
||||||
|
local indent = e and line:sub(1, e):gsub(soft_tab, "\t") or ""
|
||||||
|
return e, indent:gsub(" +", rnd_up and "\t" or "")
|
||||||
|
else
|
||||||
|
local indent = e and line:sub(1, e):gsub("\t", soft_tab) or ""
|
||||||
|
local number = #indent / #soft_tab
|
||||||
|
return e, indent:sub(1,
|
||||||
|
(rnd_up and math.ceil(number) or math.floor(number))*#soft_tab)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- un/indents text; behaviour varies based on selection and un/indent.
|
||||||
|
-- * if there's a selection, it will stay static around the
|
||||||
|
-- text for both indenting and unindenting.
|
||||||
|
-- * if you are in the beginning whitespace of a line, and are indenting, the
|
||||||
|
-- cursor will insert the exactly appropriate amount of spaces, and jump the
|
||||||
|
-- cursor to the beginning of first non whitespace characters
|
||||||
|
-- * if you are not in the beginning whitespace of a line, and you indent, it
|
||||||
|
-- inserts the appropriate whitespace, as if you typed them normally.
|
||||||
|
-- * if you are unindenting, the cursor will jump to the start of the line,
|
||||||
|
-- and remove the appropriate amount of spaces (or a tab).
|
||||||
|
local function indent_text(unindent)
|
||||||
|
local text = get_indent_string()
|
||||||
|
local line1, col1, line2, col2, swap = doc():get_selection(true)
|
||||||
|
local _, se = doc().lines[line1]:find("^[ \t]+")
|
||||||
|
local in_beginning_whitespace = col1 == 1 or (se and col1 <= se + 1)
|
||||||
|
if unindent or doc():has_selection() or in_beginning_whitespace then
|
||||||
|
local l1d, l2d = #doc().lines[line1], #doc().lines[line2]
|
||||||
|
for line = line1, line2 do
|
||||||
|
local e, rnded = get_line_indent(doc().lines[line], unindent)
|
||||||
|
doc():remove(line, 1, line, (e or 0) + 1)
|
||||||
|
doc():insert(line, 1,
|
||||||
|
unindent and rnded:sub(1, #rnded - #text) or rnded .. text)
|
||||||
|
end
|
||||||
|
l1d, l2d = #doc().lines[line1] - l1d, #doc().lines[line2] - l2d
|
||||||
|
if (unindent or in_beginning_whitespace) and not doc():has_selection() then
|
||||||
|
local start_cursor = (se and se + 1 or 1) + l1d or #(doc().lines[line1])
|
||||||
|
doc():set_selection(line1, start_cursor, line2, start_cursor, swap)
|
||||||
|
else
|
||||||
|
doc():set_selection(line1, col1 + l1d, line2, col2 + l2d, swap)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
doc():text_input(text)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local commands = {
|
local commands = {
|
||||||
["doc:undo"] = function()
|
["doc:undo"] = function()
|
||||||
|
@ -195,17 +238,11 @@ local commands = {
|
||||||
end,
|
end,
|
||||||
|
|
||||||
["doc:indent"] = function()
|
["doc:indent"] = function()
|
||||||
local text = get_indent_string()
|
indent_text()
|
||||||
if doc():has_selection() then
|
|
||||||
insert_at_start_of_selected_lines(text)
|
|
||||||
else
|
|
||||||
doc():text_input(text)
|
|
||||||
end
|
|
||||||
end,
|
end,
|
||||||
|
|
||||||
["doc:unindent"] = function()
|
["doc:unindent"] = function()
|
||||||
local text = get_indent_string()
|
indent_text(true)
|
||||||
remove_from_start_of_selected_lines(text, false, true)
|
|
||||||
end,
|
end,
|
||||||
|
|
||||||
["doc:duplicate-lines"] = function()
|
["doc:duplicate-lines"] = function()
|
||||||
|
|
|
@ -269,8 +269,8 @@ local style = require "core.style"
|
||||||
------------------------------- Fonts ----------------------------------------
|
------------------------------- Fonts ----------------------------------------
|
||||||
|
|
||||||
-- customize fonts:
|
-- customize fonts:
|
||||||
-- style.font = renderer.font.load(DATADIR .. "/fonts/font.ttf", 13 * SCALE)
|
-- style.font = renderer.font.load(DATADIR .. "/fonts/FiraSans-Medium.ttf", 13 * SCALE)
|
||||||
-- style.code_font = renderer.font.load(DATADIR .. "/fonts/monospace.ttf", 12 * SCALE)
|
-- style.code_font = renderer.font.load(DATADIR .. "/fonts/JetBrainsMono-Regular.ttf", 13 * SCALE)
|
||||||
--
|
--
|
||||||
-- font names used by lite:
|
-- font names used by lite:
|
||||||
-- style.font : user interface
|
-- style.font : user interface
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
-- this file is used by lite-xl to setup the Lua environment
|
-- this file is used by lite-xl to setup the Lua environment
|
||||||
-- when starting
|
-- when starting
|
||||||
VERSION = "1.16.9"
|
VERSION = "1.16.10"
|
||||||
MOD_VERSION = "1"
|
MOD_VERSION = "1"
|
||||||
|
|
||||||
SCALE = tonumber(os.getenv("LITE_SCALE")) or SCALE
|
SCALE = tonumber(os.getenv("LITE_SCALE")) or SCALE
|
||||||
|
|
|
@ -21,11 +21,11 @@ style.tab_width = common.round(170 * SCALE)
|
||||||
--
|
--
|
||||||
-- On High DPI monitor or non RGB monitor you may consider using antialiasing grayscale instead.
|
-- On High DPI monitor or non RGB monitor you may consider using antialiasing grayscale instead.
|
||||||
-- The antialiasing grayscale with full hinting is interesting for crisp font rendering.
|
-- The antialiasing grayscale with full hinting is interesting for crisp font rendering.
|
||||||
style.font = renderer.font.load(DATADIR .. "/fonts/font.ttf", 13 * SCALE)
|
style.font = renderer.font.load(DATADIR .. "/fonts/FiraSans-Medium.ttf", 13 * SCALE)
|
||||||
style.big_font = renderer.font.load(DATADIR .. "/fonts/font.ttf", 34 * SCALE)
|
style.big_font = renderer.font.load(DATADIR .. "/fonts/FiraSans-Medium.ttf", 40 * SCALE)
|
||||||
style.icon_font = renderer.font.load(DATADIR .. "/fonts/icons.ttf", 14 * SCALE, {antialiasing="grayscale", hinting="full"})
|
style.icon_font = renderer.font.load(DATADIR .. "/fonts/icons.ttf", 14 * SCALE, {antialiasing="grayscale", hinting="full"})
|
||||||
style.icon_big_font = renderer.font.load(DATADIR .. "/fonts/icons.ttf", 20 * SCALE, {antialiasing="grayscale", hinting="full"})
|
style.icon_big_font = renderer.font.load(DATADIR .. "/fonts/icons.ttf", 20 * SCALE, {antialiasing="grayscale", hinting="full"})
|
||||||
style.code_font = renderer.font.load(DATADIR .. "/fonts/monospace.ttf", 12 * SCALE)
|
style.code_font = renderer.font.load(DATADIR .. "/fonts/JetBrainsMono-Regular.ttf", 13 * SCALE)
|
||||||
|
|
||||||
style.background = { common.color "#2e2e32" }
|
style.background = { common.color "#2e2e32" }
|
||||||
style.background2 = { common.color "#252529" }
|
style.background2 = { common.color "#252529" }
|
||||||
|
|
|
@ -75,8 +75,19 @@ end
|
||||||
-- differnet delimiters we have open, and which subsyntaxes we have active.
|
-- differnet delimiters we have open, and which subsyntaxes we have active.
|
||||||
-- At most, there are 3 subsyntaxes active at the same time. Beyond that,
|
-- At most, there are 3 subsyntaxes active at the same time. Beyond that,
|
||||||
-- does not support further highlighting.
|
-- does not support further highlighting.
|
||||||
|
|
||||||
|
-- You can think of it as a maximum 4 integer (0-255) stack. It always has
|
||||||
|
-- 1 integer in it. Calling `push_subsyntax` increases the stack depth. Calling
|
||||||
|
-- `pop_subsyntax` decreases it. The integers represent the index of a pattern
|
||||||
|
-- that we're following in the syntax. The top of the stack can be any valid
|
||||||
|
-- pattern index, any integer lower in the stack must represent a pattern that
|
||||||
|
-- specifies a subsyntax.
|
||||||
|
|
||||||
|
-- If you do not have subsyntaxes in your syntax, the three most
|
||||||
|
-- singificant numbers will always be 0, the stack will only ever be length 1
|
||||||
|
-- and the state variable will only ever range from 0-255.
|
||||||
local function retrieve_syntax_state(incoming_syntax, state)
|
local function retrieve_syntax_state(incoming_syntax, state)
|
||||||
local current_syntax, subsyntax_info, current_state, current_level =
|
local current_syntax, subsyntax_info, current_pattern_idx, current_level =
|
||||||
incoming_syntax, nil, state, 0
|
incoming_syntax, nil, state, 0
|
||||||
if state > 0 and (state > 255 or current_syntax.patterns[state].syntax) then
|
if state > 0 and (state > 255 or current_syntax.patterns[state].syntax) then
|
||||||
-- If we have higher bits, then decode them one at a time, and find which
|
-- If we have higher bits, then decode them one at a time, and find which
|
||||||
|
@ -89,10 +100,10 @@ local function retrieve_syntax_state(incoming_syntax, state)
|
||||||
subsyntax_info = current_syntax.patterns[target]
|
subsyntax_info = current_syntax.patterns[target]
|
||||||
current_syntax = type(subsyntax_info.syntax) == "table" and
|
current_syntax = type(subsyntax_info.syntax) == "table" and
|
||||||
subsyntax_info.syntax or syntax.get(subsyntax_info.syntax)
|
subsyntax_info.syntax or syntax.get(subsyntax_info.syntax)
|
||||||
current_state = 0
|
current_pattern_idx = 0
|
||||||
current_level = i+1
|
current_level = i+1
|
||||||
else
|
else
|
||||||
current_state = target
|
current_pattern_idx = target
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
@ -100,7 +111,7 @@ local function retrieve_syntax_state(incoming_syntax, state)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return current_syntax, subsyntax_info, current_state, current_level
|
return current_syntax, subsyntax_info, current_pattern_idx, current_level
|
||||||
end
|
end
|
||||||
|
|
||||||
function tokenizer.tokenize(incoming_syntax, text, state)
|
function tokenizer.tokenize(incoming_syntax, text, state)
|
||||||
|
@ -112,17 +123,51 @@ function tokenizer.tokenize(incoming_syntax, text, state)
|
||||||
end
|
end
|
||||||
|
|
||||||
state = state or 0
|
state = state or 0
|
||||||
local current_syntax, subsyntax_info, current_state, current_level =
|
-- incoming_syntax : the parent syntax of the file.
|
||||||
|
-- state : a 32-bit number representing syntax state (see above)
|
||||||
|
|
||||||
|
-- current_syntax : the syntax we're currently in.
|
||||||
|
-- subsyntax_info : info about the delimiters of this subsyntax.
|
||||||
|
-- current_pattern_idx: the index of the pattern we're on for this syntax.
|
||||||
|
-- current_level : how many subsyntaxes deep we are.
|
||||||
|
local current_syntax, subsyntax_info, current_pattern_idx, current_level =
|
||||||
retrieve_syntax_state(incoming_syntax, state)
|
retrieve_syntax_state(incoming_syntax, state)
|
||||||
|
|
||||||
|
-- Should be used to set the state variable. Don't modify it directly.
|
||||||
|
local function set_subsyntax_pattern_idx(pattern_idx)
|
||||||
|
current_pattern_idx = pattern_idx
|
||||||
|
state = bit32.replace(state, pattern_idx, current_level*8, 8)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function push_subsyntax(entering_syntax, pattern_idx)
|
||||||
|
set_subsyntax_pattern_idx(pattern_idx)
|
||||||
|
current_level = current_level + 1
|
||||||
|
subsyntax_info = entering_syntax
|
||||||
|
current_syntax = type(entering_syntax.syntax) == "table" and
|
||||||
|
entering_syntax.syntax or syntax.get(entering_syntax.syntax)
|
||||||
|
current_pattern_idx = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
local function pop_subsyntax()
|
||||||
|
set_subsyntax_pattern_idx(0)
|
||||||
|
current_level = current_level - 1
|
||||||
|
set_subsyntax_pattern_idx(0)
|
||||||
|
current_syntax, subsyntax_info, current_pattern_idx, current_level =
|
||||||
|
retrieve_syntax_state(incoming_syntax, state)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
while i <= #text do
|
while i <= #text do
|
||||||
-- continue trying to match the end pattern of a pair if we have a state set
|
-- continue trying to match the end pattern of a pair if we have a state set
|
||||||
if current_state > 0 then
|
if current_pattern_idx > 0 then
|
||||||
local p = current_syntax.patterns[current_state]
|
local p = current_syntax.patterns[current_pattern_idx]
|
||||||
local s, e = find_non_escaped(text, p.pattern[2], i, p.pattern[3])
|
local s, e = find_non_escaped(text, p.pattern[2], i, p.pattern[3])
|
||||||
|
|
||||||
local cont = true
|
local cont = true
|
||||||
-- If we're in subsyntax mode, always check to see if we end our syntax
|
-- If we're in subsyntax mode, always check to see if we end our syntax
|
||||||
-- first.
|
-- first, before the found delimeter, as ending the subsyntax takes
|
||||||
|
-- precedence over ending the delimiter in the subsyntax.
|
||||||
if subsyntax_info then
|
if subsyntax_info then
|
||||||
local ss, se = find_non_escaped(
|
local ss, se = find_non_escaped(
|
||||||
text,
|
text,
|
||||||
|
@ -130,17 +175,22 @@ function tokenizer.tokenize(incoming_syntax, text, state)
|
||||||
i,
|
i,
|
||||||
subsyntax_info.pattern[3]
|
subsyntax_info.pattern[3]
|
||||||
)
|
)
|
||||||
|
-- If we find that we end the subsyntax before the
|
||||||
|
-- delimiter, push the token, and signal we shouldn't
|
||||||
|
-- treat the bit after as a token to be normally parsed
|
||||||
|
-- (as it's the syntax delimiter).
|
||||||
if ss and (s == nil or ss < s) then
|
if ss and (s == nil or ss < s) then
|
||||||
push_token(res, p.type, text:sub(i, ss - 1))
|
push_token(res, p.type, text:sub(i, ss - 1))
|
||||||
i = ss
|
i = ss
|
||||||
cont = false
|
cont = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
-- If we don't have any concerns about syntax delimiters,
|
||||||
|
-- continue on as normal.
|
||||||
if cont then
|
if cont then
|
||||||
if s then
|
if s then
|
||||||
push_token(res, p.type, text:sub(i, e))
|
push_token(res, p.type, text:sub(i, e))
|
||||||
current_state = 0
|
set_subsyntax_pattern_idx(0)
|
||||||
state = bit32.replace(state, 0, current_level*8, 8)
|
|
||||||
i = e + 1
|
i = e + 1
|
||||||
else
|
else
|
||||||
push_token(res, p.type, text:sub(i))
|
push_token(res, p.type, text:sub(i))
|
||||||
|
@ -148,7 +198,9 @@ function tokenizer.tokenize(incoming_syntax, text, state)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- Check for end of syntax.
|
-- General end of syntax check. Applies in the case where
|
||||||
|
-- we're ending early in the middle of a delimiter, or
|
||||||
|
-- just normally, upon finding a token.
|
||||||
if subsyntax_info then
|
if subsyntax_info then
|
||||||
local s, e = find_non_escaped(
|
local s, e = find_non_escaped(
|
||||||
text,
|
text,
|
||||||
|
@ -158,11 +210,8 @@ function tokenizer.tokenize(incoming_syntax, text, state)
|
||||||
)
|
)
|
||||||
if s then
|
if s then
|
||||||
push_token(res, subsyntax_info.type, text:sub(i, e))
|
push_token(res, subsyntax_info.type, text:sub(i, e))
|
||||||
current_level = current_level - 1
|
-- On finding unescaped delimiter, pop it.
|
||||||
-- Zero out the state above us, as well as our new current state.
|
pop_subsyntax()
|
||||||
state = bit32.replace(state, 0, current_level*8, 16)
|
|
||||||
current_syntax, subsyntax_info, current_state, current_level =
|
|
||||||
retrieve_syntax_state(incoming_syntax, state)
|
|
||||||
i = e + 1
|
i = e + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -180,17 +229,11 @@ function tokenizer.tokenize(incoming_syntax, text, state)
|
||||||
|
|
||||||
-- update state if this was a start|end pattern pair
|
-- update state if this was a start|end pattern pair
|
||||||
if type(p.pattern) == "table" then
|
if type(p.pattern) == "table" then
|
||||||
state = bit32.replace(state, n, current_level*8, 8)
|
-- If we have a subsyntax, push that onto the subsyntax stack.
|
||||||
-- If we've found a new subsyntax, bump our level, and set the
|
|
||||||
-- appropriate variables.
|
|
||||||
if p.syntax then
|
if p.syntax then
|
||||||
current_level = current_level + 1
|
push_subsyntax(p, n)
|
||||||
subsyntax_info = p
|
|
||||||
current_syntax = type(p.syntax) == "table" and
|
|
||||||
p.syntax or syntax.get(p.syntax)
|
|
||||||
current_state = 0
|
|
||||||
else
|
else
|
||||||
current_state = n
|
set_subsyntax_pattern_idx(n)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -6,21 +6,28 @@ syntax.add {
|
||||||
headers = "^#!.*[ /]lua",
|
headers = "^#!.*[ /]lua",
|
||||||
comment = "--",
|
comment = "--",
|
||||||
patterns = {
|
patterns = {
|
||||||
{ pattern = { '"', '"', '\\' }, type = "string" },
|
{ pattern = { '"', '"', '\\' }, type = "string" },
|
||||||
{ pattern = { "'", "'", '\\' }, type = "string" },
|
{ pattern = { "'", "'", '\\' }, type = "string" },
|
||||||
{ pattern = { "%[%[", "%]%]" }, type = "string" },
|
{ pattern = { "%[%[", "%]%]" }, type = "string" },
|
||||||
{ pattern = { "%-%-%[%[", "%]%]"}, type = "comment" },
|
{ pattern = { "%-%-%[%[", "%]%]"}, type = "comment" },
|
||||||
{ pattern = "%-%-.-\n", type = "comment" },
|
{ pattern = "%-%-.-\n", type = "comment" },
|
||||||
{ pattern = "-?0x%x+", type = "number" },
|
{ pattern = "0x%x+%.%x*[pP][-+]?%d+", type = "number" },
|
||||||
{ pattern = "-?%d+[%d%.eE]*", type = "number" },
|
{ pattern = "0x%x+%.%x*", type = "number" },
|
||||||
{ pattern = "-?%.?%d+", type = "number" },
|
{ pattern = "0x%.%x+[pP][-+]?%d+", type = "number" },
|
||||||
{ pattern = "<%a+>", type = "keyword2" },
|
{ pattern = "0x%.%x+", type = "number" },
|
||||||
{ pattern = "%.%.%.?", type = "operator" },
|
{ pattern = "0x%x+[pP][-+]?%d+", type = "number" },
|
||||||
{ pattern = "[<>~=]=", type = "operator" },
|
{ pattern = "0x%x+", type = "number" },
|
||||||
{ pattern = "[%+%-=/%*%^%%#<>]", type = "operator" },
|
{ pattern = "%d%.%d*[eE][-+]?%d+", type = "number" },
|
||||||
{ pattern = "[%a_][%w_]*%s*%f[(\"{]", type = "function" },
|
{ pattern = "%d%.%d*", type = "number" },
|
||||||
{ pattern = "[%a_][%w_]*", type = "symbol" },
|
{ pattern = "%.?%d*[eE][-+]?%d+", type = "number" },
|
||||||
{ pattern = "::[%a_][%w_]*::", type = "function" },
|
{ pattern = "%.?%d+", type = "number" },
|
||||||
|
{ pattern = "<%a+>", type = "keyword2" },
|
||||||
|
{ pattern = "%.%.%.?", type = "operator" },
|
||||||
|
{ pattern = "[<>~=]=", type = "operator" },
|
||||||
|
{ pattern = "[%+%-=/%*%^%%#<>]", type = "operator" },
|
||||||
|
{ pattern = "[%a_][%w_]*()%s*%f[(\"'{]", type = {"function", "normal"} },
|
||||||
|
{ pattern = "[%a_][%w_]*", type = "symbol" },
|
||||||
|
{ pattern = "::[%a_][%w_]*::", type = "function" },
|
||||||
},
|
},
|
||||||
symbols = {
|
symbols = {
|
||||||
["if"] = "keyword",
|
["if"] = "keyword",
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
-- put user settings here
|
|
||||||
-- this module will be loaded after everything else when the application starts
|
|
||||||
-- it will be automatically reloaded when saved
|
|
||||||
|
|
||||||
local core = require "core"
|
|
||||||
local keymap = require "core.keymap"
|
|
||||||
local config = require "core.config"
|
|
||||||
local style = require "core.style"
|
|
||||||
|
|
||||||
------------------------------ Themes ----------------------------------------
|
|
||||||
|
|
||||||
-- light theme:
|
|
||||||
-- core.reload_module("colors.summer")
|
|
||||||
|
|
||||||
--------------------------- Key bindings -------------------------------------
|
|
||||||
|
|
||||||
-- key binding:
|
|
||||||
-- keymap.add { ["ctrl+escape"] = "core:quit" }
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------- Fonts ----------------------------------------
|
|
||||||
|
|
||||||
-- customize fonts:
|
|
||||||
-- style.font = renderer.font.load(DATADIR .. "/fonts/font.ttf", 13 * SCALE)
|
|
||||||
-- style.code_font = renderer.font.load(DATADIR .. "/fonts/monospace.ttf", 12 * SCALE)
|
|
||||||
--
|
|
||||||
-- font names used by lite:
|
|
||||||
-- style.font : user interface
|
|
||||||
-- style.big_font : big text in welcome screen
|
|
||||||
-- style.icon_font : icons
|
|
||||||
-- style.icon_big_font : toolbar icons
|
|
||||||
-- style.code_font : code
|
|
||||||
--
|
|
||||||
-- the function to load the font accept a 3rd optional argument like:
|
|
||||||
--
|
|
||||||
-- {antialiasing="grayscale", hinting="full"}
|
|
||||||
--
|
|
||||||
-- possible values are:
|
|
||||||
-- antialiasing: grayscale, subpixel
|
|
||||||
-- hinting: none, slight, full
|
|
||||||
|
|
||||||
------------------------------ Plugins ----------------------------------------
|
|
||||||
|
|
||||||
-- enable or disable plugin loading setting config entries:
|
|
||||||
|
|
||||||
-- enable trimwhitespace, otherwise it is disable by default:
|
|
||||||
-- config.trimwhitespace = true
|
|
||||||
--
|
|
||||||
-- disable detectindent, otherwise it is enabled by default
|
|
||||||
-- config.detectindent = false
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
## rxi
|
||||||
|
|
||||||
|
Original development of lite editor.
|
||||||
|
|
||||||
|
## Francesco Abbate (franko)
|
||||||
|
|
||||||
|
Creator of lite-xl fork from rxi/lite.
|
||||||
|
|
||||||
|
## Takase (takase1121)
|
||||||
|
|
||||||
|
NagView and X Window database resource query for Xft.dpi setting.
|
||||||
|
|
||||||
|
## Nils Kvist (budRich)
|
||||||
|
|
||||||
|
Popup window replacement with CommandView dialog.
|
||||||
|
|
||||||
|
## liquidev
|
||||||
|
|
||||||
|
Tab style and animations improvements.
|
||||||
|
|
||||||
|
## adamharrison
|
||||||
|
|
||||||
|
Multi-language syntax highlighting and many other improvements.
|
||||||
|
|
||||||
|
## vincens2005
|
||||||
|
|
||||||
|
Syntax highlighting improvements.
|
||||||
|
|
||||||
|
## Janis-Leuenberger
|
||||||
|
|
||||||
|
Add keymap bindings help file and macOS testing.
|
||||||
|
|
||||||
|
## Mat Mariani (mathewmariani)
|
||||||
|
|
||||||
|
Help for Mac OS port. Some resources taken from mathewmariani/lite-macos.
|
||||||
|
|
||||||
|
## daubaris
|
||||||
|
|
||||||
|
Initial implementation of Xft.dpi query using xrdb command.
|
||||||
|
|
||||||
|
## Robert Štojs (netrobert)
|
||||||
|
|
||||||
|
Continuos integration configuration
|
|
@ -0,0 +1,113 @@
|
||||||
|
# Default keymap
|
||||||
|
|
||||||
|
*Note: When using macOS `ctrl` refers to the command key.*
|
||||||
|
|
||||||
|
| Key combination | Actions |
|
||||||
|
| --------------------- | ----------------------------------- |
|
||||||
|
| ctrl+shift+p | core:find-command |
|
||||||
|
| ctrl+p | core:find-file |
|
||||||
|
| ctrl+o | core:open-file |
|
||||||
|
| ctrl+n | core:new-doc |
|
||||||
|
| ctrl+shift+c | core:change-project-folder |
|
||||||
|
| ctrl+shift+o | core:open-project-folder |
|
||||||
|
| alt+return | core:toggle-fullscreen |
|
||||||
|
| alt+shift+j | root:split-left |
|
||||||
|
| alt+shift+l | root:split-right |
|
||||||
|
| alt+shift+i | root:split-up |
|
||||||
|
| alt+shift+k | root:split-down |
|
||||||
|
| alt+j | root:switch-to-left |
|
||||||
|
| alt+l | root:switch-to-right |
|
||||||
|
| alt+i | root:switch-to-up |
|
||||||
|
| alt+k | root:switch-to-down |
|
||||||
|
| ctrl+w | root:close |
|
||||||
|
| ctrl+tab | root:switch-to-next-tab |
|
||||||
|
| ctrl+shift+tab | root:switch-to-previous-tab |
|
||||||
|
| ctrl+pageup | root:move-tab-left |
|
||||||
|
| ctrl+pagedown | root:move-tab-right |
|
||||||
|
| alt+1 | root:switch-to-tab-1 |
|
||||||
|
| alt+2 | root:switch-to-tab-2 |
|
||||||
|
| alt+3 | root:switch-to-tab-3 |
|
||||||
|
| alt+4 | root:switch-to-tab-4 |
|
||||||
|
| alt+5 | root:switch-to-tab-5 |
|
||||||
|
| alt+6 | root:switch-to-tab-6 |
|
||||||
|
| alt+7 | root:switch-to-tab-7 |
|
||||||
|
| alt+8 | root:switch-to-tab-8 |
|
||||||
|
| alt+9 | root:switch-to-tab-9 |
|
||||||
|
| ctrl+f | find-replace:find |
|
||||||
|
| ctrl+r | find-replace:replace |
|
||||||
|
| f3 | find-replace:repeat-find |
|
||||||
|
| shift+f3 | find-replace:previous-find |
|
||||||
|
| ctrl+g | doc:go-to-line |
|
||||||
|
| ctrl+s | doc:save |
|
||||||
|
| ctrl+shift+s | doc:save-as |
|
||||||
|
| ctrl+z | doc:undo |
|
||||||
|
| ctrl+y | doc:redo |
|
||||||
|
| ctrl+x | doc:cut |
|
||||||
|
| ctrl+c | doc:copy |
|
||||||
|
| ctrl+v | doc:paste |
|
||||||
|
| ctrl+insert | doc:copy |
|
||||||
|
| shift+insert | doc:paste |
|
||||||
|
| escape | command:escape |
|
||||||
|
| escape | doc:select-none |
|
||||||
|
| escape | dialog:select-no |
|
||||||
|
| tab | command:complete |
|
||||||
|
| tab | doc:indent |
|
||||||
|
| shift+tab | doc:unindent |
|
||||||
|
| backspace | doc:backspace |
|
||||||
|
| shift+backspace | doc:backspace |
|
||||||
|
| ctrl+backspace | doc:delete-to-previous-word-start |
|
||||||
|
| ctrl+shift+backspace | doc:delete-to-previous-word-start |
|
||||||
|
| delete | doc:delete |
|
||||||
|
| shift+delete | doc:delete |
|
||||||
|
| ctrl+delete | doc:delete-to-next-word-end |
|
||||||
|
| ctrl+shift+delete | doc:delete-to-next-word-end |
|
||||||
|
| return | command:submit |
|
||||||
|
| return | doc:newline |
|
||||||
|
| return | dialog:select |
|
||||||
|
| keypad enter | command:submit |
|
||||||
|
| keypad enter | doc:newline |
|
||||||
|
| keypad enter | dialog:select |
|
||||||
|
| ctrl+return | doc:newline-below |
|
||||||
|
| ctrl+shift+return | doc:newline-above |
|
||||||
|
| ctrl+j | doc:join-lines |
|
||||||
|
| ctrl+a | doc:select-all |
|
||||||
|
| ctrl+d | find-replace:select-next |
|
||||||
|
| ctrl+d | doc:select-word |
|
||||||
|
| ctrl+l | doc:select-lines |
|
||||||
|
| ctrl+/ | doc:toggle-line-comments |
|
||||||
|
| ctrl+up | doc:move-lines-up |
|
||||||
|
| ctrl+down | doc:move-lines-down |
|
||||||
|
| ctrl+shift+d | doc:duplicate-lines |
|
||||||
|
| ctrl+shift+k | doc:delete-lines |
|
||||||
|
| left | doc:move-to-previous-char |
|
||||||
|
| left | dialog:previous-entry |
|
||||||
|
| right | doc:move-to-next-char |
|
||||||
|
| right | dialog:next-entry |
|
||||||
|
| up | command:select-previous |
|
||||||
|
| up | doc:move-to-previous-line |
|
||||||
|
| down | command:select-next |
|
||||||
|
| down | doc:move-to-next-line |
|
||||||
|
| ctrl+left | doc:move-to-previous-word-start |
|
||||||
|
| ctrl+right | doc:move-to-next-word-end |
|
||||||
|
| ctrl+[ | doc:move-to-previous-block-start |
|
||||||
|
| ctrl+] | doc:move-to-next-block-end |
|
||||||
|
| home | doc:move-to-start-of-line |
|
||||||
|
| end | doc:move-to-end-of-line |
|
||||||
|
| ctrl+home | doc:move-to-start-of-doc |
|
||||||
|
| ctrl+end | doc:move-to-end-of-doc |
|
||||||
|
| pageup | doc:move-to-previous-page |
|
||||||
|
| pagedown | doc:move-to-next-page |
|
||||||
|
| shift+left | doc:select-to-previous-char |
|
||||||
|
| shift+right | doc:select-to-next-char |
|
||||||
|
| shift+up | doc:select-to-previous-line |
|
||||||
|
| shift+down | doc:select-to-next-line |
|
||||||
|
| ctrl+shift+left | doc:select-to-previous-word-start |
|
||||||
|
| ctrl+shift+right | doc:select-to-next-word-end |
|
||||||
|
| ctrl+shift+[ | doc:select-to-previous-block-start |
|
||||||
|
| ctrl+shift+] | doc:select-to-next-block-end |
|
||||||
|
| shift+home | doc:select-to-start-of-line |
|
||||||
|
| shift+end | doc:select-to-end-of-line |
|
||||||
|
| ctrl+shift+home | doc:select-to-start-of-doc |
|
||||||
|
| ctrl+shift+end | doc:select-to-end-of-doc |
|
||||||
|
| shift+pageup | doc:select-to-previous-page |
|
||||||
|
| shift+pagedown | doc:select-to-next-page |
|
|
@ -0,0 +1,130 @@
|
||||||
|
# Licenses
|
||||||
|
|
||||||
|
## rxi/lite
|
||||||
|
|
||||||
|
Copyright (c) 2020 rxi
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
## Fira Sans
|
||||||
|
|
||||||
|
Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A.
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
## Fira Code
|
||||||
|
|
||||||
|
Copyright (c) 2014, The Fira Code Project Authors (https://github.com/tonsky/FiraCode)
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
## JetBrains Mono
|
||||||
|
|
||||||
|
Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
|
||||||
|
# SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@ -149,6 +149,8 @@ local keymap = require "core.keymap"
|
||||||
keymap.add { ["ctrl+q"] = "core:quit" }
|
keymap.add { ["ctrl+q"] = "core:quit" }
|
||||||
```
|
```
|
||||||
|
|
||||||
|
A list of default mappings can be viewed [here](./default-keymap.md).
|
||||||
|
|
||||||
|
|
||||||
## Plugins
|
## Plugins
|
||||||
Plugins in lite are normal lua modules and are treated as such — no
|
Plugins in lite are normal lua modules and are treated as such — no
|
||||||
|
|
|
@ -29,8 +29,10 @@ endif
|
||||||
|
|
||||||
lite_cargs = []
|
lite_cargs = []
|
||||||
if get_option('portable')
|
if get_option('portable')
|
||||||
|
lite_docdir = 'doc'
|
||||||
lite_datadir = 'data'
|
lite_datadir = 'data'
|
||||||
else
|
else
|
||||||
|
lite_docdir = 'share/doc'
|
||||||
lite_datadir = 'share/lite-xl'
|
lite_datadir = 'share/lite-xl'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -39,10 +41,17 @@ foreach data_module : ['core', 'fonts', 'plugins', 'colors']
|
||||||
install_subdir('data' / data_module , install_dir : lite_datadir)
|
install_subdir('data' / data_module , install_dir : lite_datadir)
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
|
foreach file : ['usage.md', 'licenses.md', 'contributors.md', 'default-keymap.md']
|
||||||
|
install_data('doc' / file, install_dir : lite_docdir)
|
||||||
|
endforeach
|
||||||
|
|
||||||
lite_link_args = []
|
lite_link_args = []
|
||||||
if cc.get_id() == 'gcc' and get_option('buildtype') == 'release'
|
if cc.get_id() == 'gcc' and get_option('buildtype') == 'release'
|
||||||
lite_link_args += ['-static-libgcc', '-static-libstdc++']
|
lite_link_args += ['-static-libgcc', '-static-libstdc++']
|
||||||
endif
|
endif
|
||||||
|
if host_machine.system() == 'darwin'
|
||||||
|
lite_link_args += ['-framework', 'CoreServices', '-framework', 'Foundation']
|
||||||
|
endif
|
||||||
|
|
||||||
lite_rc = []
|
lite_rc = []
|
||||||
if host_machine.system() == 'windows'
|
if host_machine.system() == 'windows'
|
||||||
|
|
|
@ -38,13 +38,13 @@ static int f_get_size(lua_State *L) {
|
||||||
|
|
||||||
|
|
||||||
static int f_begin_frame(lua_State *L) {
|
static int f_begin_frame(lua_State *L) {
|
||||||
rencache_begin_frame();
|
rencache_begin_frame(L);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int f_end_frame(lua_State *L) {
|
static int f_end_frame(lua_State *L) {
|
||||||
rencache_end_frame();
|
rencache_end_frame(L);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ static int draw_text_subpixel_impl(lua_State *L, bool draw_subpixel) {
|
||||||
replace_color = (RenColor) {0};
|
replace_color = (RenColor) {0};
|
||||||
}
|
}
|
||||||
|
|
||||||
x_subpixel = rencache_draw_text(font_desc, text, x_subpixel, y, color, draw_subpixel, rep_table, replace_color);
|
x_subpixel = rencache_draw_text(L, font_desc, 1, text, x_subpixel, y, color, draw_subpixel, rep_table, replace_color);
|
||||||
lua_pushnumber(L, x_subpixel);
|
lua_pushnumber(L, x_subpixel);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#include <lua.h>
|
||||||
|
#include <lauxlib.h>
|
||||||
|
|
||||||
#include "api.h"
|
#include "api.h"
|
||||||
#include "fontdesc.h"
|
#include "fontdesc.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
@ -62,7 +65,7 @@ static int f_set_tab_size(lua_State *L) {
|
||||||
|
|
||||||
static int f_gc(lua_State *L) {
|
static int f_gc(lua_State *L) {
|
||||||
FontDesc *self = luaL_checkudata(L, 1, API_TYPE_FONT);
|
FontDesc *self = luaL_checkudata(L, 1, API_TYPE_FONT);
|
||||||
rencache_free_font(self);
|
font_desc_free(self);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -159,11 +159,6 @@ init_lua:
|
||||||
enable_momentum_scroll();
|
enable_momentum_scroll();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* We need to clear the rencache commands because we may restarting the application
|
|
||||||
and it could be non-empty. It is important to clear the command buffer because it
|
|
||||||
stores pointers to font_desc objects and these are Lua managed. */
|
|
||||||
rencache_clear();
|
|
||||||
|
|
||||||
const char *init_lite_code = \
|
const char *init_lite_code = \
|
||||||
"local core\n"
|
"local core\n"
|
||||||
"xpcall(function()\n"
|
"xpcall(function()\n"
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <lauxlib.h>
|
||||||
#include "rencache.h"
|
#include "rencache.h"
|
||||||
|
|
||||||
/* a cache over the software renderer -- all drawing operations are stored as
|
/* a cache over the software renderer -- all drawing operations are stored as
|
||||||
|
@ -14,7 +16,7 @@
|
||||||
#define COMMAND_BUF_SIZE (1024 * 512)
|
#define COMMAND_BUF_SIZE (1024 * 512)
|
||||||
#define COMMAND_BARE_SIZE offsetof(Command, text)
|
#define COMMAND_BARE_SIZE offsetof(Command, text)
|
||||||
|
|
||||||
enum { FREE_FONT, SET_CLIP, DRAW_TEXT, DRAW_RECT, DRAW_TEXT_SUBPIXEL };
|
enum { SET_CLIP, DRAW_TEXT, DRAW_RECT, DRAW_TEXT_SUBPIXEL };
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int8_t type;
|
int8_t type;
|
||||||
|
@ -30,6 +32,15 @@ typedef struct {
|
||||||
char text[0];
|
char text[0];
|
||||||
} Command;
|
} Command;
|
||||||
|
|
||||||
|
#define FONT_REFS_MAX 12
|
||||||
|
struct FontRef {
|
||||||
|
FontDesc *font_desc;
|
||||||
|
int index;
|
||||||
|
};
|
||||||
|
typedef struct FontRef FontRef;
|
||||||
|
FontRef font_refs[FONT_REFS_MAX];
|
||||||
|
int font_refs_len = 0;
|
||||||
|
|
||||||
|
|
||||||
static unsigned cells_buf1[CELLS_X * CELLS_Y];
|
static unsigned cells_buf1[CELLS_X * CELLS_Y];
|
||||||
static unsigned cells_buf2[CELLS_X * CELLS_Y];
|
static unsigned cells_buf2[CELLS_X * CELLS_Y];
|
||||||
|
@ -45,6 +56,33 @@ static bool show_debug;
|
||||||
static inline int min(int a, int b) { return a < b ? a : b; }
|
static inline int min(int a, int b) { return a < b ? a : b; }
|
||||||
static inline int max(int a, int b) { return a > b ? a : b; }
|
static inline int max(int a, int b) { return a > b ? a : b; }
|
||||||
|
|
||||||
|
static int font_refs_add(lua_State *L, FontDesc *font_desc, int index) {
|
||||||
|
for (int i = 0; i < font_refs_len; i++) {
|
||||||
|
if (font_refs[i].font_desc == font_desc) {
|
||||||
|
return font_refs[i].index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (font_refs_len >= FONT_REFS_MAX) {
|
||||||
|
fprintf(stderr, "Warning: (" __FILE__ "): exhausted font reference buffer\n");
|
||||||
|
return LUA_NOREF;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushvalue(L, index);
|
||||||
|
int ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||||
|
|
||||||
|
font_refs[font_refs_len++] = (FontRef) { font_desc, ref };
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void font_refs_clear(lua_State *L) {
|
||||||
|
for (int i = 0; i < font_refs_len; i++) {
|
||||||
|
luaL_unref(L, LUA_REGISTRYINDEX, font_refs[i].index);
|
||||||
|
}
|
||||||
|
font_refs_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* 32bit fnv-1a hash */
|
/* 32bit fnv-1a hash */
|
||||||
#define HASH_INITIAL 2166136261
|
#define HASH_INITIAL 2166136261
|
||||||
|
|
||||||
|
@ -115,12 +153,6 @@ void rencache_show_debug(bool enable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void rencache_free_font(FontDesc *font_desc) {
|
|
||||||
Command *cmd = push_command(FREE_FONT, COMMAND_BARE_SIZE);
|
|
||||||
if (cmd) { cmd->font_desc = font_desc; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void rencache_set_clip_rect(RenRect rect) {
|
void rencache_set_clip_rect(RenRect rect) {
|
||||||
Command *cmd = push_command(SET_CLIP, COMMAND_BARE_SIZE);
|
Command *cmd = push_command(SET_CLIP, COMMAND_BARE_SIZE);
|
||||||
if (cmd) { cmd->rect = intersect_rects(rect, screen_rect); }
|
if (cmd) { cmd->rect = intersect_rects(rect, screen_rect); }
|
||||||
|
@ -136,7 +168,7 @@ void rencache_draw_rect(RenRect rect, RenColor color) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int rencache_draw_text(FontDesc *font_desc,
|
int rencache_draw_text(lua_State *L, FontDesc *font_desc, int font_index,
|
||||||
const char *text, int x, int y, RenColor color, bool draw_subpixel,
|
const char *text, int x, int y, RenColor color, bool draw_subpixel,
|
||||||
CPReplaceTable *replacements, RenColor replace_color)
|
CPReplaceTable *replacements, RenColor replace_color)
|
||||||
{
|
{
|
||||||
|
@ -148,7 +180,7 @@ int rencache_draw_text(FontDesc *font_desc,
|
||||||
rect.width = ren_font_subpixel_round(w_subpixel, subpixel_scale, 0);
|
rect.width = ren_font_subpixel_round(w_subpixel, subpixel_scale, 0);
|
||||||
rect.height = ren_get_font_height(font_desc);
|
rect.height = ren_get_font_height(font_desc);
|
||||||
|
|
||||||
if (rects_overlap(screen_rect, rect)) {
|
if (rects_overlap(screen_rect, rect) && font_refs_add(L, font_desc, font_index) >= 0) {
|
||||||
int sz = strlen(text) + 1;
|
int sz = strlen(text) + 1;
|
||||||
Command *cmd = push_command(draw_subpixel ? DRAW_TEXT_SUBPIXEL : DRAW_TEXT, COMMAND_BARE_SIZE + sz);
|
Command *cmd = push_command(draw_subpixel ? DRAW_TEXT_SUBPIXEL : DRAW_TEXT, COMMAND_BARE_SIZE + sz);
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
|
@ -173,7 +205,7 @@ void rencache_invalidate(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void rencache_begin_frame(void) {
|
void rencache_begin_frame(lua_State *L) {
|
||||||
/* reset all cells if the screen width/height has changed */
|
/* reset all cells if the screen width/height has changed */
|
||||||
int w, h;
|
int w, h;
|
||||||
ren_get_size(&w, &h);
|
ren_get_size(&w, &h);
|
||||||
|
@ -182,6 +214,7 @@ void rencache_begin_frame(void) {
|
||||||
screen_rect.height = h;
|
screen_rect.height = h;
|
||||||
rencache_invalidate();
|
rencache_invalidate();
|
||||||
}
|
}
|
||||||
|
font_refs_clear(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -214,7 +247,7 @@ static void push_rect(RenRect r, int *count) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void rencache_end_frame(void) {
|
void rencache_end_frame(lua_State *L) {
|
||||||
/* update cells from commands */
|
/* update cells from commands */
|
||||||
Command *cmd = NULL;
|
Command *cmd = NULL;
|
||||||
RenRect cr = screen_rect;
|
RenRect cr = screen_rect;
|
||||||
|
@ -253,7 +286,6 @@ void rencache_end_frame(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* redraw updated regions */
|
/* redraw updated regions */
|
||||||
bool has_free_commands = false;
|
|
||||||
for (int i = 0; i < rect_count; i++) {
|
for (int i = 0; i < rect_count; i++) {
|
||||||
/* draw */
|
/* draw */
|
||||||
RenRect r = rect_buf[i];
|
RenRect r = rect_buf[i];
|
||||||
|
@ -262,9 +294,6 @@ void rencache_end_frame(void) {
|
||||||
cmd = NULL;
|
cmd = NULL;
|
||||||
while (next_command(&cmd)) {
|
while (next_command(&cmd)) {
|
||||||
switch (cmd->type) {
|
switch (cmd->type) {
|
||||||
case FREE_FONT:
|
|
||||||
has_free_commands = true;
|
|
||||||
break;
|
|
||||||
case SET_CLIP:
|
case SET_CLIP:
|
||||||
ren_set_clip_rect(intersect_rects(cmd->rect, r));
|
ren_set_clip_rect(intersect_rects(cmd->rect, r));
|
||||||
break;
|
break;
|
||||||
|
@ -296,16 +325,6 @@ void rencache_end_frame(void) {
|
||||||
ren_update_rects(rect_buf, rect_count);
|
ren_update_rects(rect_buf, rect_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free fonts */
|
|
||||||
if (has_free_commands) {
|
|
||||||
cmd = NULL;
|
|
||||||
while (next_command(&cmd)) {
|
|
||||||
if (cmd->type == FREE_FONT) {
|
|
||||||
font_desc_free(cmd->font_desc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* swap cell buffer and reset */
|
/* swap cell buffer and reset */
|
||||||
unsigned *tmp = cells;
|
unsigned *tmp = cells;
|
||||||
cells = cells_prev;
|
cells = cells_prev;
|
||||||
|
@ -313,6 +332,3 @@ void rencache_end_frame(void) {
|
||||||
command_buf_idx = 0;
|
command_buf_idx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rencache_clear() {
|
|
||||||
command_buf_idx = 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,17 +2,16 @@
|
||||||
#define RENCACHE_H
|
#define RENCACHE_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <lua.h>
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
|
||||||
void rencache_show_debug(bool enable);
|
void rencache_show_debug(bool enable);
|
||||||
void rencache_free_font(FontDesc *font_desc);
|
|
||||||
void rencache_set_clip_rect(RenRect rect);
|
void rencache_set_clip_rect(RenRect rect);
|
||||||
void rencache_draw_rect(RenRect rect, RenColor color);
|
void rencache_draw_rect(RenRect rect, RenColor color);
|
||||||
int rencache_draw_text(FontDesc *font_desc, const char *text, int x, int y, RenColor color,
|
int rencache_draw_text(lua_State *L, FontDesc *font_desc, int font_index, const char *text, int x, int y, RenColor color,
|
||||||
bool draw_subpixel, CPReplaceTable *replacements, RenColor replace_color);
|
bool draw_subpixel, CPReplaceTable *replacements, RenColor replace_color);
|
||||||
void rencache_invalidate(void);
|
void rencache_invalidate(void);
|
||||||
void rencache_begin_frame(void);
|
void rencache_begin_frame(lua_State *L);
|
||||||
void rencache_end_frame(void);
|
void rencache_end_frame(lua_State *L);
|
||||||
void rencache_clear();
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue