Compare commits

...

17 Commits

Author SHA1 Message Date
George Sokianos d5d87789d5 innosetup changes 2024-04-24 21:01:21 +01:00
Takase 6ba5328697 Release v2.1.4 (#1772)
* changelog: add changes for 2.1.4

* chore: update version and changelog
2024-04-24 21:01:05 +01:00
Takase b419dca6ad ci: fix missing permission for creating releases (#1770) 2024-04-24 21:01:05 +01:00
Guldoman 2d8d39c7c0 Skip patterns matching nothing in `tokenizer` (#1743)
These patterns cause infinite loops, so warn about them and skip them.
2024-04-24 21:01:05 +01:00
Andrei Vinca a2b340efbe Fix BufferSize in g_read for Windows (#1722) 2024-04-24 21:01:05 +01:00
PerilousBooklet eee6bc24d0 Added Arduino syntax highlighting support alongside C++. (#1767) 2024-04-24 21:01:05 +01:00
PerilousBooklet be84a85dc9 Fixed some typos in core.init (#1755)
* Fixed some typos.

* Update data/core/init.lua

Co-authored-by: Takase <20792268+takase1121@users.noreply.github.com>

* Update data/core/init.lua

Co-authored-by: Takase <20792268+takase1121@users.noreply.github.com>

---------

Co-authored-by: Takase <20792268+takase1121@users.noreply.github.com>
2024-04-24 21:01:05 +01:00
Guldoman e6d706f6b8 Limit `language_js` regex avoidance to numbers, and fix starting `/*` comments (#1744)
* Avoid starting regexes only after numbers in `language_js`

* Allow starting `/*` comments after numbers in `language_js`
2024-04-24 21:01:05 +01:00
Aziz Mazouz Jaber f76b7bd600 Add from symbol to support ESM (#1754) 2024-04-24 21:01:05 +01:00
Jan a6a4f2bd0b Add SerenityOS platform support (#1745)
* Add SerenityOS platform support

* remove cpp_std default option
2024-04-24 21:01:05 +01:00
Guldoman cd49490253 Rectify `LICENSE` dates and owners (#1748) 2024-04-24 21:01:05 +01:00
Takase 74c8d03aa0 scripts: not hardcode MSYSTEM (#1739) 2024-04-24 21:01:05 +01:00
Guldoman e69f3b8c13 Fix `language_js` regex/comment distinction (#1731) 2024-04-24 21:00:21 +01:00
Guldoman 27ae51762b Improve `CommandView` and `autocomplete` scroll behavior (#1732)
* Make command palette item scrolling more natural

Also add a config option for the maximum number of visible entries in the command palette.

* Make `autocomplete` item scrolling more natural
2024-04-24 21:00:21 +01:00
Guldoman ece51922a3 Improve `autocomplete` suggestions box behavior (#1734)
* Improve `autocomplete` suggestions box sizing

This avoids that the box gets too big because of non-visible items, and makes it reactive to window sizing.

* Draw ellipsis when `autocomplete` entries aren't fully visible
2024-04-24 21:00:21 +01:00
PerilousBooklet cf76b5857a Added .pyi extension to python. (#1728) 2024-04-24 21:00:21 +01:00
Velosofy 8fd5c78312 Add "Open with Lite XL" to windows' context menu (#1333)
Closes #423
2024-04-24 21:00:21 +01:00
20 changed files with 329 additions and 80 deletions

View File

@ -9,13 +9,15 @@ on:
inputs:
version:
description: Release Version
default: v2.1.3
default: v2.1.4
required: true
jobs:
release:
name: Create Release
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
version: ${{ steps.tag.outputs.version }}

View File

@ -1,4 +1,6 @@
Copyright (c) 2020-present Lite XL Team
Copyright (c) 2020 rxi
Copyright (c) 2020-2022 Francesco Abbate
Copyright (c) 2022-present Lite XL Team
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

View File

@ -1,5 +1,58 @@
# Changes Log
## [2.1.4] - 2024-04-16
This release addresses severe bugs not found in previous releases,
and improves the usability of the program.
### Features
* Add `.pyi` extension to `language_python`.
([#1728](https://github.com/lite-xl/lite-xl/pull/1728))
* Improve autocomplete suggestions box behavior with long text
([#1734](https://github.com/lite-xl/lite-xl/pull/1734))
* Improve `CommandView` and autocomplete scroll behavior
([#1732](https://github.com/lite-xl/lite-xl/pull/1732))
* Add `from` symbol to support ESM
([#1754](https://github.com/lite-xl/lite-xl/pull/1754))
* Add Arduino syntax highlighting support in `language_cpp`
([#1767](https://github.com/lite-xl/lite-xl/pull/1767))
* Skip patterns matching nothing in tokenizer
([#1743](https://github.com/lite-xl/lite-xl/pull/1743))
### Fixes
* Fix uninitialized variables in `src/api/process.c`
([#1719](https://github.com/lite-xl/lite-xl/pull/1719))
* Fix `language_js` regex/comment distinction
([#1731](https://github.com/lite-xl/lite-xl/pull/1731))
* Fix compilation on non-MINGW64 platforms
([#1739](https://github.com/lite-xl/lite-xl/pull/1739))
* Limit `language_js` regex avoidance to numbers, and fix starting `/*` comments
([#1744](https://github.com/lite-xl/lite-xl/pull/1744))
* Fix `buffer_size` in `g_read` for Windows
([#1722](https://github.com/lite-xl/lite-xl/pull/1722))
* Fix missing permission for creating releases
([#1770](https://github.com/lite-xl/lite-xl/pull/1770))
### Other Changes
* Rectify LICENSE dates and owners
([#1748](https://github.com/lite-xl/lite-xl/pull/1748))
* Fix some typos in `core.init`
([#1755](https://github.com/lite-xl/lite-xl/pull/1755))
## [2.1.3] - 2024-01-29
This release addresses severe bugs not found in previous releases.
@ -1451,6 +1504,7 @@ A new global variable `USERDIR` is exposed to point to the user's directory.
- subpixel font rendering with gamma correction
[2.1.4]: https://github.com/lite-xl/lite-xl/releases/tag/v2.1.4
[2.1.3]: https://github.com/lite-xl/lite-xl/releases/tag/v2.1.3
[2.1.2]: https://github.com/lite-xl/lite-xl/releases/tag/v2.1.2
[2.1.1]: https://github.com/lite-xl/lite-xl/releases/tag/v2.1.1

View File

@ -1,5 +1,6 @@
local core = require "core"
local common = require "core.common"
local config = require "core.config"
local style = require "core.style"
local Doc = require "core.doc"
local DocView = require "core.docview"
@ -20,8 +21,6 @@ local CommandView = DocView:extend()
CommandView.context = "application"
local max_suggestions = 10
local noop = function() end
---@class core.commandview.state
@ -50,6 +49,7 @@ local default_state = {
function CommandView:new()
CommandView.super.new(self, SingleLineDoc())
self.suggestion_idx = 1
self.suggestions_offset = 1
self.suggestions = {}
self.suggestions_height = 0
self.last_change_id = 0
@ -128,6 +128,24 @@ function CommandView:move_suggestion_idx(dir)
end
end
local function get_suggestions_offset()
local max_visible = math.min(config.max_visible_commands, #self.suggestions)
if dir > 0 then
if self.suggestions_offset + max_visible < self.suggestion_idx + 1 then
return self.suggestion_idx - max_visible + 1
elseif self.suggestions_offset > self.suggestion_idx then
return self.suggestion_idx
end
else
if self.suggestions_offset > self.suggestion_idx then
return self.suggestion_idx
elseif self.suggestions_offset + max_visible < self.suggestion_idx + 1 then
return self.suggestion_idx - max_visible + 1
end
end
return self.suggestions_offset
end
if self.state.show_suggestions then
local n = self.suggestion_idx + dir
self.suggestion_idx = overflow_suggestion_idx(n, #self.suggestions)
@ -151,6 +169,8 @@ function CommandView:move_suggestion_idx(dir)
self.last_change_id = self.doc:get_change_id()
self.state.suggest(self:get_text())
end
self.suggestions_offset = get_suggestions_offset()
end
@ -261,6 +281,7 @@ function CommandView:update_suggestions()
end
self.suggestions = res
self.suggestion_idx = 1
self.suggestions_offset = 1
end
@ -300,11 +321,11 @@ function CommandView:update()
-- update suggestions box height
local lh = self:get_suggestion_line_height()
local dest = self.state.show_suggestions and math.min(#self.suggestions, max_suggestions) * lh or 0
local dest = self.state.show_suggestions and math.min(#self.suggestions, config.max_visible_commands) * lh or 0
self:move_towards("suggestions_height", dest, nil, "commandview")
-- update suggestion cursor offset
local dest = math.min(self.suggestion_idx, max_suggestions) * self:get_suggestion_line_height()
local dest = (self.suggestion_idx - self.suggestions_offset + 1) * self:get_suggestion_line_height()
self:move_towards("selection_offset", dest, nil, "commandview")
-- update size based on whether this is the active_view
@ -340,6 +361,7 @@ local function draw_suggestions_box(self)
local h = math.ceil(self.suggestions_height)
local rx, ry, rw, rh = self.position.x, self.position.y - h - dh, self.size.x, h
core.push_clip_rect(rx, ry, rw, rh)
-- draw suggestions background
if #self.suggestions > 0 then
renderer.draw_rect(rx, ry, rw, rh, style.background3)
@ -349,14 +371,12 @@ local function draw_suggestions_box(self)
end
-- draw suggestion text
local offset = math.max(self.suggestion_idx - max_suggestions, 0)
local last = math.min(offset + max_suggestions, #self.suggestions)
core.push_clip_rect(rx, ry, rw, rh)
local first = 1 + offset
local first = math.max(self.suggestions_offset, 1)
local last = math.min(self.suggestions_offset + config.max_visible_commands, #self.suggestions)
for i=first, last do
local item = self.suggestions[i]
local color = (i == self.suggestion_idx) and style.accent or style.text
local y = self.position.y - (i - offset) * lh - dh
local y = self.position.y - (i - first + 1) * lh - dh
common.draw_text(self:get_font(), color, item.text, nil, x, y, 0, lh)
if item.info then

View File

@ -112,6 +112,12 @@ config.max_undos = 10000
---@type number
config.max_tabs = 8
---The maximum number of entries shown at a time in the command palette.
---
---The default is 10.
---@type integer
config.max_visible_commands = 10
---Shows/hides the tab bar when there is only one tab open.
---
---The tab bar is always shown by default.

View File

@ -572,22 +572,22 @@ local config = require "core.config"
--
-- Here some examples:
--
-- "^%." match any file of directory whose basename begins with a dot.
-- "^%." matches any file of directory whose basename begins with a dot.
--
-- When there is an '/' or a '/$' at the end the pattern it will only match
-- When there is an '/' or a '/$' at the end, the pattern will only match
-- directories. When using such a pattern a final '/' will be added to the name
-- of any directory entry before checking if it matches.
--
-- "^%.git/" matches any directory named ".git" anywhere in the project.
--
-- If a "/" appears anywhere in the pattern except if it appears at the end or
-- is immediately followed by a '$' then the pattern will be applied to the full
-- If a "/" appears anywhere in the pattern (except when it appears at the end or
-- is immediately followed by a '$'), then the pattern will be applied to the full
-- path of the file or directory. An initial "/" will be prepended to the file's
-- or directory's path to indicate the project's root.
--
-- "^/node_modules/" will match a directory named "node_modules" at the project's root.
-- "^/build.*/" match any top level directory whose name begins with "build"
-- "^/subprojects/.+/" match any directory inside a top-level folder named "subprojects".
-- "^/build.*/" will match any top level directory whose name begins with "build".
-- "^/subprojects/.+/" will match any directory inside a top-level folder named "subprojects".
-- You may activate some plugins on a per-project basis to override the user's settings.
-- config.plugins.trimwitespace = true

View File

@ -122,8 +122,10 @@ local function report_bad_pattern(log_fn, syntax, pattern_idx, msg, ...)
end
if bad_patterns[syntax][pattern_idx] then return end
bad_patterns[syntax][pattern_idx] = true
log_fn("Malformed pattern #%d in %s language plugin. " .. msg,
pattern_idx, syntax.name or "unnamed", ...)
log_fn("Malformed pattern #%d <%s> in %s language plugin.\n" .. msg,
pattern_idx,
syntax.patterns[pattern_idx].pattern or syntax.patterns[pattern_idx].regex,
syntax.name or "unnamed", ...)
end
---@param incoming_syntax table
@ -337,6 +339,14 @@ function tokenizer.tokenize(incoming_syntax, text, state, resume)
for n, p in ipairs(current_syntax.patterns) do
local find_results = { find_text(text, p, i, true, false) }
if find_results[1] then
-- Check for patterns successfully matching nothing
if find_results[1] > find_results[2] then
report_bad_pattern(core.warn, current_syntax, n,
"Pattern successfully matched, but nothing was captured.")
goto continue
end
-- Check for patterns with mismatching number of `types`
local type_is_table = type(p.type) == "table"
local n_types = type_is_table and #p.type or 1
if #find_results == 2 and type_is_table then
@ -350,6 +360,7 @@ function tokenizer.tokenize(incoming_syntax, text, state, resume)
report_bad_pattern(core.warn, current_syntax, n,
"Too many token types: got %d needed %d.", n_types, #find_results - 1)
end
-- matched pattern; make and add tokens
push_tokens(res, current_syntax, p, text, find_results)
-- update state if this was a start|end pattern pair
@ -365,6 +376,7 @@ function tokenizer.tokenize(incoming_syntax, text, state, resume)
i = find_results[2] + 1
matched = true
break
::continue::
end
end

View File

@ -282,12 +282,14 @@ end)
local partial = ""
local suggestions_offset = 1
local suggestions_idx = 1
local suggestions = {}
local last_line, last_col
local function reset_suggestions()
suggestions_offset = 1
suggestions_idx = 1
suggestions = {}
@ -369,6 +371,7 @@ local function update_suggestions()
end
end
suggestions_idx = 1
suggestions_offset = 1
end
local function get_partial_symbol()
@ -384,8 +387,10 @@ local function get_active_view()
end
end
local last_max_width = 0
local function get_suggestions_rect(av)
if #suggestions == 0 then
last_max_width = 0
return 0, 0, 0, 0
end
@ -398,45 +403,59 @@ local function get_suggestions_rect(av)
local hide_info = config.plugins.autocomplete.hide_info
local hide_icons = config.plugins.autocomplete.hide_icons
local ah = config.plugins.autocomplete.max_height
local max_items = math.min(ah, #suggestions)
local show_count = math.min(#suggestions, ah)
local start_index = math.max(suggestions_idx-(ah-1), 1)
local max_width = 0
for _, s in ipairs(suggestions) do
local max_l_icon_width = 0
for i = start_index, start_index + show_count - 1 do
local s = suggestions[i]
local w = font:get_width(s.text)
if s.info and not hide_info then
w = w + style.font:get_width(s.info) + style.padding.x
end
local icon = s.icon or s.info
if not hide_icons and icon and autocomplete.icons[icon] then
w = w + autocomplete.icons[icon].font:get_width(
local icon_width = autocomplete.icons[icon].font:get_width(
autocomplete.icons[icon].char
) + (style.padding.x / 2)
)
if config.plugins.autocomplete.icon_position == "left" then
max_l_icon_width = math.max(max_l_icon_width, icon_width + (style.padding.x / 2))
end
w = w + icon_width + (style.padding.x / 2)
has_icons = true
end
max_width = math.max(max_width, w)
end
max_width = math.max(last_max_width, max_width)
last_max_width = max_width
local ah = config.plugins.autocomplete.max_height
local max_items = #suggestions
if max_items > ah then
max_items = ah
end
max_width = max_width + style.padding.x * 2
x = x - style.padding.x - max_l_icon_width
-- additional line to display total items
max_items = max_items + 1
if max_width < 150 then
max_width = 150
if max_width > core.root_view.size.x then
max_width = core.root_view.size.x
end
if max_width < 150 * SCALE then
max_width = 150 * SCALE
end
-- if portion not visiable to right, reposition to DocView right margin
if (x - av.position.x) + max_width > av.size.x then
x = (av.size.x + av.position.x) - max_width - (style.padding.x * 2)
if x + max_width > core.root_view.size.x then
x = (av.size.x + av.position.x) - max_width
end
return
x - style.padding.x,
x,
y - style.padding.y,
max_width + style.padding.x * 2,
max_width,
max_items * (th + style.padding.y) + style.padding.y,
has_icons
end
@ -565,8 +584,8 @@ local function draw_suggestions_box(av)
local font = av:get_font()
local lh = font:get_height() + style.padding.y
local y = ry + style.padding.y / 2
local show_count = #suggestions <= ah and #suggestions or ah
local start_index = suggestions_idx > ah and (suggestions_idx-(ah-1)) or 1
local show_count = math.min(#suggestions, ah)
local start_index = suggestions_offset
local hide_info = config.plugins.autocomplete.hide_info
for i=start_index, start_index+show_count-1, 1 do
@ -602,11 +621,24 @@ local function draw_suggestions_box(av)
end
end
local info_size = style.font:get_width(s.info) + style.padding.x
local color = (i == suggestions_idx) and style.accent or style.text
common.draw_text(
-- Push clip to avoid that the suggestion text gets drawn over suggestion type/icon
core.push_clip_rect(rx + icon_l_padding + style.padding.x, y,
rw - info_size - icon_l_padding - icon_r_padding - style.padding.x, lh)
local x_adv = common.draw_text(
font, color, s.text, "left",
rx + icon_l_padding + style.padding.x, y, rw, lh
)
core.pop_clip_rect()
-- If the text wasn't fully visible, draw an ellipsis
if x_adv > rx + rw - info_size - icon_r_padding then
local ellipsis_size = font:get_width("")
local ell_x = rx + rw - info_size - icon_r_padding - ellipsis_size
renderer.draw_rect(ell_x, y, ellipsis_size, lh, style.background3)
common.draw_text(font, color, "", "left", ell_x, y, ellipsis_size, lh)
end
if s.info and not hide_info then
color = (i == suggestions_idx) and style.text or style.dim
common.draw_text(
@ -819,7 +851,7 @@ command.add(predicate, {
local current_partial = get_partial_symbol()
local sz = #current_partial
for idx, line1, col1, line2, col2 in doc:get_selections(true) do
for _, line1, col1, line2, _ in doc:get_selections(true) do
local n = col1 - 1
local line = doc.lines[line1]
for i = 1, sz + 1 do
@ -840,10 +872,24 @@ command.add(predicate, {
["autocomplete:previous"] = function()
suggestions_idx = (suggestions_idx - 2) % #suggestions + 1
local ah = math.min(config.plugins.autocomplete.max_height, #suggestions)
if suggestions_offset > suggestions_idx then
suggestions_offset = suggestions_idx
elseif suggestions_offset + ah < suggestions_idx + 1 then
suggestions_offset = suggestions_idx - ah + 1
end
end,
["autocomplete:next"] = function()
suggestions_idx = (suggestions_idx % #suggestions) + 1
local ah = math.min(config.plugins.autocomplete.max_height, #suggestions)
if suggestions_offset + ah < suggestions_idx + 1 then
suggestions_offset = suggestions_idx - ah + 1
elseif suggestions_offset > suggestions_idx then
suggestions_offset = suggestions_idx
end
end,
["autocomplete:cycle"] = function()

View File

@ -5,7 +5,8 @@ syntax.add {
name = "C++",
files = {
"%.h$", "%.inl$", "%.cpp$", "%.cc$", "%.C$", "%.cxx$",
"%.c++$", "%.hh$", "%.H$", "%.hxx$", "%.hpp$", "%.h++$"
"%.c++$", "%.hh$", "%.H$", "%.hxx$", "%.hpp$", "%.h++$",
"%.ino$"
},
comment = "//",
block_comment = { "/*", "*/" },

View File

@ -20,10 +20,10 @@ local syntax = require "core.syntax"
-- followed by pattern options, and anything that can
-- be after a pattern.
--
-- Demo with some unit tests (click on the Unit Tests entry): https://regex101.com/r/R0w8Qw/1
-- Demo with some unit tests (click on the Unit Tests entry): https://regex101.com/r/Vx5L5V/1
-- Note that it has a couple of changes to make it work on that platform.
local regex_pattern = {
[=[/(?=(?!/)(?:(?>[^\\[\/]++|\\.|\[(?:[^\\\]]++|\\.)*+\])*+)++/[gmiyuvsd]*\s*[\n,;\)\]\}\.])()]=],
[=[\/(?=(?!\/)(?:(?>[^\\[\/]++|\\.|\[(?:[^\\\]]++|\\.)*+\])*+)++\/[gmiyuvsd]*\s*(?:[\n,;\)\]\}\.]|\/[\/*]))()]=],
"/()[gmiyuvsd]*", "\\"
}
@ -57,18 +57,19 @@ syntax.add {
comment = "//",
block_comment = { "/*", "*/" },
patterns = {
{ pattern = "//.*", type = "comment" },
{ pattern = { "/%*", "%*/" }, type = "comment" },
{ regex = regex_pattern, syntax = inner_regex_syntax, type = {"string", "string"} },
{ pattern = { '"', '"', '\\' }, type = "string" },
{ pattern = { "'", "'", '\\' }, type = "string" },
{ pattern = { "`", "`", '\\' }, type = "string" },
{ pattern = "-?0[xXbBoO][%da-fA-F_]+n?()%s*()/?", type = {"number", "normal", "operator"} },
{ pattern = "-?%d+[%d%.eE_n]*()%s*()/?", type = {"number", "normal", "operator"} },
{ pattern = "-?%.?%d+()%s*()/?", type = {"number", "normal", "operator"} },
{ pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" },
{ pattern = "[%a_][%w_]*%f[(]", type = "function" },
{ pattern = "[%a_][%w_]*()%s*()/?", type = {"symbol", "normal", "operator"} },
{ pattern = "//.*", type = "comment" },
{ pattern = { "/%*", "%*/" }, type = "comment" },
{ regex = regex_pattern, syntax = inner_regex_syntax, type = {"string", "string"} },
{ pattern = { '"', '"', '\\' }, type = "string" },
{ pattern = { "'", "'", '\\' }, type = "string" },
{ pattern = { "`", "`", '\\' }, type = "string" },
-- Use (?:\/(?!\/|\*))? to avoid that a regex can start after a number, while also allowing // and /* comments
{ regex = [[-?0[xXbBoO][\da-fA-F_]+n?()\s*()(?:\/(?!\/|\*))?]], type = {"number", "normal", "operator"} },
{ regex = [[-?\d+[0-9.eE_n]*()\s*()(?:\/(?!\/|\*))?]], type = {"number", "normal", "operator"} },
{ regex = [[-?\.?\d+()\s*()(?:\/(?!\/|\*))?]], type = {"number", "normal", "operator"} },
{ pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" },
{ pattern = "[%a_][%w_]*%f[(]", type = "function" },
{ pattern = "[%a_][%w_]*", type = "symbol" },
},
symbols = {
["async"] = "keyword",
@ -92,6 +93,7 @@ syntax.add {
["get"] = "keyword",
["if"] = "keyword",
["import"] = "keyword",
["from"] = "keyword",
["in"] = "keyword",
["of"] = "keyword",
["instanceof"] = "keyword",

View File

@ -3,7 +3,7 @@ local syntax = require "core.syntax"
syntax.add {
name = "Python",
files = { "%.py$", "%.pyw$", "%.rpy$" },
files = { "%.py$", "%.pyw$", "%.rpy$", "%.pyi$" },
headers = "^#!.*[ /]python",
comment = "#",
block_comment = { '"""', '"""' },

View File

@ -1,6 +1,6 @@
project('lite-xl',
['c'],
version : '2.1.3',
version : '2.1.4',
license : 'MIT',
meson_version : '>= 0.56',
default_options : [

View File

@ -29,6 +29,6 @@
</provides>
<releases>
<release version="2.1.3" date="2024-01-29" />
<release version="2.1.4" date="2024-04-16" />
</releases>
</component>

View File

@ -77,11 +77,17 @@ get_platform_arch() {
platform=$(get_platform_name)
arch=${CROSS_ARCH:-$(uname -m)}
if [[ $MSYSTEM != "" ]]; then
if [[ $MSYSTEM == "MINGW64" ]]; then
case "$MSYSTEM" in
MINGW64|UCRT64|CLANG64)
arch=x86_64
else
;;
MINGW32|CLANG32)
arch=i686
fi
;;
CLANGARM64)
arch=aarch64
;;
esac
fi
echo "$arch"
}

View File

@ -29,13 +29,24 @@ main() {
local version
local output
if [[ $MSYSTEM == "MINGW64" ]]; then
case "$MSYSTEM" in
MINGW64|UCRT64|CLANG64)
arch=x64
arch_file=x86_64
else
arch=i686;
;;
MINGW32|CLANG32)
arch=x86
arch_file=i686
fi
;;
CLANGARM64)
arch=arm64
arch_file=aarch64
;;
*)
echo "error: unsupported MSYSTEM type: $MSYSTEM"
exit 1
;;
esac
initial_arg_count=$#

View File

@ -213,14 +213,18 @@ main() {
if [[ $platform == "windows" ]]; then
exe_file="${exe_file}.exe"
stripcmd="strip --strip-all"
# Copy MinGW libraries dependencies.
# MSYS2 ldd command seems to be only 64bit, so use ntldd
# see https://github.com/msys2/MINGW-packages/issues/4164
ntldd -R "${exe_file}" \
| grep mingw \
| awk '{print $3}' \
| sed 's#\\#/#g' \
| xargs -I '{}' cp -v '{}' "$(pwd)/${dest_dir}/"
if command -v ntldd >/dev/null 2>&1; then
# Copy MinGW libraries dependencies.
# MSYS2 ldd command seems to be only 64bit, so use ntldd
# see https://github.com/msys2/MINGW-packages/issues/4164
ntldd -R "${exe_file}" \
| grep mingw \
| awk '{print $3}' \
| sed 's#\\#/#g' \
| xargs -I '{}' cp -v '{}' "$(pwd)/${dest_dir}/"
else
echo "WARNING: ntldd not found; assuming program is static"
fi
else
# Windows archive is always portable
package_name+="-portable"

View File

@ -0,0 +1,75 @@
#include <AK/NumericLimits.h>
#include <Kernel/API/InodeWatcherEvent.h>
#include <Kernel/API/InodeWatcherFlags.h>
#include <cstring>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
extern "C" {
struct dirmonitor_internal* init_dirmonitor();
void deinit_dirmonitor(struct dirmonitor_internal*);
int get_changes_dirmonitor(struct dirmonitor_internal*, char*, int);
int translate_changes_dirmonitor(struct dirmonitor_internal*, char*, int, int (*)(int, const char*, void*), void*);
int add_dirmonitor(struct dirmonitor_internal*, const char*);
void remove_dirmonitor(struct dirmonitor_internal*, int);
int get_mode_dirmonitor();
}
struct dirmonitor_internal {
int fd;
// a pipe is used to wake the thread in case of exit
int sig[2];
};
struct dirmonitor_internal* init_dirmonitor() {
struct dirmonitor_internal* monitor = (struct dirmonitor_internal*)calloc(sizeof(struct dirmonitor_internal), 1);
monitor->fd = create_inode_watcher(0);
pipe(monitor->sig);
fcntl(monitor->sig[0], F_SETFD, FD_CLOEXEC);
fcntl(monitor->sig[1], F_SETFD, FD_CLOEXEC);
return monitor;
}
void deinit_dirmonitor(struct dirmonitor_internal* monitor) {
close(monitor->fd);
close(monitor->sig[0]);
close(monitor->sig[1]);
}
int get_changes_dirmonitor(struct dirmonitor_internal* monitor, char* buffer, int length) {
struct pollfd fds[2] = { { .fd = monitor->fd, .events = POLLIN | POLLERR, .revents = 0 }, { .fd = monitor->sig[0], .events = POLLIN | POLLERR, .revents = 0 } };
poll(fds, 2, -1);
return read(monitor->fd, buffer, length);
}
int translate_changes_dirmonitor(struct dirmonitor_internal* monitor, char* buffer, int length, int (*change_callback)(int, const char*, void*), void* data) {
InodeWatcherEvent* event = (InodeWatcherEvent*)buffer;
change_callback(event->watch_descriptor, NULL, data);
return 0;
}
int add_dirmonitor(struct dirmonitor_internal* monitor, const char* path) {
return inode_watcher_add_watch(monitor->fd, path, strlen(path),
static_cast<unsigned>(
InodeWatcherEvent::Type::MetadataModified |
InodeWatcherEvent::Type::ContentModified |
InodeWatcherEvent::Type::Deleted |
InodeWatcherEvent::Type::ChildCreated |
InodeWatcherEvent::Type::ChildDeleted
));
}
void remove_dirmonitor(struct dirmonitor_internal* monitor, int fd) {
inode_watcher_remove_watch(monitor->fd, fd);
}
int get_mode_dirmonitor() { return 2; }

View File

@ -851,7 +851,7 @@ static int g_read(lua_State* L, int stream, unsigned long read_size) {
return luaL_error(L, "error: redirect to handles, FILE* and paths are not supported");
#if _WIN32
int writable_stream_idx = stream - 1;
if (self->reading[writable_stream_idx] || !ReadFile(self->child_pipes[stream][0], self->buffer[writable_stream_idx], READ_BUF_SIZE, NULL, &self->overlapped[writable_stream_idx])) {
if (self->reading[writable_stream_idx] || !ReadFile(self->child_pipes[stream][0], self->buffer[writable_stream_idx], read_size > READ_BUF_SIZE ? READ_BUF_SIZE : read_size, NULL, &self->overlapped[writable_stream_idx])) {
if (self->reading[writable_stream_idx] || GetLastError() == ERROR_IO_PENDING) {
self->reading[writable_stream_idx] = true;
DWORD bytesTransferred = 0;

View File

@ -9,7 +9,7 @@
#ifdef _WIN32
#include <windows.h>
#elif defined(__linux__)
#elif defined(__linux__) || defined(__serenity__)
#include <unistd.h>
#elif defined(__APPLE__)
#include <mach-o/dyld.h>
@ -34,7 +34,7 @@ static void get_exe_filename(char *buf, int sz) {
} else {
buf[0] = '\0';
}
#elif __linux__
#elif __linux__ || __serenity__
char path[] = "/proc/self/exe";
ssize_t len = readlink(path, buf, sz - 1);
if (len > 0)
@ -110,6 +110,9 @@ void set_macos_bundle_resources(lua_State *L);
#define ARCH_PLATFORM "freebsd"
#elif __APPLE__
#define ARCH_PLATFORM "darwin"
#elif __serenity__
#define ARCH_PLATFORM "serenity"
#else
#endif
#if !defined(ARCH_PROCESSOR) || !defined(ARCH_PLATFORM)

View File

@ -11,20 +11,31 @@ lite_sources = [
'main.c',
]
lite_sources += 'api/dirmonitor.c'
# dirmonitor backend
if get_option('dirmonitor_backend') == ''
if cc.has_function('inotify_init', prefix : '#include<sys/inotify.h>')
dirmonitor_backend = 'inotify'
lite_sources += 'api/dirmonitor/inotify.c'
elif host_machine.system() == 'darwin' and cc.check_header('CoreServices/CoreServices.h')
dirmonitor_backend = 'fsevents'
lite_sources += 'api/dirmonitor/fsevents.c'
elif cc.has_function('kqueue', prefix : '#include<sys/event.h>')
dirmonitor_backend = 'kqueue'
lite_sources += 'api/dirmonitor/kqueue.c'
elif cc.has_function('create_inode_watcher', prefix : '#include<fcntl.h>')
dirmonitor_backend = 'inodewatcher'
add_languages('cpp')
lite_sources += 'api/dirmonitor/inodewatcher.cpp'
elif dependency('libkqueue', required : false).found()
dirmonitor_backend = 'kqueue'
lite_sources += 'api/dirmonitor/kqueue.c'
elif host_machine.system() == 'windows'
dirmonitor_backend = 'win32'
lite_sources += 'api/dirmonitor/win32.c'
else
dirmonitor_backend = 'dummy'
lite_sources += 'api/dirmonitor/dummy.c'
warning('no suitable backend found, defaulting to dummy backend')
endif
else
@ -40,12 +51,6 @@ if dirmonitor_backend == 'kqueue'
endif
endif
lite_sources += [
'api/dirmonitor.c',
'api/dirmonitor/' + dirmonitor_backend + '.c',
]
lite_rc = []
if host_machine.system() == 'windows'
windows = import('windows')