diff --git a/.github/workflows/ecode-release.yml b/.github/workflows/ecode-release.yml new file mode 100644 index 000000000..6529466ca --- /dev/null +++ b/.github/workflows/ecode-release.yml @@ -0,0 +1,425 @@ +name: Release + +on: + push: + tags: + - ecode-[0-9]+.* + + workflow_dispatch: + inputs: + version: + description: Release Version + default: ecode-0.7.1 + required: true + +permissions: write-all + +jobs: + release: + name: Create Release + runs-on: ubuntu-22.04 + outputs: + upload_url: ${{ steps.create_release.outputs.upload_url }} + version: ${{ steps.tag.outputs.version }} + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: { fetch-depth: 0, submodules: 'recursive' } + - name: Set Tag + id: tag + run: | + if [[ "${{ github.event.inputs.version }}" != "" ]]; then + echo "version=${{ github.event.inputs.version }}" | sed 's/ecode-//' >> "$GITHUB_OUTPUT" + else + echo "version=${GITHUB_REF/refs\/tags\//}" | sed 's/ecode-//' >> "$GITHUB_OUTPUT" + fi + - name: Update Tag + uses: richardsimko/update-tag@v1 + with: + tag_name: ecode-${{ steps.tag.outputs.version }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Create Release + id: create_release + uses: softprops/action-gh-release@v2 + with: + tag_name: ecode-${{ steps.tag.outputs.version }} + name: ecode ${{ steps.tag.outputs.version }} + draft: false + prerelease: true + generate_release_notes: true + body: > + Changelog pending + + build_linux_x86_64: + name: Linux x86_64 + needs: release + strategy: + matrix: + config: + - 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: + repository: 'SpartanJ/eepp' + fetch-depth: 0 + submodules: 'recursive' + ref: 'refs/tags/ecode-${{ needs.release.outputs.version }}' + - name: Set Environment Variables + run: | + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + echo "INSTALL_REF=${{ needs.release.outputs.version }}" >> "$GITHUB_ENV" + echo "RARCH=$(uname -m)" >> "$GITHUB_ENV" + echo $(ldd --version) + - name: Mark Git directory as safe + run: git config --global --add safe.directory "$GITHUB_WORKSPACE" + - name: Install dependencies + run: | + 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 --with-static-cpp --arch ${{ matrix.config.arch }} + - name: Upload Files + uses: softprops/action-gh-release@v2 + with: + repository: SpartanJ/ecode + tag_name: ecode-${{ needs.release.outputs.version }} + draft: false + prerelease: true + files: | + projects/linux/ecode/ecode-linux-${{ env.INSTALL_REF }}-${{ env.RARCH }}.AppImage + projects/linux/ecode/ecode-linux-${{ env.INSTALL_REF }}-${{ env.RARCH }}.tar.gz + + build_linux_arm64: + name: Linux arm64 + needs: release + strategy: + matrix: + config: + - arch: aarch64 + container: ubuntu-22.04 + runs-on: ${{ matrix.config.container }} + env: + CC: gcc + CXX: g++ + 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 }}' + - 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 "CC=aarch64-linux-gnu-gcc" >> "$GITHUB_ENV" + echo "CXX=aarch64-linux-gnu-g++" >> "$GITHUB_ENV" + echo "AR=aarch64-linux-gnu-ar" >> "$GITHUB_ENV" + echo "RANLIB=aarch64-linux-gnu-ranlib" >> "$GITHUB_ENV" + echo "STRIP=aarch64-linux-gnu-strip" >> "$GITHUB_ENV" + echo "RARCH=arm64" >> "$GITHUB_ENV" >> "$GITHUB_ENV" + echo $(ldd --version) + echo $(gcc --version) + - name: Update Packages + run: | + codename=$(lsb_release -cs) + url="http://ports.ubuntu.com/ubuntu-ports" + repos="main restricted universe multiverse" + echo "deb [arch=arm64] $url $codename $repos" > arm64.list + echo "deb [arch=arm64] $url $codename-backports $repos" >> arm64.list + echo "deb [arch=arm64] $url $codename-security $repos" >> arm64.list + echo "deb [arch=arm64] $url $codename-updates $repos" >> arm64.list + sudo mv arm64.list /etc/apt/sources.list.d/ + sudo apt-get update + sudo dpkg --add-architecture arm64 + - name: Install dependencies + run: | + sudo apt-get install -y premake4 libfuse2 fuse gcc-aarch64-linux-gnu g++-aarch64-linux-gnu + bash projects/linux/scripts/install_sdl2.sh --aarch64 + - name: Build ecode + run: | + bash projects/linux/ecode/build.app.sh --arch ${{ matrix.config.arch }} + - name: Upload Files + uses: softprops/action-gh-release@v2 + with: + repository: SpartanJ/ecode + tag_name: ecode-${{ needs.release.outputs.version }} + draft: false + prerelease: true + files: | + projects/linux/ecode/ecode-linux-${{ env.INSTALL_REF }}-${{ env.RARCH }}.AppImage + projects/linux/ecode/ecode-linux-${{ env.INSTALL_REF }}-${{ env.RARCH }}.tar.gz + + build_windows_cross: + name: Windows x86_64 + needs: release + strategy: + matrix: + config: + - compiler: default + arch: x86_64 + container: ubuntu-22.04 + runs-on: ${{ matrix.config.container }} + env: + CC: gcc + CXX: g++ + 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 }}' + - name: Set Environment Variables + run: | + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + echo "INSTALL_REF=${{ needs.release.outputs.version }}" >> "$GITHUB_ENV" + echo "RARCH=$(uname -m)" >> "$GITHUB_ENV" + - name: Update Packages + run: | + sudo add-apt-repository -y universe + sudo add-apt-repository -y multiverse + sudo apt-get update + - name: Install dependencies + run: | + sudo apt-get install -y premake4 libfuse2 fuse mingw-w64 gcc-12 g++-12 + wget https://github.com/premake/premake-core/releases/download/v5.0.0-beta2/premake-5.0.0-beta2-linux.tar.gz + tar xvzf premake-5.0.0-beta2-linux.tar.gz + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 10 + sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 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++ + - name: Build ecode + run: | + bash projects/mingw32/ecode/build.app.sh + - name: Upload Files + uses: softprops/action-gh-release@v2 + with: + repository: SpartanJ/ecode + tag_name: ecode-${{ needs.release.outputs.version }} + draft: false + prerelease: true + files: | + projects/mingw32/ecode/ecode-windows-${{ env.INSTALL_REF }}-${{ env.RARCH }}.zip + + build_windows_arm64_cross: + name: Windows arm64 + needs: release + strategy: + matrix: + config: + - compiler: default + arch: arm64 + container: ubuntu-22.04 + runs-on: ${{ matrix.config.container }} + 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 }}' + - name: Set Environment Variables + run: | + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + echo "INSTALL_REF=${{ needs.release.outputs.version }}" >> "$GITHUB_ENV" + - name: Update Packages + run: | + sudo add-apt-repository -y universe + sudo add-apt-repository -y multiverse + sudo apt-get update + - name: Install dependencies + run: | + sudo apt-get install -y libfuse2 fuse + wget https://github.com/premake/premake-core/releases/download/v5.0.0-beta2/premake-5.0.0-beta2-linux.tar.gz + tar xvzf premake-5.0.0-beta2-linux.tar.gz + - name: Build ecode + run: | + bash projects/mingw32/ecode/build.app.sh --arch=arm64 + - name: Upload Files + uses: softprops/action-gh-release@v2 + with: + tag_name: ecode-${{ needs.release.outputs.version }} + draft: false + prerelease: true + files: | + projects/mingw32/ecode/ecode-windows-${{ env.INSTALL_REF }}-arm64.zip + + build_macos: + name: macOS arm64 + needs: release + runs-on: macos-14 + strategy: + matrix: + arch: [arm64] + env: + CC: clang + CXX: clang++ + 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 }}' + - name: System Information + run: | + system_profiler SPSoftwareDataType + bash --version + gcc -v + xcodebuild -version + uname -a + - name: Set Environment Variables + run: | + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + echo "INSTALL_REF=${{ needs.release.outputs.version }}" >> "$GITHUB_ENV" + - name: Install Dependencies + run: | + brew install bash sdl2 create-dmg premake p7zip + - name: Build + run: | + bash projects/macos/ecode/build.app.sh + - name: Create DMG Image + run: | + bash projects/macos/ecode/create.dmg.sh + - name: Upload Files + uses: softprops/action-gh-release@v2 + with: + repository: SpartanJ/ecode + tag_name: ecode-${{ needs.release.outputs.version }} + draft: false + prerelease: true + files: | + projects/macos/ecode/ecode-macos-${{ env.INSTALL_REF }}-arm64.dmg + + build_macos_cross: + name: macOS x86_64 + needs: release + runs-on: macos-14 + strategy: + matrix: + arch: [arm64] + env: + CC: clang + CXX: clang++ + 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 }}' + - name: System Information + run: | + system_profiler SPSoftwareDataType + bash --version + gcc -v + xcodebuild -version + uname -a + - name: Set Environment Variables + run: | + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + echo "INSTALL_REF=${{ needs.release.outputs.version }}" >> "$GITHUB_ENV" + - name: Install Dependencies + run: | + brew install bash create-dmg premake p7zip + 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 + run: | + bash projects/macos/ecode/cross.build.app.sh + - name: Create DMG Image + run: | + bash projects/macos/ecode/cross.create.dmg.sh + - name: Upload Files + uses: softprops/action-gh-release@v2 + with: + repository: SpartanJ/ecode + tag_name: ecode-${{ needs.release.outputs.version }} + draft: false + 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 }}' + - name: Set Environment Variables + 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 diff --git a/README.md b/README.md index 80874defb..2e635a876 100644 --- a/README.md +++ b/README.md @@ -11,21 +11,32 @@ eepp GUI library as part of one of its main objectives. ## Screenshots - - -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 * Lightweight * Portable -* Minimalist GUI -* Syntax Highlighting (including nested syntax highlighting, supporting over 90 languages and LSP semantic highlighting) +* Uncluttered GUI +* Syntax Highlighting (including nested syntax highlighting, supporting over 100 languages and LSP semantic highlighting) * Multi-cursor support -* Terminal support -* Command Palette * [LSP](https://microsoft.github.io/language-server-protocol/) support +* 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 @@ -33,6 +44,7 @@ For more screenshots checkout [running on macOS](https://github.com/SpartanJ/eco * Customizable keyboard bindings * Configurable build pipelines * Fast global search (and replace) +* AI Assistant plugin * Minimap * Unlimited editor splitting * Easily extendable language support @@ -48,7 +60,7 @@ For more screenshots checkout [running on macOS](https://github.com/SpartanJ/eco * Soft-wrap * Code-folding * Session Snapshot & Periodic Backup -* [Lua pattern searches](https://www.lua.org/manual/5.4/manual.html#6.4.1) support +* Perl Regular Expressions and [Lua pattern searches](https://www.lua.org/manual/5.4/manual.html#6.4.1) support * Plugins support. ### Folder / Project Settings (\*) @@ -87,7 +99,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) @@ -104,7 +116,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`). @@ -114,109 +126,136 @@ The project name is always *ecode* (so if you are building with make, you'll nee * *FreeBSD* build script can be found [here](https://github.com/SpartanJ/eepp/tree/develop/projects/freebsd/ecode). Running `build.app.sh` will try to build a `tar.gz` with the compressed application. `ecode.app` folder will contain the uncompressed application. * *Haiku* build script can be found [here](https://github.com/SpartanJ/eepp/tree/develop/projects/haiku/ecode). Running `build.app.sh` will try to build a `tar.gz` with the compressed application. `ecode.app` folder will contain the uncompressed application. +## Nightly Builds + +Nightly builds are being distributed [here](https://github.com/SpartanJ/eepp/releases/tag/nightly) for the more impatient users. ecode is being developed actively, nightly builds may not be stable for daily usage unless there's a pending unreleased fix required for the user. + ## Language support ecode is constantly adding more languages support and also supports extending it's language support 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 | -| 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 | ✓ | None | 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 | ✓ | 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/) | -| 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) | -| odin | ✓ | [ols](https://github.com/DanielGavin/ols) | None | None | -| pascal | ✓ | None | None | None | -| perl | ✓ | None | 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 | -| 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 | -| 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 | +| blade | ✓ | 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) | +| 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 | +| 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 | +| 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 | +| 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 | +| 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 | +| 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 | +| 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 | +| 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 | +| 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) | +| 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 | +| 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 | +| 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 | +| 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 | +| 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 | +| 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 | [gdb](https://www.gnu.org/software/gdb) / [lldb-dap](https://github.com/llvm/llvm-project/blob/main/lldb/tools/lldb-dap/README.md) | #### native @@ -241,262 +280,68 @@ 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 - -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 +`linters.json` configuration. -```json -{ - "config": { - "auto_format_on_save": false - }, - "keybindings": { - "format-doc": "alt+f" - }, - "formatters": [ - { - "file_patterns": ["%.js$", "%.ts$"], - "command": "prettier $FILENAME" - } - ] -} -``` +For more information [read the linter documentation](docs/linter.md). -#### Currently supported formatters +#### LSP Client -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 +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. -#### Formatter keybindings object keys +For more information [read the lsp client documentation](docs/lsp.md). -* **format-doc**: Keybinding to format the doc with the configured language formatter +#### Debugger -#### Formatter JSON object keys +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. -* **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 on how to use the debugger [read the debugger documentation](docs/debugger.md). -### 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 +#### 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/)) +For more information [read the git integration documentation](docs/git.md). -```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" - } -} -``` +#### Auto Formatter -#### Git config 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. -* **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. +For more information [read the formatter documentation](docs/formatter.md). -#### Git keybindings object keys +#### Auto Complete -* **git-blame**: Keybinding to display the a git blame summary over the current positioned line. +The auto-complete plugin is in charge of providing suggestions for code-completion and signature help. -### Auto Complete +For more information [read the auto-complete documentation](docs/autocomplete.md). -The auto-complete plugin is in charge of providing suggestions for code-completion and signature help. +#### AI Assistant -#### Auto Complete config object keys +The AI Assistant is a simple but effective LLM Chat UI. You'll be able to chat with different models +from within the editor. -* **max_label_characters**: Maximum characters displayed in the suggestion box. -* **suggestions_syntax_highlight**: Enables/disables syntax highlighting in suggestions. +For more information [read the AI assistant documentation](docs/aiassistant.md). -### XML Tools +#### 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 @@ -515,218 +360,35 @@ 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 check our documentation: -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. -*A minor clarification:* ecode does not currently support regex for pattern matching that it's supported -by lite-xl (it might be added in the near future). - -### 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 Listed in no particular order: -* [DAP](https://microsoft.github.io/debug-adapter-protocol/) support +* General polishing * Improved plugin system (visual configuration, more flexibility/features) +* AI assistant plugin +* 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 @@ -748,24 +410,22 @@ 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 -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). @@ -794,6 +454,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 diff --git a/docs/aiassistant.md b/docs/aiassistant.md new file mode 100644 index 000000000..6dd607c73 --- /dev/null +++ b/docs/aiassistant.md @@ -0,0 +1,161 @@ +# AI Assistant + +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/autocomplete.md b/docs/autocomplete.md new file mode 100644 index 000000000..a7caa14fd --- /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..dd1865352 --- /dev/null +++ b/docs/customlanguages.md @@ -0,0 +1,281 @@ +## 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 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. 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 + ], + "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" ] }, + // 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" }, // 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" }, // 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) + + // 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". + + // --- 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. + // - 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 file type by reading the first few lines (header). + "^#!.*[ /]bash" // Example: Identifies bash scripts like '#!/bin/bash' + ], + "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 `