Compare commits
35 Commits
Author | SHA1 | Date |
---|---|---|
George Sokianos | d5d87789d5 | |
Takase | 6ba5328697 | |
Takase | b419dca6ad | |
Guldoman | 2d8d39c7c0 | |
Andrei Vinca | a2b340efbe | |
PerilousBooklet | eee6bc24d0 | |
PerilousBooklet | be84a85dc9 | |
Guldoman | e6d706f6b8 | |
Aziz Mazouz Jaber | f76b7bd600 | |
Jan | a6a4f2bd0b | |
Guldoman | cd49490253 | |
Takase | 74c8d03aa0 | |
Guldoman | e69f3b8c13 | |
Guldoman | 27ae51762b | |
Guldoman | ece51922a3 | |
PerilousBooklet | cf76b5857a | |
Velosofy | 8fd5c78312 | |
George Sokianos | 713bdfeb7d | |
Takase | e87170b226 | |
Takase | 188297d6b4 | |
Takase | 566da99680 | |
Takase | 14260166fc | |
Chloé Vulquin | 2e26a0838c | |
Luke aka SwissalpS | 5ce34eb74c | |
Takase | 80c9128c43 | |
Takase | ddddef076d | |
vqn | ad79e26425 | |
vqn | dbeea0aff2 | |
Fiji | 3e91d07097 | |
Chloé Vulquin | 3897e59e6b | |
vqn | 2755117e2d | |
Takase | 97717b4511 | |
Velosofy | 9378646680 | |
George Sokianos | 721e0c8ee3 | |
Velosofy | ffe1e6775d |
|
@ -9,13 +9,15 @@ on:
|
|||
inputs:
|
||||
version:
|
||||
description: Release Version
|
||||
default: v2.1.1
|
||||
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 }}
|
||||
|
|
4
LICENSE
4
LICENSE
|
@ -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
|
||||
|
|
|
@ -81,6 +81,14 @@ affects only the place where the application is actually installed.
|
|||
|
||||
Head over to [releases](https://github.com/lite-xl/lite-xl/releases) and download the version for your operating system.
|
||||
|
||||
The prebuilt releases supports the following OSes:
|
||||
|
||||
- Windows 7 and above
|
||||
- Ubuntu 18.04 and above (glibc 2.27 and above)
|
||||
- OS X El Capitan and above (version 10.11 and above)
|
||||
|
||||
Some distributions may provide custom binaries for their platforms.
|
||||
|
||||
### Windows
|
||||
|
||||
Lite XL comes with installers on Windows for typical installations.
|
||||
|
|
503
changelog.md
503
changelog.md
|
@ -1,5 +1,505 @@
|
|||
# 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.
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix `doc:create-cursor-{previous,next}-line` with tabs
|
||||
([#1697](https://github.com/lite-xl/lite-xl/pull/1697))
|
||||
|
||||
* Fix heap buffer overflow and memory leaks in process and renderer API
|
||||
([#1705](https://github.com/lite-xl/lite-xl/pull/1705))
|
||||
|
||||
* Improve Python number syntax highlighting
|
||||
([#1704](https://github.com/lite-xl/lite-xl/pull/1704))
|
||||
|
||||
* Fix inconsistent NagView options on `doc:save`
|
||||
([#1696](https://github.com/lite-xl/lite-xl/pull/1696))
|
||||
|
||||
* Fix crashes with autoreload when files are deleted externally and replaced with a directory.
|
||||
([#1698](https://github.com/lite-xl/lite-xl/pull/1698))
|
||||
|
||||
* Improve JavaScript number syntax highlighting
|
||||
([#1710](https://github.com/lite-xl/lite-xl/pull/1710))
|
||||
|
||||
### Other Changes
|
||||
|
||||
* Process API style changes
|
||||
([#1709](https://github.com/lite-xl/lite-xl/pull/1709))
|
||||
|
||||
## [2.1.2] - 2023-12-29
|
||||
|
||||
This release addresses some issues present in the previous release,
|
||||
and improves the performance and stability of Lite XL.
|
||||
|
||||
### New Features
|
||||
|
||||
* The context menu in TreeView is now navigable with a keyboard.
|
||||
([#1338](https://github.com/lite-xl/lite-xl/pull/1338))
|
||||
|
||||
* A universal build of Lite XL is now available for macOS.
|
||||
This build runs natively on both Intel and Apple Silicon macs.
|
||||
([#1458](https://github.com/lite-xl/lite-xl/pull/1458))
|
||||
|
||||
* Most Unicode characters should be displayed properly
|
||||
if your fonts support them.
|
||||
([#1524](https://github.com/lite-xl/lite-xl/pull/1524))
|
||||
|
||||
* LogView will no longer scroll automatically if the user had scrolled.
|
||||
The LogView will only scroll automatically when the user scrolls up
|
||||
to the last entry.
|
||||
([#1546](https://github.com/lite-xl/lite-xl/pull/1546))
|
||||
|
||||
* When using different fonts (especially fonts that render different scripts),
|
||||
the letters will be aligned vertically.
|
||||
([#1560](https://github.com/lite-xl/lite-xl/pull/1560))
|
||||
|
||||
* Unsaved named files are now saved in the workspace.
|
||||
([#1597](https://github.com/lite-xl/lite-xl/pull/1597))
|
||||
|
||||
* macOS builds are now signed with a developer certificate.
|
||||
This allows the user to right click the application in Finder and execute
|
||||
it directly.
|
||||
([#1656](https://github.com/lite-xl/lite-xl/pull/1656))
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* Allow command buffer to be expanded.
|
||||
([#1297](https://github.com/lite-xl/lite-xl/pull/1297))
|
||||
|
||||
* Use table.move to implement `common.splice`.
|
||||
([#1324](https://github.com/lite-xl/lite-xl/pull/1324))
|
||||
|
||||
* Create renderer only when it doesn't exist.
|
||||
([#1315](https://github.com/lite-xl/lite-xl/pull/1315))
|
||||
|
||||
* Avoid drawing hidden text in `DocView:draw_line_text`.
|
||||
([#1298](https://github.com/lite-xl/lite-xl/pull/1298))
|
||||
|
||||
* Don't calculate widths per-uft8-char when not needed.
|
||||
([#1409](https://github.com/lite-xl/lite-xl/pull/1409))
|
||||
|
||||
* Allow tokenizer to pause and resume in the middle of a line.
|
||||
([#1444](https://github.com/lite-xl/lite-xl/pull/1444))
|
||||
|
||||
* Optimize CI build times on MSYS2.
|
||||
([#1435](https://github.com/lite-xl/lite-xl/pull/1435))
|
||||
|
||||
* Significant memory usage improvements when using huge fonts on Windows.
|
||||
([#1555](https://github.com/lite-xl/lite-xl/pull/1555))
|
||||
|
||||
* Optimize background tasks response time.
|
||||
([#1601](https://github.com/lite-xl/lite-xl/pull/1601))
|
||||
|
||||
### Backward Incompatible Changes
|
||||
|
||||
* The native plugin API is now usable on multiple source files,
|
||||
without causing any duplicated symbol errors during compilation.
|
||||
Plugins using the new plugin API header must define `LITE_XL_PLUGIN_ENTRYPOINT`
|
||||
before importing the header, in one of their source files.
|
||||
([#1335](https://github.com/lite-xl/lite-xl/pull/1335))
|
||||
|
||||
* The native plugin API header now follows the Lua 5.4 API.
|
||||
Previously, the plugin API header followed the Lua 5.2 API.
|
||||
([#1436](https://github.com/lite-xl/lite-xl/pull/1436))
|
||||
|
||||
* On Linux, `process.start()` will now throw an error if `execv()` fails.
|
||||
([#1363](https://github.com/lite-xl/lite-xl/pull/1363))
|
||||
|
||||
* Lite XL will use the default `SCALE` of 1 due to unreliable display
|
||||
scale detection. This may be fixed in a later version of Lite XL.
|
||||
Set the `LITE_SCALE` environment variable to override this value.
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix minor typos in user module
|
||||
([#1289](https://github.com/lite-xl/lite-xl/pull/1289))
|
||||
|
||||
* Do not allow users to create an empty font group
|
||||
([#1303](https://github.com/lite-xl/lite-xl/pull/1303))
|
||||
|
||||
* Fix a memory leak
|
||||
([#1305](https://github.com/lite-xl/lite-xl/pull/1305))
|
||||
|
||||
* Make dirwatch sorting compatible with what file_bisect expects
|
||||
([#1300](https://github.com/lite-xl/lite-xl/pull/1300))
|
||||
|
||||
* Handle readlink errors
|
||||
([#1292](https://github.com/lite-xl/lite-xl/pull/1292))
|
||||
|
||||
* Disable horizontal scrolling when linewrapping is enabled
|
||||
([#1309](https://github.com/lite-xl/lite-xl/pull/1309))
|
||||
|
||||
* Update widgets install location
|
||||
|
||||
* Add missing luaL_typeerror symbol to plugin API
|
||||
([#1313](https://github.com/lite-xl/lite-xl/pull/1313))
|
||||
|
||||
* Defer lua error until after cleanup
|
||||
([#1310](https://github.com/lite-xl/lite-xl/pull/1310))
|
||||
|
||||
* Make empty groups in regex.gmatch return their offset
|
||||
([#1325](https://github.com/lite-xl/lite-xl/pull/1325))
|
||||
|
||||
* Add missing header declaration
|
||||
|
||||
* Fix msys build now requiring ca-certificates
|
||||
([#1348](https://github.com/lite-xl/lite-xl/pull/1348))
|
||||
|
||||
* Fix path to macOS arm64 cross file in GitHub workflows
|
||||
|
||||
* Fix Doc contextmenu not registering commands if scale plugin is not found
|
||||
([#1338](https://github.com/lite-xl/lite-xl/pull/1338))
|
||||
|
||||
* Fix TreeView contextmenu commands not working if the mouse hovers DocView
|
||||
([#1338](https://github.com/lite-xl/lite-xl/pull/1338))
|
||||
|
||||
* Fix incorrect contextmenu predicate
|
||||
([#1338](https://github.com/lite-xl/lite-xl/pull/1338))
|
||||
|
||||
* Properly rescale NagView on scale change
|
||||
([#1379](https://github.com/lite-xl/lite-xl/pull/1379))
|
||||
|
||||
* Scale plugin also rescales `style.expanded_scrollbar_size`
|
||||
([#1380](https://github.com/lite-xl/lite-xl/pull/1380))
|
||||
|
||||
* Improve DocView:get_visible_line_range precision
|
||||
([#1382](https://github.com/lite-xl/lite-xl/pull/1382))
|
||||
|
||||
* Fix up some post 5.1/JIT Symbols
|
||||
([#1385](https://github.com/lite-xl/lite-xl/pull/1385))
|
||||
|
||||
* Fix incorrect x_offset if opened docs have different tab sizes
|
||||
([#1383](https://github.com/lite-xl/lite-xl/pull/1383))
|
||||
|
||||
* Use correct view for scrolling to find-replace:repeat-find results
|
||||
([#1400](https://github.com/lite-xl/lite-xl/pull/1400))
|
||||
|
||||
* Improve text width calculation precision
|
||||
([#1408](https://github.com/lite-xl/lite-xl/pull/1408))
|
||||
|
||||
* Add asynchronous process reaping
|
||||
([#1412](https://github.com/lite-xl/lite-xl/pull/1412))
|
||||
|
||||
* Fix cursors positions when deleting multiple selections
|
||||
([#1393](https://github.com/lite-xl/lite-xl/pull/1393),
|
||||
[#1463](https://github.com/lite-xl/lite-xl/pull/1463))
|
||||
|
||||
* Fix invalid EXEFILE and EXEDIR on Windows
|
||||
([#1396](https://github.com/lite-xl/lite-xl/pull/1396))
|
||||
|
||||
* Fix `os.getenv()` not supporting UTF-8 output
|
||||
([#1397](https://github.com/lite-xl/lite-xl/pull/1397))
|
||||
|
||||
* Fix differing stacktrace on stdout and file
|
||||
([#1404](https://github.com/lite-xl/lite-xl/pull/1404))
|
||||
|
||||
* Update api_require to expose more symbols
|
||||
([#1437](https://github.com/lite-xl/lite-xl/pull/1437))
|
||||
|
||||
* Make system.path_compare more case-aware
|
||||
([#1457](https://github.com/lite-xl/lite-xl/pull/1457))
|
||||
|
||||
* Fix for api_require wrong macro && conditions
|
||||
([#1465](https://github.com/lite-xl/lite-xl/pull/1465))
|
||||
|
||||
* Merge carets after doc:move-to-{previous,next}-char
|
||||
([#1462](https://github.com/lite-xl/lite-xl/pull/1462))
|
||||
|
||||
* Process API improvements (again)
|
||||
([#1370](https://github.com/lite-xl/lite-xl/pull/1370))
|
||||
|
||||
* Make system.path_compare more digit-aware
|
||||
([#1474](https://github.com/lite-xl/lite-xl/pull/1474))
|
||||
|
||||
* Check for HANDLE_INVALID in Process API
|
||||
([#1475](https://github.com/lite-xl/lite-xl/pull/1475))
|
||||
|
||||
* Fix linewrapping bug to do with wordwrapping
|
||||
|
||||
* Fix compiler warning for printing size_t in rencache.c
|
||||
|
||||
* Return error string from C searcher
|
||||
|
||||
* Restore horizontal scroll position after scale change
|
||||
([#494](https://github.com/lite-xl/lite-xl/pull/494))
|
||||
|
||||
* Fix memory leak in renderer.c when freeing glyphsets
|
||||
|
||||
* Move lineguide below blinking cursor
|
||||
([#1511](https://github.com/lite-xl/lite-xl/pull/1511))
|
||||
|
||||
* Close lua state when exiting on a runtime error
|
||||
([#1487](https://github.com/lite-xl/lite-xl/pull/1487))
|
||||
|
||||
* Mark linewrapping open_files table as weak
|
||||
|
||||
* Don't use core.status_view if not yet initialized when logging
|
||||
|
||||
* Revert "core syntax: strip the path from filename on syntax.get ([#1168](https://github.com/lite-xl/lite-xl/pull/1168))"
|
||||
([#1322](https://github.com/lite-xl/lite-xl/pull/1322))
|
||||
|
||||
* Make Doc:sanitize_position return a more appropriate col
|
||||
([#1469](https://github.com/lite-xl/lite-xl/pull/1469))
|
||||
|
||||
* Skip checking files if no filename was provided to syntax.get
|
||||
|
||||
* Normalize stroke before adding keybind
|
||||
([#1334](https://github.com/lite-xl/lite-xl/pull/1334))
|
||||
|
||||
* Make DocView aware of scrollbars sizes
|
||||
([#1177](https://github.com/lite-xl/lite-xl/pull/1177))
|
||||
|
||||
* Normalize strokes in fixed order
|
||||
([#1572](https://github.com/lite-xl/lite-xl/pull/1572))
|
||||
|
||||
* Defer core:open-log until everything is loaded
|
||||
([#1585](https://github.com/lite-xl/lite-xl/pull/1585))
|
||||
|
||||
* Fix returned percent when clicking the Scrollbar track
|
||||
|
||||
* Fix C++14 digit separators
|
||||
([#1593](https://github.com/lite-xl/lite-xl/pull/1593))
|
||||
|
||||
* Make linewrapping consider the expanded Scrollbar size
|
||||
|
||||
* Fix dimmed text when antialiasing is turned off
|
||||
([#1641](https://github.com/lite-xl/lite-xl/pull/1641))
|
||||
|
||||
* Mark unsaved named files as dirty
|
||||
([#1598](https://github.com/lite-xl/lite-xl/pull/1598))
|
||||
|
||||
* Make `common.serialize()` locale-independent and nan/inf compatible
|
||||
([#1640](https://github.com/lite-xl/lite-xl/pull/1640))
|
||||
|
||||
* Ignore keypresses during IME composition
|
||||
([#1573](https://github.com/lite-xl/lite-xl/pull/1573))
|
||||
|
||||
* Fix deadlock if error handler jumps somewhere else
|
||||
([#1647](https://github.com/lite-xl/lite-xl/pull/1647))
|
||||
|
||||
* Avoid considering single spaces in detectindent
|
||||
([#1595](https://github.com/lite-xl/lite-xl/pull/1595))
|
||||
|
||||
* Fix deleting indentation with multiple cursors
|
||||
([#1670](https://github.com/lite-xl/lite-xl/pull/1670))
|
||||
|
||||
* Fix `set_target_size` passing the wrong value to plugins
|
||||
([#1657](https://github.com/lite-xl/lite-xl/pull/1657))
|
||||
|
||||
* Limit `system.{sleep,wait_event}` to `timeouts >= 0`
|
||||
([#1666](https://github.com/lite-xl/lite-xl/pull/1666))
|
||||
|
||||
* Fix running core.step when receiving an event while not waiting
|
||||
([#1667](https://github.com/lite-xl/lite-xl/pull/1667))
|
||||
|
||||
* Fix dirmonitor sorting issues
|
||||
([#1599](https://github.com/lite-xl/lite-xl/pull/1599))
|
||||
|
||||
* Scale mouse coordinates by window scale
|
||||
([#1630](https://github.com/lite-xl/lite-xl/pull/1630))
|
||||
|
||||
* Made coroutines make more sense, and fixed a bug
|
||||
([#1381](https://github.com/lite-xl/lite-xl/pull/1381))
|
||||
|
||||
* Fix selecting newlines with `find-replace:select-add-{next,all}`
|
||||
([#1608](https://github.com/lite-xl/lite-xl/pull/1608))
|
||||
|
||||
* Fix editing after undo not clearing the change id
|
||||
([#1574](https://github.com/lite-xl/lite-xl/pull/1574))
|
||||
|
||||
* Fix language_js regex constant detection
|
||||
([#1581](https://github.com/lite-xl/lite-xl/pull/1581))
|
||||
|
||||
* Fix patterns starting with `^` in tokenizer
|
||||
([#1645](https://github.com/lite-xl/lite-xl/pull/1645))
|
||||
|
||||
* Use x offset to define render command rect in rencache_draw_text
|
||||
([#1618](https://github.com/lite-xl/lite-xl/pull/1618))
|
||||
|
||||
* Improve font/color change detection in `language_md`
|
||||
([#1614](https://github.com/lite-xl/lite-xl/pull/1614))
|
||||
|
||||
* Allow long commands and envs on process_start
|
||||
([#1477](https://github.com/lite-xl/lite-xl/pull/1477))
|
||||
|
||||
* Fix typo in `drawwhitespace.lua`
|
||||
|
||||
* Fix NagBar save failed message
|
||||
([#1678](https://github.com/lite-xl/lite-xl/pull/1678))
|
||||
|
||||
* Fix typo in `drawwhitespace.lua`
|
||||
|
||||
* Add autocompletion to multicursor
|
||||
([#1394](https://github.com/lite-xl/lite-xl/pull/1394))
|
||||
|
||||
### Other Changes
|
||||
|
||||
* Make api_require's nodes const
|
||||
([#1296](https://github.com/lite-xl/lite-xl/pull/1296))
|
||||
|
||||
* Don't set a value twice
|
||||
([#1306](https://github.com/lite-xl/lite-xl/pull/1306))
|
||||
|
||||
* Center title and version in emptyview
|
||||
([#1311](https://github.com/lite-xl/lite-xl/pull/1311))
|
||||
|
||||
* Use master branch for packaging plugins for addons release
|
||||
|
||||
* Reorganize resources folder and add wasm target
|
||||
([#1244](https://github.com/lite-xl/lite-xl/pull/1244))
|
||||
|
||||
* Replace uses of SDL_Window with RenWindow
|
||||
([#1319](https://github.com/lite-xl/lite-xl/pull/1319))
|
||||
|
||||
* Update dummy dirmonitor method signature to match prototypes
|
||||
|
||||
* Remove static libgcc from meson
|
||||
([#1290](https://github.com/lite-xl/lite-xl/pull/1290))
|
||||
|
||||
* Pass RenWindow by argument
|
||||
([#1321](https://github.com/lite-xl/lite-xl/pull/1321))
|
||||
|
||||
* Get rid of annoying forward slash on windows
|
||||
([#1345](https://github.com/lite-xl/lite-xl/pull/1345))
|
||||
|
||||
* Improve plugins config table handling
|
||||
([#1356](https://github.com/lite-xl/lite-xl/pull/1356))
|
||||
|
||||
* Add manifest on Windows
|
||||
([#1405](https://github.com/lite-xl/lite-xl/pull/1405))
|
||||
|
||||
* Split Command struct into different structs for each command type
|
||||
([#1407](https://github.com/lite-xl/lite-xl/pull/1407))
|
||||
|
||||
* Move SetProcessDPIAware to manifests
|
||||
([#1413](https://github.com/lite-xl/lite-xl/pull/1413))
|
||||
|
||||
* Use clipping functions provided by SDL
|
||||
([#1426](https://github.com/lite-xl/lite-xl/pull/1426))
|
||||
|
||||
* Aggregate SDL_Surfaces and their scale in RenSurface
|
||||
([#1429](https://github.com/lite-xl/lite-xl/pull/1429))
|
||||
|
||||
* Disable trimwhitespace and drawwhitespace via their configs
|
||||
([#1446](https://github.com/lite-xl/lite-xl/pull/1446))
|
||||
|
||||
* Bump dependency versions
|
||||
([#1434](https://github.com/lite-xl/lite-xl/pull/1434))
|
||||
|
||||
* Improvements to cross-compilation
|
||||
([#1458](https://github.com/lite-xl/lite-xl/pull/1458))
|
||||
|
||||
* Move native plugin API header into include/
|
||||
([#1440](https://github.com/lite-xl/lite-xl/pull/1440))
|
||||
|
||||
* Build releases with Ubuntu 18.04 container
|
||||
([#1460](https://github.com/lite-xl/lite-xl/pull/1460))
|
||||
|
||||
* Update GitHub Actions dependencies
|
||||
|
||||
* Make all parameters for set_window_hit_test optional in documentation
|
||||
|
||||
* Attach command buffer to Renderer Window
|
||||
([#1472](https://github.com/lite-xl/lite-xl/pull/1472))
|
||||
|
||||
* Fix comment typo in object.lua
|
||||
([#1541](https://github.com/lite-xl/lite-xl/pull/1541))
|
||||
|
||||
* Allow setting custom glyphset size
|
||||
([#1542](https://github.com/lite-xl/lite-xl/pull/1542))
|
||||
|
||||
* Use FreeType header names in renderer.c
|
||||
([#1554](https://github.com/lite-xl/lite-xl/pull/1554))
|
||||
|
||||
* Add documentation for core.common
|
||||
([#1510](https://github.com/lite-xl/lite-xl/pull/1510))
|
||||
|
||||
* Document missing parameter for system.path_compare
|
||||
([#1566](https://github.com/lite-xl/lite-xl/pull/1566))
|
||||
|
||||
* Add documentation for core.command
|
||||
([#1564](https://github.com/lite-xl/lite-xl/pull/1564))
|
||||
|
||||
* Update the *Installing prebuild* section in README.md
|
||||
([#1548](https://github.com/lite-xl/lite-xl/pull/1548))
|
||||
|
||||
* Update README.md to remove previously installed files
|
||||
prior to installing a new version
|
||||
|
||||
* Use lite-xl Build Box to build releases
|
||||
([#1571](https://github.com/lite-xl/lite-xl/pull/1571))
|
||||
|
||||
* Use Lua wrap by default
|
||||
([#1481](https://github.com/lite-xl/lite-xl/pull/1481))
|
||||
|
||||
* Add documentation for contextmenu
|
||||
([#1567](https://github.com/lite-xl/lite-xl/pull/1567))
|
||||
|
||||
* Use dmgbuild to create DMGs
|
||||
([#1664](https://github.com/lite-xl/lite-xl/pull/1664))
|
||||
|
||||
* Un-hardcode lua subproject detection and update dependencies
|
||||
([#1676](https://github.com/lite-xl/lite-xl/pull/1676))
|
||||
|
||||
* Make license time-independent
|
||||
([#1655](https://github.com/lite-xl/lite-xl/pull/1655))
|
||||
|
||||
## [2.1.1] - 2022-12-29
|
||||
|
||||
### New Features
|
||||
|
@ -1004,6 +1504,9 @@ 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
|
||||
[2.1.0]: https://github.com/lite-xl/lite-xl/releases/tag/v2.1.0
|
||||
[2.0.5]: https://github.com/lite-xl/lite-xl/releases/tag/v2.0.5
|
||||
|
|
|
@ -44,8 +44,8 @@ local function save(filename)
|
|||
else
|
||||
core.error(err)
|
||||
core.nag_view:show("Saving failed", string.format("Couldn't save file \"%s\". Do you want to save to another location?", doc().filename), {
|
||||
{ text = "No", default_no = true },
|
||||
{ text = "Yes", default_yes = true }
|
||||
{ text = "Yes", default_yes = true },
|
||||
{ text = "No", default_no = true }
|
||||
}, function(item)
|
||||
if item.text == "Yes" then
|
||||
core.add_thread(function()
|
||||
|
@ -93,11 +93,14 @@ local function cut_or_copy(delete)
|
|||
system.set_clipboard(full_text)
|
||||
end
|
||||
|
||||
local function split_cursor(direction)
|
||||
local function split_cursor(dv, direction)
|
||||
local new_cursors = {}
|
||||
for _, line1, col1 in doc():get_selections() do
|
||||
if line1 + direction >= 1 and line1 + direction <= #doc().lines then
|
||||
table.insert(new_cursors, { line1 + direction, col1 })
|
||||
local dv_translate = direction < 0
|
||||
and DocView.translate.previous_line
|
||||
or DocView.translate.next_line
|
||||
for _, line1, col1 in dv.doc:get_selections() do
|
||||
if line1 + direction >= 1 and line1 + direction <= #dv.doc.lines then
|
||||
table.insert(new_cursors, { dv_translate(dv.doc, line1, col1, dv) })
|
||||
end
|
||||
end
|
||||
-- add selections in the order that will leave the "last" added one as doc.last_selection
|
||||
|
@ -107,7 +110,7 @@ local function split_cursor(direction)
|
|||
end
|
||||
for i = start, stop, direction do
|
||||
local v = new_cursors[i]
|
||||
doc():add_selection(v[1], v[2])
|
||||
dv.doc:add_selection(v[1], v[2])
|
||||
end
|
||||
core.blink_reset()
|
||||
end
|
||||
|
@ -626,12 +629,12 @@ local commands = {
|
|||
end,
|
||||
|
||||
["doc:create-cursor-previous-line"] = function(dv)
|
||||
split_cursor(-1)
|
||||
split_cursor(dv, -1)
|
||||
dv.doc:merge_cursors()
|
||||
end,
|
||||
|
||||
["doc:create-cursor-next-line"] = function(dv)
|
||||
split_cursor(1)
|
||||
split_cursor(dv, 1)
|
||||
dv.doc:merge_cursors()
|
||||
end
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -28,7 +28,7 @@ function dirwatch:scan(directory, bool)
|
|||
end
|
||||
|
||||
-- Should be called on every directory in a subdirectory.
|
||||
-- In windows, this is a no-op for anything underneath a top-level directory,
|
||||
-- On Windows, this is a no-op for anything underneath a top-level directory,
|
||||
-- but code should be called anyway, so we can ensure that we have a proper
|
||||
-- experience across all platforms. Should be an absolute path.
|
||||
-- Can also be called on individual files, though this should be used sparingly,
|
||||
|
@ -134,11 +134,11 @@ local function compile_ignore_files()
|
|||
-- config.ignore_files could be a simple string...
|
||||
if type(ipatterns) ~= "table" then ipatterns = {ipatterns} end
|
||||
for i, pattern in ipairs(ipatterns) do
|
||||
-- we ignore malformed pattern that raise an error
|
||||
-- we ignore malformed patterns that raise an error
|
||||
if pcall(string.match, "a", pattern) then
|
||||
table.insert(compiled, {
|
||||
use_path = pattern:match("/[^/$]"), -- contains a slash but not at the end
|
||||
-- An '/' or '/$' at the end means we want to match a directory.
|
||||
-- A '/' or '/$' at the end means we want to match a directory.
|
||||
match_dir = pattern:match(".+/%$?$"), -- to be used as a boolen value
|
||||
pattern = pattern -- get the actual pattern
|
||||
})
|
||||
|
@ -175,11 +175,12 @@ end
|
|||
|
||||
|
||||
-- compute a file's info entry completed with "filename" to be used
|
||||
-- in project scan or falsy if it shouldn't appear in the list.
|
||||
-- in project scan and return it or falsy if it shouldn't appear in the list.
|
||||
local function get_project_file_info(root, file, ignore_compiled)
|
||||
local info = system.get_file_info(root .. PATHSEP .. file)
|
||||
-- info can be not nil but info.type may be nil if is neither a file neither
|
||||
-- a directory, for example for /dev/* entries on linux.
|
||||
-- In some cases info.type is nil even if info is valid.
|
||||
-- This happens when it is neither a file nor a directory,
|
||||
-- for example /dev/* entries on linux.
|
||||
if info and info.type then
|
||||
info.filename = file
|
||||
return fileinfo_pass_filter(info, ignore_compiled) and info
|
||||
|
@ -191,7 +192,7 @@ end
|
|||
-- "path" will be a path starting without '/' and without trailing '/'
|
||||
-- or the empty string.
|
||||
-- It identifies a sub-path within "root".
|
||||
-- The current path location will therefore always be: root .. path.
|
||||
-- The current path location will therefore always be: root .. '/' .. path.
|
||||
-- When recursing, "root" will always be the same, only "path" will change.
|
||||
-- Returns a list of file "items". In each item the "filename" will be the
|
||||
-- complete file path relative to "root" *without* the trailing '/', and without the starting '/'.
|
||||
|
|
|
@ -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
|
||||
|
@ -758,7 +758,7 @@ function core.init()
|
|||
cur_node = cur_node:split("down", core.command_view, {y = true})
|
||||
cur_node = cur_node:split("down", core.status_view, {y = true})
|
||||
|
||||
-- Load defaiult commands first so plugins can override them
|
||||
-- Load default commands first so plugins can override them
|
||||
command.add_defaults()
|
||||
|
||||
-- Load user module, plugins and project module
|
||||
|
@ -786,7 +786,7 @@ function core.init()
|
|||
end
|
||||
end
|
||||
|
||||
-- Load core plugins after user ones to let the user override them
|
||||
-- Load core and user plugins giving preference to user ones with same name.
|
||||
local plugins_success, plugins_refuse_list = core.load_plugins()
|
||||
|
||||
do
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -69,7 +69,7 @@ function dirwatch:check(change_callback, ...)
|
|||
for _, doc in ipairs(core.docs) do
|
||||
if doc.abs_filename and (dir == common.dirname(doc.abs_filename) or dir == doc.abs_filename) then
|
||||
local info = system.get_file_info(doc.filename or "")
|
||||
if info and times[doc] ~= info.modified then
|
||||
if info and info.type == "file" and times[doc] ~= info.modified then
|
||||
if not doc:is_dirty() and not config.plugins.autoreload.always_show_nagview then
|
||||
reload_doc(doc)
|
||||
else
|
||||
|
|
|
@ -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 = { "/*", "*/" },
|
||||
|
|
|
@ -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 = "0x[%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",
|
||||
|
|
|
@ -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 = { '"""', '"""' },
|
||||
|
@ -16,8 +16,8 @@ syntax.add {
|
|||
{ pattern = { "[ruU]?'''", "'''", '\\' }, type = "string" },
|
||||
{ pattern = { '[ruU]?"', '"', '\\' }, type = "string" },
|
||||
{ pattern = { "[ruU]?'", "'", '\\' }, type = "string" },
|
||||
{ pattern = "0x[%da-fA-F]+", type = "number" },
|
||||
{ pattern = "-?%d+[%d%.eE]*", type = "number" },
|
||||
{ pattern = "-?0[xboXBO][%da-fA-F_]+",type = "number" },
|
||||
{ pattern = "-?%d+[%d%.eE_]*", type = "number" },
|
||||
{ pattern = "-?%.?%d+", type = "number" },
|
||||
{ pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" },
|
||||
{ pattern = "[%a_][%w_]*%f[(]", type = "function" },
|
||||
|
|
|
@ -324,5 +324,13 @@ function system.load_native_plugin(name, path) end
|
|||
---@return boolean compare_result True if path1 < path2
|
||||
function system.path_compare(path1, type1, path2, type2) end
|
||||
|
||||
---
|
||||
---Sets an environment variable.
|
||||
---The converse of os.getenv.
|
||||
---
|
||||
---@param key string
|
||||
---@param val string
|
||||
---@return boolean ok True if call succeeded
|
||||
function system.setenv(key, val) end
|
||||
|
||||
return system
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
project('lite-xl',
|
||||
['c'],
|
||||
version : '2.1.1',
|
||||
version : '2.1.4',
|
||||
license : 'MIT',
|
||||
meson_version : '>= 0.56',
|
||||
default_options : [
|
||||
|
|
|
@ -12,15 +12,21 @@ asyncify_advise = '0'
|
|||
# initial heap size in bytes; make sure it is not too low (around 64mb - 250mb)
|
||||
initial_heap = '104857600'
|
||||
|
||||
# Emscripten is not always added to PATH.
|
||||
# Replace this variable with the path to Emscripten;
|
||||
# or supply a second machine file that defines this variable.
|
||||
toolchain = ''
|
||||
|
||||
|
||||
[binaries]
|
||||
c = 'emcc'
|
||||
cpp = 'em++'
|
||||
ar = 'emar'
|
||||
strip = 'emstrip'
|
||||
cmake = ['emmake', 'cmake']
|
||||
pkg-config = ['emconfigure', 'pkg-config']
|
||||
sdl2-config = ['emconfigure', 'sdl2-config']
|
||||
c = toolchain / 'emcc'
|
||||
cpp = toolchain / 'em++'
|
||||
ar = toolchain / 'emar'
|
||||
strip = toolchain / 'emstrip'
|
||||
cmake = [toolchain / 'emmake', 'cmake']
|
||||
pkg-config = [toolchain / 'emconfigure', 'pkg-config']
|
||||
sdl2-config = [toolchain / 'emconfigure', 'sdl2-config']
|
||||
file_packager = ['python3', toolchain / 'tools/file_packager.py']
|
||||
|
||||
|
||||
[properties]
|
||||
|
@ -36,7 +42,11 @@ cpp_link_args = []
|
|||
|
||||
[project options]
|
||||
buildtype = 'release'
|
||||
c_link_args = ['-s', 'ALLOW_MEMORY_GROWTH=1', '-s', 'INITIAL_MEMORY=' + initial_heap, '-s', 'ASYNCIFY=1', '-s', 'ASYNCIFY_ADVISE=' + asyncify_advise, '-s', 'ASYNCIFY_STACK_SIZE=6144', '-s', 'ASYNCIFY_REMOVE=' + asyncify_ignores, '-s', 'FORCE_FILESYSTEM=1']
|
||||
portable = true
|
||||
arch_tuple = 'wasm32-unknown'
|
||||
wrap_mode = 'nofallback'
|
||||
force_fallback_for = 'lua,pcre2,freetype2'
|
||||
c_link_args = ['-s', 'ALLOW_MEMORY_GROWTH=1', '-s', 'INITIAL_MEMORY=' + initial_heap, '-s', 'ASYNCIFY=1', '-s', 'ASYNCIFY_ADVISE=' + asyncify_advise, '-s', 'ASYNCIFY_STACK_SIZE=6144', '-s', 'ASYNCIFY_REMOVE=' + asyncify_ignores, '-s', 'FORCE_FILESYSTEM=1', '-lidbfs.js']
|
||||
|
||||
|
||||
[host_machine]
|
||||
|
|
|
@ -29,6 +29,6 @@
|
|||
</provides>
|
||||
|
||||
<releases>
|
||||
<release version="2.1.1" date="2022-12-29" />
|
||||
<release version="2.1.4" date="2024-04-16" />
|
||||
</releases>
|
||||
</component>
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#define MyAppName "Lite XL"
|
||||
#define MyAppVersion "@PROJECT_VERSION@"
|
||||
#define MyAppPublisher "Lite XL Team"
|
||||
#define MyAppURL "https://lite-xl.com"
|
||||
#define MyAppURL "https://lite-xl.github.io"
|
||||
#define MyAppExeName "lite-xl.exe"
|
||||
#define BuildDir "@PROJECT_BUILD_DIR@"
|
||||
#define SourceDir "@PROJECT_SOURCE_DIR@"
|
||||
|
@ -57,13 +57,9 @@ OutputBaseFilename=LiteXL-{#MyAppVersion}-{#ArchInternal}-setup
|
|||
|
||||
LicenseFile={#SourceDir}/LICENSE
|
||||
SetupIconFile={#SourceDir}/resources/icons/icon.ico
|
||||
UninstallDisplayIcon={app}\{#MyAppExeName}, 0
|
||||
WizardImageFile="{#SourceDir}/scripts/innosetup/wizard-modern-image.bmp"
|
||||
WizardSmallImageFile="{#SourceDir}/scripts/innosetup/litexl-55px.bmp"
|
||||
|
||||
; Required for the add to path option to refresh environment
|
||||
ChangesEnvironment=yes
|
||||
|
||||
[Languages]
|
||||
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||
|
||||
|
@ -71,10 +67,11 @@ Name: "english"; MessagesFile: "compiler:Default.isl"
|
|||
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
|
||||
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 6.1; Check: not IsAdminInstallMode
|
||||
Name: "portablemode"; Description: "Portable Mode"; Flags: unchecked
|
||||
Name: "envPath"; Description: "Add lite-xl to the PATH variable, allowing it to be run from a command line."
|
||||
|
||||
[Files]
|
||||
Source: "{#SourceDir}/lite-xl/*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs
|
||||
Source: "{#BuildDir}/src/lite-xl.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "{#BuildDir}/mingwLibs{#Arch}/*"; DestDir: "{app}"; Flags: ignoreversion ; Check: DirExists(ExpandConstant('{#BuildDir}/mingwLibs{#Arch}'))
|
||||
Source: "{#SourceDir}/data/*"; DestDir: "{app}/data"; Flags: ignoreversion recursesubdirs
|
||||
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||
|
||||
[Icons]
|
||||
|
@ -84,78 +81,8 @@ Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}";
|
|||
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon; Check: not WizardIsTaskSelected('portablemode')
|
||||
; Name: "{usersendto}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
|
||||
|
||||
[Registry]
|
||||
Root: "HKA"; Subkey: "Software\Classes\*\shell\{#MyAppName}"; ValueType: string; ValueName: ""; ValueData: "Open with {#MyAppName}"; Flags: uninsdeletekey
|
||||
Root: "HKA"; Subkey: "Software\Classes\*\shell\{#MyAppName}"; ValueType: string; ValueName: "Icon"; ValueData: "{app}\{#MyAppExeName}, 0"; Flags: uninsdeletekey
|
||||
Root: "HKA"; Subkey: "Software\Classes\*\shell\{#MyAppName}\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExename}"" ""%1"""; Flags: uninsdeletekey
|
||||
Root: "HKA"; Subkey: "Software\Classes\directory\shell\{#MyAppName}"; ValueType: string; ValueName: ""; ValueData: "Open with {#MyAppName}"; Flags: uninsdeletekey
|
||||
Root: "HKA"; Subkey: "Software\Classes\directory\shell\{#MyAppName}"; ValueType: string; ValueName: "Icon"; ValueData: "{app}\{#MyAppExeName}, 0"; Flags: uninsdeletekey
|
||||
Root: "HKA"; Subkey: "Software\Classes\directory\shell\{#MyAppName}\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExename}"" ""%1"""; Flags: uninsdeletekey
|
||||
Root: "HKA"; Subkey: "Software\Classes\directory\background\shell\{#MyAppName}"; ValueType: string; ValueName: ""; ValueData: "Open with {#MyAppName}"; Flags: uninsdeletekey
|
||||
Root: "HKA"; Subkey: "Software\Classes\directory\background\shell\{#MyAppName}"; ValueType: string; ValueName: "Icon"; ValueData: "{app}\{#MyAppExeName}, 0"; Flags: uninsdeletekey
|
||||
Root: "HKA"; Subkey: "Software\Classes\directory\background\shell\{#MyAppName}\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExename}"" ""%V"""; Flags: uninsdeletekey
|
||||
|
||||
[Run]
|
||||
Filename: "{app}/{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
|
||||
|
||||
[Setup]
|
||||
Uninstallable=not WizardIsTaskSelected('portablemode')
|
||||
|
||||
; Code to add installation path to environment taken from:
|
||||
; https://stackoverflow.com/a/46609047
|
||||
[Code]
|
||||
const EnvironmentKey = 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment';
|
||||
|
||||
procedure EnvAddPath(Path: string);
|
||||
var
|
||||
Paths: string;
|
||||
begin
|
||||
{ Retrieve current path (use empty string if entry not exists) }
|
||||
if not RegQueryStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths)
|
||||
then Paths := '';
|
||||
|
||||
{ Skip if string already found in path }
|
||||
if Pos(';' + Uppercase(Path) + ';', ';' + Uppercase(Paths) + ';') > 0 then exit;
|
||||
|
||||
{ App string to the end of the path variable }
|
||||
Paths := Paths + ';'+ Path +';'
|
||||
|
||||
{ Overwrite (or create if missing) path environment variable }
|
||||
if RegWriteStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths)
|
||||
then Log(Format('The [%s] added to PATH: [%s]', [Path, Paths]))
|
||||
else Log(Format('Error while adding the [%s] to PATH: [%s]', [Path, Paths]));
|
||||
end;
|
||||
|
||||
procedure EnvRemovePath(Path: string);
|
||||
var
|
||||
Paths: string;
|
||||
P: Integer;
|
||||
begin
|
||||
{ Skip if registry entry not exists }
|
||||
if not RegQueryStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths) then
|
||||
exit;
|
||||
|
||||
{ Skip if string not found in path }
|
||||
P := Pos(';' + Uppercase(Path) + ';', ';' + Uppercase(Paths) + ';');
|
||||
if P = 0 then exit;
|
||||
|
||||
{ Update path variable }
|
||||
Delete(Paths, P - 1, Length(Path) + 1);
|
||||
|
||||
{ Overwrite path environment variable }
|
||||
if RegWriteStringValue(HKEY_LOCAL_MACHINE, EnvironmentKey, 'Path', Paths)
|
||||
then Log(Format('The [%s] removed from PATH: [%s]', [Path, Paths]))
|
||||
else Log(Format('Error while removing the [%s] from PATH: [%s]', [Path, Paths]));
|
||||
end;
|
||||
|
||||
procedure CurStepChanged(CurStep: TSetupStep);
|
||||
begin
|
||||
if (CurStep = ssPostInstall) and WizardIsTaskSelected('envPath')
|
||||
then EnvAddPath(ExpandConstant('{app}'));
|
||||
end;
|
||||
|
||||
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
|
||||
begin
|
||||
if CurUninstallStep = usPostUninstall
|
||||
then EnvRemovePath(ExpandConstant('{app}'));
|
||||
end;
|
||||
|
|
|
@ -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=$#
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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; }
|
|
@ -36,6 +36,7 @@ typedef wchar_t *process_env_t;
|
|||
|
||||
#define HANDLE_INVALID (INVALID_HANDLE_VALUE)
|
||||
#define PROCESS_GET_HANDLE(P) ((P)->process_information.hProcess)
|
||||
#define PROCESS_ARGLIST_INITIALIZER { 0 }
|
||||
|
||||
static volatile long PipeSerialNumber;
|
||||
|
||||
|
@ -49,6 +50,7 @@ typedef char **process_env_t;
|
|||
|
||||
#define HANDLE_INVALID (0)
|
||||
#define PROCESS_GET_HANDLE(P) ((P)->pid)
|
||||
#define PROCESS_ARGLIST_INITIALIZER NULL
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -437,6 +439,7 @@ static int process_arglist_add(process_arglist_t *list, size_t *list_len, const
|
|||
|
||||
|
||||
static void process_arglist_free(process_arglist_t *list) {
|
||||
if (!*list) return;
|
||||
#ifndef _WIN32
|
||||
char **cmd = *list;
|
||||
for (int i = 0; cmd[i]; i++)
|
||||
|
@ -560,14 +563,13 @@ static int process_env_add(process_env_t *env_list, size_t *env_len, const char
|
|||
}
|
||||
|
||||
|
||||
static void process_env_free(process_env_t *list) {
|
||||
static void process_env_free(process_env_t *list, size_t list_len) {
|
||||
if (!*list) return;
|
||||
#ifdef _WIN32
|
||||
free(*list);
|
||||
#else
|
||||
for (size_t i = 0; (*list)[i]; i++) free((*list)[i]);
|
||||
free(*list);
|
||||
#ifndef _WIN32
|
||||
for (size_t i = 0; i < list_len; i++)
|
||||
free((*list)[i]);
|
||||
#endif
|
||||
free(*list);
|
||||
*list = NULL;
|
||||
}
|
||||
|
||||
|
@ -575,7 +577,8 @@ static void process_env_free(process_env_t *list) {
|
|||
static int process_start(lua_State* L) {
|
||||
int r, retval = 1;
|
||||
size_t env_len = 0, cmd_len = 0, arglist_len = 0, env_vars_len = 0;
|
||||
process_arglist_t arglist;
|
||||
process_t *self = NULL;
|
||||
process_arglist_t arglist = PROCESS_ARGLIST_INITIALIZER;
|
||||
process_env_t env_vars = NULL;
|
||||
const char *cwd = NULL;
|
||||
bool detach = false, escape = true;
|
||||
|
@ -665,7 +668,7 @@ static int process_start(lua_State* L) {
|
|||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
process_t* self = lua_newuserdata(L, sizeof(process_t));
|
||||
self = lua_newuserdata(L, sizeof(process_t));
|
||||
memset(self, 0, sizeof(process_t));
|
||||
luaL_setmetatable(L, API_TYPE_PROCESS);
|
||||
self->deadline = deadline;
|
||||
|
@ -823,14 +826,16 @@ static int process_start(lua_State* L) {
|
|||
if (control_pipe[0]) close(control_pipe[0]);
|
||||
if (control_pipe[1]) close(control_pipe[1]);
|
||||
#endif
|
||||
for (int stream = 0; stream < 3; ++stream) {
|
||||
process_stream_t* pipe = &self->child_pipes[stream][stream == STDIN_FD ? 0 : 1];
|
||||
if (*pipe) {
|
||||
close_fd(pipe);
|
||||
if (self) {
|
||||
for (int stream = 0; stream < 3; ++stream) {
|
||||
process_stream_t* pipe = &self->child_pipes[stream][stream == STDIN_FD ? 0 : 1];
|
||||
if (*pipe) {
|
||||
close_fd(pipe);
|
||||
}
|
||||
}
|
||||
}
|
||||
process_arglist_free(&arglist);
|
||||
process_env_free(&env_vars);
|
||||
process_env_free(&env_vars, env_vars_len);
|
||||
|
||||
if (retval == -1)
|
||||
return lua_error(L);
|
||||
|
@ -846,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;
|
||||
|
|
|
@ -1150,6 +1150,26 @@ static int f_text_input(lua_State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int f_setenv(lua_State* L) {
|
||||
const char *key = luaL_checkstring(L, 1);
|
||||
const char *val = luaL_checkstring(L, 2);
|
||||
|
||||
int ok;
|
||||
#ifdef _WIN32
|
||||
LPWSTR wkey = utfconv_utf8towc(key);
|
||||
LPWSTR wval = utfconv_utf8towc(val);
|
||||
ok = (wkey && wval) ? SetEnvironmentVariableW(wkey, wval)
|
||||
/* utfconv error */ : 0;
|
||||
free(wkey); free(wval);
|
||||
#else
|
||||
// right now we overwrite unconditionally
|
||||
// this could be expanded later as an optional 3rd boolean argument
|
||||
ok = !setenv(key, val, 1);
|
||||
#endif
|
||||
lua_pushboolean(L, ok);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static const luaL_Reg lib[] = {
|
||||
{ "poll_event", f_poll_event },
|
||||
|
@ -1185,6 +1205,7 @@ static const luaL_Reg lib[] = {
|
|||
{ "path_compare", f_path_compare },
|
||||
{ "get_fs_type", f_get_fs_type },
|
||||
{ "text_input", f_text_input },
|
||||
{ "setenv", f_setenv },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -508,7 +508,7 @@ RenWindow* ren_init(SDL_Window *win) {
|
|||
fprintf(stderr, "internal font error when starting the application\n");
|
||||
return NULL;
|
||||
}
|
||||
RenWindow* window_renderer = malloc(sizeof(RenWindow));
|
||||
RenWindow* window_renderer = calloc(1, sizeof(RenWindow));
|
||||
|
||||
window_renderer->window = win;
|
||||
renwin_init_surface(window_renderer);
|
||||
|
|
Loading…
Reference in New Issue