diff --git a/.gitignore b/.gitignore index 75dec714..1625829e 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,8 @@ compile_commands.json error.txt lite-xl* LiteXL* +lite +.config/ +*.lha +release_files +*.o diff --git a/Makefile.os4 b/Makefile.os4 new file mode 100644 index 00000000..16b1f414 --- /dev/null +++ b/Makefile.os4 @@ -0,0 +1,81 @@ +# +# Project: Lite XL +# +# Created on: 26-12-2021 +# + +LiteXL_OBJ := \ + src/dirmonitor.o src/main.o src/rencache.o src/renderer.o \ + src/renwindow.o src/api/api.o src/api/regex.o \ + src/api/renderer.o src/api/system.o src/platform/amigaos4.o + + +outfile := lite +compiler := gcc +cxxcompiler := g++ + +INCPATH := -Isrc -Ilib/dmon -I/sdk/local/newlib/include/SDL2 -I/sdk/local/common/include/freetype2 +DFLAGS := -D__USE_INLINE__ -DLITE_XL_DATA_USE_EXEDIR +# -DLITE_USE_SDL_RENDERER +# -Wextra -Wall +CFLAGS := -Werror -Wwrite-strings -O3 -g -std=gnu11 -fno-strict-aliasing +# "-gstabs -finstrument-functions -fno-inline -DPROFILING" +LFLAGS := -mcrt=newlib -static-libgcc -static-libstdc++ -lauto -lpcre2 -lSDL2 -llua -lagg -lfreetype -lm -lunix -lpthread -athread=native +# " -lprofyle" + + + +.PHONY: LiteXL clean release + +default: LiteXL + +clean: + @echo "Cleaning compiler objects..." + @rm -f $(LiteXL_OBJ) + +LiteXL: $(LiteXL_OBJ) + @echo "Linking LiteXL" + @$(cxxcompiler) -o $(outfile) $(LiteXL_OBJ) $(LFLAGS) + + + +.c.o: + @echo "Compiling $<" + @$(compiler) -c $< -o $*.o $(CFLAGS) $(INCPATH) $(DFLAGS) + +src/dirmonitor.o: src/dirmonitor.c src/platform/amigaos4.h + +src/main.o: src/main.c src/api/api.h src/rencache.h \ + src/renderer.h src/platform/amigaos4.h src/dirmonitor.h + +src/rencache.o: src/rencache.c + +src/renderer.o: src/renderer.c + +src/renwindow.o: src/renwindow.c + +src/api/api.o: src/api/api.c + +src/api/regex.o: src/api/regex.c + +src/api/renderer.o: src/api/renderer.c + +src/api/system.o: src/api/system.c + +src/platform/amigaos4.o: src/platform/amigaos4.c + + + + +release: + mkdir -p release/LiteXL + cp release_files/* release/LiteXL/ -r + mv release/LiteXL/LiteXL.info release/ + cp data release/LiteXL/ -r + cp changelog.md release/LiteXL/ + cp lite release/LiteXL/ + strip release/LiteXL/lite + cp README.md release/LiteXL/ + cp README_OS4.md release/LiteXL/ + cp LICENSE release/LiteXL/ + lha -aeqr3 a LiteXL.lha release/ diff --git a/README_OS4.md b/README_OS4.md new file mode 100644 index 00000000..5aea7b79 --- /dev/null +++ b/README_OS4.md @@ -0,0 +1,169 @@ +# Lite XL v2.1 for AmigaOS 4.1 FE + +Lite XL is a lightweight text editor written in Lua. + +## Installation +You can extract the Lite XL archive wherever you want and run the *lite* +editor. + +## Configuration folder +This editor creates a `.config` folder where the configuration is saved, as +well as plugins, themes etc.. By default this AmigaOS 4.1 FE version uses the +executable folder, but if you want to ovveride it, create an ENV variable +named `HOME` and set there your path. + +You can check if there is one already set by executing the following command +in a shell +``` +GetEnv HOME +``` +If there is one set, then you will see the path at the output. + +Otherwise, you can set your home path be executing the following command. +Change the path to the one of your preference. +``` +SetEnv SAVE HOME "Sys:home/" +``` + +## Addons +### Colors +Colors are lua files that set the color scheme of the editor. There are +light and dark themes for you to choose. + +To install and use them you have to copy the ones you would like from +`addons/colors/light` or `addons/colors/dark` into the folder +`.config/lite-xl/colors/`. Don't add light or dark folders. Just copy the +.lua files in there. + +Then you have to start Lite XL and open your configuration by clicking +at the cog icon at the toolbar (bottom left sixth icon). Go at the line +that looks like below +``` +-- core.reload_module("colors.summer") +``` +and change the `summer` with the name of your color theme. Also, remove +the two dashes `--` at the start of the line and save the file. If you +did everything right, the color schema should change instantly. + +The themes can also be found at +https://github.com/lite-xl/lite-xl-colors + +### Plugins +The Lite XL that you are using on AmigaOS 4 is based on version 1.16.12 +and not the latest version that is available by the development team. +This means that the latest plugins are not working at all or need some +modifications to work. + +To make it easier for you, I gathered some of the plugins that are working +well, and I included them at the `addons/plugins`. For you to install the +ones you would like to use, you have to copy the `.lua` files into the +folder `.config/lite-xl/plugins/` and restart the editor. + +The included plugins are the following: + +**autoinsert** +Automatically inserts closing brackets and quotes. Also allows selected + text to be wrapped with brackets or quotes. + +**autowrap** +Automatically hardwraps lines when typing + +**bigclock** +Shows the current time and date in a view with large text + +**bracketmatch** +Underlines matching pair for bracket under the caret + +**colorpreview** +Underlays color values (eg. `#ff00ff` or `rgb(255, 0, 255)`) with their +resultant color. + +**eofnewline-xl** +Make sure the file ends with one blank line. + +**ephemeral_tabs** +Preview tabs. Opening a doc will replace the contents of the preview tab. +Marks tabs as non-preview on any change or tab double clicking. + +**ghmarkdown** +Opens a preview of the current markdown file in a browser window + +**indentguide** +Adds indent guides + +**language_make** +Syntax for the Make build system language + +**language_sh** +Syntax for shell scripting language + +**lfautoinsert** +Automatically inserts indentation and closing bracket/text after newline + +**markers** +Add markers to docs and jump between them quickly + +**navigate** +Allows moving back and forward between document positions, reducing the +amount of scrolling + +**rainbowparen** +Show nesting of parentheses with rainbow colours + +**restoretabs** +Keep a list of recently closed tabs, and restore the tab in order on +cntrl+shift+t. + +**selectionhighlight** +Highlights regions of code that match the current selection + +## Tips and tricks + +### Transitions + +If you want to disable the transitions and make the scrolling a little faster, +open your configuration by clicking at the cog icon at the toolbar +(bottom left sixth icon) and add the followline at the end of the file and +save it. + +``` +config.transitions = false +``` + +### Hide files from the file list + +If you would like to hide files or whole folder from the left side bar list, +open your configuration by clicking at the cog icon at the toolbar +(bottom left sixth icon) and add the followline at the end of the file and +save it. This hides all the files that start with a dot, and all the `.info` +files. + +``` +config.ignore_files = {"^%.", "%.info$"} +``` + +You can add as many rules as you want in there, to hide fore files or +folders, as you like. + + +## Know issues +You can find the known issues at +https://git.walkero.gr/walkero/lite-xl/issues + + +# Changelog + +## [2.1r1] - 2022-03-27 +### Changed +- Synced with master-v2.1 tag of lite-xl official github page +- Applied all the necessary changes to make it run under AmigaOS 4.1 FE + +## [2.0.5r1] - 2022-03-27 +### Changed +- Synced with v2.0.5 tag of lite-xl official github page +- Applied all the necessary changes to make it run under AmigaOS 4.1 FE + +## [2.0.3.1] - 2022-01-18 +### Changed +- Applied all the necessary changes to make it run under AmigaOS 4.1 FE + diff --git a/README_OS4.md.info b/README_OS4.md.info new file mode 100644 index 00000000..cfd4ecb5 Binary files /dev/null and b/README_OS4.md.info differ diff --git a/data/core/init.lua b/data/core/init.lua index 31462e39..fb2ea30b 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -727,7 +727,7 @@ function core.init() local plugins_success, plugins_refuse_list = core.load_plugins() do - local pdir, pname = project_dir_abs:match("(.*)[/\\\\](.*)") + local pdir, pname = project_dir_abs:match("(.*)[:/\\\\](.*)") core.log("Opening project %q from directory %s", pname, pdir) end diff --git a/data/core/keymap.lua b/data/core/keymap.lua index 6716fca9..74a24562 100644 --- a/data/core/keymap.lua +++ b/data/core/keymap.lua @@ -7,9 +7,10 @@ keymap.map = {} keymap.reverse_map = {} local macos = PLATFORM == "Mac OS X" +local os4 = PLATFORM == "AmigaOS 4" -- Thanks to mathewmariani, taken from his lite-macos github repository. -local modkeys_os = require("core.modkeys-" .. (macos and "macos" or "generic")) +local modkeys_os = require("core.modkeys-" .. (macos and "macos" or os4 and "os4" or "generic")) local modkey_map = modkeys_os.map local modkeys = modkeys_os.keys diff --git a/data/core/modkeys-os4.lua b/data/core/modkeys-os4.lua new file mode 100644 index 00000000..45522e66 --- /dev/null +++ b/data/core/modkeys-os4.lua @@ -0,0 +1,15 @@ +local modkeys = {} + +modkeys.map = { + ["left amiga"] = "cmd", + ["right amiga"] = "cmd", + ["control"] = "ctrl", + ["left shift"] = "shift", + ["right shift"] = "shift", + ["left alt"] = "alt", + ["right alt"] = "altgr", +} + +modkeys.keys = { "cmd", "ctrl", "alt", "altgr", "shift" } + +return modkeys diff --git a/data/core/start.lua b/data/core/start.lua index dfddcbda..7d0568f1 100644 --- a/data/core/start.lua +++ b/data/core/start.lua @@ -1,5 +1,5 @@ -- this file is used by lite-xl to setup the Lua environment when starting -VERSION = "@PROJECT_VERSION@" +VERSION = "2.1beta" MOD_VERSION = "3" SCALE = tonumber(os.getenv("LITE_SCALE") or os.getenv("GDK_SCALE") or os.getenv("QT_SCALE_FACTOR")) or SCALE diff --git a/src/api/api.c b/src/api/api.c index 1a6e516d..c0a8dec1 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -3,15 +3,15 @@ int luaopen_system(lua_State *L); int luaopen_renderer(lua_State *L); int luaopen_regex(lua_State *L); -int luaopen_process(lua_State *L); -int luaopen_dirmonitor(lua_State* L); +// int luaopen_process(lua_State *L); +// int luaopen_dirmonitor(lua_State* L); static const luaL_Reg libs[] = { { "system", luaopen_system }, { "renderer", luaopen_renderer }, { "regex", luaopen_regex }, - { "process", luaopen_process }, - { "dirmonitor", luaopen_dirmonitor }, + // { "process", luaopen_process }, + // { "dirmonitor", luaopen_dirmonitor }, { NULL, NULL } }; diff --git a/src/api/system.c b/src/api/system.c index f1f9c3c7..4b522def 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -7,13 +7,15 @@ #include #include #include "api.h" -#include "../rencache.h" +#include "rencache.h" #ifdef _WIN32 #include #include #include #elif __linux__ #include +#elif __amigaos4__ + #include "platform/amigaos4.h" #endif extern SDL_Window *window; @@ -320,7 +322,11 @@ static int f_set_window_mode(lua_State *L) { int n = luaL_checkoption(L, 1, "normal", window_opts); SDL_SetWindowFullscreen(window, n == WIN_FULLSCREEN ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); - if (n == WIN_NORMAL) { SDL_RestoreWindow(window); } + if (n == WIN_NORMAL) + { + ren_resize_window(); + SDL_RestoreWindow(window); + } if (n == WIN_MAXIMIZED) { SDL_MaximizeWindow(window); } if (n == WIN_MINIMIZED) { SDL_MinimizeWindow(window); } return 0; @@ -501,6 +507,9 @@ static int f_list_dir(lua_State *L) { #include #define realpath(x, y) _fullpath(y, x, MAX_PATH) #endif +#ifdef __amigaos4__ + #define realpath(x, y) _fullpath(x) +#endif static int f_absolute_path(lua_State *L) { const char *path = luaL_checkstring(L, 1); diff --git a/src/main.c b/src/main.c index 94d2674b..16c79336 100644 --- a/src/main.c +++ b/src/main.c @@ -12,6 +12,8 @@ #include #elif __APPLE__ #include +#elif __amigaos4__ + #include "platform/amigaos4.h" #endif @@ -43,6 +45,8 @@ static void get_exe_filename(char *buf, int sz) { char exepath[size]; _NSGetExecutablePath(exepath, &size); realpath(exepath, buf); +#elif __amigaos4__ + strcpy(buf, _fullpath("./lite")); #else strcpy(buf, "./lite"); #endif @@ -109,6 +113,7 @@ int main(int argc, char **argv) { window = SDL_CreateWindow( "", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, dm.w * 0.8, dm.h * 0.8, SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_HIDDEN); + SDL_SetWindowDisplayMode(window, &dm); init_window_icon(); ren_init(window); @@ -150,6 +155,9 @@ init_lua: " HOME = os.getenv('" LITE_OS_HOME "')\n" " local exedir = EXEFILE:match('^(.*)" LITE_PATHSEP_PATTERN LITE_NONPATHSEP_PATTERN "$')\n" " local prefix = exedir:match('^(.*)" LITE_PATHSEP_PATTERN "bin$')\n" + " if not HOME then\n" + " HOME = exedir\n" + " end\n" " dofile((MACOS_RESOURCES or (prefix and prefix .. '/share/lite-xl' or exedir .. '/data')) .. '/core/start.lua')\n" " core = require(os.getenv('LITE_XL_RUNTIME') or 'core')\n" " core.init()\n" diff --git a/src/platform/amigaos4.c b/src/platform/amigaos4.c new file mode 100644 index 00000000..fd53bd2f --- /dev/null +++ b/src/platform/amigaos4.c @@ -0,0 +1,61 @@ + +#include +#include +#include + +#include "amigaos4.h" + +static char *getFullPath(const char *path) +{ + char *appPath = malloc(sizeof(char) * MAX_DOS_NAME); + BPTR pathLock = Lock(path, SHARED_LOCK); + if (pathLock) + { + NameFromLock(pathLock, appPath, sizeof(char) * MAX_DOS_NAME); + UnLock(pathLock); + + return appPath; + } + return NULL; +} + +static char *getCurrentPath(void) +{ + char *appPath = malloc(sizeof(char) * MAX_DOS_NAME); + BPTR pathLock = GetCurrentDir(); + if (pathLock) + { + NameFromLock(pathLock, appPath, sizeof(char) * MAX_DOS_NAME); + return appPath; + } + return NULL; +} + +char *_fullpath(const char *path) +{ + static char prvPath[MAX_DOS_NAME]; + static char result[MAX_DOS_NAME]; + + if (!strcmp(path, prvPath)) + { + return result; + } + + strcpy(prvPath, path); + + if (!strcmp(path, "./lite")) + { + // TODO: Add code to get the name of the executable + strcpy(result, getFullPath("PROGDIR:lite")); + return result; + } + + if (!strcmp(path, ".")) + { + strcpy(result, getCurrentPath()); + return result; + } + + strcpy(result, getFullPath(path)); + return result; +} diff --git a/src/platform/amigaos4.h b/src/platform/amigaos4.h new file mode 100644 index 00000000..a2567b61 --- /dev/null +++ b/src/platform/amigaos4.h @@ -0,0 +1,16 @@ +#ifndef _AMIGAOS4_H +#define _AMIGAOS4_H + +#include +#include + +#define VSTRING "Lite XL OS4 2.1beta (27.03.2022)" +#define VERSTAG "\0$VER: " VSTRING + +static CONST_STRPTR stack USED = "$STACK:102400"; +static CONST_STRPTR version USED = VERSTAG; + +char *_fullpath(const char *); + + +#endif diff --git a/src/renderer.c b/src/renderer.c index c2fa233e..307c3194 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -36,7 +36,7 @@ typedef struct { typedef struct { SDL_Surface* surface; - GlyphMetric metrics[MAX_GLYPHSET]; + GlyphMetric metrics[MAX_GLYPHSET]; } GlyphSet; typedef struct RenFont { @@ -67,7 +67,7 @@ static const char* utf8_to_codepoint(const char *p, unsigned *dst) { } static int font_set_load_options(RenFont* font) { - int load_target = font->antialiasing == FONT_ANTIALIASING_NONE ? FT_LOAD_TARGET_MONO + int load_target = font->antialiasing == FONT_ANTIALIASING_NONE ? FT_LOAD_TARGET_MONO : (font->hinting == FONT_HINTING_SLIGHT ? FT_LOAD_TARGET_LIGHT : FT_LOAD_TARGET_NORMAL); int hinting = font->hinting == FONT_HINTING_NONE ? FT_LOAD_NO_HINTING : FT_LOAD_FORCE_AUTOHINT; return load_target | hinting; @@ -144,7 +144,7 @@ static void font_load_glyphset(RenFont* font, int idx) { FT_GlyphSlot slot = font->face->glyph; font_set_style(&slot->outline, (64 / bitmaps_cached) * j, font->style); if (FT_Render_Glyph(slot, render_option)) - continue; + continue; for (int line = 0; line < slot->bitmap.rows; ++line) { int target_offset = set->surface->pitch * line + set->metrics[i].x0 * byte_width; int source_offset = line * slot->bitmap.pitch; @@ -202,7 +202,7 @@ RenFont* ren_font_load(const char* path, float size, ERenFontAntialiasing antial font->space_advance = font_get_glyphset(font, ' ', 0)->metrics[' '].xadvance; font->tab_advance = font->space_advance * 2; return font; - failure: + failure: FT_Done_Face(face); return NULL; } @@ -227,7 +227,7 @@ void ren_font_free(RenFont* font) { void ren_font_group_set_tab_size(RenFont **fonts, int n) { for (int j = 0; j < FONT_FALLBACK_MAX && fonts[j]; ++j) { - for (int i = 0; i < (fonts[j]->antialiasing == FONT_ANTIALIASING_SUBPIXEL ? SUBPIXEL_BITMAPS_CACHED : 1); ++i) + for (int i = 0; i < (fonts[j]->antialiasing == FONT_ANTIALIASING_SUBPIXEL ? SUBPIXEL_BITMAPS_CACHED : 1); ++i) font_get_glyphset(fonts[j], '\t', i)->metrics['\t'].xadvance = fonts[j]->space_advance * n; } } @@ -268,11 +268,11 @@ float ren_draw_text(RenFont **fonts, const char *text, float x, int y, RenColor const char* end = text + strlen(text); unsigned char* destination_pixels = surface->pixels; int clip_end_x = clip.x + clip.width, clip_end_y = clip.y + clip.height; - + while (text < end) { unsigned int codepoint, r, g, b; text = utf8_to_codepoint(text, &codepoint); - GlyphSet* set = NULL; GlyphMetric* metric = NULL; + GlyphSet* set = NULL; GlyphMetric* metric = NULL; RenFont* font = font_group_get_glyph(&set, &metric, fonts, codepoint, (int)(fmod(pen_x, 1.0) * SUBPIXEL_BITMAPS_CACHED)); int start_x = floor(pen_x) + metric->bitmap_left; int end_x = (metric->x1 - metric->x0) + start_x; @@ -344,8 +344,14 @@ void ren_draw_rect(RenRect rect, RenColor color) { SDL_Surface *surface = renwin_get_surface(&window_renderer); uint32_t *d = surface->pixels; + #ifdef __amigaos4__ + d += x1 + y1 * surface->pitch/sizeof(uint32_t); + int dr = surface->pitch/sizeof(uint32_t) - (x2 - x1); + #else d += x1 + y1 * surface->w; int dr = surface->w - (x2 - x1); + #endif + if (color.a == 0xff) { uint32_t translated = SDL_MapRGB(surface->format, color.r, color.g, color.b); SDL_Rect rect = { x1, y1, x2 - x1, y2 - y1 }; diff --git a/src/renwindow.c b/src/renwindow.c index f67002f8..c4dc5b72 100644 --- a/src/renwindow.c +++ b/src/renwindow.c @@ -9,6 +9,18 @@ static int query_surface_scale(RenWindow *ren) { SDL_GetWindowSize(ren->window, &w_points, &h_points); /* We consider that the ratio pixel/point will always be an integer and it is the same along the x and the y axis. */ + + #ifdef __amigaos4__ + // This is a workaround when the w_pixels != w_points and h_pixels != h_points + // because of redraw delays, especially when the "Resize with contents" is enabled + if (w_pixels != w_points) { + w_pixels = w_points; + } + if (h_pixels != h_points) { + h_pixels = h_points; + } + #endif + assert(w_pixels % w_points == 0 && h_pixels % h_points == 0 && w_pixels / w_points == h_pixels / h_points); return w_pixels / w_points; } @@ -20,7 +32,7 @@ static void setup_renderer(RenWindow *ren, int w, int h) { SDL_DestroyTexture(ren->texture); SDL_DestroyRenderer(ren->renderer); } - ren->renderer = SDL_CreateRenderer(ren->window, -1, 0); + ren->renderer = SDL_CreateRenderer(ren->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); ren->texture = SDL_CreateTexture(ren->renderer, SDL_PIXELFORMAT_BGRA32, SDL_TEXTUREACCESS_STREAMING, w, h); ren->surface_scale = query_surface_scale(ren); }