From 4d5f28adc94efaf39fd396e4df6d8d7af01f54d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Wed, 30 Oct 2024 01:31:19 -0300 Subject: [PATCH 01/30] Fix upload artifacts tag name. --- .github/workflows/ecode-release.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ecode-release.yml b/.github/workflows/ecode-release.yml index 0ae040bfc..d4b934129 100644 --- a/.github/workflows/ecode-release.yml +++ b/.github/workflows/ecode-release.yml @@ -105,7 +105,7 @@ jobs: uses: softprops/action-gh-release@v2 with: repository: SpartanJ/ecode - tag_name: ${{ needs.release.outputs.version }} + tag_name: ecode-${{ needs.release.outputs.version }} draft: false prerelease: true files: | @@ -169,7 +169,7 @@ jobs: uses: softprops/action-gh-release@v2 with: repository: SpartanJ/ecode - tag_name: ${{ needs.release.outputs.version }} + tag_name: ecode-${{ needs.release.outputs.version }} draft: false prerelease: true files: | @@ -227,7 +227,7 @@ jobs: uses: softprops/action-gh-release@v2 with: repository: SpartanJ/ecode - tag_name: ${{ needs.release.outputs.version }} + tag_name: ecode-${{ needs.release.outputs.version }} draft: false prerelease: true files: | @@ -271,7 +271,7 @@ jobs: - name: Upload Files uses: softprops/action-gh-release@v2 with: - tag_name: ${{ needs.release.outputs.version }} + tag_name: ecode-${{ needs.release.outputs.version }} draft: false prerelease: true files: | @@ -319,7 +319,7 @@ jobs: uses: softprops/action-gh-release@v2 with: repository: SpartanJ/ecode - tag_name: ${{ needs.release.outputs.version }} + tag_name: ecode-${{ needs.release.outputs.version }} draft: false prerelease: true files: | @@ -371,7 +371,7 @@ jobs: uses: softprops/action-gh-release@v2 with: repository: SpartanJ/ecode - tag_name: ${{ needs.release.outputs.version }} + tag_name: ecode-${{ needs.release.outputs.version }} draft: false prerelease: true files: | From c3a77db52341593c88fe48f7e37284b5511eb671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sun, 3 Nov 2024 13:26:29 -0300 Subject: [PATCH 02/30] Prepare new release. --- .github/workflows/ecode-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ecode-release.yml b/.github/workflows/ecode-release.yml index d4b934129..9fe7b2e7e 100644 --- a/.github/workflows/ecode-release.yml +++ b/.github/workflows/ecode-release.yml @@ -9,7 +9,7 @@ on: inputs: version: description: Release Version - default: ecode-0.6.2 + default: ecode-0.6.3 required: true permissions: write-all From e8852bcf6f445da92e57c813f591bc423e8b54fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Fri, 22 Nov 2024 23:44:55 -0300 Subject: [PATCH 03/30] Upgrade SDL2. --- .github/workflows/ecode-release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ecode-release.yml b/.github/workflows/ecode-release.yml index 9fe7b2e7e..ea5b9c3a9 100644 --- a/.github/workflows/ecode-release.yml +++ b/.github/workflows/ecode-release.yml @@ -357,8 +357,8 @@ jobs: - name: Install Dependencies run: | brew install bash create-dmg premake p7zip - curl -OL https://github.com/libsdl-org/SDL/releases/download/release-2.30.8/SDL2-2.30.8.dmg - hdiutil attach SDL2-2.30.8.dmg + curl -OL https://github.com/libsdl-org/SDL/releases/download/release-2.30.9/SDL2-2.30.9.dmg + hdiutil attach SDL2-2.30.9.dmg sudo cp -r /Volumes/SDL2/SDL2.framework /Library/Frameworks/ hdiutil detach /Volumes/SDL2 - name: Build From f6f65904cbca9f2f5e694644c7ce2d8febb33ed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sat, 23 Nov 2024 16:11:07 -0300 Subject: [PATCH 04/30] Update README.md. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ff71940eb..703579cd9 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,7 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | javascript | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | [eslint](https://eslint.org) | [prettier](https://prettier.io) | | javascriptreact | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | None | None | | json | ✓ | None | [jq](https://stedolan.github.io/jq/) | [native](#native) | -| julia | ✓ | None | None | None | +| julia | ✓ | [LanguageServer.jl](https://github.com/julia-vscode/LanguageServer.jl) | None | None | | kotlin | ✓ | [kotlin-language-server](https://github.com/fwcd/kotlin-language-server) | [ktlint](https://pinterest.github.io/ktlint/) | [ktlint](https://pinterest.github.io/ktlint/) | | latex | ✓ | [texlab](https://github.com/latex-lsp) | None | None | | lobster | ✓ | None | None | None | @@ -185,6 +185,7 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | nim | ✓ | [nimlsp](https://github.com/PMunch/nimlsp) | [nim](https://nim-lang.org) | None | | objeck | ✓ | None | None | None | | objective-c | ✓ | [clangd](https://clangd.llvm.org/) | None | [clang-format](https://clang.llvm.org/docs/ClangFormat.html) | +| ocaml | ✓ | [OCaml-LSP](https://github.com/ocaml/ocaml-lsp) | None | None | | odin | ✓ | [ols](https://github.com/DanielGavin/ols) | None | None | | pascal | ✓ | None | None | None | | perl | ✓ | None | None | None | From e85775bfdffc1f9871bddcbf306d03fda83e607e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Fri, 29 Nov 2024 00:18:29 -0300 Subject: [PATCH 05/30] Update language list. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 703579cd9..169323d87 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,7 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | angelscript | ✓ | None | None | None | | awk script | ✓ | None | None | None | | bat | ✓ | None | None | None | +| bazel | ✓ | None | None | None | | bend | ✓ | None | None | None | | blueprint | ✓ | None | None | None | | brainfuck | ✓ | None | None | None | @@ -187,6 +188,7 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | objective-c | ✓ | [clangd](https://clangd.llvm.org/) | None | [clang-format](https://clang.llvm.org/docs/ClangFormat.html) | | ocaml | ✓ | [OCaml-LSP](https://github.com/ocaml/ocaml-lsp) | None | None | | odin | ✓ | [ols](https://github.com/DanielGavin/ols) | None | None | +| openscad | ✓ | None | None | None | | pascal | ✓ | None | None | None | | perl | ✓ | None | None | None | | php | ✓ | [phpactor](https://phpactor.readthedocs.io) | [php](https://www.php.net) | None | @@ -198,6 +200,7 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | powershell | ✓ | None | None | None | | python | ✓ | [pylsp](https://github.com/python-lsp/python-lsp-server) | [ruff](https://ruff.rs) | [black](https://black.readthedocs.io/en/stable/) | | r | ✓ | [r languageserver](https://github.com/REditorSupport/languageserver) | None | None | +| ring | ✓ | None | None | None | | ruby | ✓ | [solargraph](https://solargraph.org) | None | None | | rust | ✓ | [rust-analyzer](https://rust-analyzer.github.io) | None | [rustfmt](https://rust-lang.github.io/rustfmt/) | | sass | ✓ | [emmet-language-server](https://github.com/olrtg/emmet-language-server) | None | None | @@ -207,6 +210,7 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | solidity | ✓ | [solc](https://soliditylang.org) | [solhint](https://protofire.github.io/solhint/) | None | | sql | ✓ | None | None | None | | swift | ✓ | [sourcekit-lsp](https://github.com/apple/sourcekit-lsp) | None | None | +| tcl | ✓ | None | None | None | | teal | ✓ | None | [tl](https://github.com/teal-language/tl) | None | | toml | ✓ | None | None | None | | typescript | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | [eslint](https://eslint.org) | [prettier](https://prettier.io) | From afe098f40f633c4c1fcff2e42a8d834c61eef73d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sun, 1 Dec 2024 15:48:28 -0300 Subject: [PATCH 06/30] Update langs. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 169323d87..9afc4cd31 100644 --- a/README.md +++ b/README.md @@ -154,7 +154,7 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | elm | ✓ | [elm-language-server](https://github.com/elm-tooling/elm-language-server) | None | None | | environment file | ✓ | None | None | None | | fantom | ✓ | None | None | None | -| fortran | ✓ | None | None | None | +| fortran | ✓ | [fortls](https://github.com/fortran-lang/fortls) | None | None | | fstab | ✓ | None | None | None | | gdscript | ✓ | None | None | None | | glsl | ✓ | [glsl_analyzer](https://github.com/nolanderc/glsl_analyzer) | None | None | @@ -190,7 +190,7 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | odin | ✓ | [ols](https://github.com/DanielGavin/ols) | None | None | | openscad | ✓ | None | None | None | | pascal | ✓ | None | None | None | -| perl | ✓ | None | None | None | +| perl | ✓ | [PerlNavigator](https://github.com/bscan/PerlNavigator) | None | None | | php | ✓ | [phpactor](https://phpactor.readthedocs.io) | [php](https://www.php.net) | None | | pico-8 | ✓ | None | None | None | | plaintext | ✓ | None | None | None | From 7d635b003172179b93487f5616661bcf7f8b8199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Fri, 27 Dec 2024 19:03:45 -0300 Subject: [PATCH 07/30] Convert color schemes from lite/lite-xl. --- tools/data-migration/lite/colors/README.md | 11 + .../lite/colors/core/common.lua | 522 ++++++++++++++++++ .../data-migration/lite/colors/core/style.lua | 5 + .../data-migration/lite/colors/lite2ecode.lua | 74 +++ tools/data-migration/lite/language/README.md | 5 - 5 files changed, 612 insertions(+), 5 deletions(-) create mode 100644 tools/data-migration/lite/colors/README.md create mode 100644 tools/data-migration/lite/colors/core/common.lua create mode 100644 tools/data-migration/lite/colors/core/style.lua create mode 100644 tools/data-migration/lite/colors/lite2ecode.lua diff --git a/tools/data-migration/lite/colors/README.md b/tools/data-migration/lite/colors/README.md new file mode 100644 index 000000000..d8d869a1c --- /dev/null +++ b/tools/data-migration/lite/colors/README.md @@ -0,0 +1,11 @@ +# Small script to migrate lite and lite-xl color schemes to ecode color schemes. + +## Usage + +You'll need to have installed lua binary, then run: + +`lua lite2ecode.lua lite_color_scheme.lua > color_scheme_name.conf` + +Then you can copy the language definition to the [ecode color schemes folder](https://github.com/SpartanJ/ecode/?tab=readme-ov-file#custom-editor-color-schemes). + +If you want to ecode support the color schemes that you're porting in the base install please [open an issue](https://github.com/SpartanJ/ecode/issues) and share the color scheme. diff --git a/tools/data-migration/lite/colors/core/common.lua b/tools/data-migration/lite/colors/core/common.lua new file mode 100644 index 000000000..b6c9db672 --- /dev/null +++ b/tools/data-migration/lite/colors/core/common.lua @@ -0,0 +1,522 @@ +local common = {} + + +function common.is_utf8_cont(s, offset) + local byte = s:byte(offset or 1) + return byte >= 0x80 and byte < 0xc0 +end + + +function common.utf8_chars(text) + return text:gmatch("[\0-\x7f\xc2-\xf4][\x80-\xbf]*") +end + + +function common.clamp(n, lo, hi) + return math.max(math.min(n, hi), lo) +end + + +function common.merge(a, b) + a = type(a) == "table" and a or {} + local t = {} + for k, v in pairs(a) do + t[k] = v + end + if b and type(b) == "table" then + for k, v in pairs(b) do + t[k] = v + end + end + return t +end + + +function common.round(n) + return n >= 0 and math.floor(n + 0.5) or math.ceil(n - 0.5) +end + + +function common.find_index(tbl, prop) + for i, o in ipairs(tbl) do + if o[prop] then return i end + end +end + + +function common.lerp(a, b, t) + if type(a) ~= "table" then + return a + (b - a) * t + end + local res = {} + for k, v in pairs(b) do + res[k] = common.lerp(a[k], v, t) + end + return res +end + + +function common.distance(x1, y1, x2, y2) + return math.sqrt(((x2-x1) ^ 2)+((y2-y1) ^ 2)) +end + + +function common.color(str) + local r, g, b, a = str:match("^#(%x%x)(%x%x)(%x%x)(%x?%x?)$") + if r then + r = tonumber(r, 16) + g = tonumber(g, 16) + b = tonumber(b, 16) + a = tonumber(a, 16) or 0xff + elseif str:match("rgba?%s*%([%d%s%.,]+%)") then + local f = str:gmatch("[%d.]+") + r = (f() or 0) + g = (f() or 0) + b = (f() or 0) + a = (f() or 1) * 0xff + else + error(string.format("bad color string '%s'", str)) + end + return r, g, b, a +end + + +function common.splice(t, at, remove, insert) + assert(remove >= 0, "bad argument #3 to 'splice' (non-negative value expected)") + insert = insert or {} + local len = #insert + if remove ~= len then table.move(t, at + remove, #t + remove, at + len) end + table.move(insert, 1, len, at, t) +end + + +local function compare_score(a, b) + return a.score > b.score +end + +local function fuzzy_match_items(items, needle, files) + local res = {} + for _, item in ipairs(items) do + local score = system.fuzzy_match(tostring(item), needle, files) + if score then + table.insert(res, { text = item, score = score }) + end + end + table.sort(res, compare_score) + for i, item in ipairs(res) do + res[i] = item.text + end + return res +end + + +function common.fuzzy_match(haystack, needle, files) + if type(haystack) == "table" then + return fuzzy_match_items(haystack, needle, files) + end + return system.fuzzy_match(haystack, needle, files) +end + + +function common.fuzzy_match_with_recents(haystack, recents, needle) + if needle == "" then + local recents_ext = {} + for i = 2, #recents do + table.insert(recents_ext, recents[i]) + end + table.insert(recents_ext, recents[1]) + local others = common.fuzzy_match(haystack, "", true) + for i = 1, #others do + table.insert(recents_ext, others[i]) + end + return recents_ext + else + return fuzzy_match_items(haystack, needle, true) + end +end + + +function common.path_suggest(text, root) + if root and root:sub(-1) ~= PATHSEP then + root = root .. PATHSEP + end + local path, name = text:match("^(.-)([^/\\]*)$") + local clean_dotslash = false + -- ignore root if path is absolute + local is_absolute = common.is_absolute_path(text) + if not is_absolute then + if path == "" then + path = root or "." + clean_dotslash = not root + else + path = (root or "") .. path + end + end + + -- Only in Windows allow using both styles of PATHSEP + if (PATHSEP == "\\" and not string.match(path:sub(-1), "[\\/]")) or + (PATHSEP ~= "\\" and path:sub(-1) ~= PATHSEP) then + path = path .. PATHSEP + end + local files = system.list_dir(path) or {} + local res = {} + for _, file in ipairs(files) do + file = path .. file + local info = system.get_file_info(file) + if info then + if info.type == "dir" then + file = file .. PATHSEP + end + if root then + -- remove root part from file path + local s, e = file:find(root, nil, true) + if s == 1 then + file = file:sub(e + 1) + end + elseif clean_dotslash then + -- remove added dot slash + local s, e = file:find("." .. PATHSEP, nil, true) + if s == 1 then + file = file:sub(e + 1) + end + end + if file:lower():find(text:lower(), nil, true) == 1 then + table.insert(res, file) + end + end + end + return res +end + + +function common.dir_path_suggest(text) + local path, name = text:match("^(.-)([^/\\]*)$") + local files = system.list_dir(path == "" and "." or path) or {} + local res = {} + for _, file in ipairs(files) do + file = path .. file + local info = system.get_file_info(file) + if info and info.type == "dir" and file:lower():find(text:lower(), nil, true) == 1 then + table.insert(res, file) + end + end + return res +end + + +function common.dir_list_suggest(text, dir_list) + local path, name = text:match("^(.-)([^/\\]*)$") + local res = {} + for _, dir_path in ipairs(dir_list) do + if dir_path:lower():find(text:lower(), nil, true) == 1 then + table.insert(res, dir_path) + end + end + return res +end + + +function common.match_pattern(text, pattern, ...) + if type(pattern) == "string" then + return text:find(pattern, ...) + end + for _, p in ipairs(pattern) do + local s, e = common.match_pattern(text, p, ...) + if s then return s, e end + end + return false +end + + +function common.draw_text(font, color, text, align, x,y,w,h) + local tw, th = font:get_width(text), font:get_height(text) + if align == "center" then + x = x + (w - tw) / 2 + elseif align == "right" then + x = x + (w - tw) + end + y = common.round(y + (h - th) / 2) + return renderer.draw_text(font, text, x, y, color), y + th +end + + +function common.bench(name, fn, ...) + local start = system.get_time() + local res = fn(...) + local t = system.get_time() - start + local ms = t * 1000 + local per = (t / (1 / 60)) * 100 + print(string.format("*** %-16s : %8.3fms %6.2f%%", name, ms, per)) + return res +end + + +local function serialize(val, pretty, indent_str, escape, sort, limit, level) + local space = pretty and " " or "" + local indent = pretty and string.rep(indent_str, level) or "" + local newline = pretty and "\n" or "" + if type(val) == "string" then + local out = string.format("%q", val) + if escape then + out = string.gsub(out, "\\\n", "\\n") + out = string.gsub(out, "\\7", "\\a") + out = string.gsub(out, "\\8", "\\b") + out = string.gsub(out, "\\9", "\\t") + out = string.gsub(out, "\\11", "\\v") + out = string.gsub(out, "\\12", "\\f") + out = string.gsub(out, "\\13", "\\r") + end + return out + elseif type(val) == "table" then + -- early exit + if level >= limit then return tostring(val) end + local next_indent = pretty and (indent .. indent_str) or "" + local t = {} + for k, v in pairs(val) do + table.insert(t, + next_indent .. "[" .. + serialize(k, pretty, indent_str, escape, sort, limit, level + 1) .. + "]" .. space .. "=" .. space .. serialize(v, pretty, indent_str, escape, sort, limit, level + 1)) + end + if #t == 0 then return "{}" end + if sort then table.sort(t) end + return "{" .. newline .. table.concat(t, "," .. newline) .. newline .. indent .. "}" + end + return tostring(val) +end + +-- Serialize `val` into a parsable string. +-- Available options +-- * pretty: enable pretty printing +-- * indent_str: indent to use (" " by default) +-- * escape: use normal escape characters instead of the ones used by string.format("%q", ...) +-- * sort: sort the keys inside tables +-- * limit: limit how deep to serialize +-- * initial_indent: the initial indentation level +function common.serialize(val, opts) + opts = opts or {} + local indent_str = opts.indent_str or " " + local initial_indent = opts.initial_indent or 0 + local indent = opts.pretty and string.rep(indent_str, initial_indent) or "" + local limit = (opts.limit or math.huge) + initial_indent + return indent .. serialize(val, opts.pretty, indent_str, + opts.escape, opts.sort, limit, initial_indent) +end + + +function common.basename(path) + -- a path should never end by / or \ except if it is '/' (unix root) or + -- 'X:\' (windows drive) + return path:match("[^\\/]+$") or path +end + + +-- can return nil if there is no directory part in the path +function common.dirname(path) + return path:match("(.+)[\\/][^\\/]+$") +end + + +function common.home_encode(text) + if HOME and string.find(text, HOME, 1, true) == 1 then + local dir_pos = #HOME + 1 + -- ensure we don't replace if the text is just "$HOME" or "$HOME/" so + -- it must have a "/" following the $HOME and some characters following. + if string.find(text, PATHSEP, dir_pos, true) == dir_pos and #text > dir_pos then + return "~" .. text:sub(dir_pos) + end + end + return text +end + + +function common.home_encode_list(paths) + local t = {} + for i = 1, #paths do + t[i] = common.home_encode(paths[i]) + end + return t +end + + +function common.home_expand(text) + return HOME and text:gsub("^~", HOME) or text +end + + +local function split_on_slash(s, sep_pattern) + local t = {} + if s:match("^[/\\]") then + t[#t + 1] = "" + end + for fragment in string.gmatch(s, "([^/\\]+)") do + t[#t + 1] = fragment + end + return t +end + + +-- The filename argument given to the function is supposed to +-- come from system.absolute_path and as such should be an +-- absolute path without . or .. elements. +-- This function exists because on Windows the drive letter returned +-- by system.absolute_path is sometimes with a lower case and sometimes +-- with an upper case so we normalize to upper case. +function common.normalize_volume(filename) + if not filename then return end + if PATHSEP == '\\' then + local drive, rem = filename:match('^([a-zA-Z]:\\)(.-)'..PATHSEP..'?$') + if drive then + return drive:upper() .. rem + end + end + return filename +end + + +function common.normalize_path(filename) + if not filename then return end + local volume + if PATHSEP == '\\' then + filename = filename:gsub('[/\\]', '\\') + local drive, rem = filename:match('^([a-zA-Z]:\\)(.*)') + if drive then + volume, filename = drive:upper(), rem + else + drive, rem = filename:match('^(\\\\[^\\]+\\[^\\]+\\)(.*)') + if drive then + volume, filename = drive, rem + end + end + else + local relpath = filename:match('^/(.+)') + if relpath then + volume, filename = "/", relpath + end + end + local parts = split_on_slash(filename, PATHSEP) + local accu = {} + for _, part in ipairs(parts) do + if part == '..' then + if #accu > 0 and accu[#accu] ~= ".." then + table.remove(accu) + elseif volume then + error("invalid path " .. volume .. filename) + else + table.insert(accu, part) + end + elseif part ~= '.' then + table.insert(accu, part) + end + end + local npath = table.concat(accu, PATHSEP) + return (volume or "") .. (npath == "" and PATHSEP or npath) +end + + +function common.is_absolute_path(path) + return path:sub(1, 1) == PATHSEP or path:match("^(%a):\\") +end + + +function common.path_belongs_to(filename, path) + return string.find(filename, path .. PATHSEP, 1, true) == 1 +end + + +function common.relative_path(ref_dir, dir) + local drive_pattern = "^(%a):\\" + local drive, ref_drive = dir:match(drive_pattern), ref_dir:match(drive_pattern) + if drive and ref_drive and drive ~= ref_drive then + -- Windows, different drives, system.absolute_path fails for C:\..\D:\ + return dir + end + local ref_ls = split_on_slash(ref_dir) + local dir_ls = split_on_slash(dir) + local i = 1 + while i <= #ref_ls do + if dir_ls[i] ~= ref_ls[i] then + break + end + i = i + 1 + end + local ups = "" + for k = i, #ref_ls do + ups = ups .. ".." .. PATHSEP + end + local rel_path = ups .. table.concat(dir_ls, PATHSEP, i) + return rel_path ~= "" and rel_path or "." +end + + +function common.mkdirp(path) + local stat = system.get_file_info(path) + if stat and stat.type then + return false, "path exists", path + end + local subdirs = {} + while path and path ~= "" do + local success_mkdir = system.mkdir(path) + if success_mkdir then break end + local updir, basedir = path:match("(.*)[/\\](.+)$") + table.insert(subdirs, 1, basedir or path) + path = updir + end + for _, dirname in ipairs(subdirs) do + path = path and path .. PATHSEP .. dirname or dirname + if not system.mkdir(path) then + return false, "cannot create directory", path + end + end + return true +end + +function common.rm(path, recursively) + local stat = system.get_file_info(path) + if not stat or (stat.type ~= "file" and stat.type ~= "dir") then + return false, "invalid path given", path + end + + if stat.type == "file" then + local removed, error = os.remove(path) + if not removed then + return false, error, path + end + else + local contents = system.list_dir(path) + if #contents > 0 and not recursively then + return false, "directory is not empty", path + end + + for _, item in pairs(contents) do + local item_path = path .. PATHSEP .. item + local item_stat = system.get_file_info(item_path) + + if not item_stat then + return false, "invalid file encountered", item_path + end + + if item_stat.type == "dir" then + local deleted, error, ipath = common.rm(item_path, recursively) + if not deleted then + return false, error, ipath + end + elseif item_stat.type == "file" then + local removed, error = os.remove(item_path) + if not removed then + return false, error, item_path + end + end + end + + local removed, error = system.rmdir(path) + if not removed then + return false, error, path + end + end + + return true +end + + +return common diff --git a/tools/data-migration/lite/colors/core/style.lua b/tools/data-migration/lite/colors/core/style.lua new file mode 100644 index 000000000..5e488785d --- /dev/null +++ b/tools/data-migration/lite/colors/core/style.lua @@ -0,0 +1,5 @@ +local style = {} +style.syntax = {} +style.syntax_fonts = {} +style.log = {} +return style diff --git a/tools/data-migration/lite/colors/lite2ecode.lua b/tools/data-migration/lite/colors/lite2ecode.lua new file mode 100644 index 000000000..96464e6a7 --- /dev/null +++ b/tools/data-migration/lite/colors/lite2ecode.lua @@ -0,0 +1,74 @@ +local style = require "core.style" +local common = require "core.common" + +function common.color_to_hex(rgba) + r = math.floor(rgba[1]) % 256 + g = math.floor(rgba[2]) % 256 + b = math.floor(rgba[3]) % 256 + a = math.floor(rgba[4]) % 256 + if a < 255 then + return string.format("#%02x%02x%02x%02x", r, g, b, a) + end + return string.format("#%02x%02x%02x", r, g, b) +end + +function print_syntax(prop, eprop) + if style.syntax[prop] then + if eprop then + print(eprop .. "=" .. common.color_to_hex(style.syntax[prop])) + else + print(prop .. "=" .. common.color_to_hex(style.syntax[prop])) + end + end +end + +function print_style(prop) + if style[prop] then + print(prop .. "=" .. common.color_to_hex(style[prop])) + end +end + +function print_lint(prop, eprop) + if style.lint and style.lint[prop] then + if eprop then + print(eprop .. "=" .. common.color_to_hex(style.lint[prop])) + else + print(prop .. "=" .. common.color_to_hex(style.lint[prop])) + end + end +end +if arg[1] == nil then + print("Expected a file name to parse") + return +end + +for i = 1, #arg do + dofile(arg[i]) +end + +local section_name = arg[1]:match("([^/\\]+)%.lua$") +print("[" .. section_name .. "]") +print_style("background") +print_style("text") +print_style("caret") +print_style("selection") +print_style("line_highlight") +print_style("line_number") +print_style("line_number2") +print_lint("error") +print_lint("warning") +print_lint("info", "notice") +print("") +print_syntax("normal") +print_syntax("keyword") +print_syntax("keyword2") +print_syntax("parameter", "keyword3") +print_syntax("number") +print_syntax("literal") +print_syntax("string") +print_syntax("operator") +print_syntax("function") +print_syntax("symbol") +print_syntax("comment") +print_syntax("link") +print_syntax("link_hover") diff --git a/tools/data-migration/lite/language/README.md b/tools/data-migration/lite/language/README.md index e81d88ea1..81307069a 100644 --- a/tools/data-migration/lite/language/README.md +++ b/tools/data-migration/lite/language/README.md @@ -1,10 +1,5 @@ # Small script to migrate lite and lite-xl language definitions to ecode language definitions. -There are currently some limitations but this can be used as a starting point to create a new language definition. -Most of the languages can be migrated without any changes, but ecode currently does not support regex -for syntax highlighting, those patterns won't be migrated (this is a feature of lite-xl, normal lite -does not support regex's). - ## Usage You'll need to have installed lua binary, then run: From 5c4bb6af5a13795ea609407e06d0872a0f33aaaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sun, 26 Jan 2025 13:26:20 -0300 Subject: [PATCH 08/30] Add DAP mention and update languages list. --- README.md | 225 +++++++++++++++++++++++++++--------------------------- 1 file changed, 114 insertions(+), 111 deletions(-) diff --git a/README.md b/README.md index 9afc4cd31..d620f6368 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ For more screenshots checkout [running on macOS](https://github.com/SpartanJ/eco * Command Palette * [LSP](https://microsoft.github.io/language-server-protocol/) support * [Git](https://git-scm.com/) integration +* Debugger support via [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol) * Auto-Completion * Customizable Linter support * Customizable Formatter support @@ -124,108 +125,109 @@ ecode is constantly adding more languages support and also supports extending it via configuration files (for every feature: syntax highlighting, LSP, linter and formatter). ### Language support table -| Language | Highlight | LSP | Linter | Formatter | -| :---: | :---: | :---: | :---: | :---: | -| .htaccess | ✓ | None | None | None | -| .ignore file | ✓ | None | None | None | -| [x]it! | ✓ | None | None | None | -| adept | ✓ | [AdeptLSP](https://github.com/AdeptLanguage/AdeptLSP) | None | None | -| angelscript | ✓ | None | None | None | -| awk script | ✓ | None | None | None | -| bat | ✓ | None | None | None | -| bazel | ✓ | None | None | None | -| bend | ✓ | None | None | None | -| blueprint | ✓ | None | None | None | -| brainfuck | ✓ | None | None | None | -| buzz | ✓ | None | None | None | -| c | ✓ | [clangd](https://clangd.llvm.org/) | [cppcheck](https://github.com/danmar/cppcheck) | [clang-format](https://clang.llvm.org/docs/ClangFormat.html) | -| carbon | ✓ | None | None | None | -| clojure | ✓ | [clojure-lsp](https://github.com/clojure-lsp/clojure-lsp) | None | None | -| cmake | ✓ | [cmake-language-server](https://github.com/regen100/cmake-language-server) | None | None | -| cpp | ✓ | [clangd](https://clangd.llvm.org/) | [cppcheck](https://github.com/danmar/cppcheck) | [clang-format](https://clang.llvm.org/docs/ClangFormat.html) | -| crystal | ✓ | [crystalline](https://github.com/elbywan/crystalline) | None | None | -| csharp | ✓ | [OmniSharp](https://github.com/OmniSharp/omnisharp-roslyn) | None | None | -| css | ✓ | [emmet-language-server](https://github.com/olrtg/emmet-language-server) | None | [native](#native) | -| d | ✓ | [serve-d](https://github.com/Pure-D/serve-d) | None | None | -| dart | ✓ | [dart language-server](https://github.com/dart-lang/sdk/blob/main/pkg/analysis_server/tool/lsp_spec) | None | None | -| diff | ✓ | None | None | None | -| dockerfile | ✓ | [docker-langserver](https://github.com/rcjsuen/dockerfile-language-server-nodejs) | None | None | -| elixir | ✓ | [elixir-ls](https://github.com/elixir-lsp/elixir-ls) | None | None | -| elm | ✓ | [elm-language-server](https://github.com/elm-tooling/elm-language-server) | None | None | -| environment file | ✓ | None | None | None | -| fantom | ✓ | None | None | None | -| fortran | ✓ | [fortls](https://github.com/fortran-lang/fortls) | None | None | -| fstab | ✓ | None | None | None | -| gdscript | ✓ | None | None | None | -| glsl | ✓ | [glsl_analyzer](https://github.com/nolanderc/glsl_analyzer) | None | None | -| go | ✓ | [gopls](https://golang.org/x/tools/gopls) | None | [gopls](https://pkg.go.dev/golang.org/x/tools/gopls) | -| graphql | ✓ | None | None | None | -| groovy | ✓ | None | None | None | -| hare | ✓ | None | None | None | -| haskell | ✓ | [haskell-language-server](https://github.com/haskell/haskell-language-server) | [hlint](https://github.com/ndmitchell/hlint) | [ormolu](https://github.com/tweag/ormolu) | -| haxe | ✓ | None | None | None | -| haxe compiler arguments | ✓ | None | None | None | -| hlsl | ✓ | None | None | None | -| html | ✓ | [emmet-language-server](https://github.com/olrtg/emmet-language-server) | None | [prettier](https://prettier.io) | -| ini | ✓ | None | None | None | -| jai | ✓ | None | None | None | -| java | ✓ | [jdtls](https://github.com/eclipse/eclipse.jdt.ls) | None | [clang-format](https://clang.llvm.org/docs/ClangFormat.html) | -| javascript | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | [eslint](https://eslint.org) | [prettier](https://prettier.io) | -| javascriptreact | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | None | None | -| json | ✓ | None | [jq](https://stedolan.github.io/jq/) | [native](#native) | -| julia | ✓ | [LanguageServer.jl](https://github.com/julia-vscode/LanguageServer.jl) | None | None | -| kotlin | ✓ | [kotlin-language-server](https://github.com/fwcd/kotlin-language-server) | [ktlint](https://pinterest.github.io/ktlint/) | [ktlint](https://pinterest.github.io/ktlint/) | -| latex | ✓ | [texlab](https://github.com/latex-lsp) | None | None | -| lobster | ✓ | None | None | None | -| lua | ✓ | [lua-language-server](https://github.com/sumneko/lua-language-server) | [luacheck](https://github.com/mpeterv/luacheck) | None | -| makefile | ✓ | None | None | None | -| markdown | ✓ | None | None | None | -| meson | ✓ | None | None | None | -| moonscript | ✓ | None | None | None | -| nelua | ✓ | None | [nelua](https://nelua.io) | None | -| nim | ✓ | [nimlsp](https://github.com/PMunch/nimlsp) | [nim](https://nim-lang.org) | None | -| objeck | ✓ | None | None | None | -| objective-c | ✓ | [clangd](https://clangd.llvm.org/) | None | [clang-format](https://clang.llvm.org/docs/ClangFormat.html) | -| ocaml | ✓ | [OCaml-LSP](https://github.com/ocaml/ocaml-lsp) | None | None | -| odin | ✓ | [ols](https://github.com/DanielGavin/ols) | None | None | -| openscad | ✓ | None | None | None | -| pascal | ✓ | None | None | None | -| perl | ✓ | [PerlNavigator](https://github.com/bscan/PerlNavigator) | None | None | -| php | ✓ | [phpactor](https://phpactor.readthedocs.io) | [php](https://www.php.net) | None | -| pico-8 | ✓ | None | None | None | -| plaintext | ✓ | None | None | None | -| po | ✓ | None | None | None | -| pony | ✓ | None | None | None | -| postgresql | ✓ | None | None | None | -| powershell | ✓ | None | None | None | -| python | ✓ | [pylsp](https://github.com/python-lsp/python-lsp-server) | [ruff](https://ruff.rs) | [black](https://black.readthedocs.io/en/stable/) | -| r | ✓ | [r languageserver](https://github.com/REditorSupport/languageserver) | None | None | -| ring | ✓ | None | None | None | -| ruby | ✓ | [solargraph](https://solargraph.org) | None | None | -| rust | ✓ | [rust-analyzer](https://rust-analyzer.github.io) | None | [rustfmt](https://rust-lang.github.io/rustfmt/) | -| sass | ✓ | [emmet-language-server](https://github.com/olrtg/emmet-language-server) | None | None | -| scala | ✓ | [metals](https://github.com/scalameta/metals) | None | None | -| shellscript | ✓ | [bash-language-server](https://github.com/bash-lsp/bash-language-server) | None | None | -| smallbasic | ✓ | None | None | None | -| solidity | ✓ | [solc](https://soliditylang.org) | [solhint](https://protofire.github.io/solhint/) | None | -| sql | ✓ | None | None | None | -| swift | ✓ | [sourcekit-lsp](https://github.com/apple/sourcekit-lsp) | None | None | -| tcl | ✓ | None | None | None | -| teal | ✓ | None | [tl](https://github.com/teal-language/tl) | None | -| toml | ✓ | None | None | None | -| typescript | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | [eslint](https://eslint.org) | [prettier](https://prettier.io) | -| typescriptreact | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | None | None | -| v | ✓ | [v-analyzer](https://github.com/v-analyzer/v-analyzer) | None | [v](https://vlang.io) | -| vala | ✓ | [vala-language-server](https://github.com/vala-lang/vala-language-server) | None | None | -| verilog | ✓ | None | None | None | -| visual basic | ✓ | None | None | None | -| vue | ✓ | [vls](https://github.com/vuejs/vetur/tree/master/server) | None | None | -| wren | ✓ | None | None | None | -| x86 assembly | ✓ | None | None | None | -| xml | ✓ | [emmet-language-server](https://github.com/olrtg/emmet-language-server) | [native](#native) | [native](#native) | -| xtend | ✓ | None | None | None | -| yaml | ✓ | [yaml-language-server](https://github.com/redhat-developer/yaml-language-server) | None | None | -| zig | ✓ | [zls](https://github.com/zigtools/zls) | [zig](https://ziglang.org) | [zig](https://ziglang.org) | +| Language | Highlight | LSP | Linter | Formatter | Debugger | +| :---: | :---: | :---: | :---: | :---: | :---: | +| .htaccess | ✓ | None | None | None | None | +| .ignore file | ✓ | None | None | None | None | +| [x]it! | ✓ | None | None | None | None | +| ada | ✓ | [ada_language_server](https://github.com/AdaCore/ada_language_server) | None | None | None | +| adept | ✓ | [AdeptLSP](https://github.com/AdeptLanguage/AdeptLSP) | None | None | None | +| angelscript | ✓ | None | None | None | None | +| awk script | ✓ | None | None | None | None | +| bat | ✓ | None | None | None | None | +| bazel | ✓ | None | None | None | None | +| bend | ✓ | None | None | None | None | +| blueprint | ✓ | None | None | None | None | +| brainfuck | ✓ | None | None | None | None | +| buzz | ✓ | None | None | None | None | +| c | ✓ | [clangd](https://clangd.llvm.org/) | [cppcheck](https://github.com/danmar/cppcheck) | [clang-format](https://clang.llvm.org/docs/ClangFormat.html) | [gdb](https://www.gnu.org/software/gdb) / [lldb-dap](https://github.com/llvm/llvm-project/blob/main/lldb/tools/lldb-dap/README.md) | +| carbon | ✓ | None | None | None | None | +| clojure | ✓ | [clojure-lsp](https://github.com/clojure-lsp/clojure-lsp) | None | None | None | +| cmake | ✓ | [cmake-language-server](https://github.com/regen100/cmake-language-server) | None | None | None | +| cpp | ✓ | [clangd](https://clangd.llvm.org/) | [cppcheck](https://github.com/danmar/cppcheck) | [clang-format](https://clang.llvm.org/docs/ClangFormat.html) | [gdb](https://www.gnu.org/software/gdb) / [lldb-dap](https://github.com/llvm/llvm-project/blob/main/lldb/tools/lldb-dap/README.md) | +| crystal | ✓ | [crystalline](https://github.com/elbywan/crystalline) | None | None | None | +| csharp | ✓ | [OmniSharp](https://github.com/OmniSharp/omnisharp-roslyn) | None | None | None | +| css | ✓ | [emmet-language-server](https://github.com/olrtg/emmet-language-server) | None | [native](#native) | None | +| d | ✓ | [serve-d](https://github.com/Pure-D/serve-d) | None | None | [gdb](https://www.gnu.org/software/gdb) | +| dart | ✓ | [dart language-server](https://github.com/dart-lang/sdk/blob/main/pkg/analysis_server/tool/lsp_spec) | None | None | [dart](https://github.com/dart-lang/sdk/blob/main/third_party/pkg/dap/tool/README.md) | +| diff | ✓ | None | None | None | None | +| dockerfile | ✓ | [docker-langserver](https://github.com/rcjsuen/dockerfile-language-server-nodejs) | None | None | None | +| elixir | ✓ | [elixir-ls](https://github.com/elixir-lsp/elixir-ls) | None | None | None | +| elm | ✓ | [elm-language-server](https://github.com/elm-tooling/elm-language-server) | None | None | None | +| environment file | ✓ | None | None | None | None | +| fantom | ✓ | None | None | None | None | +| fortran | ✓ | [fortls](https://github.com/fortran-lang/fortls) | None | None | [gdb](https://www.gnu.org/software/gdb) | +| fstab | ✓ | None | None | None | None | +| gdscript | ✓ | None | None | None | None | +| glsl | ✓ | [glsl_analyzer](https://github.com/nolanderc/glsl_analyzer) | None | None | None | +| go | ✓ | [gopls](https://golang.org/x/tools/gopls) | None | [gopls](https://pkg.go.dev/golang.org/x/tools/gopls) | [gdb](https://www.gnu.org/software/gdb) / [delve](https://github.com/go-delve/delve) | +| graphql | ✓ | None | None | None | None | +| groovy | ✓ | None | None | None | None | +| hare | ✓ | None | None | None | None | +| haskell | ✓ | [haskell-language-server](https://github.com/haskell/haskell-language-server) | [hlint](https://github.com/ndmitchell/hlint) | [ormolu](https://github.com/tweag/ormolu) | None | +| haxe | ✓ | None | None | None | None | +| haxe compiler arguments | ✓ | None | None | None | None | +| hlsl | ✓ | None | None | None | None | +| html | ✓ | [emmet-language-server](https://github.com/olrtg/emmet-language-server) | None | [prettier](https://prettier.io) | None | +| ini | ✓ | None | None | None | None | +| jai | ✓ | None | None | None | None | +| java | ✓ | [jdtls](https://github.com/eclipse/eclipse.jdt.ls) | None | [clang-format](https://clang.llvm.org/docs/ClangFormat.html) | None | +| javascript | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | [eslint](https://eslint.org) | [prettier](https://prettier.io) | None | +| javascriptreact | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | None | None | None | +| json | ✓ | None | [jq](https://stedolan.github.io/jq/) | [native](#native) | None | +| julia | ✓ | [LanguageServer.jl](https://github.com/julia-vscode/LanguageServer.jl) | None | None | None | +| kotlin | ✓ | [kotlin-language-server](https://github.com/fwcd/kotlin-language-server) | [ktlint](https://pinterest.github.io/ktlint/) | [ktlint](https://pinterest.github.io/ktlint/) | None | +| latex | ✓ | [texlab](https://github.com/latex-lsp) | None | None | None | +| lobster | ✓ | None | None | None | None | +| lua | ✓ | [lua-language-server](https://github.com/sumneko/lua-language-server) | [luacheck](https://github.com/mpeterv/luacheck) | None | None | +| makefile | ✓ | None | None | None | None | +| markdown | ✓ | None | None | None | None | +| meson | ✓ | None | None | None | None | +| moonscript | ✓ | None | None | None | None | +| nelua | ✓ | None | [nelua](https://nelua.io) | None | None | +| nim | ✓ | [nimlsp](https://github.com/PMunch/nimlsp) | [nim](https://nim-lang.org) | None | None | +| objeck | ✓ | None | None | None | None | +| objective-c | ✓ | [clangd](https://clangd.llvm.org/) | None | [clang-format](https://clang.llvm.org/docs/ClangFormat.html) | None | +| ocaml | ✓ | [OCaml-LSP](https://github.com/ocaml/ocaml-lsp) | None | None | None | +| odin | ✓ | [ols](https://github.com/DanielGavin/ols) | None | None | [lldb-dap](https://github.com/llvm/llvm-project/blob/main/lldb/tools/lldb-dap/README.md) | +| openscad | ✓ | None | None | None | None | +| pascal | ✓ | None | None | None | [gdb](https://www.gnu.org/software/gdb) | +| perl | ✓ | [PerlNavigator](https://github.com/bscan/PerlNavigator) | None | None | [perl-ls](https://github.com/richterger/Perl-LanguageServer) | +| php | ✓ | [phpactor](https://phpactor.readthedocs.io) | [php](https://www.php.net) | None | None | +| pico-8 | ✓ | None | None | None | None | +| plaintext | ✓ | None | None | None | None | +| po | ✓ | None | None | None | None | +| pony | ✓ | None | None | None | None | +| postgresql | ✓ | None | None | None | None | +| powershell | ✓ | None | None | None | None | +| python | ✓ | [pylsp](https://github.com/python-lsp/python-lsp-server) | [ruff](https://ruff.rs) | [black](https://black.readthedocs.io/en/stable/) | [debugpy](https://github.com/microsoft/debugpy) | +| r | ✓ | [r languageserver](https://github.com/REditorSupport/languageserver) | None | None | None | +| ring | ✓ | None | None | None | None | +| ruby | ✓ | [solargraph](https://solargraph.org) | None | None | None | +| rust | ✓ | [rust-analyzer](https://rust-analyzer.github.io) | None | [rustfmt](https://rust-lang.github.io/rustfmt/) | [gdb](https://www.gnu.org/software/gdb) / [lldb-dap](https://github.com/llvm/llvm-project/blob/main/lldb/tools/lldb-dap/README.md) | +| sass | ✓ | [emmet-language-server](https://github.com/olrtg/emmet-language-server) | None | None | None | +| scala | ✓ | [metals](https://github.com/scalameta/metals) | None | None | None | +| shellscript | ✓ | [bash-language-server](https://github.com/bash-lsp/bash-language-server) | None | None | None | +| smallbasic | ✓ | None | None | None | None | +| solidity | ✓ | [solc](https://soliditylang.org) | [solhint](https://protofire.github.io/solhint/) | None | None | +| sql | ✓ | None | None | None | None | +| swift | ✓ | [sourcekit-lsp](https://github.com/apple/sourcekit-lsp) | None | None | None | +| tcl | ✓ | None | None | None | None | +| teal | ✓ | None | [tl](https://github.com/teal-language/tl) | None | None | +| toml | ✓ | None | None | None | None | +| typescript | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | [eslint](https://eslint.org) | [prettier](https://prettier.io) | None | +| typescriptreact | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | None | None | None | +| v | ✓ | [v-analyzer](https://github.com/v-analyzer/v-analyzer) | None | [v](https://vlang.io) | None | +| vala | ✓ | [vala-language-server](https://github.com/vala-lang/vala-language-server) | None | None | None | +| verilog | ✓ | None | None | None | None | +| visual basic | ✓ | None | None | None | None | +| vue | ✓ | [vls](https://github.com/vuejs/vetur/tree/master/server) | None | None | None | +| wren | ✓ | None | None | None | None | +| x86 assembly | ✓ | None | None | None | None | +| xml | ✓ | [emmet-language-server](https://github.com/olrtg/emmet-language-server) | [native](#native) | [native](#native) | None | +| xtend | ✓ | None | None | None | None | +| yaml | ✓ | [yaml-language-server](https://github.com/redhat-developer/yaml-language-server) | None | None | None | +| zig | ✓ | [zls](https://github.com/zigtools/zls) | [zig](https://ziglang.org) | [zig](https://ziglang.org) | [lldb-dap](https://github.com/llvm/llvm-project/blob/main/lldb/tools/lldb-dap/README.md) | #### native @@ -727,13 +729,16 @@ by ecode [here](https://github.com/SpartanJ/eepp/tree/develop/src/eepp/ui/doc/la Listed in no particular order: -* [DAP](https://microsoft.github.io/debug-adapter-protocol/) support +* General polishing * Improved plugin system (visual configuration, more flexibility/features) +* Snippets support +* Macros support +* Better integration with OSes ### Long Term Planned Features -* Remote development support * Modal editing +* Maybe Remote development support * Maybe [Tree-sitter](https://github.com/tree-sitter/tree-sitter) support ## Collaborate @@ -755,20 +760,18 @@ you could need some special font (currently covers CJK languages). ## Current Limitations * No font sub-pixel hinting \*1 \*2 -* No VIM-mode / modal editing \*4 -* No [text-shaping](https://harfbuzz.github.io/why-do-i-need-a-shaping-engine.html) support. \*1 \*5 -* No ligatures support (requires text-shaping) \*1 \*3 +* No VIM-mode / modal editing \*3 +* No [text-shaping](https://harfbuzz.github.io/why-do-i-need-a-shaping-engine.html) support. \*1 \*4 +* No ligatures support (requires text-shaping) \*1 * No BiDi support (requires text-shaping) \*1 _\*1_ Current eepp feature limitations. _\*2_ I'm not a fan of sub-pixel hinting. But I'm more than willing to implement it, I'm not very versed in the matter, so any help will be appreciated. -_\*3_ I don't really like ligatures. I'm open to PRs implementing them. +_\*3_ I'm not a VIM user, and I'm not qualified to implement the VIM mode or any modal editing. PRs are welcome to support this. -_\*4_ I'm not a VIM user, and I'm not qualified to implement the VIM mode or any modal editing. PRs are welcome to support this. - -_\*5_ Better text-shaping support will come with time, but with no rush for the moment. eepp architecture is ready to add HarfBuzz support. +_\*4_ Some work has been done to support text-shaping but it's not ready for general usage. So it's a work in progress. ## Author comments From aa6d3fe1dd600f7f0fd6713273ec152907bafe81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sat, 1 Feb 2025 01:42:33 -0300 Subject: [PATCH 09/30] Organizing README in separated docs. --- README.md | 449 +++------------------------------------ docs/autocomplete.md | 25 +++ docs/customlanguages.md | 133 ++++++++++++ docs/formatter.md | 46 ++++ docs/git.md | 44 ++++ docs/linter.md | 59 +++++ docs/lsp.md | 85 ++++++++ docs/uicustomizations.md | 68 ++++++ docs/xmltools.md | 9 + 9 files changed, 497 insertions(+), 421 deletions(-) create mode 100644 docs/autocomplete.md create mode 100644 docs/customlanguages.md create mode 100644 docs/formatter.md create mode 100644 docs/git.md create mode 100644 docs/linter.md create mode 100644 docs/lsp.md create mode 100644 docs/uicustomizations.md create mode 100644 docs/xmltools.md diff --git a/README.md b/README.md index d620f6368..550d1bb29 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ For more screenshots checkout [running on macOS](https://github.com/SpartanJ/eco * Lightweight * Portable -* Minimalist GUI +* Uncluttered GUI * Syntax Highlighting (including nested syntax highlighting, supporting over 90 languages and LSP semantic highlighting) * Multi-cursor support * Terminal support @@ -252,262 +252,53 @@ the plugin communication. And, for example, the Linter plugin will consume the L Also the Auto Complete module will request assistance from the LSP, if available, to improve the completions and to provide signature help. -### Linter +#### Linter Linter support is provided by executing already stablished linters from each language. *ecode* provides support for several languages by default and can be extended easily by expanding the -`linters.json` configuration. `linters.json` default configuration can be obtained from [here](https://raw.githubusercontent.com/SpartanJ/eepp/develop/bin/assets/plugins/linters.json). -To configure new linters you can create a new `linters.json` file in the [default configuration path](#plugins-configuration-files-location) of *ecode*. - -#### `linters.json` format - -The format is a very simple JSON object with a config object and array of objects containing the file -formats supported, the [Lua pattern](https://www.lua.org/manual/5.4/manual.html#6.4.1) to find any error printed by the linter to the stdout, the position -of each group of the pattern, and the command to execute. It also supports some optional extra object keys. - -JavaScript linter example (using [eslint](https://eslint.org/)) - -```json -{ - "config": { - "delay_time": "0.5s" - }, - "linters": [ - { - "file_patterns": ["%.js$", "%.ts$"], - "warning_pattern": "[^:]:(%d+):(%d+): ([^%[]+)%[([^\n]+)", - "warning_pattern_order": { "line": 1, "col": 2, "message": 3, "type": 4 }, - "command": "eslint --no-ignore --format unix $FILENAME" - } - ] -} -``` - -That's all we need to have a working linter in *ecode*. Linters executables must be installed manually -by the user, linters will not come with the editor, and they also need to be visible to the executable. -This means that it must be on `PATH` environment variable or the path to the binary must be absolute. - -#### Currently supported linters - -Please check the [language support table](#language-support-table) - -#### Linter config object keys - -* **delay_time**: Delay to run the linter after editing a document -* **enable_error_lens**: Enables error lens (prints the message inline) -* **enable_lsp_diagnostics**: Boolean that enable/disable LSP diagnostics as part of the linting. Enabled by default. -* **disable_lsp_languages**: Array of LSP languages disabled for LSP diagnostics. For example: `"disable_lsp_languages": ["lua", "python"]`, disables lua and python. -* **disable_languages**: Array of linters disabled from external linter application diagnostics. For example: `"disable_languages": ["lua", "python"]`, disables luacheck and ruff respectively. -* **goto_ignore_warnings**: Defines the behavior of the "linter-go-to-next-error" and "linter-go-to-previous-error" keybindings. If ignore warnings is true it will jump only between errors. - -#### Linter JSON object keys - -* **file_patterns**: Array of [Lua Patterns](https://www.lua.org/manual/5.4/manual.html#6.4.1) representing the file extensions that must use the linter -* **warning_pattern**: [Lua Pattern](https://www.lua.org/manual/5.4/manual.html#6.4.1) to be parsed from the executable stdout -* **warning_pattern_order**: The order where the line, column, error/warning/notice message, and the type of the message (warning, error, notice, info) are read. The pattern must have at least 3 groups (line, message, and type). The error type is auto-detected from its name. -* **command**: The command to execute to run the linter. $FILENAME represents the file path. -* **url** (optional): The web page URL of the linter -* **expected_exitcodes**: Array of integer numbers accepted as parseable exit codes (optional) -* **no_errors_exit_code**: Integer number representing the exit code that means that no errors were found (optional). -* **deduplicate**: In case the linter outputs duplicated errors, this boolean will ignore duplicated errors (optional, boolean true/false) -* **use_tmp_folder**: Temporal files (files representing the current status of the modified file) will be written in the default temporal folder of the operating system, otherwise it will be written in the same folder path of the modified file (optional, boolean true/false). - -### Formatter +`linters.json` configuration. -The formatter plugin works exactly like the linter plugin, but it will execute tools that auto-format code. -*ecode* provides support for several languages by default with can be extended easily by expanding the -`formatters.json` configuration. `formatters.json` default configuration can be obtained from [here](https://raw.githubusercontent.com/SpartanJ/eepp/develop/bin/assets/plugins/formatters.json). -It also supports some formatters natively, this means that the formatter comes with ecode without requiring any external dependency. -And also supports LSP text document formatting, meaning that if you're running an LSP that supports formatting documents, formatting will be available too. -To configure new formatters you can create a new `formatters.json` file in the [default configuration path](#plugins-configuration-files-location) of *ecode*. - -#### `formatters.json` format - -```json -{ - "config": { - "auto_format_on_save": false - }, - "keybindings": { - "format-doc": "alt+f" - }, - "formatters": [ - { - "file_patterns": ["%.js$", "%.ts$"], - "command": "prettier $FILENAME" - } - ] -} -``` - -#### Currently supported formatters +For more information [read the linter documentation](docs/linter.md). -Please check the [language support table](#language-support-table) -#### Formatter config object keys +#### Auto Formatter -* **auto_format_on_save**: Indicates if after saving the file it should be auto-formatted - -#### Formatter keybindings object keys - -* **format-doc**: Keybinding to format the doc with the configured language formatter - -#### Formatter JSON object keys +The formatter plugin works exactly like the linter plugin, but it will execute tools that auto-format code. +*ecode* provides support for several languages by default with can be extended easily by expanding the +`formatters.json` configuration. -* **file_patterns**: Array of [Lua Patterns](https://www.lua.org/manual/5.4/manual.html#6.4.1) representing the file extensions that must use the formatter -* **command**: The command to execute to run the formatter. $FILENAME represents the file path -* **type**: Indicates the mode that which the formatter outputs the results. Supported two possible options: "inplace" (file is replaced with the formatted version), "output" (newly formatted file is the stdout of the program, default option) or "native" (uses the formatter provided by ecode) -* **url** (optional): The web page URL of the formatter +For more information [read the formatter documentation](docs/formatter.md). -### LSP Client +#### LSP Client LSP support is provided by executing already stablished LSP from each language. *ecode* provides support for several languages by default and can be extended easily by expanding the -`lspclient.json` configuration. `lspclient.json` default configuration can be obtained from [here](https://raw.githubusercontent.com/SpartanJ/eepp/develop/bin/assets/plugins/lspclient.json). -To configure new LSPs you can create a new `lspclient.json` file in the [default configuration path](#plugins-configuration-files-location) of *ecode*. - -Important note: LSP servers can be very resource intensive and might not be always the best option for simple projects. - -Implementation details: LSP servers are only loaded when needed, no process will be opened until a -supported file is opened in the project. - -#### `lspclient.json` format - -The format follows the same pattern that all previous configuration files. Configuration is represented -in a JSON file with three main keys: `config`, `keybindings`, `servers`. - -C and C++ LSP server example (using [clangd](https://clangd.llvm.org/)) - -```json -{ - "config": { - "hover_delay": "0.5s" - }, - "servers": [ - { - "language": "c", - "name": "clangd", - "url": "https://clangd.llvm.org/", - "command": "clangd -log=error --background-index --limit-results=500 --completion-style=bundled", - "file_patterns": ["%.c$", "%.h$", "%.C$", "%.H$", "%.objc$"] - }, - { - "language": "cpp", - "use": "clangd", - "file_patterns": ["%.inl$", "%.cpp$", "%.hpp$", "%.cc$", "%.cxx$", "%.c++$", "%.hh$", "%.hxx$", "%.h++$", "%.objcpp$"] - } - ] -} -``` - -That's all we need to have a working LSP in *ecode*. LSPs executables must be installed manually -by the user, LSPs will not come with the editor, and they also need to be visible to the executable. -This means that it must be on `PATH` environment variable or the path to the binary must be absolute. - -#### Currently supported LSPs - -Please check the [language support table](#language-support-table) - -#### LSP Client config object keys - -* **hover_delay**: The time the editor must wait to show symbol information when hovering any piece of code. -* **server_close_after_idle_time**: The time the LSP Server will keep alive after all documents that consumes that LSP Server were closed. LSP Servers are spawned and killed on demand. -* **semantic_highlighting**: Enable/Disable semantic highlighting (disabled by default, boolean) -* **disable_semantic_highlighting_lang**: An array of languages where semantic highlighting should be disabled -* **silent**: Enable/Disable non-critical LSP logs -* **trim_logs**: If logs are enabled and trim_logs is enabled it will trim the line log size at maximum 1 KiB per line (useful for debugging) -* **breadcrumb_navigation**: Enable/Disable the breadcrumb (enabled by default) -* **breadcrumb_height**: Defines the height of the breadcrumb in [CSS length](https://eepp.ensoft.dev/page_cssspecification.html#length-data-type) - -#### LSP Client keybindings object keys - -* **lsp-symbol-info**: Keybinding to request symbol information -* **lsp-go-to-definition**: Keybinding to "Go to Definition" -* **lsp-go-to-declaration**: Keybinding to "Go to Declaration" -* **lsp-go-to-implementation**: Keybinding to "Go to Implementation" -* **lsp-go-to-type-definition**: Keybinding to "Go to Type Definition" -* **lsp-symbol-references**: Keybinding to "Find References to Symbol Under Cursor" -* **lsp-symbol-code-action**: Keybinding to "Code Action" -* **lsp-switch-header-source**: Keybinding to "Switch Header/Source" (only available for C and C++) - -#### LSP Client JSON object keys - -* **language**: The LSP language identifier. Some identifiers can be found [here](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocumentItem) -* **name**: The name of the language server -* **url** (optional): The web page URL of the language server -* **use** (optional): A server can be inherit the configuration from other server. This must be the name of the server configuration that inherits (useful for LSPs that support several languages like clang and typescript-language-server). -* **file_patterns**: Array of [Lua Patterns](https://www.lua.org/manual/5.4/manual.html#6.4.1) representing the file extensions that must use the LSP client -* **command**: The command to execute to run the LSP. It's possible to override the default LSP command by declaring the server in the `lspclient.json` config. It's also possible to specify a different command for each platform, given that it might change in some ocassions per-platform. In that case an object should be used, with each key being a platform, and there's also a wildcard platform "other" to specify any other platform that does not match the platform definition. For example, `sourcekit-lsp` uses: `"command": {"macos": "xcrun sourcekit-lsp","other": "sourcekit-lsp"}` -* **command_parameters** (optional): The command parameters. Parameters can be set from the **command** also, unless the command needs to run a binary with name with spaces. Also command_parameters can be used to add more parameters to the original command. The lsp configuration can be overriden from the lspclient.json in the user configuration. For example: a user trying to append some command line arguments to clang would need to do something like: `{"name": "clangd","command_parameters": "--background-index-priority=background --malloc-trim"}` -* **rootIndicationFileNames** (optional): Some languages need to indicate the project root path to the LSP work correctly. This is an array of files that might indicate where the root path is. Usually this is resolver by the LSP itself, but it might help in some situations. -* **initializationOptions** (optional): These are custom initialization options that can be passed to the LSP. Usually not required, but it will allow the user to configure the LSP. More information can be found [here](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#initialize). -* **host** (optional): It's possible to connect to LSP servers via TCP. This is the host location of the LSP. When using TCP connections *command* can be empty or can be used to initialize the LSP server. And then use the LSP through a TCP connection. -* **port** (optional): It's possible to connect to LSP servers via TCP. This is the post location of the LSP. -* **env** (optional): Array of strings with environment variables added to the process environment. - -### Git integration +`lspclient.json` configuration. + +For more information [read the lsp client documentation](docs/lsp.md). + +#### Git integration *ecode* provides some basic Git integration (more features will come in the future). Its main purpose is to help the user to do the most basics operations with Git. Some of the current features supported: git status and stats visualization (files states), commit, push, checkout, pull, fetch, fast-forward merge, creating+renaming+deleting branches, managing stashes. All stats will be automatically updated/refreshed in real time. There's also some basic configuration available. -The plugin requires the user to have a `git` binary installed and available in `PATH` environment variable. - -#### `git.json` format - -The format follows the same pattern that all previous configuration files. Configuration is represented -in a JSON file with three main keys: `config`, `keybindings`, `servers`. - -C and C++ LSP server example (using [clangd](https://clangd.llvm.org/)) - -```json -{ - "config": { - "silent": false, - "status_recurse_submodules": true, - "statusbar_display_branch": true, - "statusbar_display_modifications": true, - "ui_refresh_frequency": "5s" - }, - "keybindings": { - "git-blame": "alt+shift+b" - } -} -``` - -#### Git config object keys - -* **silent**: Enable/Disable non-critical Git logs. -* **status_recurse_submodules**: Enables/disables recursing sub-modules for the file status report. -* **statusbar_display_branch**: Enables/disables an always visible status on the bottom statusbar. -* **statusbar_display_modifications**: Enables/disables if the number of lines affected is displayed in the statusbar. -* **ui_refresh_frequency**: Indicates the frequency in which the status is updated (it will only trigger updates if changes are detected inside the `.git` directory). -* **filetree_highlight_changes**: Enables/disables the highlighting of changes on the file-tree. -* **filetree_highlight_style_color**: Allows to change the highlight color in the file-tree. - -#### Git keybindings object keys -* **git-blame**: Keybinding to display the a git blame summary over the current positioned line. +For more information [read the git integration documentation](docs/git.md). -### Auto Complete +#### Auto Complete The auto-complete plugin is in charge of providing suggestions for code-completion and signature help. -#### Auto Complete config object keys - -* **max_label_characters**: Maximum characters displayed in the suggestion box. -* **suggestions_syntax_highlight**: Enables/disables syntax highlighting in suggestions. +For more information [read the auto-complete documentation](docs/autocomplete.md). ### XML Tools The XML Tools plugin (disabled by default) provides some nice to have improvements when editing XML content. -#### XML Tools config object keys - -* **auto_edit_match**: Automatically edits the open/close tag when the user edits the element tag name (syncs open and close element names). -* **highlight_match**: When the user moves the cursor to an open or close tag it will highlight the matched open/close tag. +For more information [read the xml tools documentation](docs/xmltools.md). ### Plugins configuration files location @@ -526,204 +317,19 @@ configuration file. The same applies to formatters and LSPs servers. Plugins will always implement a "config" for plugins customization, and will always implement a "keybindings" key to configure custom keybindings. -## Customizations - -### Custom editor color schemes - -Custom editor color schemes can be added in the user color schemes directory found at: - -* *Linux*: uses `XDG_CONFIG_HOME`, usually translates to `~/.config/ecode/editor/colorschemes` -* *macOS*: uses `Application Support` folder in `HOME`, usually translates to `~/Library/Application Support/ecode/editor/colorschemes` -* *Windows*: uses `APPDATA`, usually translates to `C:\Users\{username}\AppData\Roaming\ecode\editor\colorschemes` - -Any file written in the directory will be treated as an editor color scheme file. Each file can contain -any number of color schemes. - -The format of a color scheme can be read from [here](https://github.com/SpartanJ/eepp/blob/develop/bin/assets/colorschemes/colorschemes.conf). - -### Custom terminal color schemes - -Custom terminal color schemes can be added in the user terminal color schemes directory found at: - -* *Linux*: uses `XDG_CONFIG_HOME`, usually translates to `~/.config/ecode/terminal/colorschemes` -* *macOS*: uses `Application Support` folder in `HOME`, usually translates to `~/Library/Application Support/ecode/terminal/colorschemes` -* *Windows*: uses `APPDATA`, usually translates to `C:\Users\{username}\AppData\Roaming\ecode\terminal\colorschemes` +## UI Customizations -Any file written in the directory will be treated as a terminal color scheme file. Each file can contain -any number of color schemes. +*ecode* is highly customizable and extendable thanks to its several configuration files. +If you're interested in creating new color schemes for the editor or terminal, or in creating new +UI themes please. -The format of a color scheme can be read from [here](https://github.com/SpartanJ/eepp/blob/develop/bin/assets/colorschemes/terminalcolorschemes.conf). - -### Custom UI themes - -Custom UI schemes can be added in the user UI themes directory found at: - -* *Linux*: uses `XDG_CONFIG_HOME`, usually translates to `~/.config/ecode/themes` -* *macOS*: uses `Application Support` folder in `HOME`, usually translates to `~/Library/Application Support/ecode/themes` -* *Windows*: uses `APPDATA`, usually translates to `C:\Users\{username}\AppData\Roaming\ecode\themes` - -A custom UI theme file must have the extension `.css`, ecode will look for all the files with `.css` -extension in the directory, the UI theme name is the file name without the extension. The new theme -will appear in `Settings -> Window -> UI Theme`. - -Custom UI themes allow customizing the editor at the user's will. Since ecode uses CSS to style all the -elements of the UI, creating new themes is quite easy. It's possible to customize only the color palette -but it's also possible to customize all the UI elements if desired. Customizing the whole UI theme can -be extensive, but customizing the colors is as simple as changing the values of the CSS variables used -to color the UI. For reference, the complete base UI theme used by ecode can be seen [here](https://github.com/SpartanJ/eepp/blob/develop/bin/assets/ui/breeze.css). -The most important selector would be the `:root` selector, where all the variables are defined. Color -variables can be easily extracted from that file. - -A simple example of a custom UI theme that changes only the tint colors, let's call it `Breeze Light Red.css`: - -```css -:root { - --inherit-base-theme: true; - --primary: #e93d66; - --scrollbar-button: #a94074; - --item-hover: #502834; - --tab-hover: #5e3347; -} -``` - -That effectively would create/add a new UI theme with light red colors. -A very important detail is that if the UI theme must inherit the complete definition of the default theme, -we must add `--inherit-base-theme: true` to the `:root` element, otherwise the UI theme must be defined -completely, which means, every widget must be styled from scratch (not recommended given its complexity). -It's also possible to override the style of the different widgets redefining their properties with the -usual rules that apply to the well-known CSS specification (A.K.A. using adequate -[specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity) and probably abusing the -[!important](https://developer.mozilla.org/en-US/docs/Web/CSS/important) flag). +For more information [read the UI Customization documentation](docs/uicustomizations.md). ## Custom languages support -Custom languages support can be added in the languages directory found at: - -* *Linux*: uses `XDG_CONFIG_HOME`, usually translates to `~/.config/ecode/languages` -* *macOS*: uses `Application Support` folder in `HOME`, usually translates to `~/Library/Application Support/ecode/languages` -* *Windows*: uses `APPDATA`, usually translates to `C:\Users\{username}\AppData\Roaming\ecode\languages` - -ecode will read each file located at that directory with `json` extension. Each file can contain one -or several languages. In order to set several languages the root element of the json file should be -an array, containing one object for each language, otherwise if the root element is an object, it -should contain the language definition. Language definitions can override any currently supported -definition. ecode will prioritize user defined definitions. - -### Language definition format - -```json -{ - "name": "language_name", - "files": [ "Array of file extensions supported" ], - "comment": "Sets the comment string used for auto-comment functionality.", - "patterns": [ - { "pattern": "lua_pattern", "type": "type_name" }, - { "pattern": "no_capture(pattern_capture_1)(pattern_capture_2)", "type": { "no_capture_type_name", "capture_1_type_name", "capture_2_type_name" } }, - { "pattern": ["lua_pattern_start", "lua_pattern_end", "escape_character"], "type": "type_name" } - ], - "symbols": [ - { "symbol_name": "type_name" } - ], - "visible": true, /* sets if the language is visible as a main language in the editor, optional parameter, true by default */ - "auto_close_xml_tag": false, /* sets if the language defined supports auto close XML tags, optional parameter, false by default */ - "lsp_name": "sets the LSP name assigned for the language, optional parameter, it will use the _name_ in lowercase if not set" -} -``` - -### Porting language definitions - -ecode uses the same format for language definition as [lite](https://github.com/rxi/lite) and [lite-xl](https://github.com/lite-xl/lite-xl) editors. -This makes much easier to add new languages to ecode. There's also a helper tool that can be download from -ecode repository located [here](https://github.com/SpartanJ/ecode/tree/develop/tools/data-migration/lite/language) -that allows to directly export a lite language definition to the JSON file format used in ecode. - -### Extending language definitions - -It's possible to easily extend any language definition by exporting it using the CLI arguments provided: -`--export-lang` and `--export-lang-path`. A user wanting to extend or improve a language definition can -export it, modify it and install the definition with a `.json` extension in the [custom languages path](#custom-languages-support). -For example, to extend the language `vue` you will need to run: -`ecode --export-lang=vue --export-lang-path=./vue.json`, exit the exported file and move it to the -[custom languages path](#custom-languages-support). - -### Language definition example - -```json -{ - "name": "Elixir", - "files": [ "%.ex$", "%.exs$" ], - "comment": "#", - "patterns": [ - { "pattern": "#.*\n", "type": "comment" }, - { "pattern": [ ":\"", "\"", "\\" ], "type": "number" }, - { "pattern": [ "\"\"\"", "\"\"\"", "\\" ], "type": "string" }, - { "pattern": [ "\"", "\"", "\\" ], "type": "string" }, - { "pattern": [ "'", "'", "\\" ], "type": "string" }, - { "pattern": [ "~%a[/\"|'%(%[%{<]", "[/\"|'%)%]%}>]", "\\" ], "type": "string"}, - { "pattern": "-?0x%x+", "type": "number" }, - { "pattern": "-?%d+[%d%.eE]*f?", "type": "number" }, - { "pattern": "-?%.?%d+f?", "type": "number" }, - { "pattern": ":\"?[%a_][%w_]*\"?", "type": "number" }, - { "pattern": "[%a][%w_!?]*%f[(]", "type": "function" }, - { "pattern": "%u%w+", "type": "normal" }, - { "pattern": "@[%a_][%w_]*", "type": "keyword2" }, - { "pattern": "_%a[%w_]*", "type": "keyword2" }, - { "pattern": "[%+%-=/%*<>!|&]", "type": "operator" }, - { "pattern": "[%a_][%w_]*", "type": "symbol" } - ], - "symbols": [ - {"def": "keyword"}, - {"defp": "keyword"}, - {"defguard": "keyword"}, - {"defguardp": "keyword"}, - {"defmodule": "keyword"}, - {"defprotocol": "keyword"}, - {"defimpl": "keyword"}, - {"defrecord": "keyword"}, - {"defrecordp": "keyword"}, - {"defmacro": "keyword"}, - {"defmacrop": "keyword"}, - {"defdelegate": "keyword"}, - {"defoverridable": "keyword"}, - {"defexception": "keyword"}, - {"defcallback": "keyword"}, - {"defstruct": "keyword"}, - {"for": "keyword"}, - {"case": "keyword"}, - {"when": "keyword"}, - {"with": "keyword"}, - {"cond": "keyword"}, - {"if": "keyword"}, - {"unless": "keyword"}, - {"try": "keyword"}, - {"receive": "keyword"}, - {"after": "keyword"}, - {"raise": "keyword"}, - {"rescue": "keyword"}, - {"catch": "keyword"}, - {"else": "keyword"}, - {"quote": "keyword"}, - {"unquote": "keyword"}, - {"super": "keyword"}, - {"unquote_splicing": "keyword"}, - {"do": "keyword"}, - {"end": "keyword"}, - {"fn": "keyword"}, - {"import": "keyword2"}, - {"alias": "keyword2"}, - {"use": "keyword2"}, - {"require": "keyword2"}, - {"and": "operator"}, - {"or": "operator"}, - {"true": "literal"}, - {"false": "literal"}, - {"nil": "literal"} - ] -} -``` - -For more complex syntax definitions please see the definition of all the native languages supported -by ecode [here](https://github.com/SpartanJ/eepp/tree/develop/src/eepp/ui/doc/languages). +Users can add support for new languages with a very simple JSON file format. + +For more information [read the custom languages documentation](docs/customlanguages.md). ## Planned Features @@ -731,6 +337,7 @@ Listed in no particular order: * General polishing * Improved plugin system (visual configuration, more flexibility/features) +* AI assistant plugin * Snippets support * Macros support * Better integration with OSes diff --git a/docs/autocomplete.md b/docs/autocomplete.md new file mode 100644 index 000000000..af8fc6526 --- /dev/null +++ b/docs/autocomplete.md @@ -0,0 +1,25 @@ +## Auto Complete + +The auto-complete plugin is in charge of providing suggestions for code-completion and signature help. + +### Auto Complete config object keys + +* **max_label_characters**: Maximum characters displayed in the suggestion box. +* **suggestions_syntax_highlight**: Enables/disables syntax highlighting in suggestions. + +### Auto Complete keybindings object keys + +* ** autocomplete-close-signature-help**: Closes the signature help +* ** autocomplete-close-suggestion**: Closes the suggestions +* ** autocomplete-first-suggestion**: Moves to the first suggestion in the auto complete list +* ** autocomplete-last-suggestion**: Moves to the last suggestion in the auto complete list +* ** autocomplete-next-signature-help**: Moves to the next signature help +* ** autocomplete-next-suggestion**: Moves to the next suggestion +* ** autocomplete-next-suggestion-page**: Moves to the next page of suggestions +* ** autocomplete-pick-suggestion**: Picks a suggestion +* ** autocomplete-pick-suggestion-alt**: Picks a suggestion (alternative keybinding) +* ** autocomplete-pick-suggestion-alt-2**: Picks a suggestion (alternative keybinding) +* ** autocomplete-prev-signature-help**: Moves to the previous signature help +* ** autocomplete-prev-suggestion**: Moves to the previous suggestion +* ** autocomplete-prev-suggestion-page**: Moves to the previous suggestion page +* ** autocomplete-update-suggestions**: Request to display or update currently displayed suggestions (if possible) diff --git a/docs/customlanguages.md b/docs/customlanguages.md new file mode 100644 index 000000000..5bbe8df78 --- /dev/null +++ b/docs/customlanguages.md @@ -0,0 +1,133 @@ +## Custom languages support + +Custom languages support can be added in the languages directory found at: + +* *Linux*: uses `XDG_CONFIG_HOME`, usually translates to `~/.config/ecode/languages` +* *macOS*: uses `Application Support` folder in `HOME`, usually translates to `~/Library/Application Support/ecode/languages` +* *Windows*: uses `APPDATA`, usually translates to `C:\Users\{username}\AppData\Roaming\ecode\languages` + +ecode will read each file located at that directory with `json` extension. Each file can contain one +or several languages. In order to set several languages the root element of the json file should be +an array, containing one object for each language, otherwise if the root element is an object, it +should contain the language definition. Language definitions can override any currently supported +definition. ecode will prioritize user defined definitions. + +### Language definition format + +```json +{ + "name": "language_name", + "files": [ "Array of file extensions supported" ], + "comment": "Sets the comment string used for auto-comment functionality.", + "patterns": [ + { "pattern": "lua_pattern", "type": "type_name" }, + { "pattern": "no_capture(pattern_capture_1)(pattern_capture_2)", "type": { "no_capture_type_name", "capture_1_type_name", "capture_2_type_name" } }, + { "pattern": ["lua_pattern_start", "lua_pattern_end", "escape_character"], "type": "type_name" } + { "regex": "perl_regex", "type": "type_name" }, + { "regex": "no_capture(pattern_capture_1)(pattern_capture_2)", "type": { "no_capture_type_name", "capture_1_type_name", "capture_2_type_name" } }, + { "regex": ["regex_start", "regex_end", "escape_character"], "type": "type_name" } + ], + "symbols": [ + { "symbol_name": "type_name" } + ], + "visible": true, /* sets if the language is visible as a main language in the editor, optional parameter, true by default */ + "auto_close_xml_tag": false, /* sets if the language defined supports auto close XML tags, optional parameter, false by default */ + "lsp_name": "sets the LSP name assigned for the language, optional parameter, it will use the _name_ in lowercase if not set" +} +``` + +### Porting language definitions + +ecode uses the same format for language definition as [lite](https://github.com/rxi/lite) and [lite-xl](https://github.com/lite-xl/lite-xl) editors. +This makes much easier to add new languages to ecode. There's also a helper tool that can be download from +ecode repository located [here](https://github.com/SpartanJ/ecode/tree/develop/tools/data-migration/lite/language) +that allows to directly export a lite language definition to the JSON file format used in ecode. + +### Extending language definitions + +It's possible to easily extend any language definition by exporting it using the CLI arguments provided: +`--export-lang` and `--export-lang-path`. A user wanting to extend or improve a language definition can +export it, modify it and install the definition with a `.json` extension in the [custom languages path](#custom-languages-support). +For example, to extend the language `vue` you will need to run: +`ecode --export-lang=vue --export-lang-path=./vue.json`, exit the exported file and move it to the +[custom languages path](#custom-languages-support). + +### Language definition example + +```json +{ + "name": "Elixir", + "files": [ "%.ex$", "%.exs$" ], + "comment": "#", + "patterns": [ + { "pattern": "#.*\n", "type": "comment" }, + { "pattern": [ ":\"", "\"", "\\" ], "type": "number" }, + { "pattern": [ "\"\"\"", "\"\"\"", "\\" ], "type": "string" }, + { "pattern": [ "\"", "\"", "\\" ], "type": "string" }, + { "pattern": [ "'", "'", "\\" ], "type": "string" }, + { "pattern": [ "~%a[/\"|'%(%[%{<]", "[/\"|'%)%]%}>]", "\\" ], "type": "string"}, + { "pattern": "-?0x%x+", "type": "number" }, + { "pattern": "-?%d+[%d%.eE]*f?", "type": "number" }, + { "pattern": "-?%.?%d+f?", "type": "number" }, + { "pattern": ":\"?[%a_][%w_]*\"?", "type": "number" }, + { "pattern": "[%a][%w_!?]*%f[(]", "type": "function" }, + { "pattern": "%u%w+", "type": "normal" }, + { "pattern": "@[%a_][%w_]*", "type": "keyword2" }, + { "pattern": "_%a[%w_]*", "type": "keyword2" }, + { "pattern": "[%+%-=/%*<>!|&]", "type": "operator" }, + { "pattern": "[%a_][%w_]*", "type": "symbol" } + ], + "symbols": [ + {"def": "keyword"}, + {"defp": "keyword"}, + {"defguard": "keyword"}, + {"defguardp": "keyword"}, + {"defmodule": "keyword"}, + {"defprotocol": "keyword"}, + {"defimpl": "keyword"}, + {"defrecord": "keyword"}, + {"defrecordp": "keyword"}, + {"defmacro": "keyword"}, + {"defmacrop": "keyword"}, + {"defdelegate": "keyword"}, + {"defoverridable": "keyword"}, + {"defexception": "keyword"}, + {"defcallback": "keyword"}, + {"defstruct": "keyword"}, + {"for": "keyword"}, + {"case": "keyword"}, + {"when": "keyword"}, + {"with": "keyword"}, + {"cond": "keyword"}, + {"if": "keyword"}, + {"unless": "keyword"}, + {"try": "keyword"}, + {"receive": "keyword"}, + {"after": "keyword"}, + {"raise": "keyword"}, + {"rescue": "keyword"}, + {"catch": "keyword"}, + {"else": "keyword"}, + {"quote": "keyword"}, + {"unquote": "keyword"}, + {"super": "keyword"}, + {"unquote_splicing": "keyword"}, + {"do": "keyword"}, + {"end": "keyword"}, + {"fn": "keyword"}, + {"import": "keyword2"}, + {"alias": "keyword2"}, + {"use": "keyword2"}, + {"require": "keyword2"}, + {"and": "operator"}, + {"or": "operator"}, + {"true": "literal"}, + {"false": "literal"}, + {"nil": "literal"} + ] +} +``` + +For more complex syntax definitions please see the definition of all the native languages supported +by ecode [here](https://github.com/SpartanJ/eepp/tree/develop/src/eepp/ui/doc/languages) and +[here](https://github.com/SpartanJ/eepp/tree/develop/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages). diff --git a/docs/formatter.md b/docs/formatter.md new file mode 100644 index 000000000..e87059733 --- /dev/null +++ b/docs/formatter.md @@ -0,0 +1,46 @@ +## Auto Formatter + +The formatter plugin works exactly like the linter plugin, but it will execute tools that auto-format code. +*ecode* provides support for several languages by default with can be extended easily by expanding the +`formatters.json` configuration. `formatters.json` default configuration can be obtained from [here](https://raw.githubusercontent.com/SpartanJ/eepp/develop/bin/assets/plugins/formatters.json). +It also supports some formatters natively, this means that the formatter comes with ecode without requiring any external dependency. +And also supports LSP text document formatting, meaning that if you're running an LSP that supports formatting documents, formatting will be available too. +To configure new formatters you can create a new `formatters.json` file in the [default configuration path](#plugins-configuration-files-location) of *ecode*. + +### `formatters.json` format + +```json +{ + "config": { + "auto_format_on_save": false + }, + "keybindings": { + "format-doc": "alt+f" + }, + "formatters": [ + { + "file_patterns": ["%.js$", "%.ts$"], + "command": "prettier $FILENAME" + } + ] +} +``` + +### Currently supported formatters + +Please check the [language support table](#language-support-table) + +### Formatter config object keys + +* **auto_format_on_save**: Indicates if after saving the file it should be auto-formatted + +### Formatter keybindings object keys + +* **format-doc**: Keybinding to format the doc with the configured language formatter + +### Formatter JSON object keys + +* **file_patterns**: Array of [Lua Patterns](https://www.lua.org/manual/5.4/manual.html#6.4.1) representing the file extensions that must use the formatter +* **command**: The command to execute to run the formatter. $FILENAME represents the file path +* **type**: Indicates the mode that which the formatter outputs the results. Supported two possible options: "inplace" (file is replaced with the formatted version), "output" (newly formatted file is the stdout of the program, default option) or "native" (uses the formatter provided by ecode) +* **url** (optional): The web page URL of the formatter diff --git a/docs/git.md b/docs/git.md new file mode 100644 index 000000000..117284396 --- /dev/null +++ b/docs/git.md @@ -0,0 +1,44 @@ +## Git integration + +*ecode* provides some basic Git integration (more features will come in the future). Its main purpose +is to help the user to do the most basics operations with Git. Some of the current features supported: +git status and stats visualization (files states), commit, push, checkout, pull, fetch, fast-forward +merge, creating+renaming+deleting branches, managing stashes. All stats will be automatically +updated/refreshed in real time. There's also some basic configuration available. +The plugin requires the user to have a `git` binary installed and available in `PATH` environment variable. + +### `git.json` format + +The format follows the same pattern that all previous configuration files. Configuration is represented +in a JSON file with three main keys: `config`, `keybindings`, `servers`. + +C and C++ LSP server example (using [clangd](https://clangd.llvm.org/)) + +```json +{ + "config": { + "silent": false, + "status_recurse_submodules": true, + "statusbar_display_branch": true, + "statusbar_display_modifications": true, + "ui_refresh_frequency": "5s" + }, + "keybindings": { + "git-blame": "alt+shift+b" + } +} +``` + +### Git config object keys + +* **silent**: Enable/Disable non-critical Git logs. +* **status_recurse_submodules**: Enables/disables recursing sub-modules for the file status report. +* **statusbar_display_branch**: Enables/disables an always visible status on the bottom statusbar. +* **statusbar_display_modifications**: Enables/disables if the number of lines affected is displayed in the statusbar. +* **ui_refresh_frequency**: Indicates the frequency in which the status is updated (it will only trigger updates if changes are detected inside the `.git` directory). +* **filetree_highlight_changes**: Enables/disables the highlighting of changes on the file-tree. +* **filetree_highlight_style_color**: Allows to change the highlight color in the file-tree. + +### Git keybindings object keys + +* **git-blame**: Keybinding to display the a git blame summary over the current positioned line. diff --git a/docs/linter.md b/docs/linter.md new file mode 100644 index 000000000..11da175a7 --- /dev/null +++ b/docs/linter.md @@ -0,0 +1,59 @@ +## Linter + +Linter support is provided by executing already stablished linters from each language. +*ecode* provides support for several languages by default and can be extended easily by expanding the +`linters.json` configuration. `linters.json` default configuration can be obtained from [here](https://raw.githubusercontent.com/SpartanJ/eepp/develop/bin/assets/plugins/linters.json). +To configure new linters you can create a new `linters.json` file in the [default configuration path](#plugins-configuration-files-location) of *ecode*. + +### `linters.json` format + +The format is a very simple JSON object with a config object and array of objects containing the file +formats supported, the [Lua pattern](https://www.lua.org/manual/5.4/manual.html#6.4.1) to find any error printed by the linter to the stdout, the position +of each group of the pattern, and the command to execute. It also supports some optional extra object keys. + +JavaScript linter example (using [eslint](https://eslint.org/)) + +```json +{ + "config": { + "delay_time": "0.5s" + }, + "linters": [ + { + "file_patterns": ["%.js$", "%.ts$"], + "warning_pattern": "[^:]:(%d+):(%d+): ([^%[]+)%[([^\n]+)", + "warning_pattern_order": { "line": 1, "col": 2, "message": 3, "type": 4 }, + "command": "eslint --no-ignore --format unix $FILENAME" + } + ] +} +``` + +That's all we need to have a working linter in *ecode*. Linters executables must be installed manually +by the user, linters will not come with the editor, and they also need to be visible to the executable. +This means that it must be on `PATH` environment variable or the path to the binary must be absolute. + +### Currently supported linters + +Please check the [language support table](#language-support-table) + +### Linter config object keys + +* **delay_time**: Delay to run the linter after editing a document +* **enable_error_lens**: Enables error lens (prints the message inline) +* **enable_lsp_diagnostics**: Boolean that enable/disable LSP diagnostics as part of the linting. Enabled by default. +* **disable_lsp_languages**: Array of LSP languages disabled for LSP diagnostics. For example: `"disable_lsp_languages": ["lua", "python"]`, disables lua and python. +* **disable_languages**: Array of linters disabled from external linter application diagnostics. For example: `"disable_languages": ["lua", "python"]`, disables luacheck and ruff respectively. +* **goto_ignore_warnings**: Defines the behavior of the "linter-go-to-next-error" and "linter-go-to-previous-error" keybindings. If ignore warnings is true it will jump only between errors. + +### Linter JSON object keys + +* **file_patterns**: Array of [Lua Patterns](https://www.lua.org/manual/5.4/manual.html#6.4.1) representing the file extensions that must use the linter +* **warning_pattern**: [Lua Pattern](https://www.lua.org/manual/5.4/manual.html#6.4.1) to be parsed from the executable stdout +* **warning_pattern_order**: The order where the line, column, error/warning/notice message, and the type of the message (warning, error, notice, info) are read. The pattern must have at least 3 groups (line, message, and type). The error type is auto-detected from its name. +* **command**: The command to execute to run the linter. $FILENAME represents the file path. +* **url** (optional): The web page URL of the linter +* **expected_exitcodes**: Array of integer numbers accepted as parseable exit codes (optional) +* **no_errors_exit_code**: Integer number representing the exit code that means that no errors were found (optional). +* **deduplicate**: In case the linter outputs duplicated errors, this boolean will ignore duplicated errors (optional, boolean true/false) +* **use_tmp_folder**: Temporal files (files representing the current status of the modified file) will be written in the default temporal folder of the operating system, otherwise it will be written in the same folder path of the modified file (optional, boolean true/false). diff --git a/docs/lsp.md b/docs/lsp.md new file mode 100644 index 000000000..e4946f639 --- /dev/null +++ b/docs/lsp.md @@ -0,0 +1,85 @@ +## LSP Client + +LSP support is provided by executing already stablished LSP from each language. +*ecode* provides support for several languages by default and can be extended easily by expanding the +`lspclient.json` configuration. `lspclient.json` default configuration can be obtained from [here](https://raw.githubusercontent.com/SpartanJ/eepp/develop/bin/assets/plugins/lspclient.json). +To configure new LSPs you can create a new `lspclient.json` file in the [default configuration path](#plugins-configuration-files-location) of *ecode*. + +Important note: LSP servers can be very resource intensive and might not be always the best option for simple projects. + +Implementation details: LSP servers are only loaded when needed, no process will be opened until a +supported file is opened in the project. + +### `lspclient.json` format + +The format follows the same pattern that all previous configuration files. Configuration is represented +in a JSON file with three main keys: `config`, `keybindings`, `servers`. + +C and C++ LSP server example (using [clangd](https://clangd.llvm.org/)) + +```json +{ + "config": { + "hover_delay": "0.5s" + }, + "servers": [ + { + "language": "c", + "name": "clangd", + "url": "https://clangd.llvm.org/", + "command": "clangd -log=error --background-index --limit-results=500 --completion-style=bundled", + "file_patterns": ["%.c$", "%.h$", "%.C$", "%.H$", "%.objc$"] + }, + { + "language": "cpp", + "use": "clangd", + "file_patterns": ["%.inl$", "%.cpp$", "%.hpp$", "%.cc$", "%.cxx$", "%.c++$", "%.hh$", "%.hxx$", "%.h++$", "%.objcpp$"] + } + ] +} +``` + +That's all we need to have a working LSP in *ecode*. LSPs executables must be installed manually +by the user, LSPs will not come with the editor, and they also need to be visible to the executable. +This means that it must be on `PATH` environment variable or the path to the binary must be absolute. + +### Currently supported LSPs + +Please check the [language support table](#language-support-table) + +### LSP Client config object keys + +* **hover_delay**: The time the editor must wait to show symbol information when hovering any piece of code. +* **server_close_after_idle_time**: The time the LSP Server will keep alive after all documents that consumes that LSP Server were closed. LSP Servers are spawned and killed on demand. +* **semantic_highlighting**: Enable/Disable semantic highlighting (disabled by default, boolean) +* **disable_semantic_highlighting_lang**: An array of languages where semantic highlighting should be disabled +* **silent**: Enable/Disable non-critical LSP logs +* **trim_logs**: If logs are enabled and trim_logs is enabled it will trim the line log size at maximum 1 KiB per line (useful for debugging) +* **breadcrumb_navigation**: Enable/Disable the breadcrumb (enabled by default) +* **breadcrumb_height**: Defines the height of the breadcrumb in [CSS length](https://eepp.ensoft.dev/page_cssspecification.html#length-data-type) + +### LSP Client keybindings object keys + +* **lsp-symbol-info**: Keybinding to request symbol information +* **lsp-go-to-definition**: Keybinding to "Go to Definition" +* **lsp-go-to-declaration**: Keybinding to "Go to Declaration" +* **lsp-go-to-implementation**: Keybinding to "Go to Implementation" +* **lsp-go-to-type-definition**: Keybinding to "Go to Type Definition" +* **lsp-symbol-references**: Keybinding to "Find References to Symbol Under Cursor" +* **lsp-symbol-code-action**: Keybinding to "Code Action" +* **lsp-switch-header-source**: Keybinding to "Switch Header/Source" (only available for C and C++) + +### LSP Client JSON object keys + +* **language**: The LSP language identifier. Some identifiers can be found [here](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocumentItem) +* **name**: The name of the language server +* **url** (optional): The web page URL of the language server +* **use** (optional): A server can be inherit the configuration from other server. This must be the name of the server configuration that inherits (useful for LSPs that support several languages like clang and typescript-language-server). +* **file_patterns**: Array of [Lua Patterns](https://www.lua.org/manual/5.4/manual.html#6.4.1) representing the file extensions that must use the LSP client +* **command**: The command to execute to run the LSP. It's possible to override the default LSP command by declaring the server in the `lspclient.json` config. It's also possible to specify a different command for each platform, given that it might change in some ocassions per-platform. In that case an object should be used, with each key being a platform, and there's also a wildcard platform "other" to specify any other platform that does not match the platform definition. For example, `sourcekit-lsp` uses: `"command": {"macos": "xcrun sourcekit-lsp","other": "sourcekit-lsp"}` +* **command_parameters** (optional): The command parameters. Parameters can be set from the **command** also, unless the command needs to run a binary with name with spaces. Also command_parameters can be used to add more parameters to the original command. The lsp configuration can be overriden from the lspclient.json in the user configuration. For example: a user trying to append some command line arguments to clang would need to do something like: `{"name": "clangd","command_parameters": "--background-index-priority=background --malloc-trim"}` +* **rootIndicationFileNames** (optional): Some languages need to indicate the project root path to the LSP work correctly. This is an array of files that might indicate where the root path is. Usually this is resolver by the LSP itself, but it might help in some situations. +* **initializationOptions** (optional): These are custom initialization options that can be passed to the LSP. Usually not required, but it will allow the user to configure the LSP. More information can be found [here](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#initialize). +* **host** (optional): It's possible to connect to LSP servers via TCP. This is the host location of the LSP. When using TCP connections *command* can be empty or can be used to initialize the LSP server. And then use the LSP through a TCP connection. +* **port** (optional): It's possible to connect to LSP servers via TCP. This is the post location of the LSP. +* **env** (optional): Array of strings with environment variables added to the process environment. diff --git a/docs/uicustomizations.md b/docs/uicustomizations.md new file mode 100644 index 000000000..f39049a94 --- /dev/null +++ b/docs/uicustomizations.md @@ -0,0 +1,68 @@ +## UI Customizations + +### Custom editor color schemes + +Custom editor color schemes can be added in the user color schemes directory found at: + +* *Linux*: uses `XDG_CONFIG_HOME`, usually translates to `~/.config/ecode/editor/colorschemes` +* *macOS*: uses `Application Support` folder in `HOME`, usually translates to `~/Library/Application Support/ecode/editor/colorschemes` +* *Windows*: uses `APPDATA`, usually translates to `C:\Users\{username}\AppData\Roaming\ecode\editor\colorschemes` + +Any file written in the directory will be treated as an editor color scheme file. Each file can contain +any number of color schemes. + +The format of a color scheme can be read from [here](https://github.com/SpartanJ/eepp/blob/develop/bin/assets/colorschemes/colorschemes.conf). + +### Custom terminal color schemes + +Custom terminal color schemes can be added in the user terminal color schemes directory found at: + +* *Linux*: uses `XDG_CONFIG_HOME`, usually translates to `~/.config/ecode/terminal/colorschemes` +* *macOS*: uses `Application Support` folder in `HOME`, usually translates to `~/Library/Application Support/ecode/terminal/colorschemes` +* *Windows*: uses `APPDATA`, usually translates to `C:\Users\{username}\AppData\Roaming\ecode\terminal\colorschemes` + +Any file written in the directory will be treated as a terminal color scheme file. Each file can contain +any number of color schemes. + +The format of a color scheme can be read from [here](https://github.com/SpartanJ/eepp/blob/develop/bin/assets/colorschemes/terminalcolorschemes.conf). + +### Custom UI themes + +Custom UI schemes can be added in the user UI themes directory found at: + +* *Linux*: uses `XDG_CONFIG_HOME`, usually translates to `~/.config/ecode/themes` +* *macOS*: uses `Application Support` folder in `HOME`, usually translates to `~/Library/Application Support/ecode/themes` +* *Windows*: uses `APPDATA`, usually translates to `C:\Users\{username}\AppData\Roaming\ecode\themes` + +A custom UI theme file must have the extension `.css`, ecode will look for all the files with `.css` +extension in the directory, the UI theme name is the file name without the extension. The new theme +will appear in `Settings -> Window -> UI Theme`. + +Custom UI themes allow customizing the editor at the user's will. Since ecode uses CSS to style all the +elements of the UI, creating new themes is quite easy. It's possible to customize only the color palette +but it's also possible to customize all the UI elements if desired. Customizing the whole UI theme can +be extensive, but customizing the colors is as simple as changing the values of the CSS variables used +to color the UI. For reference, the complete base UI theme used by ecode can be seen [here](https://github.com/SpartanJ/eepp/blob/develop/bin/assets/ui/breeze.css). +The most important selector would be the `:root` selector, where all the variables are defined. Color +variables can be easily extracted from that file. + +A simple example of a custom UI theme that changes only the tint colors, let's call it `Breeze Light Red.css`: + +```css +:root { + --inherit-base-theme: true; + --primary: #e93d66; + --scrollbar-button: #a94074; + --item-hover: #502834; + --tab-hover: #5e3347; +} +``` + +That effectively would create/add a new UI theme with light red colors. +A very important detail is that if the UI theme must inherit the complete definition of the default theme, +we must add `--inherit-base-theme: true` to the `:root` element, otherwise the UI theme must be defined +completely, which means, every widget must be styled from scratch (not recommended given its complexity). +It's also possible to override the style of the different widgets redefining their properties with the +usual rules that apply to the well-known CSS specification (A.K.A. using adequate +[specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity) and probably abusing the +[!important](https://developer.mozilla.org/en-US/docs/Web/CSS/important) flag). diff --git a/docs/xmltools.md b/docs/xmltools.md new file mode 100644 index 000000000..55e2898cb --- /dev/null +++ b/docs/xmltools.md @@ -0,0 +1,9 @@ +## XML Tools + +The XML Tools plugin (disabled by default) provides some nice to have improvements when editing XML +content. + +### XML Tools config object keys + +* **auto_edit_match**: Automatically edits the open/close tag when the user edits the element tag name (syncs open and close element names). +* **highlight_match**: When the user moves the cursor to an open or close tag it will highlight the matched open/close tag. From eef7b77d3f8233a441f83a3ecd918e7fd72853df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sat, 1 Feb 2025 11:06:44 -0300 Subject: [PATCH 10/30] Minor changes. --- README.md | 43 ++++++++++++++++++++++++++----------------- docs/autocomplete.md | 28 ++++++++++++++-------------- 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 550d1bb29..69a347729 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,17 @@ eepp GUI library as part of one of its main objectives. ![ecode - Code Editor](https://github.com/SpartanJ/ecode/assets/650416/7926c3f3-1b3b-4fe5-859a-3099df73b7e8) -For more screenshots checkout [running on macOS](https://github.com/SpartanJ/ecode/assets/650416/9e8e00a7-fbcc-479b-8588-0023d8f86a9a), [running on Windows](https://user-images.githubusercontent.com/650416/172760308-30d5335c-d5f7-4dbe-94ce-2e556d858909.png), [running on Haiku](https://user-images.githubusercontent.com/650416/172760331-799b7d16-104b-4cac-ba34-c0cf60ba4374.png), [low dpi](https://user-images.githubusercontent.com/650416/172519582-1aab1e94-8d69-4c2c-b4ba-de9f2d8729cf.png), [code completion](https://user-images.githubusercontent.com/650416/172521557-f68aa855-0534-49c9-b33e-8f9f8b47b9d2.png), [terminal](https://user-images.githubusercontent.com/650416/180109676-a1f9dbc6-d170-4e67-a19c-611cff9f04dd.png), [file locator](https://user-images.githubusercontent.com/650416/172521593-bb8fde13-2600-44e5-87d2-3fc41370fc77.png), [file formats](https://user-images.githubusercontent.com/650416/172521619-ac1aeb82-80e5-49fd-894e-afc780d4c0fd.png), [global find](https://user-images.githubusercontent.com/650416/172523164-2ca9b988-7d2d-4b8c-b6d2-10e593d7fc14.png), [global replace](https://user-images.githubusercontent.com/650416/172523195-00451552-2a56-4595-8b3a-cf8071b36dc6.png), [linter](https://user-images.githubusercontent.com/650416/172523272-45c267af-2585-4c54-86e0-739b5202569e.png). +For more screenshots checkout +[running on macOS](https://github.com/SpartanJ/ecode/assets/650416/9e8e00a7-fbcc-479b-8588-0023d8f86a9a), +[running on Windows](https://user-images.githubusercontent.com/650416/172760308-30d5335c-d5f7-4dbe-94ce-2e556d858909.png), +[running on Haiku](https://user-images.githubusercontent.com/650416/172760331-799b7d16-104b-4cac-ba34-c0cf60ba4374.png), +[low dpi](https://user-images.githubusercontent.com/650416/172519582-1aab1e94-8d69-4c2c-b4ba-de9f2d8729cf.png), +[code completion](https://user-images.githubusercontent.com/650416/172521557-f68aa855-0534-49c9-b33e-8f9f8b47b9d2.png), [terminal](https://user-images.githubusercontent.com/650416/180109676-a1f9dbc6-d170-4e67-a19c-611cff9f04dd.png), +[file locator](https://user-images.githubusercontent.com/650416/172521593-bb8fde13-2600-44e5-87d2-3fc41370fc77.png), +[file formats](https://user-images.githubusercontent.com/650416/172521619-ac1aeb82-80e5-49fd-894e-afc780d4c0fd.png), +[global find](https://user-images.githubusercontent.com/650416/172523164-2ca9b988-7d2d-4b8c-b6d2-10e593d7fc14.png), +[global replace](https://user-images.githubusercontent.com/650416/172523195-00451552-2a56-4595-8b3a-cf8071b36dc6.png), +[linter](https://user-images.githubusercontent.com/650416/172523272-45c267af-2585-4c54-86e0-739b5202569e.png). ## Notable Features @@ -22,11 +32,11 @@ For more screenshots checkout [running on macOS](https://github.com/SpartanJ/eco * Uncluttered GUI * Syntax Highlighting (including nested syntax highlighting, supporting over 90 languages and LSP semantic highlighting) * Multi-cursor support -* Terminal support -* Command Palette * [LSP](https://microsoft.github.io/language-server-protocol/) support -* [Git](https://git-scm.com/) integration * Debugger support via [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol) +* [Git](https://git-scm.com/) integration +* Terminal support +* Command Palette * Auto-Completion * Customizable Linter support * Customizable Formatter support @@ -88,7 +98,7 @@ there. But you can give it a try: ### Demo Clarifications * You'll need a modern browser with [SharedArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#browser_compatibility) support -* Linter, Formatter and LSP plugins won't work since both work running other processes (except for the native formatters that are available) +* Linter, Formatter,, LSP Client and Debugger plugins won't work since they work by running other processes (except for the native formatters that are available) * WebGL renderer isn't optimized, so it's not as fast as it could/should be (still, performance is good in chromium based browsers) * Demo is designed for desktop resolutions (mobile is unusable, IME keyboard won't show up due to an emscripten limitation) @@ -260,15 +270,6 @@ Linter support is provided by executing already stablished linters from each lan For more information [read the linter documentation](docs/linter.md). - -#### Auto Formatter - -The formatter plugin works exactly like the linter plugin, but it will execute tools that auto-format code. -*ecode* provides support for several languages by default with can be extended easily by expanding the -`formatters.json` configuration. - -For more information [read the formatter documentation](docs/formatter.md). - #### LSP Client LSP support is provided by executing already stablished LSP from each language. @@ -287,13 +288,21 @@ updated/refreshed in real time. There's also some basic configuration available. For more information [read the git integration documentation](docs/git.md). +#### Auto Formatter + +The formatter plugin works exactly like the linter plugin, but it will execute tools that auto-format code. +*ecode* provides support for several languages by default with can be extended easily by expanding the +`formatters.json` configuration. + +For more information [read the formatter documentation](docs/formatter.md). + #### Auto Complete The auto-complete plugin is in charge of providing suggestions for code-completion and signature help. For more information [read the auto-complete documentation](docs/autocomplete.md). -### XML Tools +#### XML Tools The XML Tools plugin (disabled by default) provides some nice to have improvements when editing XML content. @@ -321,7 +330,7 @@ Plugins will always implement a "config" for plugins customization, and will alw *ecode* is highly customizable and extendable thanks to its several configuration files. If you're interested in creating new color schemes for the editor or terminal, or in creating new -UI themes please. +UI themes please check our documentation: For more information [read the UI Customization documentation](docs/uicustomizations.md). @@ -382,7 +391,7 @@ _\*4_ Some work has been done to support text-shaping but it's not ready for gen ## Author comments -This editor has a deeply rooted inspiration from the lite, lite-xl, QtCreator, and Sublime Text +This editor has a deeply rooted inspiration from the lite, lite-xl, QtCreator and Sublime Text editors. Several features were developed based on the lite/lite-xl implementations. Some features can be ported directly from lite: color-schemes and syntax-highlighting patterns (eepp implementation expands original lite implementation to add many more features). diff --git a/docs/autocomplete.md b/docs/autocomplete.md index af8fc6526..a7caa14fd 100644 --- a/docs/autocomplete.md +++ b/docs/autocomplete.md @@ -9,17 +9,17 @@ The auto-complete plugin is in charge of providing suggestions for code-completi ### Auto Complete keybindings object keys -* ** autocomplete-close-signature-help**: Closes the signature help -* ** autocomplete-close-suggestion**: Closes the suggestions -* ** autocomplete-first-suggestion**: Moves to the first suggestion in the auto complete list -* ** autocomplete-last-suggestion**: Moves to the last suggestion in the auto complete list -* ** autocomplete-next-signature-help**: Moves to the next signature help -* ** autocomplete-next-suggestion**: Moves to the next suggestion -* ** autocomplete-next-suggestion-page**: Moves to the next page of suggestions -* ** autocomplete-pick-suggestion**: Picks a suggestion -* ** autocomplete-pick-suggestion-alt**: Picks a suggestion (alternative keybinding) -* ** autocomplete-pick-suggestion-alt-2**: Picks a suggestion (alternative keybinding) -* ** autocomplete-prev-signature-help**: Moves to the previous signature help -* ** autocomplete-prev-suggestion**: Moves to the previous suggestion -* ** autocomplete-prev-suggestion-page**: Moves to the previous suggestion page -* ** autocomplete-update-suggestions**: Request to display or update currently displayed suggestions (if possible) +* **autocomplete-close-signature-help**: Closes the signature help +* **autocomplete-close-suggestion**: Closes the suggestions +* **autocomplete-first-suggestion**: Moves to the first suggestion in the auto complete list +* **autocomplete-last-suggestion**: Moves to the last suggestion in the auto complete list +* **autocomplete-next-signature-help**: Moves to the next signature help +* **autocomplete-next-suggestion**: Moves to the next suggestion +* **autocomplete-next-suggestion-page**: Moves to the next page of suggestions +* **autocomplete-pick-suggestion**: Picks a suggestion +* **autocomplete-pick-suggestion-alt**: Picks a suggestion (alternative keybinding) +* **autocomplete-pick-suggestion-alt-2**: Picks a suggestion (alternative keybinding) +* **autocomplete-prev-signature-help**: Moves to the previous signature help +* **autocomplete-prev-suggestion**: Moves to the previous suggestion +* **autocomplete-prev-suggestion-page**: Moves to the previous suggestion page +* **autocomplete-update-suggestions**: Request to display or update currently displayed suggestions (if possible) From dd52b9308027e45b44be1d982fe6c72eae701d11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sat, 1 Feb 2025 16:18:55 -0300 Subject: [PATCH 11/30] Debugger docs WIP. --- README.md | 9 +++++++++ docs/debugger.md | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 docs/debugger.md diff --git a/README.md b/README.md index 69a347729..200f04335 100644 --- a/README.md +++ b/README.md @@ -278,6 +278,15 @@ LSP support is provided by executing already stablished LSP from each language. For more information [read the lsp client documentation](docs/lsp.md). +#### Debugger + +Debugger support is provided by the implementation the [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol). +ecode is able to debug any language implementing this protocol, although the protocol is generic sometimes +requires to support some of the languages some specific adaptation is needed, so initially the support +is limited to the languages mentoined in the support list. + +For more information on how to use the debugger [read the debugger documentation](docs/debugger.md). + #### Git integration *ecode* provides some basic Git integration (more features will come in the future). Its main purpose diff --git a/docs/debugger.md b/docs/debugger.md new file mode 100644 index 000000000..f652f9371 --- /dev/null +++ b/docs/debugger.md @@ -0,0 +1,39 @@ +## Debugger + +*ecode* implements the [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol) for its debugger support. +This facilitates debugging integration with various languages thanks to the usage of a common protocol. This protocol it's +being used by vscode and other major editors and it has been implemented for a great range if programming languages, see +[implementors list](https://microsoft.github.io/debug-adapter-protocol/implementors/adapters/). +Initially ecode provides support for some of the most common debug adapters implementation, and it will continue adding +more languages by default. + +### How it works? + +Initially there are to ways of using the debugger: the first option is by using the default ecode +configurations provided. These configurations are designed to work in conjunction with the build +settings. This means that the executable used for the default options is the `Run Target` of your +currently selected `Build Configuration`. The second option is by consuming a custom launch +configuration that the user must provide inside the project folder. The configuration must be located +at `.ecode/launch.json` or at `.vscode/launch.json`. *ecode* uses the same *vscode* `launch.json` format +and it will always read and try to consume those configurations, this is to ease users migrating from +the most common DAP implementation. + +#### Using ecode default configurations + +Once you have a `Build Configuration` with a `Run Target` selected, this will be used for the `Launch` +configuration corresponding for your language. All languages will provide a `Launch` type of `Debugger Configuration`. +`Launch` means that an executable will be executed / launched from your local, based on your `Run Target` configuration. +This is the most common configuration for most users. So, after the `Run Target` is ready user must +go to the `Debugger` tab at the Side Panel and pick the debugger that wants to use based on the language +that needs to be debugged. For example a binary compiled from C or C++ can be debugged with `gdb` or `lldb-dap` +(this will also depend on the platform). So user must pick one of the two, let's say `lldb-dap` and +select the appropiate `Debugger Configuration`, for our use example that would be `Launch binary`, and +just click `Debug`. + + +Any `Attach` option refers to the action for attaching the debugger to an already running binary (locally or remote). +There is also the option to attach to a binary via its process ID or via its binary name (already running +or about to be executed, in that case it will `(wait)` for the process). + +There are also some language specific configurations like loading core dumps. Each debugger and language +will provided different configurations depending on the capabilities of the debugger and language. From 635a648a298fde87676e8999b25feb06e1e4786e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Thu, 6 Feb 2025 00:31:38 -0300 Subject: [PATCH 12/30] Improve debugger documentation. --- docs/debugger.md | 148 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 111 insertions(+), 37 deletions(-) diff --git a/docs/debugger.md b/docs/debugger.md index f652f9371..9540e11ac 100644 --- a/docs/debugger.md +++ b/docs/debugger.md @@ -1,39 +1,113 @@ ## Debugger -*ecode* implements the [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol) for its debugger support. -This facilitates debugging integration with various languages thanks to the usage of a common protocol. This protocol it's -being used by vscode and other major editors and it has been implemented for a great range if programming languages, see -[implementors list](https://microsoft.github.io/debug-adapter-protocol/implementors/adapters/). -Initially ecode provides support for some of the most common debug adapters implementation, and it will continue adding -more languages by default. - -### How it works? - -Initially there are to ways of using the debugger: the first option is by using the default ecode -configurations provided. These configurations are designed to work in conjunction with the build -settings. This means that the executable used for the default options is the `Run Target` of your -currently selected `Build Configuration`. The second option is by consuming a custom launch -configuration that the user must provide inside the project folder. The configuration must be located -at `.ecode/launch.json` or at `.vscode/launch.json`. *ecode* uses the same *vscode* `launch.json` format -and it will always read and try to consume those configurations, this is to ease users migrating from -the most common DAP implementation. - -#### Using ecode default configurations - -Once you have a `Build Configuration` with a `Run Target` selected, this will be used for the `Launch` -configuration corresponding for your language. All languages will provide a `Launch` type of `Debugger Configuration`. -`Launch` means that an executable will be executed / launched from your local, based on your `Run Target` configuration. -This is the most common configuration for most users. So, after the `Run Target` is ready user must -go to the `Debugger` tab at the Side Panel and pick the debugger that wants to use based on the language -that needs to be debugged. For example a binary compiled from C or C++ can be debugged with `gdb` or `lldb-dap` -(this will also depend on the platform). So user must pick one of the two, let's say `lldb-dap` and -select the appropiate `Debugger Configuration`, for our use example that would be `Launch binary`, and -just click `Debug`. - - -Any `Attach` option refers to the action for attaching the debugger to an already running binary (locally or remote). -There is also the option to attach to a binary via its process ID or via its binary name (already running -or about to be executed, in that case it will `(wait)` for the process). - -There are also some language specific configurations like loading core dumps. Each debugger and language -will provided different configurations depending on the capabilities of the debugger and language. +*ecode* implements the [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol) (DAP) for debugger support. This enables seamless debugging integration with various languages through a common protocol. DAP is used by VS Code and other major editors and has been implemented for a wide range of programming languages. For more information, see the [list of implementations](https://microsoft.github.io/debug-adapter-protocol/implementors/adapters/). + +Initially, *ecode* provides support for some of the most common debug adapter implementations, with plans to add support for more languages in future updates. + +### How It Works + +There are two ways to use the debugger in *ecode*: + +1. **Using Default *ecode* Configurations:** These configurations are designed to work seamlessly with your build settings. The executable used in these default options is the `Run Target` of your currently selected `Build Configuration`. + +2. **Using Custom Launch Configurations:** Users can provide custom launch configurations within the project folder. These configurations should be located at `.ecode/launch.json` or `.vscode/launch.json`. *ecode* uses the same `launch.json` format as VS Code, ensuring compatibility for users migrating from other DAP-based editors. However, *ecode* will only recognize currently supported debuggers, as DAP implementations can vary significantly in configuration details. + +### Using *ecode* Default Configurations + +Once you have a `Build Configuration` with a selected `Run Target`, this will be used for the default `Launch` and `Attach` configurations for your language. + +- **Launch Configurations:** These configurations start an executable from your local environment, with the process managed by the debugger. This is the most common setup for most users. To use it: + + - Ensure your `Run Target` is ready. + - Go to the `Debugger` tab in the Side Panel. + - Select the debugger based on the language you want to debug. For example, C or C++ binaries can be debugged using `gdb` or `lldb-dap` (also known as `lldb-vscode`), depending on your platform. + - Choose the appropriate `Debugger Configuration`, such as `Launch Binary`. + - Click `Debug` or press `Ctrl/Cmd + F5` to start debugging. + +- **Attach Configurations:** These configurations allow the debugger to attach to an already running process, either locally or remotely. You can attach to a process via its process ID or its binary name/path. Some configurations include a `(wait)` option, which waits for the process to start before attaching. + + The default `Attach to Binary` option will also use the current `Run Target` to execute the binary. Unlike the `Launch` configuration, here the process is managed by *ecode* instead of the debugger. This feature is particularly useful for debugging CLI programs from the terminal if the `Run Target` is configured with `Run in Terminal`. + +### Using Custom Launch Configurations + +*ecode* supports custom launch configurations through the `launch.json` file, which can be placed in either the `.ecode/` or `.vscode/` folder within your project directory. This format is fully compatible with VS Code, making it easy for users transitioning from other editors. + +#### Creating a `launch.json` File + +The `launch.json` file defines how debugging sessions are launched or attached. A basic configuration looks like this: + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Program", + "type": "lldb", + "request": "launch", + "program": "${workspaceFolder}/bin/myapp", + "args": ["--verbose"], + "cwd": "${workspaceFolder}", + "stopOnEntry": false + } + ] +} +``` + +#### Key Fields Explained + +- **`name`**: The display name for the configuration in the *ecode* debugger interface. +- **`type`**: The debugger type, such as `gdb`, `lldb`, or any supported DAP adapter. +- **`request`**: Specifies whether to `launch` a new process or `attach` to an existing one. +- **`program`**: The path to the executable you want to debug. +- **`args`**: Optional. Command-line arguments passed to the program. +- **`cwd`**: The working directory for the program. +- **`stopOnEntry`**: Optional. If `true`, the debugger will pause at the program's entry point. + +#### Advanced Customization + +You can create multiple configurations for different scenarios, such as: + +- Attaching to a remote process: + +```json +{ + "name": "Attach to Remote", + "type": "gdb", + "request": "attach", + "host": "192.168.1.100", + "port": 1234 +} +``` + +- Debugging with environment variables: + +```json +{ + "name": "Launch with Env Vars", + "type": "lldb", + "request": "launch", + "program": "${workspaceFolder}/bin/myapp", + "env": { + "DEBUG": "1", + "LOG_LEVEL": "verbose" + } +} +``` + +*ecode* will automatically detect and load configurations from `launch.json`, prioritizing `.ecode/launch.json` if both are present. This approach ensures flexibility and consistency across projects, whether you're starting fresh or migrating from VS Code. + +*ecode* supports the same `launch.json` schema as VS Code, including standard input types such as: + +- **`pickProcess`**: Prompts the user to select a running process from a list. This is useful for attaching the debugger to an already running application. +- **`pickString`**: Allows the user to select from a predefined list of string options. +- **`promptString`**: Prompts the user to manually enter a string value, useful for dynamic input during debugging sessions. + +In addition to these standard inputs, *ecode* extends functionality with an extra input type: + +- **`pickFile`**: This *ecode*-specific input allows users to select a binary file directly from the file system. It is particularly useful when you need to choose an executable to be run and debugged without hardcoding the path in your `launch.json`. + +These input options make custom configurations flexible and dynamic, adapting to different debugging workflows and environments. + +### Language-Specific Configurations + +In addition to general configurations, *ecode* offers language-specific settings, such as loading core dumps. Each debugger and language may provide different configurations based on the debugger's capabilities and the language's characteristics. From 5a2f38556fd995dabbe0ea58a07e6bbf12923df4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Thu, 6 Feb 2025 01:22:03 -0300 Subject: [PATCH 13/30] Update debugger docs. --- docs/debugger.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/docs/debugger.md b/docs/debugger.md index 9540e11ac..492fefd54 100644 --- a/docs/debugger.md +++ b/docs/debugger.md @@ -108,6 +108,36 @@ In addition to these standard inputs, *ecode* extends functionality with an extr These input options make custom configurations flexible and dynamic, adapting to different debugging workflows and environments. +#### Variables Reference + +ecode supports all vscode variable substitution in debugger configuration files. Variable substitution is supported inside some key and value strings in `launch.json` files using **${variableName}** syntax. + +##### Predefined variables + +The following predefined variables are supported: + +- **${userHome}** - the path of the user's home folder +- **${workspaceFolder}** - the path of the folder opened in VS Code +- **${workspaceFolderBasename}** - the name of the folder opened in VS Code without any slashes (/) +- **${file}** - the current opened file +- **${fileWorkspaceFolder}** - the current opened file's workspace folder +- **${relativeFile}** - the current opened file relative to `workspaceFolder` +- **${relativeFileDirname}** - the current opened file's dirname relative to `workspaceFolder` +- **${fileBasename}** - the current opened file's basename +- **${fileBasenameNoExtension}** - the current opened file's basename with no file extension +- **${fileExtname}** - the current opened file's extension +- **${fileDirname}** - the current opened file's folder path +- **${fileDirnameBasename}** - the current opened file's folder name +- **${cwd}** - the task runner's current working directory upon the startup of VS Code +- **${lineNumber}** - the current selected line number in the active file +- **${selectedText}** - the current selected text in the active file +- **${execPath}** - the path to the running VS Code executable +- **${defaultBuildTask}** - the name of the default build task +- **${pathSeparator}** - the character used by the operating system to separate components in file paths +- **${/}** - shorthand for **${pathSeparator}** + +For more information check + ### Language-Specific Configurations In addition to general configurations, *ecode* offers language-specific settings, such as loading core dumps. Each debugger and language may provide different configurations based on the debugger's capabilities and the language's characteristics. From ea424d5e8c8a06cc83394cb04b0141c5ebd315f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Thu, 6 Feb 2025 01:22:33 -0300 Subject: [PATCH 14/30] Nit in debugger docs. --- docs/debugger.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/debugger.md b/docs/debugger.md index 492fefd54..ef150a63b 100644 --- a/docs/debugger.md +++ b/docs/debugger.md @@ -136,8 +136,6 @@ The following predefined variables are supported: - **${pathSeparator}** - the character used by the operating system to separate components in file paths - **${/}** - shorthand for **${pathSeparator}** -For more information check - ### Language-Specific Configurations In addition to general configurations, *ecode* offers language-specific settings, such as loading core dumps. Each debugger and language may provide different configurations based on the debugger's capabilities and the language's characteristics. From 51060b000616be1d616e74f7d0ce1e2f6ebebd6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sat, 8 Feb 2025 20:46:02 -0300 Subject: [PATCH 15/30] More docs for debugger. --- docs/debugger.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docs/debugger.md b/docs/debugger.md index ef150a63b..8f91b1b2c 100644 --- a/docs/debugger.md +++ b/docs/debugger.md @@ -139,3 +139,22 @@ The following predefined variables are supported: ### Language-Specific Configurations In addition to general configurations, *ecode* offers language-specific settings, such as loading core dumps. Each debugger and language may provide different configurations based on the debugger's capabilities and the language's characteristics. + +### Debugger keybindings object keys + +* **debugger-breakpoint-enable-toggle**: Toggles enable/disable current line breakpoint (if any) +* **debugger-breakpoint-toggle**: Toggles breakpoint in current line +* **debugger-continue-interrupt**: If debugger is running: continues or interrupt the current execution. If debugger is not running builds and run the debugger. +* **debugger-start**: Starts the debugger +* **debugger-start-stop**: Starts or stops the debugger (depending on its current status) +* **debugger-step-into**: Steps into the current debugged line +* **debugger-step-out**: Steps out the current debugged line +* **debugger-step-over**: Steps over the current debugged line +* **debugger-stop**: Stops the debugger +* **toggle-status-app-debugger**: Opens/hides the debugger status bar panel + +### Debugger config object keys + +* **fetch_globals**: Enable/Disable if global variables should be fetched automatically (when available) +* **fetch_registers**: Enable/Disable if registers should be fetched automatically (when available) +* **silent**: Enable/Disable non-critical Debugger logs From 28fe38f8716ddd66ffb9496e1517c0905ab519f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sun, 23 Feb 2025 11:25:53 -0300 Subject: [PATCH 16/30] Fix regex conversion from lite-xl. --- tools/data-migration/lite/language/lite2ecode.lua | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tools/data-migration/lite/language/lite2ecode.lua b/tools/data-migration/lite/language/lite2ecode.lua index d317031d4..400ab45f2 100644 --- a/tools/data-migration/lite/language/lite2ecode.lua +++ b/tools/data-migration/lite/language/lite2ecode.lua @@ -62,6 +62,20 @@ for i = 1, #syntax.items do syntax.items[i].patterns[p].pattern = new_pattern end + if syntax.items[i].patterns[p].regex ~= nil then + local ptr = {} + local result = split(syntax.items[i].patterns[p].regex, "()", true) + for _, v in ipairs(result) do + -- print(v) + table.insert(ptr, "(" .. v .. ")") + end + local new_regex = "" + for z = 1, #ptr do + new_regex = new_regex .. ptr[z] + end + syntax.items[i].patterns[p].regex = new_regex + end + local new_type = {} table.insert(new_type, "normal") for t = 1, #syntax.items[i].patterns[p].type do From 4b0faa2b14a09a68bfea8a205494fb1014f68828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Tue, 4 Mar 2025 11:50:31 -0300 Subject: [PATCH 17/30] Added acknowledgements. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 200f04335..c3ddb1f8f 100644 --- a/README.md +++ b/README.md @@ -429,6 +429,8 @@ using the editor daily and is stable enough for me, but use it at your own risk. * Andreas Kling for [SerenityOS](https://github.com/SerenityOS/serenity) +* [vyfor icons](https://github.com/vyfor/icons) + * And a **lot** more people! ## Code License From 9b15f195b5e773ebbdc7879bb496f6b660710242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sat, 29 Mar 2025 12:56:20 -0300 Subject: [PATCH 18/30] Fix typo in language definition. --- docs/customlanguages.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/customlanguages.md b/docs/customlanguages.md index 5bbe8df78..467872734 100644 --- a/docs/customlanguages.md +++ b/docs/customlanguages.md @@ -21,10 +21,10 @@ definition. ecode will prioritize user defined definitions. "comment": "Sets the comment string used for auto-comment functionality.", "patterns": [ { "pattern": "lua_pattern", "type": "type_name" }, - { "pattern": "no_capture(pattern_capture_1)(pattern_capture_2)", "type": { "no_capture_type_name", "capture_1_type_name", "capture_2_type_name" } }, + { "pattern": "no_capture(pattern_capture_1)(pattern_capture_2)", "type": [ "no_capture_type_name", "capture_1_type_name", "capture_2_type_name" ] }, { "pattern": ["lua_pattern_start", "lua_pattern_end", "escape_character"], "type": "type_name" } { "regex": "perl_regex", "type": "type_name" }, - { "regex": "no_capture(pattern_capture_1)(pattern_capture_2)", "type": { "no_capture_type_name", "capture_1_type_name", "capture_2_type_name" } }, + { "regex": "no_capture(pattern_capture_1)(pattern_capture_2)", "type": [ "no_capture_type_name", "capture_1_type_name", "capture_2_type_name" ] }, { "regex": ["regex_start", "regex_end", "escape_character"], "type": "type_name" } ], "symbols": [ From 946f420586906e44f6a032cbaca2a050ac1aa5c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sat, 29 Mar 2025 18:48:18 -0300 Subject: [PATCH 19/30] Update custom languages doc and README. Pump SDL2 version in release builds. --- .github/workflows/ecode-release.yml | 4 +- README.md | 13 +- docs/customlanguages.md | 180 +++++++++++++++++----------- 3 files changed, 125 insertions(+), 72 deletions(-) diff --git a/.github/workflows/ecode-release.yml b/.github/workflows/ecode-release.yml index ea5b9c3a9..89673cdea 100644 --- a/.github/workflows/ecode-release.yml +++ b/.github/workflows/ecode-release.yml @@ -357,8 +357,8 @@ jobs: - name: Install Dependencies run: | brew install bash create-dmg premake p7zip - curl -OL https://github.com/libsdl-org/SDL/releases/download/release-2.30.9/SDL2-2.30.9.dmg - hdiutil attach SDL2-2.30.9.dmg + curl -OL https://github.com/libsdl-org/SDL/releases/download/release-2.32.2/SDL2-2.32.2.dmg + hdiutil attach SDL2-2.32.2.dmg sudo cp -r /Volumes/SDL2/SDL2.framework /Library/Frameworks/ hdiutil detach /Volumes/SDL2 - name: Build diff --git a/README.md b/README.md index c3ddb1f8f..9af3c96e5 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ For more screenshots checkout * Lightweight * Portable * Uncluttered GUI -* Syntax Highlighting (including nested syntax highlighting, supporting over 90 languages and LSP semantic highlighting) +* Syntax Highlighting (including nested syntax highlighting, supporting over 100 languages and LSP semantic highlighting) * Multi-cursor support * [LSP](https://microsoft.github.io/language-server-protocol/) support * Debugger support via [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol) @@ -115,7 +115,7 @@ PRs for ecode will be accepted at the eepp repository. There are scripts for each supported platform ready to build the application. For *Linux* and *macOS* it is trivial to build the project, you'll just need to have GCC/Clang installed and also the development library from libSDL2. Windows build script is currently a cross-compiling script and it uses mingw64. -But it also can be easily built with Visual Studio and [libSDL2 development libraries](https://www.libsdl.org/release/SDL2-devel-2.30.7-VC.zip) installed. +But it also can be easily built with Visual Studio and [libSDL2 development libraries](https://www.libsdl.org/release/SDL2-devel-2.32.2-VC.zip) installed. For more information on how to build manually a project please follow the [eepp build instructions](https://github.com/SpartanJ/eepp/#how-to-build-it). The project name is always *ecode* (so if you are building with make, you'll need to run `make ecode`). @@ -147,6 +147,7 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | bat | ✓ | None | None | None | None | | bazel | ✓ | None | None | None | None | | bend | ✓ | None | None | None | None | +| blade | ✓ | None | None | None | None | | blueprint | ✓ | None | None | None | None | | brainfuck | ✓ | None | None | None | None | | buzz | ✓ | None | None | None | None | @@ -166,6 +167,7 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | elm | ✓ | [elm-language-server](https://github.com/elm-tooling/elm-language-server) | None | None | None | | environment file | ✓ | None | None | None | None | | fantom | ✓ | None | None | None | None | +| fennel | ✓ | None | None | None | None | | fortran | ✓ | [fortls](https://github.com/fortran-lang/fortls) | None | None | [gdb](https://www.gnu.org/software/gdb) | | fstab | ✓ | None | None | None | None | | gdscript | ✓ | None | None | None | None | @@ -185,13 +187,14 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | javascript | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | [eslint](https://eslint.org) | [prettier](https://prettier.io) | None | | javascriptreact | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | None | None | None | | json | ✓ | None | [jq](https://stedolan.github.io/jq/) | [native](#native) | None | +| jule | ✓ | None | None | None | None | | julia | ✓ | [LanguageServer.jl](https://github.com/julia-vscode/LanguageServer.jl) | None | None | None | | kotlin | ✓ | [kotlin-language-server](https://github.com/fwcd/kotlin-language-server) | [ktlint](https://pinterest.github.io/ktlint/) | [ktlint](https://pinterest.github.io/ktlint/) | None | | latex | ✓ | [texlab](https://github.com/latex-lsp) | None | None | None | | lobster | ✓ | None | None | None | None | | lua | ✓ | [lua-language-server](https://github.com/sumneko/lua-language-server) | [luacheck](https://github.com/mpeterv/luacheck) | None | None | | makefile | ✓ | None | None | None | None | -| markdown | ✓ | None | None | None | None | +| markdown | ✓ | [md-lsp](https://github.com/matkrin/md-lsp) | None | None | None | | meson | ✓ | None | None | None | None | | moonscript | ✓ | None | None | None | None | | nelua | ✓ | None | [nelua](https://nelua.io) | None | None | @@ -212,6 +215,7 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | powershell | ✓ | None | None | None | None | | python | ✓ | [pylsp](https://github.com/python-lsp/python-lsp-server) | [ruff](https://ruff.rs) | [black](https://black.readthedocs.io/en/stable/) | [debugpy](https://github.com/microsoft/debugpy) | | r | ✓ | [r languageserver](https://github.com/REditorSupport/languageserver) | None | None | None | +| rave | ✓ | None | None | None | None | | ring | ✓ | None | None | None | None | | ruby | ✓ | [solargraph](https://solargraph.org) | None | None | None | | rust | ✓ | [rust-analyzer](https://rust-analyzer.github.io) | None | [rustfmt](https://rust-lang.github.io/rustfmt/) | [gdb](https://www.gnu.org/software/gdb) / [lldb-dap](https://github.com/llvm/llvm-project/blob/main/lldb/tools/lldb-dap/README.md) | @@ -221,6 +225,7 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | smallbasic | ✓ | None | None | None | None | | solidity | ✓ | [solc](https://soliditylang.org) | [solhint](https://protofire.github.io/solhint/) | None | None | | sql | ✓ | None | None | None | None | +| svelte | ✓ | None | None | None | None | | swift | ✓ | [sourcekit-lsp](https://github.com/apple/sourcekit-lsp) | None | None | None | | tcl | ✓ | None | None | None | None | | teal | ✓ | None | [tl](https://github.com/teal-language/tl) | None | None | @@ -228,6 +233,7 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | typescript | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | [eslint](https://eslint.org) | [prettier](https://prettier.io) | None | | typescriptreact | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | None | None | None | | v | ✓ | [v-analyzer](https://github.com/v-analyzer/v-analyzer) | None | [v](https://vlang.io) | None | +| v1 | ✓ | None | None | None | None | | vala | ✓ | [vala-language-server](https://github.com/vala-lang/vala-language-server) | None | None | None | | verilog | ✓ | None | None | None | None | | visual basic | ✓ | None | None | None | None | @@ -237,6 +243,7 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | xml | ✓ | [emmet-language-server](https://github.com/olrtg/emmet-language-server) | [native](#native) | [native](#native) | None | | xtend | ✓ | None | None | None | None | | yaml | ✓ | [yaml-language-server](https://github.com/redhat-developer/yaml-language-server) | None | None | None | +| yuescript | ✓ | None | None | None | None | | zig | ✓ | [zls](https://github.com/zigtools/zls) | [zig](https://ziglang.org) | [zig](https://ziglang.org) | [lldb-dap](https://github.com/llvm/llvm-project/blob/main/lldb/tools/lldb-dap/README.md) | #### native diff --git a/docs/customlanguages.md b/docs/customlanguages.md index 467872734..de42f019b 100644 --- a/docs/customlanguages.md +++ b/docs/customlanguages.md @@ -17,7 +17,7 @@ definition. ecode will prioritize user defined definitions. ```json { "name": "language_name", - "files": [ "Array of file extensions supported" ], + "files": [ "Array of file extensions supported represented as lua patterns" ], "comment": "Sets the comment string used for auto-comment functionality.", "patterns": [ { "pattern": "lua_pattern", "type": "type_name" }, @@ -25,17 +25,43 @@ definition. ecode will prioritize user defined definitions. { "pattern": ["lua_pattern_start", "lua_pattern_end", "escape_character"], "type": "type_name" } { "regex": "perl_regex", "type": "type_name" }, { "regex": "no_capture(pattern_capture_1)(pattern_capture_2)", "type": [ "no_capture_type_name", "capture_1_type_name", "capture_2_type_name" ] }, - { "regex": ["regex_start", "regex_end", "escape_character"], "type": "type_name" } + { "regex": ["regex_start", "regex_end", "escape_character"], "type": "type_name" }, + { "parser": "custom_parser_name", "type": "type_name" } /* ecode allows to implement custom parsers in native code for improved performance (ex: "cpp_number_parser" and "c_number_parser") */ ], - "symbols": [ + "symbols": [ /* symbols are accesed when the type is set as "symbol" in a matched pattern */ { "symbol_name": "type_name" } ], + "headers": [ + "Optional array of Lua Patterns to identify the file type by reading the headers of the document", + "For example a bash script can be identified with the following pattern: '^#!.*[ /]bash' that searches for thinks like '#!/bin/bash'" + ], "visible": true, /* sets if the language is visible as a main language in the editor, optional parameter, true by default */ + "case_insensitive": false, /* sets if the language is a case insensitive language, false by default */ "auto_close_xml_tag": false, /* sets if the language defined supports auto close XML tags, optional parameter, false by default */ + "extension_priority": false, /* sets if any shared extension with other language should have priority over any other language, false by default */ "lsp_name": "sets the LSP name assigned for the language, optional parameter, it will use the _name_ in lowercase if not set" } ``` +### Type Names + +Type names are used to define the color of the tokenized pattern. + +These are the currently supported type names: + +* *normal*: Used for non-highlighted words. This is the default color. +* *comment*: Code comments color. +* *keyword*: Usually used for language reserved words (if, else, class, struct, then, enum, etc). +* *keyword2*: Usually used for type names. +* *keyword3*: Currently used for coloring parameters but can be used for anything. +* *number*: Number colors +* *literal*: Word literals colors (usually things like NULL, true, false, undefined, etc). Can be used also for any particular reserved symbol. +* *string*: String colors. +* *operator*: Operators colors (+, -, =, <, >, etc). +* *function*: Function name color. +* *link*: Links color. +* *link_hover*: Hovered Links color. + ### Porting language definitions ecode uses the same format for language definition as [lite](https://github.com/rxi/lite) and [lite-xl](https://github.com/lite-xl/lite-xl) editors. @@ -56,74 +82,94 @@ For example, to extend the language `vue` you will need to run: ```json { - "name": "Elixir", - "files": [ "%.ex$", "%.exs$" ], "comment": "#", + "files": [ + "%.sh$", + "%.bash$", + "^%.bashrc$", + "^%.bash_profile$", + "^%.profile$", + "%.zsh$", + "%.fish$", + "^PKGBUILD$", + "%.winlib$" + ], + "headers": [ + "^#!.*[ /]bash", + "^#!.*[ /]sh" + ], + "lsp_name": "shellscript", + "name": "Shell script", "patterns": [ - { "pattern": "#.*\n", "type": "comment" }, - { "pattern": [ ":\"", "\"", "\\" ], "type": "number" }, - { "pattern": [ "\"\"\"", "\"\"\"", "\\" ], "type": "string" }, - { "pattern": [ "\"", "\"", "\\" ], "type": "string" }, - { "pattern": [ "'", "'", "\\" ], "type": "string" }, - { "pattern": [ "~%a[/\"|'%(%[%{<]", "[/\"|'%)%]%}>]", "\\" ], "type": "string"}, - { "pattern": "-?0x%x+", "type": "number" }, - { "pattern": "-?%d+[%d%.eE]*f?", "type": "number" }, - { "pattern": "-?%.?%d+f?", "type": "number" }, - { "pattern": ":\"?[%a_][%w_]*\"?", "type": "number" }, - { "pattern": "[%a][%w_!?]*%f[(]", "type": "function" }, - { "pattern": "%u%w+", "type": "normal" }, - { "pattern": "@[%a_][%w_]*", "type": "keyword2" }, - { "pattern": "_%a[%w_]*", "type": "keyword2" }, - { "pattern": "[%+%-=/%*<>!|&]", "type": "operator" }, - { "pattern": "[%a_][%w_]*", "type": "symbol" } + { "pattern": "$[%a_@*#][%w_]*", "type": "keyword2" }, + { "pattern": "#.*\n", "type": "comment" }, + { "pattern": [ "<<%-?%s*EOF", "EOF" ], "type": "string" }, + { "pattern": [ "\"", "\"", "\\" ], "type": "string" }, + { "pattern": [ "'", "'", "\\" ], "type": "string" }, + { "pattern": [ "`", "`", "\\" ], "type": "string" }, + { "pattern": "%f[%w_%.%/]%d[%d%.]*%f[^%w_%.]", "type": "number" }, + { "pattern": "[!<>|&%[%]:=*]", "type": "operator" }, + { "pattern": "%f[%S][%+%-][%w%-_:]+", "type": "function" }, + { "pattern": "%f[%S][%+%-][%w%-_]+%f[=]", "type": "function" }, + { "pattern": "(%s%-%a[%w_%-]*%s+)(%d[%d%.]+)", "type": [ "normal", "function", "number" ] }, + { "pattern": "(%s%-%a[%w_%-]*%s+)(%a[%a%-_:=]+)", "type": [ "normal", "function", "symbol" ] }, + { "pattern": "[_%a][%w_]+%f[%+=]", "type": "keyword2" }, + { "pattern": "${.-}", "type": "keyword2" }, + { "pattern": "$[%d$%a_@*][%w_]*", "type": "keyword2" }, + { "pattern": "[%a_%-][%w_%-]*[%s]*%f[(]", "type": "function" }, + { "pattern": "[%a_][%w_]*", "type": "symbol" } ], "symbols": [ - {"def": "keyword"}, - {"defp": "keyword"}, - {"defguard": "keyword"}, - {"defguardp": "keyword"}, - {"defmodule": "keyword"}, - {"defprotocol": "keyword"}, - {"defimpl": "keyword"}, - {"defrecord": "keyword"}, - {"defrecordp": "keyword"}, - {"defmacro": "keyword"}, - {"defmacrop": "keyword"}, - {"defdelegate": "keyword"}, - {"defoverridable": "keyword"}, - {"defexception": "keyword"}, - {"defcallback": "keyword"}, - {"defstruct": "keyword"}, - {"for": "keyword"}, - {"case": "keyword"}, - {"when": "keyword"}, - {"with": "keyword"}, - {"cond": "keyword"}, - {"if": "keyword"}, - {"unless": "keyword"}, - {"try": "keyword"}, - {"receive": "keyword"}, - {"after": "keyword"}, - {"raise": "keyword"}, - {"rescue": "keyword"}, - {"catch": "keyword"}, - {"else": "keyword"}, - {"quote": "keyword"}, - {"unquote": "keyword"}, - {"super": "keyword"}, - {"unquote_splicing": "keyword"}, - {"do": "keyword"}, - {"end": "keyword"}, - {"fn": "keyword"}, - {"import": "keyword2"}, - {"alias": "keyword2"}, - {"use": "keyword2"}, - {"require": "keyword2"}, - {"and": "operator"}, - {"or": "operator"}, - {"true": "literal"}, - {"false": "literal"}, - {"nil": "literal"} + { "in": "keyword" }, + { "then": "keyword" }, + { "exit": "keyword" }, + { "alias": "keyword" }, + { "continue": "keyword" }, + { "getopts": "keyword" }, + { "set": "keyword" }, + { "return": "keyword" }, + { "unalias": "keyword" }, + { "pwd": "keyword" }, + { "fi": "keyword" }, + { "printf": "keyword" }, + { "unset": "keyword" }, + { "cd": "keyword" }, + { "echo": "keyword" }, + { "false": "literal" }, + { "help": "keyword" }, + { "for": "keyword" }, + { "test": "keyword" }, + { "mapfile": "keyword" }, + { "shift": "keyword" }, + { "while": "keyword" }, + { "readarray": "keyword" }, + { "eval": "keyword" }, + { "select": "keyword" }, + { "elif": "keyword" }, + { "function": "keyword" }, + { "true": "literal" }, + { "else": "keyword" }, + { "exec": "keyword" }, + { "enable": "keyword" }, + { "local": "keyword" }, + { "jobs": "keyword" }, + { "source": "keyword" }, + { "break": "keyword" }, + { "declare": "keyword" }, + { "history": "keyword" }, + { "case": "keyword" }, + { "until": "keyword" }, + { "if": "keyword" }, + { "esac": "keyword" }, + { "hash": "keyword" }, + { "kill": "keyword" }, + { "time": "keyword" }, + { "let": "keyword" }, + { "export": "keyword" }, + { "do": "keyword" }, + { "done": "keyword" }, + { "read": "keyword" }, + { "type": "keyword" } ] } ``` From 5fe87675fa13259d8dd320ff235aff34bba23d99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sat, 5 Apr 2025 20:43:26 -0300 Subject: [PATCH 20/30] Update ecode-release.yml. Update README.md. --- .github/workflows/ecode-release.yml | 7 +++---- README.md | 7 +++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ecode-release.yml b/.github/workflows/ecode-release.yml index 89673cdea..fcdfd8e42 100644 --- a/.github/workflows/ecode-release.yml +++ b/.github/workflows/ecode-release.yml @@ -87,9 +87,9 @@ jobs: sudo apt-get update - name: Install dependencies run: | - sudo apt-get install -y gcc-11 g++-11 - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 10 - sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-11 10 + sudo apt-get install -y gcc-13 g++-13 libdw-dev + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 10 + sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 10 sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 30 sudo update-alternatives --set cc /usr/bin/gcc sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 30 @@ -160,7 +160,6 @@ jobs: - name: Install dependencies run: | sudo apt-get install -y premake4 libfuse2 fuse gcc-aarch64-linux-gnu g++-aarch64-linux-gnu - # sudo apt-get install -y libsdl2-dev:arm64 libsdl2-2.0-0:arm64 bash projects/linux/scripts/install_sdl2.sh --aarch64 - name: Build ecode run: | diff --git a/README.md b/README.md index 9af3c96e5..6f1cced3d 100644 --- a/README.md +++ b/README.md @@ -152,9 +152,11 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | brainfuck | ✓ | None | None | None | None | | buzz | ✓ | None | None | None | None | | c | ✓ | [clangd](https://clangd.llvm.org/) | [cppcheck](https://github.com/danmar/cppcheck) | [clang-format](https://clang.llvm.org/docs/ClangFormat.html) | [gdb](https://www.gnu.org/software/gdb) / [lldb-dap](https://github.com/llvm/llvm-project/blob/main/lldb/tools/lldb-dap/README.md) | +| c3 | ✓ | [c3-lsp](https://github.com/pherrymason/c3-lsp) | None | None | None | | carbon | ✓ | None | None | None | None | | clojure | ✓ | [clojure-lsp](https://github.com/clojure-lsp/clojure-lsp) | None | None | None | | cmake | ✓ | [cmake-language-server](https://github.com/regen100/cmake-language-server) | None | None | None | +| covscript | ✓ | None | None | None | None | | cpp | ✓ | [clangd](https://clangd.llvm.org/) | [cppcheck](https://github.com/danmar/cppcheck) | [clang-format](https://clang.llvm.org/docs/ClangFormat.html) | [gdb](https://www.gnu.org/software/gdb) / [lldb-dap](https://github.com/llvm/llvm-project/blob/main/lldb/tools/lldb-dap/README.md) | | crystal | ✓ | [crystalline](https://github.com/elbywan/crystalline) | None | None | None | | csharp | ✓ | [OmniSharp](https://github.com/OmniSharp/omnisharp-roslyn) | None | None | None | @@ -168,6 +170,7 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | environment file | ✓ | None | None | None | None | | fantom | ✓ | None | None | None | None | | fennel | ✓ | None | None | None | None | +| flow9 | ✓ | None | None | None | None | | fortran | ✓ | [fortls](https://github.com/fortran-lang/fortls) | None | None | [gdb](https://www.gnu.org/software/gdb) | | fstab | ✓ | None | None | None | None | | gdscript | ✓ | None | None | None | None | @@ -191,11 +194,14 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | julia | ✓ | [LanguageServer.jl](https://github.com/julia-vscode/LanguageServer.jl) | None | None | None | | kotlin | ✓ | [kotlin-language-server](https://github.com/fwcd/kotlin-language-server) | [ktlint](https://pinterest.github.io/ktlint/) | [ktlint](https://pinterest.github.io/ktlint/) | None | | latex | ✓ | [texlab](https://github.com/latex-lsp) | None | None | None | +| lisp | ✓ | None | None | [ros](https://github.com/roswell/roswell) | None | | lobster | ✓ | None | None | None | None | | lua | ✓ | [lua-language-server](https://github.com/sumneko/lua-language-server) | [luacheck](https://github.com/mpeterv/luacheck) | None | None | | makefile | ✓ | None | None | None | None | | markdown | ✓ | [md-lsp](https://github.com/matkrin/md-lsp) | None | None | None | | meson | ✓ | None | None | None | None | +| modula2 | ✓ | None | None | None | None | +| modula3 | ✓ | None | None | None | None | | moonscript | ✓ | None | None | None | None | | nelua | ✓ | None | [nelua](https://nelua.io) | None | None | | nim | ✓ | [nimlsp](https://github.com/PMunch/nimlsp) | [nim](https://nim-lang.org) | None | None | @@ -232,6 +238,7 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | toml | ✓ | None | None | None | None | | typescript | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | [eslint](https://eslint.org) | [prettier](https://prettier.io) | None | | typescriptreact | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | None | None | None | +| u | ✓ | None | None | None | None | | v | ✓ | [v-analyzer](https://github.com/v-analyzer/v-analyzer) | None | [v](https://vlang.io) | None | | v1 | ✓ | None | None | None | None | | vala | ✓ | [vala-language-server](https://github.com/vala-lang/vala-language-server) | None | None | None | From f39cb4be81d4dbb63b3596ac89fee1b2d6389905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Mon, 7 Apr 2025 20:41:50 -0300 Subject: [PATCH 21/30] Update documentation. --- README.md | 11 ++- docs/aiassistant.md | 161 ++++++++++++++++++++++++++++++++++++++++ docs/customlanguages.md | 92 +++++++++++++++++++---- docs/formatter.md | 2 +- docs/linter.md | 2 +- docs/lsp.md | 2 +- 6 files changed, 250 insertions(+), 20 deletions(-) create mode 100644 docs/aiassistant.md diff --git a/README.md b/README.md index 6f1cced3d..5ab4062b0 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ For more screenshots checkout * Customizable keyboard bindings * Configurable build pipelines * Fast global search (and replace) +* AI Assistant plugin * Minimap * Unlimited editor splitting * Easily extendable language support @@ -231,6 +232,7 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | smallbasic | ✓ | None | None | None | None | | solidity | ✓ | [solc](https://soliditylang.org) | [solhint](https://protofire.github.io/solhint/) | None | None | | sql | ✓ | None | None | None | None | +| squirrel | ✓ | None | None | None | None | | svelte | ✓ | None | None | None | None | | swift | ✓ | [sourcekit-lsp](https://github.com/apple/sourcekit-lsp) | None | None | None | | tcl | ✓ | None | None | None | None | @@ -238,7 +240,6 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | toml | ✓ | None | None | None | None | | typescript | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | [eslint](https://eslint.org) | [prettier](https://prettier.io) | None | | typescriptreact | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | None | None | None | -| u | ✓ | None | None | None | None | | v | ✓ | [v-analyzer](https://github.com/v-analyzer/v-analyzer) | None | [v](https://vlang.io) | None | | v1 | ✓ | None | None | None | None | | vala | ✓ | [vala-language-server](https://github.com/vala-lang/vala-language-server) | None | None | None | @@ -252,6 +253,7 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | yaml | ✓ | [yaml-language-server](https://github.com/redhat-developer/yaml-language-server) | None | None | None | | yuescript | ✓ | None | None | None | None | | zig | ✓ | [zls](https://github.com/zigtools/zls) | [zig](https://ziglang.org) | [zig](https://ziglang.org) | [lldb-dap](https://github.com/llvm/llvm-project/blob/main/lldb/tools/lldb-dap/README.md) | +| ü | ✓ | [Ü language server](https://github.com/Panzerschrek/U-00DC-Sprache) | None | None | None | #### native @@ -325,6 +327,13 @@ The auto-complete plugin is in charge of providing suggestions for code-completi For more information [read the auto-complete documentation](docs/autocomplete.md). +#### AI Assistant + +The AI Assistant is a simple but effective LLM Chat UI. You'll be able to chat with different models +from within the editor. + +For more information [read the AI assistant documentation](docs/aiassistant.md). + #### XML Tools The XML Tools plugin (disabled by default) provides some nice to have improvements when editing XML diff --git a/docs/aiassistant.md b/docs/aiassistant.md new file mode 100644 index 000000000..36de7a419 --- /dev/null +++ b/docs/aiassistant.md @@ -0,0 +1,161 @@ +# ecode LLM Chat UI Documentation + +This feature allows you to interact directly with various AI models from different providers within the editor. + +## Overview + +The LLM Chat UI provides a dedicated panel where you can: + +* Start multiple chat conversations. +* Interact with different LLM providers and models (like OpenAI, Anthropic, Google AI, Mistral, DeepSeek, XAI, and local models via Ollama/LMStudio). +* Manage chat history (save, rename, clone, lock). +* Use AI assistance directly related to your code or general queries without leaving the editor. + +## Configuration + +Configuration is managed through `ecode`'s settings file (a JSON file). The relevant sections are `config`, `keybindings`, and `providers`. + +```json +// Example structure in your ecode settings file +{ + "config": { + // API Keys go here + }, + "keybindings": { + // Chat UI keybindings + }, + "providers": { + // LLM Provider definitions + } +} +``` + +### API Keys (`config` section) + +To use cloud-based LLM providers, you need to add your API keys. You can do this in two ways: + +1. **Via the `config` object in settings:** + + Add your keys directly into the `config` section of your `ecode` settings file. + + ```json + { + "config": { + "anthropic_api_key": "YOUR_ANTHROPIC_API_KEY", + "deepseek_api_key": "YOUR_DEEPSEEK_API_KEY", + "google_ai_api_key": "YOUR_GOOGLE_AI_API_KEY", // For Google AI / Gemini models + "mistral_api_key": "YOUR_MISTRAL_API_KEY", + "openai_api_key": "YOUR_OPENAI_API_KEY", + "xai_api_key": "YOUR_XAI_API_KEY" // For xAI / Grok models + } + } + ``` + Leave the string empty (`""`) for services you don't intend to use. + +2. **Via Environment Variables:** + + The application can also read API keys from environment variables. This is often a more secure method, especially in shared environments or when committing configuration files. If an environment variable is set, it will override the corresponding key in the `config` object. + + The supported environment variables are: + + * `ANTHROPIC_API_KEY` + * `DEEPSEEK_API_KEY` + * `GOOGLE_AI_API_KEY` (or `GEMINI_API_KEY`) + * `MISTRAL_API_KEY` + * `OPENAI_API_KEY` + * `XAI_API_KEY` (or `GROK_API_KEY`) + +### Keybindings (`keybindings` section) + +The following default keybindings are provided for interacting with the LLM Chat UI. You can customize these in the `keybindings` section of your settings file. + +*(Note: `mod` typically refers to `Cmd` on macOS and `Ctrl` on Windows/Linux)* + +| Action | Default Keybinding | Description | +| :--------------------------- | :----------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Add New Chat | `mod+shift+return` | Adds a new, empty chat tab to the UI. | +| Show Chat History | `mod+h` | Displays a chat history panel. | +| Toggle Message Role | `mod+shift+r` | Changes the role [user/assistant] of a selected message | +| Clone Current Chat | `mod+shift+c` | Creates a duplicate of the current chat conversation in a new tab. | +| Send Prompt / Submit Message | `mod+return` | Sends the message currently typed in the input box to the selected LLM. | +| Refresh Local Models | `mod+shift+l` | Re-fetches the list of available models from local providers like Ollama or LMStudio. | +| Rename Current Chat | `f2` | Allows you to rename the currently active chat tab. | +| Save Current Chat | `mod+s` | Saves the current chat conversation state. | +| Open AI Settings | `mod+shift+s` | Opens the settings file | +| Show Chat Menu | `mod+m` | Displays a context menu with common chat actions: New Chat, Save Chat, Rename Chat, Clone Chat, Lock Chat Memory (prevents removal during batch clear operations). | +| Toggle Private Chat | `mod+shift+p` | Toggles if chat must be persisted or no in the chat history (incognito mode) | +| Open New AI Assistant Tab | `mod+shift+m` | Opens a new LLM Chat UI | + +## LLM Providers (`providers` section) + +### Overview + +The `providers` object defines the different LLM services available in the chat UI. `ecode` comes pre-configured with several popular providers (Anthropic, DeepSeek, Google, Mistral, OpenAI, XAI) and local providers (Ollama, LMStudio). + +You generally don't need to modify the default providers unless you want to disable one or add/adjust model parameters. However, you can add definitions for new or custom LLM providers and models. + +### Adding Custom Providers + +To add a new provider, you need to add a new key-value pair to the `providers` object in your settings file. The key should be a unique identifier for your provider (e.g., `"my_custom_ollama"`), and the value should be an object describing the provider and its models. + +**Provider Object Structure:** + +```json +"your_provider_id": { + "api_url": "string", // Required: The base URL endpoint for the chat completion API. + "display_name": "string", // Optional: User-friendly name shown in the UI. Defaults to the provider ID if missing. + "enabled": boolean, // Optional: Set to `false` to disable this provider. Defaults to `true`. + "version": number, // Optional: Identifier for the API version if the provider requires it (e.g., 1 for Anthropic). + "open_api": boolean, // Optional: Set to `true` if the provider uses an OpenAI-compatible API schema (common for local models like Ollama, LMStudio). + "fetch_models_url": "string", // Optional: URL to dynamically fetch the list of available models (e.g., from Ollama or LMStudio). If provided, the static `models` array below might be ignored or populated dynamically. + "models": [ // Required (unless `fetch_models_url` is used and sufficient): An array of model objects available from this provider. + // Model Object structure described below + ] +} +``` + +**Model Object Structure (within the `models` array):** + +```json +{ + "name": "string", // Required: The internal model identifier used in API requests (e.g., "claude-3-5-sonnet-latest"). + "display_name": "string", // Optional: User-friendly name shown in the model selection dropdown. Defaults to `name` if missing. + "max_tokens": number, // Optional: The maximum context window size (input tokens + output tokens) supported by the model. + "max_output_tokens": number, // Optional: The maximum number of tokens the model can generate in a single response. + "default_temperature": number, // Optional: Default sampling temperature (controls randomness/creativity). Typically between 0.0 and 2.0. Defaults might vary per provider or model. (e.g., 1.0) + "cheapest": boolean, // Optional: Flag to indicate if this model is considered a cheaper option. It's usually used to generate the summary of the chat when the specific provider is being used. + "cache_configuration": { // Optional: Configuration for potential internal caching or speculative execution features. May not apply to all providers or setups. + "max_cache_anchors": number, // Specific caching parameter. + "min_total_token": number, // Specific caching parameter. + "should_speculate": boolean // Specific caching parameter. + } + // or "cache_configuration": null if not applicable/used for this model. +} +``` + +**Example: Adding a hypothetical local provider** + +```json +{ + "providers": { + // ... other existing providers ... + "my_local_llm": { + "api_url": "http://localhost:8080/v1/chat/completions", + "display_name": "My Local LLM", + "open_api": true, // Assuming it uses an OpenAI-compatible API + "models": [ + { + "name": "local-model-v1", + "display_name": "Local Model V1", + "max_tokens": 4096 + }, + { + "name": "local-model-v2-experimental", + "display_name": "Local Model V2 (Experimental)", + "max_tokens": 8192 + } + ] + } + } +} +``` diff --git a/docs/customlanguages.md b/docs/customlanguages.md index de42f019b..f1ec33bbb 100644 --- a/docs/customlanguages.md +++ b/docs/customlanguages.md @@ -16,30 +16,90 @@ definition. ecode will prioritize user defined definitions. ```json { - "name": "language_name", - "files": [ "Array of file extensions supported represented as lua patterns" ], - "comment": "Sets the comment string used for auto-comment functionality.", - "patterns": [ + "name": "language_name", // (Required) The display name of the language. + "files": [ // (Required if `visible` is `true`) An array of Lua patterns matching filenames for this language. + "%.ext$", // Example: Matches files ending in .ext + "^Makefile$" // Example: Matches the exact filename Makefile + ], + "comment": "//", // (Optional) Sets the single-line comment string used for auto-comment functionality. + "patterns": [ // (Required) An array defining syntax highlighting rules. + // Rule using Lua patterns: { "pattern": "lua_pattern", "type": "type_name" }, + // Rule using Lua patterns with capture groups mapping to different types: { "pattern": "no_capture(pattern_capture_1)(pattern_capture_2)", "type": [ "no_capture_type_name", "capture_1_type_name", "capture_2_type_name" ] }, - { "pattern": ["lua_pattern_start", "lua_pattern_end", "escape_character"], "type": "type_name" } + // Rule defining a multi-line block using Lua patterns (start, end, escape character): + { "pattern": ["lua_pattern_start", "lua_pattern_end", "escape_character"], "type": "type_name" }, + // Rule using Perl-compatible regular expressions (PCRE): { "regex": "perl_regex", "type": "type_name" }, + // Rule using PCRE with capture groups mapping to different types: { "regex": "no_capture(pattern_capture_1)(pattern_capture_2)", "type": [ "no_capture_type_name", "capture_1_type_name", "capture_2_type_name" ] }, + // Rule defining a multi-line block using PCRE (start, end, escape character): { "regex": ["regex_start", "regex_end", "escape_character"], "type": "type_name" }, - { "parser": "custom_parser_name", "type": "type_name" } /* ecode allows to implement custom parsers in native code for improved performance (ex: "cpp_number_parser" and "c_number_parser") */ + // Rule using a custom parser implemented in native code for performance (e.g., number parsing): + { "parser": "custom_parser_name", "type": "type_name" } // Currently available: "cpp_number_parser", "c_number_parser", "js_number_parser", "common_number_parser" (matches decimal and hexa), "common_number_parser_o" (matches the same as "common_number_parser" plus octal numbers), "common_number_parser_ob" (matches the same as "common_number_parser_o" plus binary numbers) + + // Rule assigning the "symbol" type: + { "pattern": "[%a_][%w_]*", "type": "symbol" }, + // When this pattern matches text (e.g., the word "if"), instead of directly applying a "symbol" style, + // ecode performs a lookup. It takes the matched text ("if") and searches for it within the language's "symbols" definition. + // If "if" is found in "symbols" (e.g., { "if": "keyword" }), the type specified there ("keyword") is applied. + // If the matched text is not found in "symbols", it typically defaults to the "normal" type (or the editor's default). + // This allows generic patterns to capture potential keywords, literals, etc., which are then specifically typed via the "symbols" map. + + // Rule using "symbol" within capture groups: + { "pattern": "(%s%-%a[%w_%-]*%s+)(%a[%a%-_:=]+)", "type": [ "normal", "function", "symbol" ] }, + // Here, the pattern has three capture groups. + // - The first capture (whitespace, hyphen, word, whitespace) is typed as "normal". + // - The second capture (word) is typed as "function". + // - The third capture (word with extra allowed chars) is typed as "symbol". + // Similar to the above, when the third group matches text (e.g., "true"), ecode looks up "true" in the "symbols" definition. + // If { "true": "literal" } exists, the matched text "true" will be highlighted as "literal". Otherwise, it defaults to "normal". ], - "symbols": [ /* symbols are accesed when the type is set as "symbol" in a matched pattern */ - { "symbol_name": "type_name" } + "symbols": [ // (Optional) An array defining specific types for exact words, primarily used in conjunction with patterns having `type: "symbol"`. + // Structure: An array where each element is an object containing exactly one key-value pair. + // - The key is the literal word (symbol) to match. + // - The value is the `type_name` to apply when that word is matched via a `type: "symbol"` pattern rule. + + // How it works: + // When a pattern rule results in a `type: "symbol"` match (either for the whole pattern or a capture group), + // the actual text matched by that pattern/group is looked up within this `symbols` array. + // The editor iterates through the array, checking if the key of any object matches the text. + // If a match is found (e.g., the text is "if" and an object `{ "if": "keyword" }` exists), + // the corresponding value ("keyword") is used for highlighting. + // If the matched text is not found as a key in any object within this array, the highlighting typically falls back to the "normal" type. + // This mechanism is essential for highlighting keywords, built-in constants/literals, and other reserved words + // that might otherwise be matched by more general patterns (like a pattern for all words). + + // Example: + { "if": "keyword" }, // If a `type: "symbol"` pattern matches "if", it will be highlighted as "keyword". + { "else": "keyword" }, + { "true": "literal" }, // If a `type: "symbol"` pattern matches "true", it will be highlighted as "literal". + { "false": "literal" }, + { "MyClass": "keyword2" }, // If a `type: "symbol"` pattern matches "MyClass", it will be highlighted as "keyword2". + { "begin": "keyword" }, + { "end": "keyword" } + // ... add other specific words and their types as needed ... ], - "headers": [ - "Optional array of Lua Patterns to identify the file type by reading the headers of the document", - "For example a bash script can be identified with the following pattern: '^#!.*[ /]bash' that searches for thinks like '#!/bin/bash'" + "headers": [ // (Optional) Array of Lua Patterns to identify file type by reading the first few lines (header). + "^#!.*[ /]bash" // Example: Identifies bash scripts like '#!/bin/bash' ], - "visible": true, /* sets if the language is visible as a main language in the editor, optional parameter, true by default */ - "case_insensitive": false, /* sets if the language is a case insensitive language, false by default */ - "auto_close_xml_tag": false, /* sets if the language defined supports auto close XML tags, optional parameter, false by default */ - "extension_priority": false, /* sets if any shared extension with other language should have priority over any other language, false by default */ - "lsp_name": "sets the LSP name assigned for the language, optional parameter, it will use the _name_ in lowercase if not set" + "visible": true, // (Optional) If true (default), language appears in main selection menus. Set to false for internal/helper languages. + "case_insensitive": false, // (Optional) If true, pattern matching ignores case. Default is false (case-sensitive). + "auto_close_xml_tag": false, // (Optional) If true, enables auto-closing of XML/HTML tags (e.g., typing `
` automatically adds `
`). Default is false. + "extension_priority": false, // (Optional) If true, this language definition takes priority if multiple languages define the same file extension. Default is false. + "lsp_name": "language_server_name", // (Optional) Specifies the name recognized by Language Servers (LSP). Defaults to the 'name' field in lowercase if omitted. + + "fold_range_type": "braces", // (Optional) Specifies the strategy used to detect foldable code regions. Default behavior if omitted might be no folding or a global default. Possible values: + // - "braces": Folding is determined by matching pairs of characters (defined in `fold_braces`). Suitable for languages like C, C++, Java, JavaScript, JSON. + // - "indentation": Folding is determined by changes in indentation level. Suitable for languages like Python, YAML, Nim. + // - "tag": Folding is based on matching HTML/XML tags (e.g., `
...
`). Suitable for HTML, XML, SVG. + // - "markdown": Folding is based on Markdown header levels (e.g., `## Section Title`). Suitable for Markdown. + "fold_braces": [ // (Required *only if* `fold_range_type` is "braces") Defines the pairs of characters used for brace-based folding. + // This is an array of objects, where each object specifies a starting and ending character pair. + { "start": "{", "end": "}" }, // Example: Standard curly braces + { "start": "[", "end": "]" }, // Example: Square brackets + { "start": "(", "end": ")" } // Example: Parentheses + ] } ``` diff --git a/docs/formatter.md b/docs/formatter.md index e87059733..3d05b481d 100644 --- a/docs/formatter.md +++ b/docs/formatter.md @@ -5,7 +5,7 @@ The formatter plugin works exactly like the linter plugin, but it will execute t `formatters.json` configuration. `formatters.json` default configuration can be obtained from [here](https://raw.githubusercontent.com/SpartanJ/eepp/develop/bin/assets/plugins/formatters.json). It also supports some formatters natively, this means that the formatter comes with ecode without requiring any external dependency. And also supports LSP text document formatting, meaning that if you're running an LSP that supports formatting documents, formatting will be available too. -To configure new formatters you can create a new `formatters.json` file in the [default configuration path](#plugins-configuration-files-location) of *ecode*. +To configure new formatters you can create a new `formatters.json` file in the [default configuration path](../README.md##plugins-configuration-files-location) of *ecode*. ### `formatters.json` format diff --git a/docs/linter.md b/docs/linter.md index 11da175a7..9f9781f35 100644 --- a/docs/linter.md +++ b/docs/linter.md @@ -3,7 +3,7 @@ Linter support is provided by executing already stablished linters from each language. *ecode* provides support for several languages by default and can be extended easily by expanding the `linters.json` configuration. `linters.json` default configuration can be obtained from [here](https://raw.githubusercontent.com/SpartanJ/eepp/develop/bin/assets/plugins/linters.json). -To configure new linters you can create a new `linters.json` file in the [default configuration path](#plugins-configuration-files-location) of *ecode*. +To configure new linters you can create a new `linters.json` file in the [default configuration path](../README.md#plugins-configuration-files-location) of *ecode*. ### `linters.json` format diff --git a/docs/lsp.md b/docs/lsp.md index e4946f639..7d0a73820 100644 --- a/docs/lsp.md +++ b/docs/lsp.md @@ -3,7 +3,7 @@ LSP support is provided by executing already stablished LSP from each language. *ecode* provides support for several languages by default and can be extended easily by expanding the `lspclient.json` configuration. `lspclient.json` default configuration can be obtained from [here](https://raw.githubusercontent.com/SpartanJ/eepp/develop/bin/assets/plugins/lspclient.json). -To configure new LSPs you can create a new `lspclient.json` file in the [default configuration path](#plugins-configuration-files-location) of *ecode*. +To configure new LSPs you can create a new `lspclient.json` file in the [default configuration path](../README.md##plugins-configuration-files-location) of *ecode*. Important note: LSP servers can be very resource intensive and might not be always the best option for simple projects. From 904b8d6cf88e503b39ce51ec7f5eebca4139ded5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Mon, 7 Apr 2025 21:06:06 -0300 Subject: [PATCH 22/30] Fix title. --- docs/aiassistant.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/aiassistant.md b/docs/aiassistant.md index 36de7a419..6dd607c73 100644 --- a/docs/aiassistant.md +++ b/docs/aiassistant.md @@ -1,4 +1,4 @@ -# ecode LLM Chat UI Documentation +# AI Assistant This feature allows you to interact directly with various AI models from different providers within the editor. From 1894d155d89cd6f2077971f6f753336aaaed76ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sat, 12 Apr 2025 18:57:59 -0300 Subject: [PATCH 23/30] Update README.md. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5ab4062b0..8620681c9 100644 --- a/README.md +++ b/README.md @@ -187,6 +187,7 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | html | ✓ | [emmet-language-server](https://github.com/olrtg/emmet-language-server) | None | [prettier](https://prettier.io) | None | | ini | ✓ | None | None | None | None | | jai | ✓ | None | None | None | None | +| janet | ✓ | None | None | None | None | | java | ✓ | [jdtls](https://github.com/eclipse/eclipse.jdt.ls) | None | [clang-format](https://clang.llvm.org/docs/ClangFormat.html) | None | | javascript | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | [eslint](https://eslint.org) | [prettier](https://prettier.io) | None | | javascriptreact | ✓ | [typescript-language-server](https://github.com/theia-ide/typescript-language-server) | None | None | None | @@ -252,8 +253,9 @@ via configuration files (for every feature: syntax highlighting, LSP, linter and | xtend | ✓ | None | None | None | None | | yaml | ✓ | [yaml-language-server](https://github.com/redhat-developer/yaml-language-server) | None | None | None | | yuescript | ✓ | None | None | None | None | +| zephir | ✓ | None | None | None | None | | zig | ✓ | [zls](https://github.com/zigtools/zls) | [zig](https://ziglang.org) | [zig](https://ziglang.org) | [lldb-dap](https://github.com/llvm/llvm-project/blob/main/lldb/tools/lldb-dap/README.md) | -| ü | ✓ | [Ü language server](https://github.com/Panzerschrek/U-00DC-Sprache) | None | None | None | +| ü | ✓ | [Ü language server](https://github.com/Panzerschrek/U-00DC-Sprache) | None | None | [gdb](https://www.gnu.org/software/gdb) / [lldb-dap](https://github.com/llvm/llvm-project/blob/main/lldb/tools/lldb-dap/README.md) | #### native From ddf48b47fd9952498c136f9251dfbb23c2725bfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sun, 13 Apr 2025 16:55:27 -0300 Subject: [PATCH 24/30] Update release number. --- .github/workflows/ecode-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ecode-release.yml b/.github/workflows/ecode-release.yml index fcdfd8e42..64e1de47b 100644 --- a/.github/workflows/ecode-release.yml +++ b/.github/workflows/ecode-release.yml @@ -9,7 +9,7 @@ on: inputs: version: description: Release Version - default: ecode-0.6.3 + default: ecode-0.7.1 required: true permissions: write-all From 5facbc5338ad303320770a5ee5da9fc5aee18e3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sat, 19 Apr 2025 01:24:50 -0300 Subject: [PATCH 25/30] Update ubuntu in release builds. --- .github/workflows/ecode-release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ecode-release.yml b/.github/workflows/ecode-release.yml index 64e1de47b..fabc12748 100644 --- a/.github/workflows/ecode-release.yml +++ b/.github/workflows/ecode-release.yml @@ -17,7 +17,7 @@ permissions: write-all jobs: release: name: Create Release - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 outputs: upload_url: ${{ steps.create_release.outputs.upload_url }} version: ${{ steps.tag.outputs.version }} @@ -58,7 +58,7 @@ jobs: matrix: config: - arch: x86_64 - container: ubuntu-20.04 + container: ubuntu-22.04 runs-on: ${{ matrix.config.container }} env: CC: gcc From 5ec85a7aabb06007ecfe5a4ebc4eadf7b5207c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sat, 26 Apr 2025 16:10:11 -0300 Subject: [PATCH 26/30] Update Linux x86_64 build. --- .github/workflows/ecode-release.yml | 45 +++++++++++++++++------------ 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ecode-release.yml b/.github/workflows/ecode-release.yml index fabc12748..3f6127a6e 100644 --- a/.github/workflows/ecode-release.yml +++ b/.github/workflows/ecode-release.yml @@ -60,10 +60,17 @@ jobs: - arch: x86_64 container: ubuntu-22.04 runs-on: ${{ matrix.config.container }} + container: + image: ubuntu:20.04 env: CC: gcc CXX: g++ steps: + - name: Install essentials + run: | + export DEBIAN_FRONTEND=noninteractive + apt-get update + apt-get install -y --no-install-recommends software-properties-common build-essential git ca-certificates - name: Checkout Code uses: actions/checkout@v4 with: @@ -74,33 +81,33 @@ jobs: - name: Set Environment Variables run: | echo "$HOME/.local/bin" >> "$GITHUB_PATH" - echo "/usr/lib/ccache" >> "$GITHUB_PATH" echo "INSTALL_REF=${{ needs.release.outputs.version }}" >> "$GITHUB_ENV" echo "RARCH=$(uname -m)" >> "$GITHUB_ENV" echo $(ldd --version) - echo $(gcc --version) - - name: Update Packages - run: | - sudo add-apt-repository -y universe - sudo add-apt-repository -y multiverse - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test - sudo apt-get update + - name: Mark Git directory as safe + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" - name: Install dependencies run: | - sudo apt-get install -y gcc-13 g++-13 libdw-dev - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 10 - sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 10 - sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 30 - sudo update-alternatives --set cc /usr/bin/gcc - sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 30 - sudo update-alternatives --set c++ /usr/bin/g++ - sudo update-alternatives --config gcc - sudo update-alternatives --config g++ - sudo apt-get install -y libfuse2 fuse premake4 mesa-common-dev libgl1-mesa-dev + apt-get install -y curl libfuse2 fuse premake4 mesa-common-dev libgl1-mesa-dev sudo file appstream + curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - + apt-get install -y nodejs + add-apt-repository -y universe + add-apt-repository -y multiverse + add-apt-repository -y ppa:ubuntu-toolchain-r/test + apt-get update + apt-get install -y gcc-13 g++-13 libdw-dev + update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 10 + update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 10 + update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 30 + update-alternatives --set cc /usr/bin/gcc + update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 30 + update-alternatives --set c++ /usr/bin/g++ + update-alternatives --config gcc + update-alternatives --config g++ bash projects/linux/scripts/install_sdl2.sh - name: Build ecode run: | - bash projects/linux/ecode/build.app.sh --arch ${{ matrix.config.arch }} + bash projects/linux/ecode/build.app.sh --with-static-cpp --arch ${{ matrix.config.arch }} - name: Upload Files uses: softprops/action-gh-release@v2 with: From 16474139aada960c8decaa53d2eff8ef1e5b9466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sat, 26 Apr 2025 19:43:20 -0300 Subject: [PATCH 27/30] Add FreeBSD build. --- .github/workflows/ecode-release.yml | 40 +++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/.github/workflows/ecode-release.yml b/.github/workflows/ecode-release.yml index 3f6127a6e..d0a5d29e1 100644 --- a/.github/workflows/ecode-release.yml +++ b/.github/workflows/ecode-release.yml @@ -382,3 +382,43 @@ jobs: prerelease: true files: | projects/macos/ecode/ecode-macos-${{ env.INSTALL_REF }}-x86_64.dmg + + build_freebsd_x86_64: + name: FreeBSD x86_64 + needs: release + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + repository: 'SpartanJ/eepp' + fetch-depth: 0 + submodules: 'recursive' + ref: 'refs/tags/ecode-${{ needs.release.outputs.version }}' + run: | + echo "INSTALL_REF=${{ needs.release.outputs.version }}" >> "$GITHUB_ENV" + echo "RARCH=$(uname -m)" >> "$GITHUB_ENV" + - uses: vmactions/freebsd-vm@v1 + env: + INSTALL_REF: ${{ needs.release.outputs.version }} + with: + release: '14.1' + envs: 'INSTALL_REF' + sync: sshfs + usesh: true + mem: 8192 + prepare: | + pkg install -y bash git sdl2 curl premake5 gsed gmake + run: | + export CC=clang + export CXX=clang++ + git config --global --add safe.directory "$GITHUB_WORKSPACE" + sh projects/freebsd/ecode/build.app.sh + - name: Upload Files + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ needs.release.outputs.version }} + draft: false + prerelease: true + files: | + projects/freebsd/ecode/ecode-freebsd-${{ env.INSTALL_REF }}-x86_64.tar.gz From 7a56085f32f10f8d94b1c1d4bf304ee32f8b4883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sat, 26 Apr 2025 19:44:51 -0300 Subject: [PATCH 28/30] Ups --- .github/workflows/ecode-release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ecode-release.yml b/.github/workflows/ecode-release.yml index d0a5d29e1..6529466ca 100644 --- a/.github/workflows/ecode-release.yml +++ b/.github/workflows/ecode-release.yml @@ -395,6 +395,7 @@ jobs: fetch-depth: 0 submodules: 'recursive' ref: 'refs/tags/ecode-${{ needs.release.outputs.version }}' + - name: Set Environment Variables run: | echo "INSTALL_REF=${{ needs.release.outputs.version }}" >> "$GITHUB_ENV" echo "RARCH=$(uname -m)" >> "$GITHUB_ENV" From bb4b8dcb8353ce32fc3fbaea904d3f421a1ddef3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Mon, 28 Apr 2025 19:57:12 -0300 Subject: [PATCH 29/30] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8620681c9..2e635a876 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ eepp GUI library as part of one of its main objectives. ## Screenshots -![ecode - Code Editor](https://github.com/SpartanJ/ecode/assets/650416/7926c3f3-1b3b-4fe5-859a-3099df73b7e8) +![ecode - Code Editor](https://github.com/user-attachments/assets/fa995b21-a612-4565-b08e-bb6c72799ef1) For more screenshots checkout [running on macOS](https://github.com/SpartanJ/ecode/assets/650416/9e8e00a7-fbcc-479b-8588-0023d8f86a9a), From 74abc73a51a3b1ed3e62bb6e213d97f868305265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Tue, 29 Apr 2025 00:07:32 -0300 Subject: [PATCH 30/30] Update Custom Languages docs. --- docs/customlanguages.md | 58 +++++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/docs/customlanguages.md b/docs/customlanguages.md index f1ec33bbb..dd1865352 100644 --- a/docs/customlanguages.md +++ b/docs/customlanguages.md @@ -6,17 +6,18 @@ Custom languages support can be added in the languages directory found at: * *macOS*: uses `Application Support` folder in `HOME`, usually translates to `~/Library/Application Support/ecode/languages` * *Windows*: uses `APPDATA`, usually translates to `C:\Users\{username}\AppData\Roaming\ecode\languages` -ecode will read each file located at that directory with `json` extension. Each file can contain one -or several languages. In order to set several languages the root element of the json file should be -an array, containing one object for each language, otherwise if the root element is an object, it -should contain the language definition. Language definitions can override any currently supported -definition. ecode will prioritize user defined definitions. +ecode will read each file located at that directory with `json` extension. Each file can contain one or several language definitions. + +* **Single Language:** If the root element of the JSON file is an object, it defines a single language. +* **Multiple Languages / Sub-Grammars:** If the root element is an array, it can define multiple independent languages *or* a main language along with **sub-language definitions** used for nesting within the main language (see Nested Syntaxes below). Each object in the array must be a complete language definition with at least a unique `"name"`. + +Language definitions can override any currently supported definition. ecode will prioritize user defined definitions. Sub-language definitions used only for nesting might not need fields like `"files"` or `"headers"` if they aren't intended to be selectable top-level languages. ### Language definition format ```json { - "name": "language_name", // (Required) The display name of the language. + "name": "language_name", // (Required) The display name of the language. Must be unique, especially if referenced by other definitions for nesting. "files": [ // (Required if `visible` is `true`) An array of Lua patterns matching filenames for this language. "%.ext$", // Example: Matches files ending in .ext "^Makefile$" // Example: Matches the exact filename Makefile @@ -28,13 +29,13 @@ definition. ecode will prioritize user defined definitions. // Rule using Lua patterns with capture groups mapping to different types: { "pattern": "no_capture(pattern_capture_1)(pattern_capture_2)", "type": [ "no_capture_type_name", "capture_1_type_name", "capture_2_type_name" ] }, // Rule defining a multi-line block using Lua patterns (start, end, escape character): - { "pattern": ["lua_pattern_start", "lua_pattern_end", "escape_character"], "type": "type_name" }, + { "pattern": ["lua_pattern_start", "lua_pattern_end", "escape_character"], "type": "type_name" }, // This rule highlights the entire block, including delimiters, with the specified `type_name`. // Rule using Perl-compatible regular expressions (PCRE): { "regex": "perl_regex", "type": "type_name" }, // Rule using PCRE with capture groups mapping to different types: { "regex": "no_capture(pattern_capture_1)(pattern_capture_2)", "type": [ "no_capture_type_name", "capture_1_type_name", "capture_2_type_name" ] }, // Rule defining a multi-line block using PCRE (start, end, escape character): - { "regex": ["regex_start", "regex_end", "escape_character"], "type": "type_name" }, + { "regex": ["regex_start", "regex_end", "escape_character"], "type": "type_name" }, // Similar to the Lua pattern block, highlights the entire block with `type_name`. // Rule using a custom parser implemented in native code for performance (e.g., number parsing): { "parser": "custom_parser_name", "type": "type_name" } // Currently available: "cpp_number_parser", "c_number_parser", "js_number_parser", "common_number_parser" (matches decimal and hexa), "common_number_parser_o" (matches the same as "common_number_parser" plus octal numbers), "common_number_parser_ob" (matches the same as "common_number_parser_o" plus binary numbers) @@ -54,6 +55,28 @@ definition. ecode will prioritize user defined definitions. // - The third capture (word with extra allowed chars) is typed as "symbol". // Similar to the above, when the third group matches text (e.g., "true"), ecode looks up "true" in the "symbols" definition. // If { "true": "literal" } exists, the matched text "true" will be highlighted as "literal". Otherwise, it defaults to "normal". + + // --- NESTED SYNTAX RULE --- + // Rule defining a multi-line block that switches to a DIFFERENT language syntax inside: + { + "pattern": ["lua_pattern_start", "lua_pattern_end", "escape_character"], // Can also use "regex" + "syntax": "NestedLanguageName", // (Optional) The 'name' of another language definition to use for highlighting *within* this block. + "type": "type_name" // OR ["type_for_start_capture1", "type_for_start_capture2", ...] // (Optional) Defines the type(s) for the text matched by the START and END patterns themselves (using capture groups if needed). If omitted, delimiters usually get 'normal' type. + }, + // How nesting works: + // 1. The `pattern` (or `regex`) defines the start and end delimiters of the block. + // 2. The `syntax` key specifies the `name` of another language definition (which must be loaded, often defined in the same JSON file using an array). + // 3. The text *between* the start and end delimiters will be highlighted using the rules defined in the "NestedLanguageName" language definition. + // 4. The `type` key here applies ONLY to the text matched by the start and end patterns themselves. If the start/end patterns have capture groups, you can provide an array of types matching those captures. + // 5. Nesting can occur up to 4 levels deep (e.g., Language A contains Language B, which contains Language C, etc.). + // Use Case: Essential for languages embedding other languages, like HTML containing CSS and JavaScript. + + // Example of a nested syntax rule (C++ raw string containing XML): + { + "pattern": [ "R%\"(xml)%(", "%)(xml)%\"" ], // Start: R"(xml)(, End: )(xml)" + "syntax": "XML", // Use the "XML" language definition inside. + "type": [ "string", "keyword2", "string", "keyword2" ] // Types for captures in start/end: "R\"(" + "xml" + ")(" and ")(" + "xml" + ")\"". Needs adjustment based on exact captures. Assumes captures are (xml) in start and (xml) in end. Often, the delimiters are just styled as 'string' or 'keyword2'. Example simplification: "type": "string" might apply to the whole delimiter match if no captures are typed. + }, ], "symbols": [ // (Optional) An array defining specific types for exact words, primarily used in conjunction with patterns having `type: "symbol"`. // Structure: An array where each element is an object containing exactly one key-value pair. @@ -102,6 +125,25 @@ definition. ecode will prioritize user defined definitions. ] } ``` +### Nested Syntaxes (Sub-Grammars) + +ecode supports **nested syntaxes**, allowing a block of code within one language to be highlighted according to the rules of another language. This is crucial for accurately representing modern languages that often embed other languages or domain-specific languages. + +**How it works:** + +1. **Define Sub-Languages:** Define the syntax for the language to be embedded (e.g., "CSS", "JavaScript", "XML", "SQL") as a separate language definition. Often, these are defined within the *same JSON file* as the main language, using a JSON array as the root element (see [Custom languages support](#custom-languages-support)). The sub-language definition needs a unique `"name"`. +2. **Reference in Patterns:** In the main language's `"patterns"`, use a multi-line block rule (`pattern` or `regex` array). Add the `"syntax"` key to this rule, setting its value to the `"name"` of the sub-language definition you want to use inside the block. +3. **Highlighting:** When ecode encounters this block, it applies the highlighting rules from the specified sub-language to the content *between* the start and end delimiters. The delimiters themselves are styled according to the `type` specified in the *outer* rule. + +**Example Use Cases:** + +* HTML files containing `