diff --git a/.agent/rules/umide-roadmap.md b/.agent/rules/umide-roadmap.md index 9809c3ba..6378505b 100644 --- a/.agent/rules/umide-roadmap.md +++ b/.agent/rules/umide-roadmap.md @@ -35,13 +35,13 @@ Future-proof for complex graphics (Metal/Vulkan/OpenGL) No IDE rewrite -Lapce remains the editor core +Umide remains the editor core 2. High-Level Architecture (Layered & Decoupled) ┌────────────────────────────────────────────┐ │ UMIDE (Shell) │ │ │ - │ ┌───────────── Lapce / Floem ───────────┐ │ + │ ┌───────────── Umide / Floem ───────────┐ │ │ │ Editor, LSP, Git, Commands, Panels │ │ │ └────────────────────────────────────────┘ │ │ │ @@ -62,12 +62,12 @@ Lapce remains the editor core │ │ └────────────────────────────────────────────┘ -3. Why Lapce + C++ Is the Correct Choice +3. Why Umide + C++ Is the Correct Choice Why NOT rewrite the IDE Editor/LSP/keybindings are hard problems already solved -Lapce is fast, native, modern +Umide is fast, native, modern Floem is evolving rapidly @@ -128,7 +128,7 @@ It is a native GPU surface embedded into the window. Create a native GPU surface -Attach it to the same window Lapce owns +Attach it to the same window Umide owns Share the graphics context @@ -165,7 +165,7 @@ Future rendering APIs └─ NativeSurfaceHandle ─────▶ C++ Emulator Core Responsibilities -Rust (Lapce side) +Rust (Umide side) Layout & docking diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 2dad4588..869d172f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,21 +1,21 @@ --- name: Bug report about: Create a report to help us improve -title: '' -labels: 'C-bug' -assignees: '' - +title: "" +labels: "C-bug" +assignees: "" --- -## Lapce Version +## Umide Version -The Lapce version you are using, which can be found in "About Lapce" at the top right settings icon. +The Umide version you are using, which can be found in "About Umide" at the top right settings icon. ## System information the operating system used, including its version, e.g. Windows 10, Ubuntu 18.04 ## Describe the bug + A clear and concise description of what the bug is. ## Additional information diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index aac61aa4..ab7739a7 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,11 +1,11 @@ blank_issues_enabled: false contact_links: - - name: Lapce community on Discord + - name: Umide community on Discord url: https://discord.gg/n8tGJ6Rn6D about: Please ask and answer questions here. - - name: Lapce community on Matrix + - name: Umide community on Matrix url: https://matrix.to/#/#lapce-editor:matrix.org about: Please ask and answer questions here. - - name: Lapce documentation + - name: Umide documentation url: https://docs.lapce.dev/ - about: Documentation for Lapce + about: Documentation for Umide diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index eba040d9..e86275f7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,373 +1,255 @@ name: Release on: - schedule: - - cron: 0 0 * * * + push: + tags: + - "v*" workflow_dispatch: inputs: tag_name: - description: "Tag name for release" - required: false - default: nightly - push: - tags: ["v[0-9]+.[0-9]+.[0-9]+*"] + description: "Release tag (for example: v1.0.0)" + required: true pull_request: paths: - # trigger release workflow only if this file changed - - .github/workflows/release.yml + - ".github/workflows/release.yml" concurrency: group: ${{ github.ref }}-${{ github.workflow }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CARGO_TERM_COLOR: always + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse + FLOEM_REPOSITORY: https://github.com/bridgerust/floem + FLOEM_REV: e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3 jobs: - tagname: + meta: runs-on: ubuntu-latest outputs: - tag_name: ${{ steps.tag.outputs.tag }} + tag_name: ${{ steps.meta.outputs.tag_name }} + prerelease: ${{ steps.meta.outputs.prerelease }} steps: - - id: vars + - id: meta shell: bash - run: echo "sha_short=${GITHUB_SHA::7}" | tee -a $GITHUB_OUTPUT - - - if: github.event_name == 'workflow_dispatch' - run: echo "TAG_NAME=${{ github.event.inputs.tag_name }}" | tee -a $GITHUB_ENV - - - if: github.event_name == 'schedule' || github.event_name == 'pull_request' - run: echo 'TAG_NAME=nightly-${{ steps.vars.outputs.sha_short }}' | tee -a $GITHUB_ENV - - - if: github.event_name == 'push' run: | - TAG_NAME=${{ github.ref }} - echo "TAG_NAME=${TAG_NAME#refs/tags/}" | tee -a $GITHUB_ENV + if [[ "${{ github.event_name }}" == "push" ]]; then + TAG_NAME="${GITHUB_REF_NAME}" + elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + TAG_NAME="${{ github.event.inputs.tag_name }}" + else + TAG_NAME="dry-run-${GITHUB_SHA::7}" + fi - - id: tag - run: echo "tag=$TAG_NAME" | tee -a $GITHUB_OUTPUT + if [[ -z "${TAG_NAME}" ]]; then + echo "tag_name input is required for workflow_dispatch" + exit 1 + fi - windows: - runs-on: windows-latest - needs: tagname - env: - RELEASE_TAG_NAME: ${{ needs.tagname.outputs.tag_name }} + PRERELEASE=false + if [[ "${TAG_NAME}" == *-* ]]; then + PRERELEASE=true + fi - defaults: - run: - shell: bash + echo "tag_name=${TAG_NAME}" | tee -a "$GITHUB_OUTPUT" + echo "prerelease=${PRERELEASE}" | tee -a "$GITHUB_OUTPUT" + linux: + name: Build Linux + runs-on: ubuntu-latest + needs: meta steps: - uses: actions/checkout@v4 - - name: Update rust - run: rustup update --no-self-update - - - name: Fetch dependencies - run: cargo fetch --locked - - - name: Build - run: cargo build --frozen --profile release-lto - - - name: Crate msi installer - run: | - candle.exe -arch "x64" -ext WixUIExtension -ext WixUtilExtension \ - -out "./lapce.wixobj" "extra/windows/wix/lapce.wxs" - - light.exe -ext WixUIExtension -ext WixUtilExtension \ - -out "./Lapce-windows.msi" -sice:ICE61 -sice:ICE91 \ - "./lapce.wixobj" - - - name: Create portable - shell: pwsh - run: | - cargo build --profile release-lto --features lapce-app/portable - Compress-Archive ./target/release-lto/lapce.exe ./Lapce-windows-portable.zip - - - name: Create lapce-proxy archive - shell: pwsh - run: | - $file = [System.IO.File]::Open((Join-Path $PWD '.\target\release-lto\lapce-proxy.exe'), [System.IO.FileMode]::Open) - $archive = [System.IO.File]::Create((Join-Path $PWD '.\lapce-proxy-windows-x86_64.gz')) - $compressor = [System.IO.Compression.GZipStream]::new($archive, [System.IO.Compression.CompressionMode]::Compress) - $file.CopyTo($compressor) - Start-Sleep -Seconds 10 - $compressor.close() - - - uses: actions/upload-artifact@v4 + - name: Set up protoc + uses: arduino/setup-protoc@v3 with: - name: lapce-windows - path: | - ./lapce-proxy-windows-*.gz - ./Lapce-windows-portable.zip - ./Lapce-windows.msi - retention-days: 1 + repo-token: ${{ secrets.GITHUB_TOKEN }} - linux: - runs-on: ubuntu-latest - needs: tagname - env: - RELEASE_TAG_NAME: ${{ needs.tagname.outputs.tag_name }} - steps: - - uses: actions/checkout@v4 - - name: Build deb packages - run: | - docker buildx create --driver=docker-container --use - docker buildx bake --pull ubuntu-focal-binary + - name: Install Linux build dependencies + run: sudo make ubuntu-deps - - name: Gzip + - name: Prepare floem dependency run: | - mkdir Lapce - cp ./target/linux_amd64/lapce Lapce/ - tar -zcvf ./lapce-linux-amd64.tar.gz Lapce + rm -rf ../floem + git clone "${FLOEM_REPOSITORY}" ../floem + git -C ../floem checkout "${FLOEM_REV}" - rm -rf Lapce + - name: Update toolchain + run: rustup update --no-self-update - mkdir Lapce - cp ./target/linux_arm64/lapce Lapce/ - tar -zcvf ./lapce-linux-arm64.tar.gz Lapce + - name: Cache Rust dependencies + uses: Swatinem/rust-cache@v2 - - name: Fetch dependencies - run: cargo fetch --locked + - name: Build binaries + run: cargo build --profile release-lto --bin umide --bin umide-proxy - - name: Vendor dependencies + - name: Package artifacts + shell: bash run: | - cargo vendor --frozen > ./vendor-config.toml - mv ./vendor-config.toml ./vendor/ - tar -zcf vendor.tar.gz ./vendor/ + cp ./target/release-lto/umide ./umide-linux-x86_64 + cp ./target/release-lto/umide-proxy ./umide-proxy-linux-x86_64 + tar -czf ./umide-linux-x86_64.tar.gz ./umide-linux-x86_64 + gzip -c ./umide-proxy-linux-x86_64 > ./umide-proxy-linux-x86_64.gz - uses: actions/upload-artifact@v4 with: - name: lapce-linux + name: release-linux path: | - ./lapce-linux-*.tar.gz - ./vendor.tar.gz - retention-days: 1 + ./umide-linux-x86_64.tar.gz + ./umide-proxy-linux-x86_64.gz + retention-days: 7 - deb: - runs-on: ubuntu-latest - needs: tagname - env: - RELEASE_TAG_NAME: ${{ needs.tagname.outputs.tag_name }} - strategy: - fail-fast: false - matrix: - include: - - os-name: debian - os-version: bookworm - - os-name: debian - os-version: bullseye - - os-name: ubuntu - os-version: jammy - - os-name: ubuntu - os-version: noble - - os-name: ubuntu - os-version: plucky + windows: + name: Build Windows + runs-on: windows-latest + needs: meta + defaults: + run: + shell: pwsh steps: - uses: actions/checkout@v4 - - name: Build deb packages - run: | - docker buildx create --driver=docker-container --use - docker buildx bake --pull ${{ matrix.os-name }}-${{ matrix.os-version }}-package - - - uses: actions/upload-artifact@v4 + - name: Set up protoc + uses: arduino/setup-protoc@v3 with: - name: lapce-${{ matrix.os-name }}-${{ matrix.os-version }} - path: | - ./target/linux_*/* - retention-days: 1 + repo-token: ${{ secrets.GITHUB_TOKEN }} - rpm: - runs-on: ubuntu-latest - needs: tagname - env: - RELEASE_TAG_NAME: ${{ needs.tagname.outputs.tag_name }} - strategy: - fail-fast: false - matrix: - include: - - os-name: fedora - os-version: 41 - - os-name: fedora - os-version: 42 - # - os-name: fedora - # os-version: rawhide - steps: - - uses: actions/checkout@v4 - - - name: Build rpm packages + - name: Prepare floem dependency run: | - docker buildx create --driver=docker-container --use - docker buildx bake --pull ${{ matrix.os-name }}-${{ matrix.os-version }}-package + if (Test-Path ../floem) { Remove-Item -Path ../floem -Recurse -Force } + git clone "${env:FLOEM_REPOSITORY}" ../floem + git -C ../floem checkout "${env:FLOEM_REV}" - - uses: actions/upload-artifact@v4 - with: - name: lapce-${{ matrix.os-name }}-${{ matrix.os-version }} - path: | - ./target/* - retention-days: 1 + - name: Update toolchain + run: rustup update --no-self-update - lapce-proxy: - runs-on: ubuntu-latest - needs: tagname - env: - RELEASE_TAG_NAME: ${{ needs.tagname.outputs.tag_name }} - strategy: - fail-fast: false - matrix: - include: - - os-name: alpine - os-version: "" # uses latest - steps: - - uses: actions/checkout@v4 + - name: Cache Rust dependencies + uses: Swatinem/rust-cache@v2 - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + - name: Build binaries + run: cargo build --profile release-lto --bin umide --bin umide-proxy - - name: Build lapce-proxy binary + - name: Package artifacts run: | - docker buildx create --driver=docker-container --use - docker buildx bake --pull ${{ matrix.os-name }}-${{ matrix.os-version }} + Compress-Archive -Path .\target\release-lto\umide.exe -DestinationPath .\umide-windows-x86_64.zip -Force - - name: Gzip - run: | - gzip -c ./target/linux_amd64/lapce-proxy > ./lapce-proxy-linux-x86_64.gz - gzip -c ./target/linux_arm64/lapce-proxy > ./lapce-proxy-linux-aarch64.gz + $source = Join-Path $PWD '.\target\release-lto\umide-proxy.exe' + $target = Join-Path $PWD '.\umide-proxy-windows-x86_64.gz' + $inStream = [System.IO.File]::OpenRead($source) + $outStream = [System.IO.File]::Create($target) + $gzipStream = New-Object System.IO.Compression.GzipStream($outStream, [System.IO.Compression.CompressionLevel]::Optimal) + $inStream.CopyTo($gzipStream) + $gzipStream.Dispose() + $inStream.Dispose() + $outStream.Dispose() - uses: actions/upload-artifact@v4 with: - name: lapce-proxy-linux + name: release-windows path: | - ./lapce-proxy-linux-*.gz - retention-days: 1 + ./umide-windows-x86_64.zip + ./umide-proxy-windows-x86_64.gz + retention-days: 7 macos: + name: Build macOS runs-on: macos-14 - needs: tagname - env: - RELEASE_TAG_NAME: ${{ needs.tagname.outputs.tag_name }} - - NOTARIZE_USERNAME: ${{ secrets.NOTARIZE_USERNAME }} - NOTARIZE_PASSWORD: ${{ secrets.NOTARIZE_PASSWORD }} - + needs: meta steps: - uses: actions/checkout@v4 - - name: Install ARM target - run: rustup update && rustup target add x86_64-apple-darwin - - - name: Import Certificate - uses: Apple-Actions/import-codesign-certs@v3 + - name: Set up protoc + uses: arduino/setup-protoc@v3 with: - p12-file-base64: ${{ secrets.MACOS_CERTIFICATE }} - p12-password: ${{ secrets.MACOS_CERTIFICATE_PWD }} + repo-token: ${{ secrets.GITHUB_TOKEN }} - - name: Select newer Xcode for building + - name: Prepare floem dependency + shell: bash run: | - sudo xcode-select -s /Applications/Xcode_15.4.app/Contents/Developer + rm -rf ../floem + git clone "${FLOEM_REPOSITORY}" ../floem + git -C ../floem checkout "${FLOEM_REV}" - - name: Fetch dependencies - run: cargo fetch --locked + - name: Update toolchain and install targets + run: | + rustup update --no-self-update + rustup target add x86_64-apple-darwin aarch64-apple-darwin - - name: Make DMG - run: make dmg-universal + - name: Cache Rust dependencies + uses: Swatinem/rust-cache@v2 - - name: Rename + - name: Build binaries run: | - cp ./target/release-lto/macos/Lapce.dmg ./target/release-lto/macos/Lapce-macos.dmg + cargo build --profile release-lto --target x86_64-apple-darwin --bin umide --bin umide-proxy + cargo build --profile release-lto --target aarch64-apple-darwin --bin umide --bin umide-proxy - - name: Gzip lapce-proxy + - name: Build universal artifacts + shell: bash run: | - gzip -c ./target/x86_64-apple-darwin/release-lto/lapce-proxy > ./target/release-lto/macos/lapce-proxy-darwin-x86_64.gz - gzip -c ./target/aarch64-apple-darwin/release-lto/lapce-proxy > ./target/release-lto/macos/lapce-proxy-darwin-aarch64.gz + lipo -create \ + ./target/x86_64-apple-darwin/release-lto/umide \ + ./target/aarch64-apple-darwin/release-lto/umide \ + -output ./umide-macos-universal - - name: Notarize Release Build - uses: lando/notarize-action@v2 - with: - product-path: "./target/release-lto/macos/Lapce-macos.dmg" - appstore-connect-username: ${{ secrets.NOTARIZE_USERNAME }} - appstore-connect-password: ${{ secrets.NOTARIZE_PASSWORD }} - appstore-connect-team-id: CYSGAZFR8D - primary-bundle-id: "io.lapce" - verbose: true - - - name: "Staple Release Build" - uses: lapce/xcode-staple@062485d6eeafe841c18a412f012e80f49e23c517 - with: - product-path: "./target/release-lto/macos/Lapce-macos.dmg" + lipo -create \ + ./target/x86_64-apple-darwin/release-lto/umide-proxy \ + ./target/aarch64-apple-darwin/release-lto/umide-proxy \ + -output ./umide-proxy-macos-universal + + tar -czf ./umide-macos-universal.tar.gz ./umide-macos-universal + gzip -c ./umide-proxy-macos-universal > ./umide-proxy-macos-universal.gz - uses: actions/upload-artifact@v4 with: - name: lapce-macos + name: release-macos path: | - ./target/release-lto/macos/lapce-proxy-darwin-*.gz - ./target/release-lto/macos/Lapce-macos.dmg - retention-days: 3 + ./umide-macos-universal.tar.gz + ./umide-proxy-macos-universal.gz + retention-days: 7 publish: + name: Publish GitHub Release + if: github.event_name != 'pull_request' + runs-on: ubuntu-latest needs: + - meta - linux - - lapce-proxy - - deb - - rpm - windows - macos - runs-on: ubuntu-latest - env: - GH_REPO: ${{ github.repository }} - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} permissions: contents: write + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG_NAME: ${{ needs.meta.outputs.tag_name }} + PRERELEASE: ${{ needs.meta.outputs.prerelease }} steps: - # Must perform checkout first, since it deletes the target directory - # before running, and would therefore delete the downloaded artifacts - - uses: actions/checkout@v4 - - uses: actions/download-artifact@v4 - - if: github.event_name == 'workflow_dispatch' - run: echo "TAG_NAME=${{ github.event.inputs.tag_name }}" | tee -a $GITHUB_ENV - - - if: github.event_name == 'schedule' - run: echo 'TAG_NAME=nightly' | tee -a $GITHUB_ENV - - - if: github.event_name == 'push' - run: | - TAG_NAME=${{ github.ref }} - echo "TAG_NAME=${TAG_NAME#refs/tags/}" | tee -a $GITHUB_ENV - - - if: env.TAG_NAME == 'nightly' - run: | - { - echo 'SUBJECT=Lapce development build' - echo 'PRERELEASE=--prerelease' - } | tee -a $GITHUB_ENV - - - if: env.TAG_NAME == 'nightly' && github.event_name != 'pull_request' - name: Re-Tag nightly - run: | - gh release delete nightly --yes || true - git push origin :nightly || true - - - if: env.TAG_NAME != 'nightly' - run: | - { - echo 'SUBJECT=Lapce release build' - echo 'PRERELEASE=' - } | tee -a $GITHUB_ENV - - - name: Publish release - if: github.event_name != 'pull_request' - env: - DEBUG: api + - name: Create or update release + shell: bash run: | - gh release create $TAG_NAME $PRERELEASE --title "$TAG_NAME" --target $GITHUB_SHA \ - lapce-macos/* \ - lapce-linux/* \ - lapce-debian*/*/* \ - lapce-ubuntu*/*/* \ - lapce-fedora*/* \ - lapce-proxy-linux/* \ - lapce-windows/* + if gh release view "${TAG_NAME}" --repo "${GITHUB_REPOSITORY}" >/dev/null 2>&1; then + gh release upload "${TAG_NAME}" \ + --repo "${GITHUB_REPOSITORY}" \ + ./release-linux/* \ + ./release-windows/* \ + ./release-macos/* \ + --clobber + exit 0 + fi + + RELEASE_ARGS=() + if [[ "${PRERELEASE}" == "true" ]]; then + RELEASE_ARGS+=(--prerelease) + fi + + gh release create "${TAG_NAME}" \ + --repo "${GITHUB_REPOSITORY}" \ + --target "${GITHUB_SHA}" \ + --title "${TAG_NAME}" \ + --generate-notes \ + "${RELEASE_ARGS[@]}" \ + ./release-linux/* \ + ./release-windows/* \ + ./release-macos/* diff --git a/.gitignore b/.gitignore index e7ed190f..01f24016 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,17 @@ shell.nix lib/ target/ core/languages/ -vendor/ +vendor/* +!vendor/structdesc/ +!vendor/structdesc/** +!vendor/lsp-types/ +!vendor/lsp-types/** +!vendor/psp-types/ +!vendor/psp-types/** +!vendor/locale_config/ +!vendor/locale_config/** +!vendor/wasi-experimental-http/ +!vendor/wasi-experimental-http/** .DS_Store *.patch diff --git a/CHANGELOG.md b/CHANGELOG.md index c1f0f9ec..d8f89f9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -147,14 +147,14 @@ - [#2190](https://github.com/lapce/lapce/pull/2190): Rewrite with Floem UI - [#2425](https://github.com/lapce/lapce/pull/2425): Reimplement completion lens -- [#2498](https://github.com/lapce/lapce/pull/2498): Show Lapce as an option when doing "Open With..." on Linux +- [#2498](https://github.com/lapce/lapce/pull/2498): Show Umide as an option when doing "Open With..." on Linux - [#2549](https://github.com/lapce/lapce/pull/2549): Implement multi-line vim-motion yank and delete (`3dd`, `2yy`, etc.) - [#2553](https://github.com/lapce/lapce/pull/2553): Implement search and replace - [#1809](https://github.com/lapce/lapce/pull/1809): Implement debug adapter protocol ### Bug Fixes -- [#2650](https://github.com/lapce/lapce/pull/2650): Inform language servers that Lapce supports LSP diagnostics +- [#2650](https://github.com/lapce/lapce/pull/2650): Inform language servers that Umide supports LSP diagnostics ## 0.2.8 @@ -172,7 +172,7 @@ ### Bug Fixes - [#2209](https://github.com/lapce/lapce/pull/2209): Fix macOS crashes -- [#2228](https://github.com/lapce/lapce/pull/2228): Fix `.desktop` entry to properly associate with Lapce on Wayland +- [#2228](https://github.com/lapce/lapce/pull/2228): Fix `.desktop` entry to properly associate with Umide on Wayland ## 0.2.6 @@ -200,7 +200,7 @@ - [#2045](https://github.com/lapce/lapce/pull/2045): Add 'Rename Symbol' option on right-click - [#2071](https://github.com/lapce/lapce/pull/2071): Add command and keybinds to delete line - [#2073](https://github.com/lapce/lapce/pull/2073): Add Ctrl+{a,e,k} keybinds on macOS -- [#2128](https://github.com/lapce/lapce/pull/2128): Add Lapce app icon to logo collection +- [#2128](https://github.com/lapce/lapce/pull/2128): Add Umide app icon to logo collection - [#2127](https://github.com/lapce/lapce/pull/2127): Extended double-click options with file-only and file + folders mode - [#1944](https://github.com/lapce/lapce/pull/1944): Add filter input in git branch selection - ![image](https://user-images.githubusercontent.com/4404609/211232461-293e3b31-4e17-457e-825c-3018699a6fc2.png) @@ -304,7 +304,7 @@ - [#1472](https://github.com/lapce/lapce/pull/1472): Added SQL language support - [#1531](https://github.com/lapce/lapce/pull/1531): Improved Ctrl+Left command on spaces at the beginning of a line - [#1491](https://github.com/lapce/lapce/pull/1491): Added Vim shift+c to delete remainder of line -- [#1508](https://github.com/lapce/lapce/pull/1508): Show in progress when Lapce is self updating +- [#1508](https://github.com/lapce/lapce/pull/1508): Show in progress when Umide is self updating - [#1475](https://github.com/lapce/lapce/pull/1475): Add editor setting: "Cursor Surrounding Lines" which sets minimum number of lines above and below cursor - [#1525](https://github.com/lapce/lapce/pull/1525): Add editor indent guide - [#1521](https://github.com/lapce/lapce/pull/1521): Show unique paths to disambiguate same file names @@ -360,7 +360,7 @@ - [#1440](https://github.com/lapce/lapce/pull/1440): IME support - [#1449](https://github.com/lapce/lapce/pull/1449): Plugin settings in the editor support. Though this still needs some work from plugins to expose them all nicely! - [#1441](https://github.com/lapce/lapce/pull/1441): Button for Case-Sensitive search -- [#1471](https://github.com/lapce/lapce/pull/1471): Add command to (un)install Lapce from/to PATH +- [#1471](https://github.com/lapce/lapce/pull/1471): Add command to (un)install Umide from/to PATH - [#1419](https://github.com/lapce/lapce/pull/1419): Add atomic soft tabs: now you can move your cursor over four spaces as if it was a single block ### Syntax / Extensions @@ -388,7 +388,7 @@ - [#1030](https://github.com/lapce/lapce/pull/1030): Don't try to open an font file with an empty name if there is no font family set - [9f0120d](https://github.com/lapce/lapce/commit/9f0120df85e3aaaef7fbb43385bb15d88443260a): Fix excessive CPU usage in part of the code -- [bf5a98a](https://github.com/lapce/lapce/commit/bf5a98a6d432f9d2abdc1737da2d075e204771fb): Fix issue where sometimes Lapce can't open +- [bf5a98a](https://github.com/lapce/lapce/commit/bf5a98a6d432f9d2abdc1737da2d075e204771fb): Fix issue where sometimes Umide can't open - [#1084](https://github.com/lapce/lapce/pull/1084): Use host shell in terminal when running inside Flatpak - [#1120](https://github.com/lapce/lapce/pull/1120): Make Alt+Backspace work in the terminal properly - [#1127](https://github.com/lapce/lapce/pull/1127): Improve Julia highlighting @@ -410,7 +410,7 @@ ### Other -- [#1191](https://github.com/lapce/lapce/pull/1191): Tone down default inlay hint background color in Lapce dark theme +- [#1191](https://github.com/lapce/lapce/pull/1191): Tone down default inlay hint background color in Umide dark theme - [#1227](https://github.com/lapce/lapce/pull/1227): Don't restore cursor mode on undo - [#1413](https://github.com/lapce/lapce/pull/1413): Disable format-on-save by default. Remember to re-enable this if you want it! - [#1404](https://github.com/lapce/lapce/pull/1404): Log panics with full backtrace as error diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6fd0e72a..5d9da3aa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,26 +1,27 @@ # How to contribute -Thank you for your interest in contributing to Lapce! No contribution is too small and we consider _all_ contributions to the project. There are many ways to contribute (a few are listed here) but if you think of something else, join us on [Discord](https://discord.gg/n8tGJ6Rn6D) or let us know via an [issue](https://github.com/lapce/lapce/issues). + +Thank you for your interest in contributing to Umide! No contribution is too small and we consider _all_ contributions to the project. There are many ways to contribute (a few are listed here) but if you think of something else, join us on [Discord](https://discord.gg/n8tGJ6Rn6D) or let us know via an [issue](https://github.com/bridgerust/umide/issues). ## Questions -We're always around hanging on our [Discord](https://discord.gg/n8tGJ6Rn6D) server but if you're only participating on GitHub, you can open a [Discussion](https://github.com/lapce/lapce/discussions) +We're always around hanging on our [Discord](https://discord.gg/n8tGJ6Rn6D) server but if you're only participating on GitHub, you can open a [Discussion](https://github.com/bridgerust/umide/discussions) ## Feature Requests -A feature request is _editor behaviour that you want to have included in Lapce_. We track feature requests on GitHub via [issues](https://github.com/lapce/lapce/issues). There are generally few kinds of features: +A feature request is _editor behaviour that you want to have included in Umide_. We track feature requests on GitHub via [issues](https://github.com/bridgerust/umide/issues). There are generally few kinds of features: ### Core features -A feature more suited to the core development of Lapce. If this is the case please make a suggestion in an [issue](https://github.com/lapce/lapce/issues). +A feature more suited to the core development of Umide. If this is the case please make a suggestion in an [issue](https://github.com/bridgerust/umide/issues). ### Programming language support (autocompletion/intellisense/formatting) A feature that relates to specific programming language or development tool that provides intellisense, or various editor commands. -We do not track plugins development here, each plugin should have own issue tracker with eventual issues linked/referenced to main Lapce issue tracker. +We do not track plugins development here, each plugin should have own issue tracker with eventual issues linked/referenced to main Umide issue tracker. ### Syntax highlighting -There is main issue for tracking syntax highlighting grammars support at https://github.com/lapce/lapce/issues/272. +There is main issue for tracking syntax highlighting grammars support at https://github.com/bridgerust/umide/issues/272. --- @@ -28,15 +29,15 @@ To reduce the number of duplicate requests, please search through the issues to ## Bug Reports -Bugs should also be reported on GitHub via [issues](https://github.com/lapce/lapce/issues). This allows us to track them and see how prevalent they are. +Bugs should also be reported on GitHub via [issues](https://github.com/bridgerust/umide/issues). This allows us to track them and see how prevalent they are. -If you encounter a bug when using Lapce, check the issues to see if anyone else has encountered it. If it already exists, you can use emoji reactions so we can see community interest in specific issues and how important they are. +If you encounter a bug when using Umide, check the issues to see if anyone else has encountered it. If it already exists, you can use emoji reactions so we can see community interest in specific issues and how important they are. Please follow the rule of [NoPlusOne](https://github.com/golang/go/wiki/NoPlusOne) ## Pull Requests -If you want to write some code, develop the documentation, or otherwise work on a certain feature or bug, let us know by replying to or creating an [issue](https://github.com/lapce/lapce/issues). +If you want to write some code, develop the documentation, or otherwise work on a certain feature or bug, let us know by replying to or creating an [issue](https://github.com/bridgerust/umide/issues). Run `cargo fmt --all` and `cargo clippy` on your code before submitting pull requests and fix any issues; this makes sure that the CI runs only fail on genuine build errors and not formatting/Clippy lints. @@ -44,4 +45,4 @@ We are currently in the process of improving the documentation for new developer ## Contact -As always, if you have any questions or are just not sure where to start, post a message into the [Discord](https://discord.gg/n8tGJ6Rn6D) server. We suggest you start here as it is the most popular way for Lapce's contributors and users to communicate. +As always, if you have any questions or are just not sure where to start, post a message into the [Discord](https://discord.gg/n8tGJ6Rn6D) server. We suggest you start here as it is the most popular way for Umide's contributors and users to communicate. diff --git a/Cargo.lock b/Cargo.lock index 3451bac4..03554456 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2133,6 +2133,7 @@ checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" [[package]] name = "floem" version = "0.2.0" +source = "git+https://github.com/bridgerust/floem?rev=e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3#e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3" dependencies = [ "bitflags 2.10.0", "clipboard-win", @@ -2142,7 +2143,7 @@ dependencies = [ "floem-editor-core", "floem-winit 25.10.0", "floem_reactive", - "floem_renderer 0.2.0", + "floem_renderer 0.2.0 (git+https://github.com/bridgerust/floem?rev=e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3)", "floem_tiny_skia_renderer", "floem_vger_renderer", "futures", @@ -2178,6 +2179,7 @@ dependencies = [ [[package]] name = "floem-editor-core" version = "0.2.0" +source = "git+https://github.com/bridgerust/floem?rev=e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3#e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3" dependencies = [ "bitflags 2.10.0", "itertools 0.14.0", @@ -2470,27 +2472,12 @@ dependencies = [ [[package]] name = "floem_reactive" version = "0.2.0" +source = "git+https://github.com/bridgerust/floem?rev=e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3#e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3" dependencies = [ "parking_lot", "smallvec", ] -[[package]] -name = "floem_renderer" -version = "0.2.0" -dependencies = [ - "cosmic-text 0.14.2", - "floem-winit 25.10.0", - "futures", - "parking_lot", - "peniko 0.5.0", - "resvg 0.45.1", - "swash 0.2.6", - "unicode-segmentation", - "wasm-bindgen-futures", - "wgpu 26.0.1", -] - [[package]] name = "floem_renderer" version = "0.2.0" @@ -2510,12 +2497,30 @@ dependencies = [ "wgpu 22.1.0", ] +[[package]] +name = "floem_renderer" +version = "0.2.0" +source = "git+https://github.com/bridgerust/floem?rev=e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3#e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3" +dependencies = [ + "cosmic-text 0.14.2", + "floem-winit 25.10.0", + "futures", + "parking_lot", + "peniko 0.5.0", + "resvg 0.45.1", + "swash 0.2.6", + "unicode-segmentation", + "wasm-bindgen-futures", + "wgpu 26.0.1", +] + [[package]] name = "floem_tiny_skia_renderer" version = "0.2.0" +source = "git+https://github.com/bridgerust/floem?rev=e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3#e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3" dependencies = [ "anyhow", - "floem_renderer 0.2.0", + "floem_renderer 0.2.0 (git+https://github.com/bridgerust/floem?rev=e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3)", "peniko 0.5.0", "raw-window-handle 0.6.2", "resvg 0.45.1", @@ -2525,10 +2530,11 @@ dependencies = [ [[package]] name = "floem_vger_renderer" version = "0.2.0" +source = "git+https://github.com/bridgerust/floem?rev=e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3#e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3" dependencies = [ "anyhow", "floem-vger", - "floem_renderer 0.2.0", + "floem_renderer 0.2.0 (git+https://github.com/bridgerust/floem?rev=e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3)", "image", "peniko 0.5.0", "resvg 0.45.1", @@ -4431,7 +4437,6 @@ checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" [[package]] name = "locale_config" version = "0.3.1-alpha.0" -source = "git+https://github.com/lapce/locale_config.git?branch=lapce#54c9fe6a247c3618c224ec57e6c3a747bc3a96e4" dependencies = [ "lazy_static", "objc2 0.5.2", @@ -4473,7 +4478,6 @@ checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" [[package]] name = "lsp-types" version = "0.95.1" -source = "git+https://github.com/lapce/lsp-types?rev=feaa1e2ec80975c9dadd400a238ceacf071058e6#feaa1e2ec80975c9dadd400a238ceacf071058e6" dependencies = [ "bitflags 1.3.2", "serde", @@ -5942,7 +5946,6 @@ dependencies = [ [[package]] name = "psp-types" version = "0.1.0" -source = "git+https://github.com/lapce/psp-types?rev=f7fea28f59e7b2d6faa1034a21679ad49b3524ad#f7fea28f59e7b2d6faa1034a21679ad49b3524ad" dependencies = [ "lsp-types", "serde", @@ -7314,7 +7317,6 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "structdesc" version = "0.1.0" -source = "git+https://github.com/lapce/structdesc?rev=bb56969f22fdb2c2d6c03f158fd4a2bdc983b659#bb56969f22fdb2c2d6c03f158fd4a2bdc983b659" dependencies = [ "darling", "proc-macro2", @@ -8222,6 +8224,7 @@ dependencies = [ [[package]] name = "ui-events-floem-winit" version = "0.2.0" +source = "git+https://github.com/bridgerust/floem?rev=e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3#e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3" dependencies = [ "dpi 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "floem-winit 25.10.0", @@ -8255,6 +8258,8 @@ dependencies = [ "dmg", "flate2", "floem", + "floem-editor-core", + "floem_renderer 0.2.0 (git+https://github.com/bridgerust/floem?rev=e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3)", "fs_extra", "globset", "im", diff --git a/Cargo.toml b/Cargo.toml index f401c073..799cc5d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,8 +28,8 @@ version = "0.4.6" edition = "2024" rust-version = "1.87.0" license = "Apache-2.0" -homepage = "https://lapce.dev" -authors = ["Dongdong Zhou "] +homepage = "https://github.com/bridgerust/umide" +authors = ["KOLOGO JOSIAS "] [workspace.dependencies] anyhow = { version = "1.0" } @@ -69,7 +69,7 @@ url = { version = "2.5.0" } zstd = { version = "0.11.2" } # follow same version wasmtime-cache in lockfile lsp-types = { version = "0.95.1", features = ["proposed"] } # not following semver, so should be locked to patch version updates only -psp-types = { git = "https://github.com/lapce/psp-types", rev = "f7fea28f59e7b2d6faa1034a21679ad49b3524ad" } +psp-types = { path = "vendor/psp-types" } lapce-xi-rope = { version = "0.4.0", features = ["serde"] } @@ -79,14 +79,12 @@ umide-proxy = { path = "./umide-proxy" } umide_emulator = { path = "./crates/umide_emulator" } umide_native = { path = "./crates/umide_native" } -# floem = { git = "https://github.com/lapce/floem", rev = "e0dd862564e3afbad5cba8ebe60df166a7a41e56", features = ["editor", "serde", "default-image-formats", "rfd-async-std"] } -floem = { path = "../floem", features = ["editor", "serde", "default-image-formats"] } -# floem-editor-core = { git = "https://github.com/lapce/floem", rev = "e0dd862564e3afbad5cba8ebe60df166a7a41e56", features = ["serde"] } -floem-editor-core = { path = "../floem/editor-core/", features = ["serde"] } - +floem = { git = "https://github.com/bridgerust/floem", rev = "e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3", features = ["editor", "serde", "default-image-formats"] } +floem_renderer = { git = "https://github.com/bridgerust/floem", rev = "e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3", package = "floem_renderer" } +floem-editor-core = { git = "https://github.com/bridgerust/floem", rev = "e880fd3e921215b1f8e31cb78a85f4c6b3aaa9e3", package = "floem-editor-core", features = ["serde"] } [patch.crates-io] # Temporarily patch lsp-types with a version that adds message-type debug -lsp-types = { git = "https://github.com/lapce/lsp-types", rev = "feaa1e2ec80975c9dadd400a238ceacf071058e6" } +lsp-types = { path = "vendor/lsp-types" } [workspace.dependencies.tracing] @@ -123,7 +121,7 @@ lto = true codegen-units = 1 # A profile which compiles all (non-workspace) dependencies in release mode -# but Lapce code in dev mode. This gives a good debugging experience for your +# but Umide code in dev mode. This gives a good debugging experience for your # code and fast performance of other people's code. After the initial # build subsequent ones are as fast as dev mode builds. # See https://doc.rust-lang.org/cargo/reference/profiles.html diff --git a/LICENSE b/LICENSE index 0c738f68..4953b92a 100644 --- a/LICENSE +++ b/LICENSE @@ -187,7 +187,7 @@ APPENDIX: How to apply the Apache License to your work. identification within third-party archives. Copyright 2026 UMIDE contributors -Portions (original editor) Copyright 2023 Lapce contributors +Portions (original editor) Copyright 2023 Umide contributors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Makefile b/Makefile index 5047b4f1..d4e1bc44 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# This Makefile is intended *only* for building macOS binaries of Lapce. +# This Makefile is intended *only* for building macOS binaries of Umide. # It uses macOS-specific tools like `lipo`, `codesign`, and `hdiutil`, # and requires that a valid Apple Developer signing identity is installed # and available in the system Keychain under the fingerprint set in @@ -14,7 +14,7 @@ ASSETS_DIR = extra RELEASE_DIR = target/release-lto APP_NAME = UMIDE.app -APP_TEMPLATE = $(ASSETS_DIR)/macos/Lapce.app +APP_TEMPLATE = $(ASSETS_DIR)/macos/Umide.app APP_DIR = $(RELEASE_DIR)/macos APP_BINARY = $(RELEASE_DIR)/$(TARGET) APP_BINARY_DIR = $(APP_DIR)/$(APP_NAME)/Contents/MacOS @@ -47,8 +47,8 @@ $(TARGET)-universal: @lipo target/{x86_64,aarch64}-apple-darwin/release-lto/$(TARGET) -create -output $(APP_BINARY) /usr/bin/codesign -vvv --deep --entitlements $(ASSETS_DIR)/entitlements.plist --strict --options=runtime --force -s $(CODESIGN_IDENTITY) $(APP_BINARY) -app: $(APP_NAME)-native ## Create a Lapce.app -app-universal: $(APP_NAME)-universal ## Create a universal Lapce.app +app: $(APP_NAME)-native ## Create a Umide.app +app-universal: $(APP_NAME)-universal ## Create a universal Umide.app $(APP_NAME)-%: $(TARGET)-% @mkdir -p $(APP_BINARY_DIR) @mkdir -p $(APP_EXTRAS_DIR) @@ -60,13 +60,13 @@ $(APP_NAME)-%: $(TARGET)-% xattr -c $(APP_DIR)/$(APP_NAME)/Contents/Resources/lapce.icns /usr/bin/codesign -vvv --deep --entitlements $(ASSETS_DIR)/entitlements.plist --strict --options=runtime --force -s $(CODESIGN_IDENTITY) $(APP_DIR)/$(APP_NAME) -dmg: $(DMG_NAME)-native ## Create a Lapce.dmg -dmg-universal: $(DMG_NAME)-universal ## Create a universal Lapce.dmg +dmg: $(DMG_NAME)-native ## Create a Umide.dmg +dmg-universal: $(DMG_NAME)-universal ## Create a universal Umide.dmg $(DMG_NAME)-%: $(APP_NAME)-% @echo "Packing disk image..." @ln -sf /Applications $(DMG_DIR)/Applications @hdiutil create $(DMG_DIR)/$(DMG_NAME) \ - -volname "Lapce" \ + -volname "Umide" \ -fs HFS+ \ -srcfolder $(APP_DIR) \ -ov -format UDZO diff --git a/README.md b/README.md index 6acf7fca..96bb7bed 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,11 @@ UMIDE is a unified IDE for cross-platform mobile development (React Native + Flu - **Unified Mobile Environment**: Android Emulator and iOS Simulator embedded directly in the IDE. - **Cross-Platform Support**: First-class support for React Native and Flutter. - **High Performance**: Built on [Floem](https://github.com/lapce/floem) and Rust for lightning-fast speeds. -- **Based on Lapce**: Inherits all the great features of Lapce editor. +- **Based on Umide**: Inherits all the great features of Umide editor. ## License -Copyright 2024 UMIDE contributors -Portions (original editor) Copyright 2023 Lapce contributors +Copyright 2026 UMIDE contributors +Portions (original editor) Copyright 2023 Umide contributors Released under the Apache License Version 2. diff --git a/crates/umide/Cargo.toml b/crates/umide/Cargo.toml index 751da60f..67edec36 100644 --- a/crates/umide/Cargo.toml +++ b/crates/umide/Cargo.toml @@ -50,6 +50,7 @@ umide-proxy = { workspace = true } url = { workspace = true } zstd = { workspace = true } floem = { workspace = true } +umide_native = { workspace = true } pulldown-cmark = { version = "0.13.0" } Inflector = { version = "0.11.4" } @@ -58,7 +59,9 @@ unicode-width = { version = "0.2.2" } nucleo = { version = "0.5.0" } bytemuck = { version = "1.22.0" } config = { version = "0.15.19", default-features = false, features = ["toml"] } -structdesc = { git = "https://github.com/lapce/structdesc", rev = "bb56969f22fdb2c2d6c03f158fd4a2bdc983b659" } +floem_renderer = { workspace = true } +floem-editor-core = { workspace = true } +structdesc = { path = "../../vendor/structdesc" } base64 = { version = "0.22.1" } sha2 = { version = "0.10.8" } zip = { version = "7.2.0", default-features = false, features = ["deflate"] } @@ -72,7 +75,6 @@ image = "0.25" [target.'cfg(target_os="macos")'.dependencies] fs_extra = "1.2.0" dmg = "0.1.1" -umide_native = { workspace = true } [target.'cfg(windows)'.dependencies.windows-sys] workspace = true diff --git a/crates/umide/src/about.rs b/crates/umide/src/about.rs index f64f0c51..cb89d653 100644 --- a/crates/umide/src/about.rs +++ b/crates/umide/src/about.rs @@ -12,7 +12,7 @@ use umide_core::{command::FocusCommand, meta::VERSION, mode::Mode}; use crate::{ command::{CommandExecuted, CommandKind}, - config::color::LapceColor, + config::color::UmideColor, keypress::KeyPressFocus, web_link::web_link, window_tab::{Focus, WindowTabData}, @@ -66,7 +66,7 @@ impl KeyPressFocus for AboutData { fn run_command( &self, - command: &crate::command::LapceCommand, + command: &crate::command::UmideCommand, _count: Option, _mods: Modifiers, ) -> crate::command::CommandExecuted { @@ -103,54 +103,54 @@ pub fn about_popup(window_tab_data: Rc) -> impl View { Stack::new(( svg(move || (config.get()).logo_svg()).style(move |s| { s.size(logo_size, logo_size) - .color(config.get().color(LapceColor::EDITOR_FOREGROUND)) + .color(config.get().color(UmideColor::EDITOR_FOREGROUND)) }), Label::new("UMIDE".to_string()).style(move |s| { s.font_bold() .margin_top(10.0) - .color(config.get().color(LapceColor::EDITOR_FOREGROUND)) + .color(config.get().color(UmideColor::EDITOR_FOREGROUND)) }), Label::new(format!("Version: {}", VERSION)).style(move |s| { s.margin_top(10.0) - .color(config.get().color(LapceColor::EDITOR_DIM)) + .color(config.get().color(UmideColor::EDITOR_DIM)) }), web_link( || "Website".to_string(), || AboutUri::LAPCE.to_string(), - move || config.get().color(LapceColor::EDITOR_LINK), + move || config.get().color(UmideColor::EDITOR_LINK), internal_command, ) .style(|s| s.margin_top(20.0)), web_link( || "GitHub".to_string(), || AboutUri::GITHUB.to_string(), - move || config.get().color(LapceColor::EDITOR_LINK), + move || config.get().color(UmideColor::EDITOR_LINK), internal_command, ) .style(|s| s.margin_top(10.0)), web_link( || "Discord".to_string(), || AboutUri::DISCORD.to_string(), - move || config.get().color(LapceColor::EDITOR_LINK), + move || config.get().color(UmideColor::EDITOR_LINK), internal_command, ) .style(|s| s.margin_top(10.0)), web_link( || "Matrix".to_string(), || AboutUri::MATRIX.to_string(), - move || config.get().color(LapceColor::EDITOR_LINK), + move || config.get().color(UmideColor::EDITOR_LINK), internal_command, ) .style(|s| s.margin_top(10.0)), Label::new("Attributions".to_string()).style(move |s| { s.font_bold() - .color(config.get().color(LapceColor::EDITOR_DIM)) + .color(config.get().color(UmideColor::EDITOR_DIM)) .margin_top(40.0) }), web_link( || "Codicons (CC-BY-4.0)".to_string(), || AboutUri::CODICONS.to_string(), - move || config.get().color(LapceColor::EDITOR_LINK), + move || config.get().color(UmideColor::EDITOR_LINK), internal_command, ) .style(|s| s.margin_top(10.0)), @@ -176,8 +176,8 @@ fn exclusive_popup( .padding_horiz(100.0) .border(1.0) .border_radius(6.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) - .background(config.color(LapceColor::PANEL_BACKGROUND)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) + .background(config.color(UmideColor::PANEL_BACKGROUND)) }) .on_event_stop(EventListener::PointerDown, move |_| {}), ) @@ -206,7 +206,7 @@ fn exclusive_popup( .background( config .get() - .color(LapceColor::LAPCE_DROPDOWN_SHADOW) + .color(UmideColor::LAPCE_DROPDOWN_SHADOW) .multiply_alpha(0.5), ) }) diff --git a/crates/umide/src/alert.rs b/crates/umide/src/alert.rs index 48d7fdcf..1326501e 100644 --- a/crates/umide/src/alert.rs +++ b/crates/umide/src/alert.rs @@ -13,7 +13,7 @@ use floem::{ }; use crate::{ - config::{LapceConfig, color::LapceColor, icon::LapceIcons}, + config::{UmideConfig, color::UmideColor, icon::UmideIcons}, window_tab::CommonData, }; @@ -37,7 +37,7 @@ pub struct AlertBoxData { pub title: RwSignal, pub msg: RwSignal, pub buttons: RwSignal>, - pub config: ReadSignal>, + pub config: ReadSignal>, } impl AlertBoxData { @@ -63,10 +63,10 @@ pub fn alert_box(alert_data: AlertBoxData) -> impl View { Container::new({ Container::new({ Stack::new(( - svg(move || config.get().ui_svg(LapceIcons::WARNING)).style( + svg(move || config.get().ui_svg(UmideIcons::WARNING)).style( move |s| { s.size(50.0, 50.0) - .color(config.get().color(LapceColor::LAPCE_WARN)) + .color(config.get().color(UmideColor::LAPCE_WARN)) }, ), Label::derived(move || title.get()).style(move |s| { @@ -97,18 +97,18 @@ pub fn alert_box(alert_data: AlertBoxData) -> impl View { .border(1.0) .border_radius(6.0) .border_color( - config.color(LapceColor::LAPCE_BORDER), + config.color(UmideColor::LAPCE_BORDER), ) .hover(|s| { s.cursor(CursorStyle::Pointer).background( config.color( - LapceColor::PANEL_HOVERED_BACKGROUND, + UmideColor::PANEL_HOVERED_BACKGROUND, ), ) }) .active(|s| { s.background(config.color( - LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND, + UmideColor::PANEL_HOVERED_ACTIVE_BACKGROUND, )) }) }) @@ -128,16 +128,16 @@ pub fn alert_box(alert_data: AlertBoxData) -> impl View { .line_height(1.5) .border(1.0) .border_radius(6.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) .hover(|s| { s.cursor(CursorStyle::Pointer).background( config - .color(LapceColor::PANEL_HOVERED_BACKGROUND), + .color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }) .active(|s| { s.background(config.color( - LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND, + UmideColor::PANEL_HOVERED_ACTIVE_BACKGROUND, )) }) }), @@ -151,9 +151,9 @@ pub fn alert_box(alert_data: AlertBoxData) -> impl View { .width(250.0) .border(1.0) .border_radius(6.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) - .color(config.color(LapceColor::EDITOR_FOREGROUND)) - .background(config.color(LapceColor::PANEL_BACKGROUND)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) + .color(config.color(UmideColor::EDITOR_FOREGROUND)) + .background(config.color(UmideColor::PANEL_BACKGROUND)) }) }) .on_event_stop(EventListener::PointerDown, move |_| {}) @@ -166,7 +166,7 @@ pub fn alert_box(alert_data: AlertBoxData) -> impl View { .background( config .get() - .color(LapceColor::LAPCE_DROPDOWN_SHADOW) + .color(UmideColor::LAPCE_DROPDOWN_SHADOW) .multiply_alpha(0.5), ) }) diff --git a/crates/umide/src/app.rs b/crates/umide/src/app.rs index a2a69283..a13299cb 100644 --- a/crates/umide/src/app.rs +++ b/crates/umide/src/app.rs @@ -54,14 +54,14 @@ use crate::{ about, alert, code_action::CodeActionStatus, command::{ - CommandKind, InternalCommand, LapceCommand, LapceWorkbenchCommand, + CommandKind, InternalCommand, UmideCommand, UmideWorkbenchCommand, WindowCommand, }, config::{ - LapceConfig, color::LapceColor, icon::LapceIcons, ui::TabSeparatorHeight, + UmideConfig, color::UmideColor, icon::UmideIcons, ui::TabSeparatorHeight, watcher::ConfigWatcher, }, - db::LapceDb, + db::UmideDb, debug::RunDebugMode, editor::{ diff::diff_show_more_section_view, @@ -92,7 +92,7 @@ use crate::{ update::ReleaseInfo, window::{TabsInfo, WindowData, WindowInfo}, window_tab::{Focus, WindowTabData}, - workspace::{LapceWorkspace, LapceWorkspaceType}, + workspace::{UmideWorkspace, UmideWorkspaceType}, }; mod grammars; @@ -103,7 +103,7 @@ mod logging; #[clap(version=meta::VERSION)] #[derive(Debug)] struct Cli { - /// Launch new window even if Lapce is already running + /// Launch new window even if Umide is already running #[clap(short, long, action)] new: bool, /// Don't return instantly when opened in a terminal @@ -151,7 +151,7 @@ pub struct AppData { pub latest_release: RwSignal>>, pub watcher: Arc, pub tracing_handle: Handle, - pub config: RwSignal>, + pub config: RwSignal>, /// Paths to extra plugins to load pub plugin_paths: Arc>, } @@ -159,7 +159,7 @@ pub struct AppData { impl AppData { pub fn reload_config(&self) { let config = - LapceConfig::load(&LapceWorkspace::default(), &[], &self.plugin_paths); + UmideConfig::load(&UmideWorkspace::default(), &[], &self.plugin_paths); self.config.set(Arc::new(config)); self.window_scale.set(self.config.get().ui.scale()); @@ -201,7 +201,7 @@ impl AppData { .position(window.position.get_untracked() + (50.0, 50.0)) }) .or_else(|| { - let db: Arc = Context::get().unwrap(); + let db: Arc = Context::get().unwrap(); db.get_window().ok().map(|info| { self.default_window_config() .size(info.size) @@ -218,11 +218,12 @@ impl AppData { } else { config }; - let workspace = LapceWorkspace { + let workspace = UmideWorkspace { path: folder, ..Default::default() }; let app_data = self.clone(); + let db: Arc = Context::get().unwrap(); floem::new_window( move |window_id| { app_data.app_view( @@ -237,6 +238,7 @@ impl AppData { }, }, vec![], + db, ) }, Some(config), @@ -246,7 +248,7 @@ impl AppData { pub fn run_app_command(&self, cmd: AppCommand) { match cmd { AppCommand::SaveApp => { - let db: Arc = Context::get().unwrap(); + let db: Arc = Context::get().unwrap(); if let Err(err) = db.save_app(self) { tracing::error!("{:?}", err); } @@ -255,7 +257,7 @@ impl AppData { if self.app_terminated.get_untracked() { return; } - let db: Arc = Context::get().unwrap(); + let db: Arc = Context::get().unwrap(); if self.windows.with_untracked(|w| w.len()) == 1 { if let Err(err) = db.insert_app(self.clone()) { tracing::error!("{:?}", err); @@ -286,7 +288,7 @@ impl AppData { fn create_windows( &self, - db: Arc, + db: Arc, paths: Vec, ) -> floem::Application { let mut app = floem::Application::new(); @@ -317,14 +319,14 @@ impl AppData { .is_empty() || !std::env::var("WSL_INTEROP").unwrap_or_default().is_empty() { - LapceWorkspaceType::RemoteWSL(crate::workspace::WslHost { + UmideWorkspaceType::RemoteWSL(crate::workspace::WslHost { host: String::new(), }) } else { - LapceWorkspaceType::Local + UmideWorkspaceType::Local }; #[cfg(not(windows))] - let workspace_type = LapceWorkspaceType::Local; + let workspace_type = UmideWorkspaceType::Local; let info = WindowInfo { size, @@ -332,7 +334,7 @@ impl AppData { maximised: false, tabs: TabsInfo { active_tab: 0, - workspaces: vec![LapceWorkspace { + workspaces: vec![UmideWorkspace { kind: workspace_type, path: Some(dir.path.to_owned()), last_open: 0, @@ -355,8 +357,9 @@ impl AppData { }; let app_data = self.clone(); let files = files.take().unwrap_or_default(); + let db = db.clone(); app = app.window( - move |window_id| app_data.app_view(window_id, info, files), + move |window_id| app_data.app_view(window_id, info, files, db), Some(config), ); inital_windows += 1; @@ -378,9 +381,10 @@ impl AppData { config }; let app_data = self.clone(); + let db = db.clone(); app = app.window( move |window_id| { - app_data.app_view(window_id, info, vec![]) + app_data.app_view(window_id, info, vec![], db) }, Some(config), ); @@ -388,7 +392,17 @@ impl AppData { } } Err(err) => { - tracing::error!("{:?}", err); + // Start a new instance if we can't connect to an existing one + // ConnectionRefused/NotFound means no existing instance is running + let is_expected = err.downcast_ref::() + .map(|e| e.kind() == std::io::ErrorKind::ConnectionRefused || e.kind() == std::io::ErrorKind::NotFound) + .unwrap_or(false); + + if !is_expected { + tracing::error!("Failed to check for existing instance: {:?}", err); + } else { + tracing::debug!("No existing instance found, starting new one."); + } } } } @@ -400,12 +414,12 @@ impl AppData { maximised: false, tabs: TabsInfo { active_tab: 0, - workspaces: vec![LapceWorkspace::default()], + workspaces: vec![UmideWorkspace::default()], }, }); info.tabs = TabsInfo { active_tab: 0, - workspaces: vec![LapceWorkspace::default()], + workspaces: vec![UmideWorkspace::default()], }; let config = self .default_window_config() @@ -419,12 +433,14 @@ impl AppData { config }; let app_data = self.clone(); + let db = db.clone(); app = app.window( move |window_id| { app_data.app_view( window_id, info, files.take().unwrap_or_default(), + db, ) }, Some(config), @@ -441,7 +457,9 @@ impl AppData { window_id: WindowId, info: WindowInfo, files: Vec, + db: Arc, ) -> impl View + use<> { + Context::provide(db); let app_view_id = RwSignal::new(floem::ViewId::new()); let window_data = WindowData::new( window_id, @@ -737,7 +755,7 @@ fn editor_tab_header( !info.with(|info| info.is_pristine) && config.ui.tab_close_button == TabCloseButton::Off, - |s| s.color(config.color(LapceColor::LAPCE_WARN)), + |s| s.color(config.color(UmideColor::LAPCE_WARN)), ) }) }) @@ -770,9 +788,9 @@ fn editor_tab_header( let tab_close_button = clickable_icon( move || { if hovered.get() || info.with(|info| info.is_pristine) { - LapceIcons::CLOSE + UmideIcons::CLOSE } else { - LapceIcons::UNSAVED + UmideIcons::UNSAVED } }, move || { @@ -834,7 +852,7 @@ fn editor_tab_header( .justify_center() .border_left(if i.get() == 0 { 1.0 } else { 0.0 }) .border_right(1.0) - .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + .border_color(config.get().color(UmideColor::LAPCE_BORDER)) .padding_horiz(6.) .gap(6.) .grid() @@ -916,10 +934,10 @@ fn editor_tab_header( .border_radius(6.0) .background( config - .color(LapceColor::PANEL_BACKGROUND) + .color(UmideColor::PANEL_BACKGROUND) .multiply_alpha(0.7), ) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) }) .style(|s| s.align_items(Some(AlignItems::Center)).flex_grow(1.0).draggable(true)), Empty::new() @@ -931,9 +949,9 @@ fn editor_tab_header( 0.0 }) .border_color(config.get().color(if is_focused() { - LapceColor::LAPCE_TAB_ACTIVE_UNDERLINE + UmideColor::LAPCE_TAB_ACTIVE_UNDERLINE } else { - LapceColor::LAPCE_TAB_INACTIVE_UNDERLINE + UmideColor::LAPCE_TAB_INACTIVE_UNDERLINE })) }) .style(|s| { @@ -969,7 +987,7 @@ fn editor_tab_header( .border_color( config .get() - .color(LapceColor::LAPCE_TAB_ACTIVE_UNDERLINE) + .color(UmideColor::LAPCE_TAB_ACTIVE_UNDERLINE) .multiply_alpha(0.5), ) }) @@ -985,7 +1003,7 @@ fn editor_tab_header( .items_center() .justify_center() .cursor(CursorStyle::Pointer) - .hover(|s| s.background(config.color(LapceColor::HOVER_BACKGROUND))) + .hover(|s| s.background(config.color(UmideColor::HOVER_BACKGROUND))) }) .debug_name("Tab and Active Indicator") .on_event_stop(EventListener::DragOver, move |event| { @@ -1036,10 +1054,10 @@ fn editor_tab_header( s.absolute() .height_full() .width(size.get().width as f32) - .background(config.color(LapceColor::PANEL_BACKGROUND)) + .background(config.color(UmideColor::PANEL_BACKGROUND)) .box_shadow_blur(3.0) .box_shadow_color( - config.color(LapceColor::LAPCE_DROPDOWN_SHADOW), + config.color(UmideColor::LAPCE_DROPDOWN_SHADOW), ) })) .style(move |s| { @@ -1051,10 +1069,10 @@ fn editor_tab_header( }), Stack::new(( clickable_icon( - || LapceIcons::TAB_PREVIOUS, + || UmideIcons::TAB_PREVIOUS, move || { workbench_command - .send(LapceWorkbenchCommand::PreviousEditorTab); + .send(UmideWorkbenchCommand::PreviousEditorTab); }, || false, || false, @@ -1063,10 +1081,10 @@ fn editor_tab_header( ) .style(|s| s.margin_horiz(6.0).margin_vert(7.0)), clickable_icon( - || LapceIcons::TAB_NEXT, + || UmideIcons::TAB_NEXT, move || { workbench_command - .send(LapceWorkbenchCommand::NextEditorTab); + .send(UmideWorkbenchCommand::NextEditorTab); }, || false, || false, @@ -1123,10 +1141,10 @@ fn editor_tab_header( .height_full() .margin_left(30.0) .width(size.get().width as f32) - .background(config.color(LapceColor::PANEL_BACKGROUND)) + .background(config.color(UmideColor::PANEL_BACKGROUND)) .box_shadow_blur(3.0) .box_shadow_color( - config.color(LapceColor::LAPCE_DROPDOWN_SHADOW), + config.color(UmideColor::LAPCE_DROPDOWN_SHADOW), ) }) }) @@ -1143,7 +1161,7 @@ fn editor_tab_header( }), Stack::new(( clickable_icon( - || LapceIcons::SPLIT_HORIZONTAL, + || UmideIcons::SPLIT_HORIZONTAL, move || { let editor_tab_id = editor_tab.with_untracked(|t| t.editor_tab_id); @@ -1159,7 +1177,7 @@ fn editor_tab_header( ) .style(|s| s.margin_left(6.0)), clickable_icon( - || LapceIcons::CLOSE, + || UmideIcons::CLOSE, move || { let editor_tab_id = editor_tab.with_untracked(|t| t.editor_tab_id); @@ -1197,8 +1215,8 @@ fn editor_tab_header( s.items_center() .max_width_full() .border_bottom(1.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) - .background(config.color(LapceColor::PANEL_BACKGROUND)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) + .background(config.color(UmideColor::PANEL_BACKGROUND)) .height(config.ui.header_height() as i32) }) .debug_name("Editor Tab Header") @@ -1345,7 +1363,7 @@ fn editor_tab_content( .flex_basis(0.0) .border_right(1.0) .border_color( - config.get().color(LapceColor::LAPCE_BORDER), + config.get().color(UmideColor::LAPCE_BORDER), ) }), Container::new( @@ -1494,7 +1512,7 @@ fn editor_tab( .background( config .get() - .color(LapceColor::EDITOR_DRAG_DROP_BACKGROUND), + .color(UmideColor::EDITOR_DRAG_DROP_BACKGROUND), ) }) .debug_name("Drag Over Handle"), @@ -1619,7 +1637,7 @@ fn split_resize_border( splits: ReadSignal>>, editor_tabs: ReadSignal>>, split: ReadSignal, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { let content_rect = move |content: &SplitContent, tracked: bool| { if tracked { @@ -1783,14 +1801,14 @@ fn split_resize_border( SplitDirection::Vertical => CursorStyle::ColResize, SplitDirection::Horizontal => CursorStyle::RowResize, }) - .background(config.get().color(LapceColor::EDITOR_CARET)) + .background(config.get().color(UmideColor::EDITOR_CARET)) }) .hover(|s| { s.cursor(match direction { SplitDirection::Vertical => CursorStyle::ColResize, SplitDirection::Horizontal => CursorStyle::RowResize, }) - .background(config.get().color(LapceColor::EDITOR_CARET)) + .background(config.get().color(UmideColor::EDITOR_CARET)) }) .pointer_events_auto() }) @@ -1808,7 +1826,7 @@ fn split_border( splits: ReadSignal>>, editor_tabs: ReadSignal>>, split: ReadSignal, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { let direction = move || split.with(|split| split.direction); dyn_stack( @@ -1825,7 +1843,7 @@ fn split_border( SplitDirection::Vertical => PxPctAuto::Pct(100.0), SplitDirection::Horizontal => PxPctAuto::Px(1.0), }) - .background(config.get().color(LapceColor::LAPCE_BORDER)) + .background(config.get().color(UmideColor::LAPCE_BORDER)) })) .style(move |s| { let rect = match &content { @@ -2030,8 +2048,8 @@ fn main_split(window_tab_data: Rc) -> impl View { let config = config.get(); let is_hidden = panel.panel_bottom_maximized(true) && panel.is_container_shown(&PanelContainerPosition::Bottom, true); - s.border_color(config.color(LapceColor::LAPCE_BORDER)) - .background(config.color(LapceColor::EDITOR_BACKGROUND)) + s.border_color(config.color(UmideColor::LAPCE_BORDER)) + .background(config.color(UmideColor::EDITOR_BACKGROUND)) .apply_if(is_hidden, |s| s.display(Display::None)) .width_full() .flex_grow(1.0) @@ -2045,7 +2063,7 @@ pub fn not_clickable_icon( active_fn: impl Fn() -> bool + 'static, disabled_fn: impl Fn() -> bool + 'static + Copy, tooltip_: impl Fn() -> S + 'static + Clone, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { tooltip_label( config, @@ -2067,7 +2085,7 @@ pub fn clickable_icon( active_fn: impl Fn() -> bool + 'static, disabled_fn: impl Fn() -> bool + 'static + Copy, tooltip_: impl Fn() -> S + 'static + Clone, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { tooltip_label( config, @@ -2081,7 +2099,7 @@ pub fn clickable_icon_base( on_click: Option, active_fn: impl Fn() -> bool + 'static, disabled_fn: impl Fn() -> bool + 'static + Copy, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { let view = Container::new( svg(move || config.get().ui_svg(icon())) @@ -2089,9 +2107,9 @@ pub fn clickable_icon_base( let config = config.get(); let size = config.ui.icon_size() as f32; s.size(size, size) - .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + .color(config.color(UmideColor::LAPCE_ICON_ACTIVE)) .disabled(|s| { - s.color(config.color(LapceColor::LAPCE_ICON_INACTIVE)) + s.color(config.color(UmideColor::LAPCE_ICON_INACTIVE)) .cursor(CursorStyle::Default) }).set_disabled(disabled_fn()) }) @@ -2103,15 +2121,15 @@ pub fn clickable_icon_base( .border(1.0) .border_color(Color::TRANSPARENT) .apply_if(active_fn(), |s| { - s.border_color(config.color(LapceColor::EDITOR_CARET)) + s.border_color(config.color(UmideColor::EDITOR_CARET)) }) .hover(|s| { s.cursor(CursorStyle::Pointer) - .background(config.color(LapceColor::PANEL_HOVERED_BACKGROUND)) + .background(config.color(UmideColor::PANEL_HOVERED_BACKGROUND)) }) .active(|s| { s.background( - config.color(LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND), + config.color(UmideColor::PANEL_HOVERED_ACTIVE_BACKGROUND), ) }).set_disabled(disabled_fn()) }); @@ -2129,7 +2147,7 @@ pub fn clickable_icon_base( /// When styling an element that has the tooltip, it will style the child rather than the tooltip /// label. pub fn tooltip_label( - config: ReadSignal>, + config: ReadSignal>, child: V, text: impl Fn() -> S + 'static + Clone, ) -> impl View { @@ -2142,7 +2160,7 @@ pub fn tooltip_label( } fn tooltip_tip( - config: ReadSignal>, + config: ReadSignal>, child: V, ) -> impl IntoView { Container::new(child).style(move |s| { @@ -2151,13 +2169,13 @@ fn tooltip_tip( .padding_vert(5.0) .font_size(config.ui.font_size() as f32) .font_family(config.ui.font_family.clone()) - .color(config.color(LapceColor::TOOLTIP_FOREGROUND)) - .background(config.color(LapceColor::TOOLTIP_BACKGROUND)) + .color(config.color(UmideColor::TOOLTIP_FOREGROUND)) + .background(config.color(UmideColor::TOOLTIP_BACKGROUND)) .border(1) .border_radius(6) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) .box_shadow_blur(3.0) - .box_shadow_color(config.color(LapceColor::LAPCE_DROPDOWN_SHADOW)) + .box_shadow_color(config.color(UmideColor::LAPCE_DROPDOWN_SHADOW)) .margin_left(0.0) .margin_top(4.0) }) @@ -2199,12 +2217,12 @@ fn workbench(window_tab_data: Rc) -> impl View { } fn palette_item( - workspace: Arc, + workspace: Arc, i: usize, item: PaletteItem, index: ReadSignal, palette_item_height: f64, - config: ReadSignal>, + config: ReadSignal>, keymap: Option<&KeyMap>, ) -> impl View + use<> { match &item.content { @@ -2261,16 +2279,16 @@ fn palette_item( focus_text( move || file_name.clone(), move || file_name_indices.clone(), - move || config.get().color(LapceColor::EDITOR_FOCUS), + move || config.get().color(UmideColor::EDITOR_FOCUS), ) .style(|s| s.margin_right(6.0).max_width_full()), focus_text( move || folder.clone(), move || folder_indices.clone(), - move || config.get().color(LapceColor::EDITOR_FOCUS), + move || config.get().color(UmideColor::EDITOR_FOCUS), ) .style(move |s| { - s.color(config.get().color(LapceColor::EDITOR_DIM)) + s.color(config.get().color(UmideColor::EDITOR_DIM)) .min_width(0.0) .flex_grow(1.0) .flex_basis(0.0) @@ -2314,30 +2332,30 @@ fn palette_item( let config = config.get(); config .symbol_svg(&kind) - .unwrap_or_else(|| config.ui_svg(LapceIcons::FILE)) + .unwrap_or_else(|| config.ui_svg(UmideIcons::FILE)) }) .style(move |s| { let config = config.get(); let size = config.ui.icon_size() as f32; s.min_width(size).size(size, size).margin_right(5.0).color( config.symbol_color(&kind).unwrap_or_else(|| { - config.color(LapceColor::LAPCE_ICON_ACTIVE) + config.color(UmideColor::LAPCE_ICON_ACTIVE) }), ) }), focus_text( move || text.clone(), move || text_indices.clone(), - move || config.get().color(LapceColor::EDITOR_FOCUS), + move || config.get().color(UmideColor::EDITOR_FOCUS), ) .style(|s| s.margin_right(6.0).max_width_full()), focus_text( move || hint.clone(), move || hint_indices.clone(), - move || config.get().color(LapceColor::EDITOR_FOCUS), + move || config.get().color(UmideColor::EDITOR_FOCUS), ) .style(move |s| { - s.color(config.get().color(LapceColor::EDITOR_DIM)) + s.color(config.get().color(UmideColor::EDITOR_DIM)) .min_width(0.0) .flex_grow(1.0) .flex_basis(0.0) @@ -2392,7 +2410,7 @@ fn palette_item( let config = config.get(); config .symbol_svg(&kind) - .unwrap_or_else(|| config.ui_svg(LapceIcons::FILE)) + .unwrap_or_else(|| config.ui_svg(UmideIcons::FILE)) }) .style(move |s| { let config = config.get(); @@ -2400,21 +2418,21 @@ fn palette_item( s.min_width(size) .size(size, size) .margin_right(5.0) - .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + .color(config.color(UmideColor::LAPCE_ICON_ACTIVE)) }), focus_text( move || text.clone(), move || text_indices.clone(), - move || config.get().color(LapceColor::EDITOR_FOCUS), + move || config.get().color(UmideColor::EDITOR_FOCUS), ) .style(|s| s.margin_right(6.0).max_width_full()), focus_text( move || hint.clone(), move || hint_indices.clone(), - move || config.get().color(LapceColor::EDITOR_FOCUS), + move || config.get().color(UmideColor::EDITOR_FOCUS), ) .style(move |s| { - s.color(config.get().color(LapceColor::EDITOR_DIM)) + s.color(config.get().color(UmideColor::EDITOR_DIM)) .min_width(0.0) .flex_grow(1.0) .flex_basis(0.0) @@ -2459,8 +2477,8 @@ fn palette_item( svg(move || { let config = config.get(); match mode { - RunDebugMode::Run => config.ui_svg(LapceIcons::START), - RunDebugMode::Debug => config.ui_svg(LapceIcons::DEBUG), + RunDebugMode::Run => config.ui_svg(UmideIcons::START), + RunDebugMode::Debug => config.ui_svg(UmideIcons::DEBUG), } }) .style(move |s| { @@ -2469,21 +2487,21 @@ fn palette_item( s.min_width(size) .size(size, size) .margin_right(5.0) - .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + .color(config.color(UmideColor::LAPCE_ICON_ACTIVE)) }), focus_text( move || text.clone(), move || text_indices.clone(), - move || config.get().color(LapceColor::EDITOR_FOCUS), + move || config.get().color(UmideColor::EDITOR_FOCUS), ) .style(|s| s.margin_right(6.0).max_width_full()), focus_text( move || hint.clone(), move || hint_indices.clone(), - move || config.get().color(LapceColor::EDITOR_FOCUS), + move || config.get().color(UmideColor::EDITOR_FOCUS), ) .style(move |s| { - s.color(config.get().color(LapceColor::EDITOR_DIM)) + s.color(config.get().color(UmideColor::EDITOR_DIM)) .min_width(0.0) .flex_grow(1.0) .flex_basis(0.0) @@ -2511,7 +2529,7 @@ fn palette_item( focus_text( move || text.clone(), move || indices.clone(), - move || config.get().color(LapceColor::EDITOR_FOCUS), + move || config.get().color(UmideColor::EDITOR_FOCUS), ) .style(|s| { s.flex_row() @@ -2529,7 +2547,7 @@ fn palette_item( .border(1.0) .border_radius(3.0) .border_color( - config.get().color(LapceColor::LAPCE_BORDER), + config.get().color(UmideColor::LAPCE_BORDER), ) .selectable(false) }) @@ -2554,7 +2572,7 @@ fn palette_item( focus_text( move || text.clone(), move || indices.clone(), - move || config.get().color(LapceColor::EDITOR_FOCUS), + move || config.get().color(UmideColor::EDITOR_FOCUS), ) .style(|s| s.align_items(Some(AlignItems::Center)).max_width_full()), ) @@ -2567,7 +2585,7 @@ fn palette_item( focus_text( move || text.clone(), move || indices.clone(), - move || config.get().color(LapceColor::EDITOR_FOCUS), + move || config.get().color(UmideColor::EDITOR_FOCUS), ) .style(|s| s.align_items(Some(AlignItems::Center)).max_width_full()), ) @@ -2579,7 +2597,7 @@ fn palette_item( .padding_horiz(10.0) .apply_if(index.get() == i, |style| { style.background( - config.get().color(LapceColor::PALETTE_CURRENT_BACKGROUND), + config.get().color(UmideColor::PALETTE_CURRENT_BACKGROUND), ) }) }) @@ -2603,8 +2621,8 @@ fn palette_input(window_tab_data: Rc) -> impl View { .height(25.0) .items_center() .border_bottom(1.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) - .background(config.color(LapceColor::EDITOR_BACKGROUND)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) + .background(config.color(UmideColor::EDITOR_BACKGROUND)) })) .style(|s| s.padding_bottom(5.0)) } @@ -2664,7 +2682,7 @@ fn palette_content( Some(CommandKind::Workbench(cmd.clone())) } PaletteItemContent::Command { - cmd: LapceCommand { kind, .. }, + cmd: UmideCommand { kind, .. }, } => Some(kind.clone()), _ => None, }; @@ -2690,7 +2708,7 @@ fn palette_content( s.background( config .get() - .color(LapceColor::PANEL_HOVERED_BACKGROUND), + .color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }) }) @@ -2751,9 +2769,9 @@ fn palette_preview(window_tab_data: Rc) -> impl View { let config = config.get(); s.position(Position::Absolute) .border_top(1.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) .size_full() - .background(config.color(LapceColor::EDITOR_BACKGROUND)) + .background(config.color(UmideColor::EDITOR_BACKGROUND)) }), ) .style(move |s| { @@ -2796,9 +2814,9 @@ fn palette(window_tab_data: Rc) -> impl View { .margin_top(4.0) .border(1.0) .border_radius(6.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) .flex_col() - .background(config.color(LapceColor::PALETTE_BACKGROUND)) + .background(config.color(UmideColor::PALETTE_BACKGROUND)) .pointer_events_auto() }), ) @@ -2819,25 +2837,25 @@ fn palette(window_tab_data: Rc) -> impl View { fn window_message_view( messages: RwSignal>, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { let view_fn = move |(i, (title, message)): (usize, (String, ShowMessageParams))| { Stack::new(( svg(move || { if let MessageType::ERROR = message.typ { - config.get().ui_svg(LapceIcons::ERROR) + config.get().ui_svg(UmideIcons::ERROR) } else { - config.get().ui_svg(LapceIcons::WARNING) + config.get().ui_svg(UmideIcons::WARNING) } }) .style(move |s| { let config = config.get(); let size = config.ui.icon_size() as f32; let color = if let MessageType::ERROR = message.typ { - config.color(LapceColor::LAPCE_ERROR) + config.color(UmideColor::LAPCE_ERROR) } else { - config.color(LapceColor::LAPCE_WARN) + config.color(UmideColor::LAPCE_WARN) }; s.min_width(size) .size(size, size) @@ -2857,7 +2875,7 @@ fn window_message_view( s.flex_col().min_width(0.0).flex_basis(0.0).flex_grow(1.0) }), clickable_icon( - || LapceIcons::CLOSE, + || UmideIcons::CLOSE, move || { messages.update(|messages| { messages.remove(i); @@ -2892,8 +2910,8 @@ fn window_message_view( .padding(10.0) .border(1.0) .border_radius(6.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) - .background(config.color(LapceColor::PANEL_BACKGROUND)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) + .background(config.color(UmideColor::PANEL_BACKGROUND)) .apply_if(i > 0, |s| s.margin_top(10.0)) }) }; @@ -2992,7 +3010,7 @@ fn hover(window_tab_data: Rc) -> impl View { s.width_full() .margin_vert(5.0) .height(1.0) - .background(config.get().color(LapceColor::LAPCE_BORDER)) + .background(config.get().color(UmideColor::LAPCE_BORDER)) })), }, ) @@ -3016,8 +3034,8 @@ fn hover(window_tab_data: Rc) -> impl View { .max_height(300.0) .border(1.0) .border_radius(6.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) - .background(config.color(LapceColor::PANEL_BACKGROUND)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) + .background(config.color(UmideColor::PANEL_BACKGROUND)) .set(PropagatePointerWheel, false) } else { s.hide() @@ -3074,7 +3092,7 @@ fn completion(window_tab_data: Rc) -> impl View { } }, move || item.indices.clone(), - move || config.get().color(LapceColor::EDITOR_FOCUS), + move || config.get().color(UmideColor::EDITOR_FOCUS), ) .on_click_stop(move |_| { active.set(i); @@ -3092,13 +3110,13 @@ fn completion(window_tab_data: Rc) -> impl View { .cursor(CursorStyle::Pointer) .apply_if(active.get() == i, |s| { s.background( - config.color(LapceColor::COMPLETION_CURRENT), + config.color(UmideColor::COMPLETION_CURRENT), ) }) .hover(move |s| { s.background( config - .color(LapceColor::PANEL_HOVERED_BACKGROUND), + .color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }) }), @@ -3141,7 +3159,7 @@ fn completion(window_tab_data: Rc) -> impl View { .max_height(400.0) .margin_left(origin.x as f32) .margin_top(origin.y as f32) - .background(config.color(LapceColor::COMPLETION_BACKGROUND)) + .background(config.color(UmideColor::COMPLETION_BACKGROUND)) .font_family(config.editor.font_family.clone()) .font_size(config.editor.font_size() as f32) .border_radius(6.0) @@ -3187,13 +3205,13 @@ fn code_action(window_tab_data: Rc) -> impl View { .cursor(CursorStyle::Pointer) .apply_if(active.get() == i, |s| { s.background( - config.color(LapceColor::COMPLETION_CURRENT), + config.color(UmideColor::COMPLETION_CURRENT), ) }) .hover(move |s| { s.background( config - .color(LapceColor::PANEL_HOVERED_BACKGROUND), + .color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }) }) @@ -3230,7 +3248,7 @@ fn code_action(window_tab_data: Rc) -> impl View { .max_height(400.0) .margin_left(origin.x as f32) .margin_top(origin.y as f32) - .background(config.get().color(LapceColor::COMPLETION_BACKGROUND)) + .background(config.get().color(UmideColor::COMPLETION_BACKGROUND)) .border_radius(6.0) }) .debug_name("Code Action Layer") @@ -3255,8 +3273,8 @@ fn rename(window_tab_data: Rc) -> impl View { .font_size(config.editor.font_size() as f32) .border(1.0) .border_radius(6.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) - .background(config.color(LapceColor::EDITOR_BACKGROUND)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) + .background(config.color(UmideColor::EDITOR_BACKGROUND)) }), ) .on_resize(move |rect| { @@ -3270,7 +3288,7 @@ fn rename(window_tab_data: Rc) -> impl View { .apply_if(!active.get(), |s| s.hide()) .margin_left(origin.x as f32) .margin_top(origin.y as f32) - .background(config.get().color(LapceColor::PANEL_BACKGROUND)) + .background(config.get().color(UmideColor::PANEL_BACKGROUND)) .border_radius(6.0) .padding(6.0) }) @@ -3326,14 +3344,14 @@ fn window_tab(window_tab_data: Rc) -> impl View { .style(move |s| { let config = config.get(); s.size_full() - .color(config.color(LapceColor::EDITOR_FOREGROUND)) - .background(config.color(LapceColor::EDITOR_BACKGROUND)) + .color(config.color(UmideColor::EDITOR_FOREGROUND)) + .background(config.color(UmideColor::EDITOR_BACKGROUND)) .font_size(config.ui.font_size() as f32) .apply_if(!config.ui.font_family.is_empty(), |s| { s.font_family(config.ui.font_family.clone()) }) .class(floem::views::scroll::Handle, |s| { - s.background(config.color(LapceColor::LAPCE_SCROLL_BAR)) + s.background(config.color(UmideColor::LAPCE_SCROLL_BAR)) }) }) .debug_name("Window Tab"); @@ -3343,14 +3361,14 @@ fn window_tab(window_tab_data: Rc) -> impl View { view } -fn workspace_title(workspace: &LapceWorkspace) -> Option { +fn workspace_title(workspace: &UmideWorkspace) -> Option { let p = workspace.path.as_ref()?; let dir = p.file_name().unwrap_or(p.as_os_str()).to_string_lossy(); Some(match &workspace.kind { - LapceWorkspaceType::Local => format!("{dir}"), - LapceWorkspaceType::RemoteSSH(remote) => format!("{dir} [{remote}]"), + UmideWorkspaceType::Local => format!("{dir}"), + UmideWorkspaceType::RemoteSSH(remote) => format!("{dir} [{remote}]"), #[cfg(windows)] - LapceWorkspaceType::RemoteWSL(remote) => format!("{dir} [{remote}]"), + UmideWorkspaceType::RemoteWSL(remote) => format!("{dir} [{remote}]"), }) } @@ -3411,7 +3429,7 @@ fn workspace_tab_header(window_data: WindowData) -> impl View { { let window_data = local_window_data.clone(); clickable_icon( - || LapceIcons::WINDOW_CLOSE, + || UmideIcons::WINDOW_CLOSE, move || { window_data.run_window_command( WindowCommand::CloseWorkspaceTab { @@ -3470,7 +3488,7 @@ fn workspace_tab_header(window_data: WindowData) -> impl View { .min_width(0.0) .items_center() .border_right(1.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) .apply_if( cfg!(target_os = "macos") && index.get() == 0, |s| s.border_left(1.0), @@ -3484,7 +3502,7 @@ fn workspace_tab_header(window_data: WindowData) -> impl View { .border_color( config .get() - .color(LapceColor::LAPCE_TAB_ACTIVE_UNDERLINE), + .color(UmideColor::LAPCE_TAB_ACTIVE_UNDERLINE), ) })) .style(move |s| { @@ -3506,15 +3524,15 @@ fn workspace_tab_header(window_data: WindowData) -> impl View { let config = config.get(); s.border(1.0) .border_radius(6.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) .color( config - .color(LapceColor::EDITOR_FOREGROUND) + .color(UmideColor::EDITOR_FOREGROUND) .multiply_alpha(0.7), ) .background( config - .color(LapceColor::PANEL_BACKGROUND) + .color(UmideColor::PANEL_BACKGROUND) .multiply_alpha(0.7), ) }) @@ -3531,7 +3549,7 @@ fn workspace_tab_header(window_data: WindowData) -> impl View { ) .height_full() .border_color( - config.get().color(LapceColor::LAPCE_TAB_ACTIVE_UNDERLINE), + config.get().color(UmideColor::LAPCE_TAB_ACTIVE_UNDERLINE), ) .apply_if(drag_over_left.get().is_some(), move |s| { let drag_over_left = drag_over_left.get_untracked().unwrap(); @@ -3569,10 +3587,10 @@ fn workspace_tab_header(window_data: WindowData) -> impl View { ) .style(|s| s.height_full()), Container::new(clickable_icon( - || LapceIcons::ADD, + || UmideIcons::ADD, move || { window_data.run_window_command(WindowCommand::NewWorkspaceTab { - workspace: LapceWorkspace::default(), + workspace: UmideWorkspace::default(), end: true, }); }, @@ -3626,9 +3644,9 @@ fn workspace_tab_header(window_data: WindowData) -> impl View { s.font_family(config.ui.font_family.clone()) }) .apply_if(tabs.with(|tabs| tabs.len() < 2), |s| s.hide()) - .color(config.color(LapceColor::EDITOR_FOREGROUND)) - .border_color(config.color(LapceColor::LAPCE_BORDER)) - .background(config.color(LapceColor::PANEL_BACKGROUND)) + .color(config.color(UmideColor::EDITOR_FOREGROUND)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) + .background(config.color(UmideColor::PANEL_BACKGROUND)) .items_center() }) .debug_name("Workspace Tab Header") @@ -3657,8 +3675,8 @@ fn window(window_data: WindowData) -> impl View { .or_else(|| window_tabs.last()) .and_then(|(_, window_tab)| window_tab.workspace.display()); match workspace { - Some(workspace) => format!("{workspace} - Lapce"), - None => "Lapce".to_string(), + Some(workspace) => format!("{workspace} - Umide"), + None => "Umide".to_string(), } }) .on_event_stop(EventListener::ImeEnabled, move |_| { @@ -3701,7 +3719,7 @@ pub fn launch() { } let (reload_handle, _guard) = logging::logging(); - trace!(TraceLevel::INFO, "Starting up Lapce.."); + trace!(TraceLevel::INFO, "Starting up Umide.."); #[cfg(feature = "vendored-fonts")] { @@ -3779,7 +3797,7 @@ pub fn launch() { } // If the cli is not requesting a new window, and we're not developing a plugin, we try to open - // in the existing Lapce process + // in the existing Umide process if !cli.new { match get_socket() { Ok(socket) => { @@ -3800,13 +3818,13 @@ pub fn launch() { if let Err(err) = umide_proxy::register_lapce_path() { tracing::error!("{:?}", err); } - let db = match LapceDb::new() { + let db = match UmideDb::new() { Ok(db) => Arc::new(db), Err(e) => { #[cfg(windows)] - logging::error_modal("Error", &format!("Failed to create LapceDb: {e}")); + logging::error_modal("Error", &format!("Failed to create UmideDb: {e}")); - trace!(TraceLevel::ERROR, "Failed to create LapceDb: {e}"); + trace!(TraceLevel::ERROR, "Failed to create UmideDb: {e}"); std::process::exit(1); } }; @@ -3821,7 +3839,7 @@ pub fn launch() { let (tx, rx) = channel(); let mut watcher = notify::recommended_watcher(ConfigWatcher::new(tx)).unwrap(); - if let Some(path) = LapceConfig::settings_file() { + if let Some(path) = UmideConfig::settings_file() { if let Err(err) = watcher.watch(&path, notify::RecursiveMode::Recursive) { tracing::error!("{:?}", err); } @@ -3831,7 +3849,7 @@ pub fn launch() { tracing::error!("{:?}", err); } } - if let Some(path) = LapceConfig::keymaps_file() { + if let Some(path) = UmideConfig::keymaps_file() { if let Err(err) = watcher.watch(&path, notify::RecursiveMode::Recursive) { tracing::error!("{:?}", err); } @@ -3843,7 +3861,7 @@ pub fn launch() { } let windows = scope.create_rw_signal(im::HashMap::new()); - let config = LapceConfig::load(&LapceWorkspace::default(), &[], &plugin_paths); + let config = UmideConfig::load(&UmideWorkspace::default(), &[], &plugin_paths); // Restore scale from config window_scale.set(config.ui.scale()); @@ -3950,7 +3968,7 @@ pub fn launch() { } }); std::thread::Builder::new() - .name("LapceUpdater".to_owned()) + .name("UmideUpdater".to_owned()) .spawn(move || { loop { if let Ok(release) = crate::update::get_latest_release() { @@ -4148,36 +4166,36 @@ fn listen_local_socket(tx: SyncSender) -> Result<()> { } pub fn window_menu( - lapce_command: Listener, - workbench_command: Listener, + lapce_command: Listener, + workbench_command: Listener, ) -> Menu { let mut menu = Menu::new(); - // Lapce Menu - menu = menu.submenu("Lapce", move |m| { - let mut m = m.item("About Lapce", |i| i.action(move || { - workbench_command.send(LapceWorkbenchCommand::ShowAbout) + // Umide Menu + menu = menu.submenu("Umide", move |m| { + let mut m = m.item("About Umide", |i| i.action(move || { + workbench_command.send(UmideWorkbenchCommand::ShowAbout) })) .separator() .submenu("Settings...", move |s| { s.item("Open Settings", |i| i.action(move || { workbench_command - .send(LapceWorkbenchCommand::OpenSettings); + .send(UmideWorkbenchCommand::OpenSettings); })) .item("Open Keyboard Shortcuts", |i| i.action(move || { workbench_command.send( - LapceWorkbenchCommand::OpenKeyboardShortcuts, + UmideWorkbenchCommand::OpenKeyboardShortcuts, ); })) }) .separator() - .item("Quit Lapce", |i| i.action(move || { - workbench_command.send(LapceWorkbenchCommand::Quit); + .item("Quit Umide", |i| i.action(move || { + workbench_command.send(UmideWorkbenchCommand::Quit); })); if cfg!(target_os = "macos") { m = m.separator() - .item("Hide Lapce", |i| i) + .item("Hide Umide", |i| i) .item("Hide Others", |i| i) .item("Show All", |i| i); } @@ -4188,70 +4206,70 @@ pub fn window_menu( // File Menu menu = menu.submenu("File", move |m| { m.item("New File", |i| i.action(move || { - workbench_command.send(LapceWorkbenchCommand::NewFile); + workbench_command.send(UmideWorkbenchCommand::NewFile); })) .separator() .item("Open", |i| i.action(move || { - workbench_command.send(LapceWorkbenchCommand::OpenFile); + workbench_command.send(UmideWorkbenchCommand::OpenFile); })) .item("Open Folder", |i| i.action(move || { - workbench_command.send(LapceWorkbenchCommand::OpenFolder); + workbench_command.send(UmideWorkbenchCommand::OpenFolder); })) .separator() .item("Save", |i| i.action(move || { - lapce_command.send(LapceCommand { + lapce_command.send(UmideCommand { kind: CommandKind::Focus(FocusCommand::Save), data: None, }); })) .item("Save All", |i| i.action(move || { - workbench_command.send(LapceWorkbenchCommand::SaveAll); + workbench_command.send(UmideWorkbenchCommand::SaveAll); })) .separator() .item("Close Folder", |i| i.action(move || { - workbench_command.send(LapceWorkbenchCommand::CloseFolder); + workbench_command.send(UmideWorkbenchCommand::CloseFolder); })) .item("Close Window", |i| i.action(move || { - workbench_command.send(LapceWorkbenchCommand::CloseWindow); + workbench_command.send(UmideWorkbenchCommand::CloseWindow); })) }); // Edit Menu menu = menu.submenu("Edit", move |m| { m.item("Cut", |i| i.action(move || { - lapce_command.send(LapceCommand { + lapce_command.send(UmideCommand { kind: CommandKind::Edit(EditCommand::ClipboardCut), data: None, }); })) .item("Copy", |i| i.action(move || { - lapce_command.send(LapceCommand { + lapce_command.send(UmideCommand { kind: CommandKind::Edit(EditCommand::ClipboardCopy), data: None, }); })) .item("Paste", |i| i.action(move || { - lapce_command.send(LapceCommand { + lapce_command.send(UmideCommand { kind: CommandKind::Edit(EditCommand::ClipboardPaste), data: None, }); })) .separator() .item("Undo", |i| i.action(move || { - lapce_command.send(LapceCommand { + lapce_command.send(UmideCommand { kind: CommandKind::Edit(EditCommand::Undo), data: None, }); })) .item("Redo", |i| i.action(move || { - lapce_command.send(LapceCommand { + lapce_command.send(UmideCommand { kind: CommandKind::Edit(EditCommand::Redo), data: None, }); })) .separator() .item("Find", |i| i.action(move || { - lapce_command.send(LapceCommand { + lapce_command.send(UmideCommand { kind: CommandKind::Focus(FocusCommand::Search), data: None, }); diff --git a/crates/umide/src/app/grammars.rs b/crates/umide/src/app/grammars.rs index 2ce2923f..5a54fa96 100644 --- a/crates/umide/src/app/grammars.rs +++ b/crates/umide/src/app/grammars.rs @@ -10,7 +10,7 @@ use umide_core::directory::Directory; use crate::{tracing::*, update::ReleaseInfo}; fn get_github_api(url: &str) -> Result { - let user_agent = format!("Lapce/{}", umide_core::meta::VERSION); + let user_agent = format!("Umide/{}", umide_core::meta::VERSION); let resp = umide_proxy::get_url(url, Some(user_agent.as_str()))?; if !resp.status().is_success() { return Err(anyhow!("get release info failed {}", resp.text()?)); diff --git a/crates/umide/src/app/logging.rs b/crates/umide/src/app/logging.rs index efb02987..45d4e3bc 100644 --- a/crates/umide/src/app/logging.rs +++ b/crates/umide/src/app/logging.rs @@ -18,7 +18,7 @@ pub(super) fn logging() -> (Handle, Vec) { tracing_appender::rolling::Builder::new() .max_log_files(10) .rotation(tracing_appender::rolling::Rotation::DAILY) - .filename_prefix("lapce") + .filename_prefix("umide") .filename_suffix("log") .build(dir) .ok() @@ -45,7 +45,7 @@ pub(super) fn logging() -> (Handle, Vec) { // Filters let log_file_filter_targets = filter::Targets::new() - .with_target("lapce_app", LevelFilter::DEBUG) + .with_target("umide_app", LevelFilter::DEBUG) .with_target("umide_proxy", LevelFilter::DEBUG) .with_target("umide_core", LevelFilter::DEBUG) .with_target("umide_emulator", LevelFilter::TRACE) // Added emulator trace diff --git a/crates/umide/src/code_action.rs b/crates/umide/src/code_action.rs index ab063d17..eff6a232 100644 --- a/crates/umide/src/code_action.rs +++ b/crates/umide/src/code_action.rs @@ -63,7 +63,7 @@ impl KeyPressFocus for CodeActionData { fn run_command( &self, - command: &crate::command::LapceCommand, + command: &crate::command::UmideCommand, _count: Option, _mods: Modifiers, ) -> crate::command::CommandExecuted { diff --git a/crates/umide/src/command.rs b/crates/umide/src/command.rs index 5246c6df..a92becf4 100644 --- a/crates/umide/src/command.rs +++ b/crates/umide/src/command.rs @@ -29,18 +29,18 @@ use crate::{ editor_tab::EditorTabChild, id::EditorTabId, main_split::{SplitDirection, SplitMoveDirection, TabCloseKind}, - workspace::LapceWorkspace, + workspace::UmideWorkspace, }; #[derive(Clone, Debug, PartialEq, Eq)] -pub struct LapceCommand { +pub struct UmideCommand { pub kind: CommandKind, pub data: Option, } #[derive(Clone, Debug, PartialEq, Eq)] pub enum CommandKind { - Workbench(LapceWorkbenchCommand), + Workbench(UmideWorkbenchCommand), Edit(EditCommand), Move(MoveCommand), Scroll(ScrollCommand), @@ -89,11 +89,11 @@ impl From for CommandKind { } } -pub fn lapce_internal_commands() -> IndexMap { +pub fn lapce_internal_commands() -> IndexMap { let mut commands = IndexMap::new(); - for c in LapceWorkbenchCommand::iter() { - let command = LapceCommand { + for c in UmideWorkbenchCommand::iter() { + let command = UmideCommand { kind: CommandKind::Workbench(c.clone()), data: None, }; @@ -101,7 +101,7 @@ pub fn lapce_internal_commands() -> IndexMap { } for c in EditCommand::iter() { - let command = LapceCommand { + let command = UmideCommand { kind: CommandKind::Edit(c.clone()), data: None, }; @@ -109,7 +109,7 @@ pub fn lapce_internal_commands() -> IndexMap { } for c in MoveCommand::iter() { - let command = LapceCommand { + let command = UmideCommand { kind: CommandKind::Move(c.clone()), data: None, }; @@ -117,7 +117,7 @@ pub fn lapce_internal_commands() -> IndexMap { } for c in ScrollCommand::iter() { - let command = LapceCommand { + let command = UmideCommand { kind: CommandKind::Scroll(c.clone()), data: None, }; @@ -125,7 +125,7 @@ pub fn lapce_internal_commands() -> IndexMap { } for c in FocusCommand::iter() { - let command = LapceCommand { + let command = UmideCommand { kind: CommandKind::Focus(c.clone()), data: None, }; @@ -133,7 +133,7 @@ pub fn lapce_internal_commands() -> IndexMap { } for c in MotionModeCommand::iter() { - let command = LapceCommand { + let command = UmideCommand { kind: CommandKind::MotionMode(c.clone()), data: None, }; @@ -141,7 +141,7 @@ pub fn lapce_internal_commands() -> IndexMap { } for c in MultiSelectionCommand::iter() { - let command = LapceCommand { + let command = UmideCommand { kind: CommandKind::MultiSelection(c.clone()), data: None, }; @@ -162,7 +162,7 @@ pub fn lapce_internal_commands() -> IndexMap { EnumMessage, IntoStaticStr, )] -pub enum LapceWorkbenchCommand { +pub enum UmideWorkbenchCommand { #[strum(serialize = "enable_modal_editing")] #[strum(message = "Enable Modal Editing")] EnableModal, @@ -548,7 +548,7 @@ pub enum LapceWorkbenchCommand { RestartToUpdate, #[strum(serialize = "show_about")] - #[strum(message = "About Lapce")] + #[strum(message = "About Umide")] ShowAbout, #[strum(message = "Save All Files")] @@ -556,12 +556,12 @@ pub enum LapceWorkbenchCommand { SaveAll, #[cfg(target_os = "macos")] - #[strum(message = "Install Lapce to PATH")] + #[strum(message = "Install Umide to PATH")] #[strum(serialize = "install_to_path")] InstallToPATH, #[cfg(target_os = "macos")] - #[strum(message = "Uninstall Lapce from PATH")] + #[strum(message = "Uninstall Umide from PATH")] #[strum(serialize = "uninstall_from_path")] UninstallFromPATH, @@ -720,12 +720,12 @@ pub enum InternalCommand { s: String, }, FindEditorCommand { - command: LapceCommand, + command: UmideCommand, count: Option, mods: Modifiers, }, ReplaceEditorCommand { - command: LapceCommand, + command: UmideCommand, count: Option, mods: Modifiers, }, @@ -802,13 +802,13 @@ pub enum InternalCommand { #[derive(Clone)] pub enum WindowCommand { SetWorkspace { - workspace: LapceWorkspace, + workspace: UmideWorkspace, }, CloseWorkspaceTab { index: Option, }, NewWorkspaceTab { - workspace: LapceWorkspace, + workspace: UmideWorkspace, end: bool, }, NextWorkspaceTab, diff --git a/crates/umide/src/completion.rs b/crates/umide/src/completion.rs index 21bfcd3a..e237c3ff 100644 --- a/crates/umide/src/completion.rs +++ b/crates/umide/src/completion.rs @@ -15,7 +15,7 @@ use lsp_types::{ }; use nucleo::Utf32Str; -use crate::{config::LapceConfig, editor::EditorData, snippet::Snippet}; +use crate::{config::UmideConfig, editor::EditorData, snippet::Snippet}; #[derive(Clone, Copy, PartialEq, Eq)] pub enum CompletionStatus { @@ -63,11 +63,11 @@ pub struct CompletionData { pub latest_editor_id: Option, /// Matcher for filtering the completion items matcher: RwSignal, - config: ReadSignal>, + config: ReadSignal>, } impl CompletionData { - pub fn new(cx: Scope, config: ReadSignal>) -> Self { + pub fn new(cx: Scope, config: ReadSignal>) -> Self { let active = cx.create_rw_signal(0); Self { status: CompletionStatus::Inactive, @@ -404,7 +404,7 @@ fn completion_lens_text( // If the text does not include a prefix in the expected position, then we do not display it. let item = as AsRef>::as_ref(&item).strip_prefix(&completion.input)?; - // Get only the first line of text, because Lapce does not currently support + // Get only the first line of text, because Umide does not currently support // multi-line phantom text. let item = item.lines().next().unwrap_or(item); diff --git a/crates/umide/src/config.rs b/crates/umide/src/config.rs index 379d9b69..4afe5d90 100644 --- a/crates/umide/src/config.rs +++ b/crates/umide/src/config.rs @@ -18,17 +18,17 @@ use strum::VariantNames; use tracing::error; use self::{ - color::LapceColor, + color::UmideColor, color_theme::{ColorThemeConfig, ThemeColor, ThemeColorPreference}, core::CoreConfig, editor::{EditorConfig, SCALE_OR_SIZE_LIMIT, WrapStyle}, - icon::LapceIcons, + icon::UmideIcons, icon_theme::IconThemeConfig, svg::SvgStore, terminal::TerminalConfig, ui::UIConfig, }; -use crate::workspace::{LapceWorkspace, LapceWorkspaceType}; +use crate::workspace::{UmideWorkspace, UmideWorkspaceType}; pub mod color; pub mod color_theme; @@ -47,9 +47,9 @@ const DEFAULT_LIGHT_THEME: &str = include_str!("../../../defaults/light-theme.to const DEFAULT_DARK_THEME: &str = include_str!("../../../defaults/dark-theme.toml"); const DEFAULT_ICON_THEME: &str = include_str!("../../../defaults/icon-theme.toml"); -static DEFAULT_CONFIG: Lazy = Lazy::new(LapceConfig::default_config); -static DEFAULT_LAPCE_CONFIG: Lazy = - Lazy::new(LapceConfig::default_lapce_config); +static DEFAULT_CONFIG: Lazy = Lazy::new(UmideConfig::default_config); +static DEFAULT_LAPCE_CONFIG: Lazy = + Lazy::new(UmideConfig::default_lapce_config); static DEFAULT_DARK_THEME_CONFIG: Lazy = Lazy::new(|| { config::Config::builder() @@ -64,7 +64,7 @@ static DEFAULT_DARK_THEME_CONFIG: Lazy = Lazy::new(|| { /// The default theme is the dark theme. static DEFAULT_DARK_THEME_COLOR_CONFIG: Lazy = Lazy::new(|| { let (_, theme) = - LapceConfig::load_color_theme_from_str(DEFAULT_DARK_THEME).unwrap(); + UmideConfig::load_color_theme_from_str(DEFAULT_DARK_THEME).unwrap(); theme.get::("color-theme") .expect("Failed to load default dark theme. This is likely due to a missing or misnamed field in dark-theme.toml") }); @@ -93,7 +93,7 @@ pub struct DropdownInfo { #[derive(Debug, Clone, Deserialize, Default)] #[serde(rename_all = "kebab-case")] -pub struct LapceConfig { +pub struct UmideConfig { #[serde(skip)] pub id: u64, pub core: CoreConfig, @@ -128,14 +128,14 @@ pub struct LapceConfig { wrap_style_list: im::Vector, } -impl LapceConfig { +impl UmideConfig { pub fn load( - workspace: &LapceWorkspace, + workspace: &UmideWorkspace, disabled_volts: &[VoltID], extra_plugin_paths: &[PathBuf], ) -> Self { let config = Self::merge_config(workspace, None, None); - let mut lapce_config: LapceConfig = match config.try_deserialize() { + let mut lapce_config: UmideConfig = match config.try_deserialize() { Ok(config) => config, Err(error) => { error!("Failed to deserialize configuration file: {error}"); @@ -178,7 +178,7 @@ impl LapceConfig { } fn merge_config( - workspace: &LapceWorkspace, + workspace: &UmideWorkspace, color_theme_config: Option, icon_theme_config: Option, ) -> config::Config { @@ -212,7 +212,7 @@ impl LapceConfig { } match workspace.kind { - LapceWorkspaceType::Local => { + UmideWorkspaceType::Local => { if let Some(path) = workspace.path.as_ref() { let path = path.join("./.lapce/settings.toml"); config = config::Config::builder() @@ -224,9 +224,9 @@ impl LapceConfig { .unwrap_or_else(|_| config.clone()); } } - LapceWorkspaceType::RemoteSSH(_) => {} + UmideWorkspaceType::RemoteSSH(_) => {} #[cfg(windows)] - LapceWorkspaceType::RemoteWSL(_) => {} + UmideWorkspaceType::RemoteWSL(_) => {} } config @@ -249,8 +249,8 @@ impl LapceConfig { .unwrap() } - fn default_lapce_config() -> LapceConfig { - let mut default_lapce_config: LapceConfig = + fn default_lapce_config() -> UmideConfig { + let mut default_lapce_config: UmideConfig = DEFAULT_CONFIG.clone().try_deserialize().expect("Failed to deserialize default config, this likely indicates a missing or misnamed field in settings.toml"); default_lapce_config.color_theme = DEFAULT_DARK_THEME_COLOR_CONFIG.clone(); default_lapce_config.icon_theme = DEFAULT_ICON_THEME_ICON_CONFIG.clone(); @@ -258,7 +258,7 @@ impl LapceConfig { default_lapce_config } - fn resolve_theme(&mut self, workspace: &LapceWorkspace) { + fn resolve_theme(&mut self, workspace: &UmideWorkspace) { let default_lapce_config = DEFAULT_LAPCE_CONFIG.clone(); let color_theme_config = self @@ -283,7 +283,7 @@ impl LapceConfig { Some(color_theme_config.clone()), Some(icon_theme_config.clone()), ) - .try_deserialize::() + .try_deserialize::() { self.core = new.core; self.ui = new.ui; @@ -330,19 +330,19 @@ impl LapceConfig { /// Set the active color theme. /// Note that this does not save the config. - pub fn set_color_theme(&mut self, workspace: &LapceWorkspace, theme: &str) { + pub fn set_color_theme(&mut self, workspace: &UmideWorkspace, theme: &str) { self.core.color_theme = theme.to_string(); self.resolve_theme(workspace); } /// Set the active icon theme. /// Note that this does not save the config. - pub fn set_icon_theme(&mut self, workspace: &LapceWorkspace, theme: &str) { + pub fn set_icon_theme(&mut self, workspace: &UmideWorkspace, theme: &str) { self.core.icon_theme = theme.to_string(); self.resolve_theme(workspace); } - pub fn set_modal(&mut self, _workspace: &LapceWorkspace, modal: bool) { + pub fn set_modal(&mut self, _workspace: &UmideWorkspace, modal: bool) { self.core.modal = modal; } @@ -392,7 +392,7 @@ impl LapceConfig { self.style_color(theme_str) } - fn resolve_colors(&mut self, default_config: Option<&LapceConfig>) { + fn resolve_colors(&mut self, default_config: Option<&UmideConfig>) { self.color.base = self .color_theme .base @@ -405,8 +405,8 @@ impl LapceConfig { default_config.map(|c| &c.color.syntax), ); - let fg = self.color(LapceColor::EDITOR_FOREGROUND).to_rgba8(); - let bg = self.color(LapceColor::EDITOR_BACKGROUND).to_rgba8(); + let fg = self.color(UmideColor::EDITOR_FOREGROUND).to_rgba8(); + let bg = self.color(UmideColor::EDITOR_BACKGROUND).to_rgba8(); let is_light = fg.r as u32 + fg.g as u32 + fg.b as u32 > bg.r as u32 + bg.g as u32 + bg.b as u32; let high_contrast = self.color_theme.high_contrast.unwrap_or(false); @@ -614,15 +614,15 @@ impl LapceConfig { if let Some(svg) = svg { let color = if self.icon_theme.use_editor_color.unwrap_or(false) { - Some(self.color(LapceColor::LAPCE_ICON_ACTIVE)) + Some(self.color(UmideColor::LAPCE_ICON_ACTIVE)) } else { None }; (svg, color) } else { ( - self.ui_svg(LapceIcons::FILE), - Some(self.color(LapceColor::LAPCE_ICON_ACTIVE)), + self.ui_svg(UmideIcons::FILE), + Some(self.color(UmideColor::LAPCE_ICON_ACTIVE)), ) } } @@ -633,28 +633,28 @@ impl LapceConfig { pub fn symbol_svg(&self, kind: &SymbolKind) -> Option { let kind_str = match *kind { - SymbolKind::ARRAY => LapceIcons::SYMBOL_KIND_ARRAY, - SymbolKind::BOOLEAN => LapceIcons::SYMBOL_KIND_BOOLEAN, - SymbolKind::CLASS => LapceIcons::SYMBOL_KIND_CLASS, - SymbolKind::CONSTANT => LapceIcons::SYMBOL_KIND_CONSTANT, - SymbolKind::ENUM_MEMBER => LapceIcons::SYMBOL_KIND_ENUM_MEMBER, - SymbolKind::ENUM => LapceIcons::SYMBOL_KIND_ENUM, - SymbolKind::EVENT => LapceIcons::SYMBOL_KIND_EVENT, - SymbolKind::FIELD => LapceIcons::SYMBOL_KIND_FIELD, - SymbolKind::FILE => LapceIcons::SYMBOL_KIND_FILE, - SymbolKind::INTERFACE => LapceIcons::SYMBOL_KIND_INTERFACE, - SymbolKind::KEY => LapceIcons::SYMBOL_KIND_KEY, - SymbolKind::FUNCTION => LapceIcons::SYMBOL_KIND_FUNCTION, - SymbolKind::METHOD => LapceIcons::SYMBOL_KIND_METHOD, - SymbolKind::OBJECT => LapceIcons::SYMBOL_KIND_OBJECT, - SymbolKind::NAMESPACE => LapceIcons::SYMBOL_KIND_NAMESPACE, - SymbolKind::NUMBER => LapceIcons::SYMBOL_KIND_NUMBER, - SymbolKind::OPERATOR => LapceIcons::SYMBOL_KIND_OPERATOR, - SymbolKind::TYPE_PARAMETER => LapceIcons::SYMBOL_KIND_TYPE_PARAMETER, - SymbolKind::PROPERTY => LapceIcons::SYMBOL_KIND_PROPERTY, - SymbolKind::STRING => LapceIcons::SYMBOL_KIND_STRING, - SymbolKind::STRUCT => LapceIcons::SYMBOL_KIND_STRUCT, - SymbolKind::VARIABLE => LapceIcons::SYMBOL_KIND_VARIABLE, + SymbolKind::ARRAY => UmideIcons::SYMBOL_KIND_ARRAY, + SymbolKind::BOOLEAN => UmideIcons::SYMBOL_KIND_BOOLEAN, + SymbolKind::CLASS => UmideIcons::SYMBOL_KIND_CLASS, + SymbolKind::CONSTANT => UmideIcons::SYMBOL_KIND_CONSTANT, + SymbolKind::ENUM_MEMBER => UmideIcons::SYMBOL_KIND_ENUM_MEMBER, + SymbolKind::ENUM => UmideIcons::SYMBOL_KIND_ENUM, + SymbolKind::EVENT => UmideIcons::SYMBOL_KIND_EVENT, + SymbolKind::FIELD => UmideIcons::SYMBOL_KIND_FIELD, + SymbolKind::FILE => UmideIcons::SYMBOL_KIND_FILE, + SymbolKind::INTERFACE => UmideIcons::SYMBOL_KIND_INTERFACE, + SymbolKind::KEY => UmideIcons::SYMBOL_KIND_KEY, + SymbolKind::FUNCTION => UmideIcons::SYMBOL_KIND_FUNCTION, + SymbolKind::METHOD => UmideIcons::SYMBOL_KIND_METHOD, + SymbolKind::OBJECT => UmideIcons::SYMBOL_KIND_OBJECT, + SymbolKind::NAMESPACE => UmideIcons::SYMBOL_KIND_NAMESPACE, + SymbolKind::NUMBER => UmideIcons::SYMBOL_KIND_NUMBER, + SymbolKind::OPERATOR => UmideIcons::SYMBOL_KIND_OPERATOR, + SymbolKind::TYPE_PARAMETER => UmideIcons::SYMBOL_KIND_TYPE_PARAMETER, + SymbolKind::PROPERTY => UmideIcons::SYMBOL_KIND_PROPERTY, + SymbolKind::STRING => UmideIcons::SYMBOL_KIND_STRING, + SymbolKind::STRUCT => UmideIcons::SYMBOL_KIND_STRUCT, + SymbolKind::VARIABLE => UmideIcons::SYMBOL_KIND_VARIABLE, _ => return None, }; @@ -787,91 +787,91 @@ impl LapceConfig { ) -> Color { let (color, alpha) = match color { alacritty_terminal::vte::ansi::NamedColor::Cursor => { - (LapceColor::TERMINAL_CURSOR, 1.0) + (UmideColor::TERMINAL_CURSOR, 1.0) } alacritty_terminal::vte::ansi::NamedColor::Foreground => { - (LapceColor::TERMINAL_FOREGROUND, 1.0) + (UmideColor::TERMINAL_FOREGROUND, 1.0) } alacritty_terminal::vte::ansi::NamedColor::Background => { - (LapceColor::TERMINAL_BACKGROUND, 1.0) + (UmideColor::TERMINAL_BACKGROUND, 1.0) } alacritty_terminal::vte::ansi::NamedColor::Blue => { - (LapceColor::TERMINAL_BLUE, 1.0) + (UmideColor::TERMINAL_BLUE, 1.0) } alacritty_terminal::vte::ansi::NamedColor::Green => { - (LapceColor::TERMINAL_GREEN, 1.0) + (UmideColor::TERMINAL_GREEN, 1.0) } alacritty_terminal::vte::ansi::NamedColor::Yellow => { - (LapceColor::TERMINAL_YELLOW, 1.0) + (UmideColor::TERMINAL_YELLOW, 1.0) } alacritty_terminal::vte::ansi::NamedColor::Red => { - (LapceColor::TERMINAL_RED, 1.0) + (UmideColor::TERMINAL_RED, 1.0) } alacritty_terminal::vte::ansi::NamedColor::White => { - (LapceColor::TERMINAL_WHITE, 1.0) + (UmideColor::TERMINAL_WHITE, 1.0) } alacritty_terminal::vte::ansi::NamedColor::Black => { - (LapceColor::TERMINAL_BLACK, 1.0) + (UmideColor::TERMINAL_BLACK, 1.0) } alacritty_terminal::vte::ansi::NamedColor::Cyan => { - (LapceColor::TERMINAL_CYAN, 1.0) + (UmideColor::TERMINAL_CYAN, 1.0) } alacritty_terminal::vte::ansi::NamedColor::Magenta => { - (LapceColor::TERMINAL_MAGENTA, 1.0) + (UmideColor::TERMINAL_MAGENTA, 1.0) } alacritty_terminal::vte::ansi::NamedColor::BrightBlue => { - (LapceColor::TERMINAL_BRIGHT_BLUE, 1.0) + (UmideColor::TERMINAL_BRIGHT_BLUE, 1.0) } alacritty_terminal::vte::ansi::NamedColor::BrightGreen => { - (LapceColor::TERMINAL_BRIGHT_GREEN, 1.0) + (UmideColor::TERMINAL_BRIGHT_GREEN, 1.0) } alacritty_terminal::vte::ansi::NamedColor::BrightYellow => { - (LapceColor::TERMINAL_BRIGHT_YELLOW, 1.0) + (UmideColor::TERMINAL_BRIGHT_YELLOW, 1.0) } alacritty_terminal::vte::ansi::NamedColor::BrightRed => { - (LapceColor::TERMINAL_BRIGHT_RED, 1.0) + (UmideColor::TERMINAL_BRIGHT_RED, 1.0) } alacritty_terminal::vte::ansi::NamedColor::BrightWhite => { - (LapceColor::TERMINAL_BRIGHT_WHITE, 1.0) + (UmideColor::TERMINAL_BRIGHT_WHITE, 1.0) } alacritty_terminal::vte::ansi::NamedColor::BrightBlack => { - (LapceColor::TERMINAL_BRIGHT_BLACK, 1.0) + (UmideColor::TERMINAL_BRIGHT_BLACK, 1.0) } alacritty_terminal::vte::ansi::NamedColor::BrightCyan => { - (LapceColor::TERMINAL_BRIGHT_CYAN, 1.0) + (UmideColor::TERMINAL_BRIGHT_CYAN, 1.0) } alacritty_terminal::vte::ansi::NamedColor::BrightMagenta => { - (LapceColor::TERMINAL_BRIGHT_MAGENTA, 1.0) + (UmideColor::TERMINAL_BRIGHT_MAGENTA, 1.0) } alacritty_terminal::vte::ansi::NamedColor::BrightForeground => { - (LapceColor::TERMINAL_FOREGROUND, 1.0) + (UmideColor::TERMINAL_FOREGROUND, 1.0) } alacritty_terminal::vte::ansi::NamedColor::DimBlack => { - (LapceColor::TERMINAL_BLACK, 0.66) + (UmideColor::TERMINAL_BLACK, 0.66) } alacritty_terminal::vte::ansi::NamedColor::DimRed => { - (LapceColor::TERMINAL_RED, 0.66) + (UmideColor::TERMINAL_RED, 0.66) } alacritty_terminal::vte::ansi::NamedColor::DimGreen => { - (LapceColor::TERMINAL_GREEN, 0.66) + (UmideColor::TERMINAL_GREEN, 0.66) } alacritty_terminal::vte::ansi::NamedColor::DimYellow => { - (LapceColor::TERMINAL_YELLOW, 0.66) + (UmideColor::TERMINAL_YELLOW, 0.66) } alacritty_terminal::vte::ansi::NamedColor::DimBlue => { - (LapceColor::TERMINAL_BLUE, 0.66) + (UmideColor::TERMINAL_BLUE, 0.66) } alacritty_terminal::vte::ansi::NamedColor::DimMagenta => { - (LapceColor::TERMINAL_MAGENTA, 0.66) + (UmideColor::TERMINAL_MAGENTA, 0.66) } alacritty_terminal::vte::ansi::NamedColor::DimCyan => { - (LapceColor::TERMINAL_CYAN, 0.66) + (UmideColor::TERMINAL_CYAN, 0.66) } alacritty_terminal::vte::ansi::NamedColor::DimWhite => { - (LapceColor::TERMINAL_WHITE, 0.66) + (UmideColor::TERMINAL_WHITE, 0.66) } alacritty_terminal::vte::ansi::NamedColor::DimForeground => { - (LapceColor::TERMINAL_FOREGROUND, 0.66) + (UmideColor::TERMINAL_FOREGROUND, 0.66) } }; self.color(color).multiply_alpha(alpha) diff --git a/crates/umide/src/config/color.rs b/crates/umide/src/config/color.rs index 158fabf8..e15d4f62 100644 --- a/crates/umide/src/config/color.rs +++ b/crates/umide/src/config/color.rs @@ -19,9 +19,9 @@ pub enum LoadThemeError { Read(std::io::Error), } -pub struct LapceColor {} +pub struct UmideColor {} -impl LapceColor { +impl UmideColor { pub const LAPCE_WARN: &'static str = "lapce.warn"; pub const LAPCE_ERROR: &'static str = "lapce.error"; pub const LAPCE_DROPDOWN_SHADOW: &'static str = "lapce.dropdown_shadow"; diff --git a/crates/umide/src/config/color_theme.rs b/crates/umide/src/config/color_theme.rs index b9c0d97e..7c2b38ae 100644 --- a/crates/umide/src/config/color_theme.rs +++ b/crates/umide/src/config/color_theme.rs @@ -185,15 +185,15 @@ mod tests { use config::Config; use floem::{peniko::Color, prelude::palette::css}; - use crate::{config::LapceConfig, workspace::LapceWorkspace}; + use crate::{config::UmideConfig, workspace::UmideWorkspace}; #[test] fn test_resolve() { // Mimicking load - let workspace = LapceWorkspace::default(); + let workspace = UmideWorkspace::default(); - let config = LapceConfig::merge_config(&workspace, None, None); - let mut lapce_config: LapceConfig = config.try_deserialize().unwrap(); + let config = UmideConfig::merge_config(&workspace, None, None); + let mut lapce_config: UmideConfig = config.try_deserialize().unwrap(); let test_theme_str = r##" [color-theme] diff --git a/crates/umide/src/config/core.rs b/crates/umide/src/config/core.rs index c230b9cb..f571c5ca 100644 --- a/crates/umide/src/config/core.rs +++ b/crates/umide/src/config/core.rs @@ -6,9 +6,9 @@ use structdesc::FieldNames; pub struct CoreConfig { #[field_names(desc = "Enable modal editing (Vim like)")] pub modal: bool, - #[field_names(desc = "Set the color theme of Lapce")] + #[field_names(desc = "Set the color theme of Umide")] pub color_theme: String, - #[field_names(desc = "Set the icon theme of Lapce")] + #[field_names(desc = "Set the icon theme of Umide")] pub icon_theme: String, #[field_names( desc = "Enable customised titlebar and disable OS native one (Linux, BSD, Windows)" diff --git a/crates/umide/src/config/icon.rs b/crates/umide/src/config/icon.rs index 574a79de..c2a5b262 100644 --- a/crates/umide/src/config/icon.rs +++ b/crates/umide/src/config/icon.rs @@ -1,6 +1,6 @@ -pub struct LapceIcons {} +pub struct UmideIcons {} -impl LapceIcons { +impl UmideIcons { pub const WINDOW_CLOSE: &'static str = "window.close"; pub const WINDOW_RESTORE: &'static str = "window.restore"; pub const WINDOW_MAXIMIZE: &'static str = "window.maximize"; diff --git a/crates/umide/src/db.rs b/crates/umide/src/db.rs index d10e7b65..c1044d7d 100644 --- a/crates/umide/src/db.rs +++ b/crates/umide/src/db.rs @@ -17,7 +17,7 @@ use crate::{ panel::{data::PanelOrder, kind::PanelKind}, window::{WindowData, WindowInfo}, window_tab::WindowTabData, - workspace::{LapceWorkspace, WorkspaceInfo}, + workspace::{UmideWorkspace, WorkspaceInfo}, }; const APP: &str = "app"; @@ -30,22 +30,22 @@ const RECENT_WORKSPACES: &str = "recent_workspaces"; pub enum SaveEvent { App(AppInfo), - Workspace(LapceWorkspace, WorkspaceInfo), - RecentWorkspace(LapceWorkspace), + Workspace(UmideWorkspace, WorkspaceInfo), + RecentWorkspace(UmideWorkspace), Doc(DocInfo), DisabledVolts(Vec), - WorkspaceDisabledVolts(Arc, Vec), + WorkspaceDisabledVolts(Arc, Vec), PanelOrder(PanelOrder), } #[derive(Clone)] -pub struct LapceDb { +pub struct UmideDb { folder: PathBuf, workspace_folder: PathBuf, save_tx: Sender, } -impl LapceDb { +impl UmideDb { pub fn new() -> Result { let folder = Directory::config_directory() .ok_or_else(|| anyhow!("can't get config directory"))? @@ -131,7 +131,7 @@ impl LapceDb { pub fn save_workspace_disabled_volts( &self, - workspace: Arc, + workspace: Arc, volts: Vec, ) { if let Err(err) = self @@ -150,7 +150,7 @@ impl LapceDb { pub fn insert_workspace_disabled_volts( &self, - workspace: Arc, + workspace: Arc, volts: Vec, ) -> Result<()> { let folder = self @@ -167,7 +167,7 @@ impl LapceDb { pub fn get_workspace_disabled_volts( &self, - workspace: &LapceWorkspace, + workspace: &UmideWorkspace, ) -> Result> { let folder = self.workspace_folder.join(workspace_folder_name(workspace)); let volts = std::fs::read_to_string(folder.join(DISABLED_VOLTS))?; @@ -175,14 +175,14 @@ impl LapceDb { Ok(volts) } - pub fn recent_workspaces(&self) -> Result> { + pub fn recent_workspaces(&self) -> Result> { let workspaces = std::fs::read_to_string(self.folder.join(RECENT_WORKSPACES))?; - let workspaces: Vec = serde_json::from_str(&workspaces)?; + let workspaces: Vec = serde_json::from_str(&workspaces)?; Ok(workspaces) } - pub fn update_recent_workspace(&self, workspace: &LapceWorkspace) -> Result<()> { + pub fn update_recent_workspace(&self, workspace: &UmideWorkspace) -> Result<()> { if workspace.path.is_none() { return Ok(()); } @@ -191,7 +191,7 @@ impl LapceDb { Ok(()) } - fn insert_recent_workspace(&self, workspace: LapceWorkspace) -> Result<()> { + fn insert_recent_workspace(&self, workspace: UmideWorkspace) -> Result<()> { let mut workspaces = self.recent_workspaces().unwrap_or_default(); let mut exits = false; @@ -233,7 +233,7 @@ impl LapceDb { pub fn get_workspace_info( &self, - workspace: &LapceWorkspace, + workspace: &UmideWorkspace, ) -> Result { let info = std::fs::read_to_string( self.workspace_folder @@ -246,7 +246,7 @@ impl LapceDb { fn insert_workspace( &self, - workspace: &LapceWorkspace, + workspace: &UmideWorkspace, info: &WorkspaceInfo, ) -> Result<()> { let folder = self.workspace_folder.join(workspace_folder_name(workspace)); @@ -395,7 +395,7 @@ impl LapceDb { pub fn save_doc_position( &self, - workspace: &LapceWorkspace, + workspace: &UmideWorkspace, path: PathBuf, cursor_offset: usize, scroll_offset: Vec2, @@ -426,7 +426,7 @@ impl LapceDb { pub fn get_doc_info( &self, - workspace: &LapceWorkspace, + workspace: &UmideWorkspace, path: &Path, ) -> Result { let folder = self @@ -439,7 +439,7 @@ impl LapceDb { } } -fn workspace_folder_name(workspace: &LapceWorkspace) -> String { +fn workspace_folder_name(workspace: &UmideWorkspace) -> String { url::form_urlencoded::Serializer::new(String::new()) .append_key_only(&workspace.to_string()) .finish() diff --git a/crates/umide/src/debug.rs b/crates/umide/src/debug.rs index bc61ae97..e8fc0d44 100644 --- a/crates/umide/src/debug.rs +++ b/crates/umide/src/debug.rs @@ -61,13 +61,13 @@ pub struct RunDebugConfigs { pub struct RunDebugData { pub active_term: RwSignal>, pub daps: RwSignal>, - pub breakpoints: RwSignal>>, + pub breakpoints: RwSignal>>, } impl RunDebugData { pub fn new( cx: Scope, - breakpoints: RwSignal>>, + breakpoints: RwSignal>>, ) -> Self { let active_term: RwSignal> = cx.create_rw_signal(None); let daps: RwSignal> = @@ -117,7 +117,7 @@ pub struct StackTraceData { } #[derive(Clone, Serialize, Deserialize)] -pub struct LapceBreakpoint { +pub struct UmideBreakpoint { pub id: Option, pub verified: bool, pub message: Option, diff --git a/crates/umide/src/doc.rs b/crates/umide/src/doc.rs index 425b2b09..15778b96 100644 --- a/crates/umide/src/doc.rs +++ b/crates/umide/src/doc.rs @@ -38,7 +38,7 @@ use umide_core::{ cursor::{Cursor, CursorAffinity}, editor::{Action, EditConf, EditType}, indent::IndentStyle, - language::LapceLanguage, + language::UmideLanguage, line_ending::LineEnding, mode::MotionMode, register::Register, @@ -66,8 +66,8 @@ use serde::{Deserialize, Serialize}; use smallvec::SmallVec; use crate::{ - command::{CommandKind, LapceCommand}, - config::{LapceConfig, color::LapceColor}, + command::{CommandKind, UmideCommand}, + config::{UmideConfig, color::UmideColor}, editor::{EditorData, compute_screen_lines, gutter::FoldingRanges}, find::{Find, FindProgress, FindResult}, history::DocumentHistory, @@ -78,7 +78,7 @@ use crate::{ kind::PanelKind, }, window_tab::{CommonData, Focus}, - workspace::LapceWorkspace, + workspace::UmideWorkspace, }; #[derive(Clone, Debug)] @@ -142,7 +142,7 @@ impl DocContent { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct DocInfo { - pub workspace: LapceWorkspace, + pub workspace: UmideWorkspace, pub path: PathBuf, pub scroll_offset: (f64, f64), pub cursor_offset: usize, @@ -418,7 +418,7 @@ impl Doc { } /// Set the syntax highlighting this document should use. - pub fn set_language(&self, language: LapceLanguage) { + pub fn set_language(&self, language: UmideLanguage) { self.syntax.set(Syntax::from_language(language)); } @@ -491,7 +491,7 @@ impl Doc { &self, cursor: &mut Cursor, s: &str, - config: &LapceConfig, + config: &UmideConfig, ) -> Vec<(Rope, RopeDelta, InvalLines)> { if self.content.with_untracked(|c| c.read_only()) { return Vec::new(); @@ -1584,7 +1584,7 @@ impl Document for Doc { }; let cmd = CommandKind::from(cmd.clone()); - let cmd = LapceCommand { + let cmd = UmideCommand { kind: cmd, data: None, }; @@ -1691,10 +1691,10 @@ impl DocumentPhantom for Doc { col, text, affinity, - fg: Some(config.color(LapceColor::INLAY_HINT_FOREGROUND)), + fg: Some(config.color(UmideColor::INLAY_HINT_FOREGROUND)), // font_family: Some(config.editor.inlay_hint_font_family()), font_size: Some(config.editor.inlay_hint_font_size()), - bg: Some(config.color(LapceColor::INLAY_HINT_BACKGROUND)), + bg: Some(config.color(UmideColor::INLAY_HINT_BACKGROUND)), under_line: None, } }); @@ -1730,14 +1730,14 @@ impl DocumentPhantom for Doc { let theme_prop = if severity == DiagnosticSeverity::ERROR { - LapceColor::ERROR_LENS_ERROR_FOREGROUND + UmideColor::ERROR_LENS_ERROR_FOREGROUND } else if severity == DiagnosticSeverity::WARNING { - LapceColor::ERROR_LENS_WARNING_FOREGROUND + UmideColor::ERROR_LENS_WARNING_FOREGROUND } else { // information + hint (if we keep that) + things without a severity - LapceColor::ERROR_LENS_OTHER_FOREGROUND + UmideColor::ERROR_LENS_OTHER_FOREGROUND }; config.color(theme_prop) @@ -1790,7 +1790,7 @@ impl DocumentPhantom for Doc { kind: PhantomTextKind::Completion, col: completion_col, text: completion.clone(), - fg: Some(config.color(LapceColor::COMPLETION_LENS_FOREGROUND)), + fg: Some(config.color(UmideColor::COMPLETION_LENS_FOREGROUND)), font_size: Some(config.editor.completion_lens_font_size()), affinity: Some(CursorAffinity::Backward), // font_family: Some(config.editor.completion_lens_font_family()), @@ -1818,7 +1818,7 @@ impl DocumentPhantom for Doc { col: inline_completion_col, text: completion.clone(), affinity: Some(CursorAffinity::Backward), - fg: Some(config.color(LapceColor::COMPLETION_LENS_FOREGROUND)), + fg: Some(config.color(UmideColor::COMPLETION_LENS_FOREGROUND)), font_size: Some(config.editor.completion_lens_font_size()), // font_family: Some(config.editor.completion_lens_font_family()), bg: None, @@ -1830,7 +1830,7 @@ impl DocumentPhantom for Doc { } if let Some(preedit) = self - .preedit_phantom(Some(config.color(LapceColor::EDITOR_FOREGROUND)), line) + .preedit_phantom(Some(config.color(UmideColor::EDITOR_FOREGROUND)), line) { text.push(preedit) } @@ -1893,7 +1893,7 @@ impl CommonAction for Doc { #[derive(Clone)] pub struct DocStyling { - config: ReadSignal>, + config: ReadSignal>, doc: Rc, } impl DocStyling { @@ -2075,9 +2075,9 @@ impl Styling for DocStyling { let color_name = match diag.severity { Some(DiagnosticSeverity::ERROR) => { - LapceColor::LAPCE_ERROR + UmideColor::LAPCE_ERROR } - _ => LapceColor::LAPCE_WARN, + _ => UmideColor::LAPCE_WARN, }; let color = config.color(color_name); let styles = extra_styles_for_range( @@ -2096,11 +2096,11 @@ impl Styling for DocStyling { // Add the styling for the diagnostic severity, if applicable if let Some(max_severity) = max_severity { let theme_prop = if max_severity == DiagnosticSeverity::ERROR { - LapceColor::ERROR_LENS_ERROR_BACKGROUND + UmideColor::ERROR_LENS_ERROR_BACKGROUND } else if max_severity == DiagnosticSeverity::WARNING { - LapceColor::ERROR_LENS_WARNING_BACKGROUND + UmideColor::ERROR_LENS_WARNING_BACKGROUND } else { - LapceColor::ERROR_LENS_OTHER_BACKGROUND + UmideColor::ERROR_LENS_OTHER_BACKGROUND }; let size = layout.size(); diff --git a/crates/umide/src/editor.rs b/crates/umide/src/editor.rs index 1aa548d7..1fe46e42 100644 --- a/crates/umide/src/editor.rs +++ b/crates/umide/src/editor.rs @@ -9,7 +9,7 @@ use std::{ use umide_core::cursor::CursorAffinity; use floem::{ - ViewId, action::{TimerToken, exec_after, show_context_menu}, ext_event::create_ext_action, kurbo::{Affine, Point, Rect, Vec2}, menu::Menu, prelude::{ + ViewId, action::{TimerToken, exec_after, show_context_menu}, ext_event::create_ext_action, kurbo::{Point, Rect, Vec2}, menu::Menu, prelude::{ Modifiers, PointerButtonEvent, PointerEvent, SignalTrack, }, reactive::{ Context, Effect, ReadSignal, RwSignal, Scope, SignalGet, SignalUpdate, SignalWith @@ -36,7 +36,7 @@ use umide_core::{ EditCommand, FocusCommand, MotionModeCommand, MultiSelectionCommand, ScrollCommand, }, - cursor::{ColPosition, Cursor, CursorMode}, + cursor::{Cursor, CursorMode}, editor::EditType, mode::{Mode, MotionMode}, rope_text_pos::RopeTextPosition, @@ -58,10 +58,10 @@ use self::{ location::{EditorLocation, EditorPosition}, }; use crate::{ - command::{CommandKind, InternalCommand, LapceCommand, LapceWorkbenchCommand}, + command::{CommandKind, InternalCommand, UmideCommand, UmideWorkbenchCommand}, completion::CompletionStatus, - config::LapceConfig, - db::LapceDb, + config::UmideConfig, + db::UmideDb, doc::{Doc, DocContent}, editor_tab::EditorTabChild, id::{DiffEditorId, EditorTabId}, @@ -508,7 +508,7 @@ impl EditorData { let doc = self.doc(); let config = self.common.config.get_untracked(); - // This is currently special-cased in Lapce because floem editor does not have 'find' + // This is currently special-cased in Umide because floem editor does not have 'find' match cmd { MultiSelectionCommand::SelectAllCurrent => { if let CursorMode::Insert(mut selection) = cursor.mode.clone() { @@ -2157,7 +2157,7 @@ impl EditorData { } else if let Some(edits) = edits.as_ref() { self.do_text_edit(edits); } else { - let db: Arc = Context::get().unwrap(); + let db: Arc = Context::get().unwrap(); if let Ok(info) = db.get_doc_info(&self.common.workspace, &location.path) { self.go_to_position( @@ -2507,7 +2507,7 @@ impl EditorData { let cursor_offset = self.cursor().with_untracked(|c| c.offset()); let scroll_offset = self.viewport().with_untracked(|v| v.origin().to_vec2()); - let db: Arc = Context::get().unwrap(); + let db: Arc = Context::get().unwrap(); db.save_doc_position( &self.common.workspace, path, @@ -2706,7 +2706,7 @@ impl EditorData { match rs { FindHintRs::NoMatchBreak | FindHintRs::NoMatchContinue { .. } => { - self.common.lapce_command.send(LapceCommand { + self.common.lapce_command.send(UmideCommand { kind: CommandKind::Focus( FocusCommand::GotoDefinition, ), @@ -2908,24 +2908,24 @@ impl EditorData { { vec![ Some(CommandKind::Workbench( - LapceWorkbenchCommand::RevealInPanel, + UmideWorkbenchCommand::RevealInPanel, )), Some(CommandKind::Workbench( - LapceWorkbenchCommand::RevealInFileExplorer, + UmideWorkbenchCommand::RevealInFileExplorer, )), Some(CommandKind::Workbench( - LapceWorkbenchCommand::SourceControlOpenActiveFileRemoteUrl, + UmideWorkbenchCommand::SourceControlOpenActiveFileRemoteUrl, )), None, Some(CommandKind::Edit(EditCommand::ClipboardCut)), Some(CommandKind::Edit(EditCommand::ClipboardCopy)), Some(CommandKind::Edit(EditCommand::ClipboardPaste)), Some(CommandKind::Workbench( - LapceWorkbenchCommand::AddRunDebugConfig, + UmideWorkbenchCommand::AddRunDebugConfig, )), None, Some(CommandKind::Workbench( - LapceWorkbenchCommand::PaletteCommand, + UmideWorkbenchCommand::PaletteCommand, )), ] } else { @@ -2933,27 +2933,27 @@ impl EditorData { Some(CommandKind::Focus(FocusCommand::GotoDefinition)), Some(CommandKind::Focus(FocusCommand::GotoTypeDefinition)), Some(CommandKind::Workbench( - LapceWorkbenchCommand::ShowCallHierarchy, + UmideWorkbenchCommand::ShowCallHierarchy, )), Some(CommandKind::Workbench( - LapceWorkbenchCommand::FindReferences, + UmideWorkbenchCommand::FindReferences, )), Some(CommandKind::Workbench( - LapceWorkbenchCommand::GoToImplementation, + UmideWorkbenchCommand::GoToImplementation, )), Some(CommandKind::Focus(FocusCommand::Rename)), Some(CommandKind::Workbench( - LapceWorkbenchCommand::RunInTerminal, + UmideWorkbenchCommand::RunInTerminal, )), None, Some(CommandKind::Workbench( - LapceWorkbenchCommand::RevealInPanel, + UmideWorkbenchCommand::RevealInPanel, )), Some(CommandKind::Workbench( - LapceWorkbenchCommand::RevealInFileExplorer, + UmideWorkbenchCommand::RevealInFileExplorer, )), Some(CommandKind::Workbench( - LapceWorkbenchCommand::SourceControlOpenActiveFileRemoteUrl, + UmideWorkbenchCommand::SourceControlOpenActiveFileRemoteUrl, )), None, Some(CommandKind::Edit(EditCommand::ClipboardCut)), @@ -2961,7 +2961,7 @@ impl EditorData { Some(CommandKind::Edit(EditCommand::ClipboardPaste)), None, Some(CommandKind::Workbench( - LapceWorkbenchCommand::PaletteCommand, + UmideWorkbenchCommand::PaletteCommand, )), ] } @@ -2972,13 +2972,13 @@ impl EditorData { Some(CommandKind::Edit(EditCommand::ClipboardPaste)), None, Some(CommandKind::Workbench( - LapceWorkbenchCommand::PaletteCommand, + UmideWorkbenchCommand::PaletteCommand, )), ] }; if self.diff_editor_id.get_untracked().is_some() && is_file { cmds.push(Some(CommandKind::Workbench( - LapceWorkbenchCommand::GoToLocation, + UmideWorkbenchCommand::GoToLocation, ))); } let lapce_command = self.common.lapce_command; @@ -2987,7 +2987,7 @@ impl EditorData { menu = menu.item( cmd.desc().unwrap_or_else(|| cmd.str()), |i| i.action( move || { - lapce_command.send(LapceCommand { + lapce_command.send(UmideCommand { kind: cmd.clone(), data: None, }) @@ -3289,7 +3289,7 @@ impl KeyPressFocus for EditorData { #[instrument] fn run_command( &self, - command: &crate::command::LapceCommand, + command: &crate::command::UmideCommand, count: Option, mods: Modifiers, ) -> CommandExecuted { @@ -3520,7 +3520,7 @@ fn show_inline_completion(cmd: &EditCommand) -> bool { // TODO(minor): Should we just put this on view, since it only requires those values? pub(crate) fn compute_screen_lines( - config: ReadSignal>, + config: ReadSignal>, base: RwSignal, view_kind: ReadSignal, doc: &Doc, @@ -3850,7 +3850,7 @@ pub(crate) fn compute_screen_lines( fn parse_hover_resp( hover: lsp_types::Hover, - config: &LapceConfig, + config: &UmideConfig, ) -> Vec { match hover.contents { HoverContents::Scalar(text) => match text { diff --git a/crates/umide/src/editor/diff.rs b/crates/umide/src/editor/diff.rs index eeeb21b6..9a2ca4e9 100644 --- a/crates/umide/src/editor/diff.rs +++ b/crates/umide/src/editor/diff.rs @@ -20,7 +20,7 @@ use serde::{Deserialize, Serialize}; use super::{EditorData, EditorViewKind}; use crate::{ - config::{color::LapceColor, icon::LapceIcons}, + config::{color::UmideColor, icon::UmideIcons}, doc::{Doc, DocContent}, id::{DiffEditorId, EditorTabId}, main_split::{Editors, MainSplitData}, @@ -363,16 +363,16 @@ pub fn diff_show_more_section_view( wave_box().style(move |s| { s.absolute() .size_pct(100.0, 100.0) - .color(config.get().color(LapceColor::PANEL_BACKGROUND)) + .color(config.get().color(UmideColor::PANEL_BACKGROUND)) }), Label::new(format!("{} Hidden Lines", section.lines)), Label::new("|".to_string()).style(|s| s.margin_left(10.0)), Stack::new(( - svg(move || config.get().ui_svg(LapceIcons::FOLD)).style(move |s| { + svg(move || config.get().ui_svg(UmideIcons::FOLD)).style(move |s| { let config = config.get(); let size = config.ui.icon_size() as f32; s.size(size, size) - .color(config.color(LapceColor::EDITOR_FOREGROUND)) + .color(config.color(UmideColor::EDITOR_FOREGROUND)) }), Label::new("Expand All".to_string()).style(|s| s.margin_left(6.0)), )) @@ -407,12 +407,12 @@ pub fn diff_show_more_section_view( }), Label::new("|".to_string()).style(|s| s.margin_left(10.0)), Stack::new(( - svg(move || config.get().ui_svg(LapceIcons::FOLD_UP)).style( + svg(move || config.get().ui_svg(UmideIcons::FOLD_UP)).style( move |s| { let config = config.get(); let size = config.ui.icon_size() as f32; s.size(size, size) - .color(config.color(LapceColor::EDITOR_FOREGROUND)) + .color(config.color(UmideColor::EDITOR_FOREGROUND)) }, ), Label::new("Expand Up".to_string()).style(|s| s.margin_left(6.0)), @@ -448,12 +448,12 @@ pub fn diff_show_more_section_view( }), Label::new("|".to_string()).style(|s| s.margin_left(10.0)), Stack::new(( - svg(move || config.get().ui_svg(LapceIcons::FOLD_DOWN)).style( + svg(move || config.get().ui_svg(UmideIcons::FOLD_DOWN)).style( move |s| { let config = config.get(); let size = config.ui.icon_size() as f32; s.size(size, size) - .color(config.color(LapceColor::EDITOR_FOREGROUND)) + .color(config.color(UmideColor::EDITOR_FOREGROUND)) }, ), Label::new("Expand Down".to_string()).style(|s| s.margin_left(6.0)), diff --git a/crates/umide/src/editor/gutter.rs b/crates/umide/src/editor/gutter.rs index 646c142d..44534c25 100644 --- a/crates/umide/src/editor/gutter.rs +++ b/crates/umide/src/editor/gutter.rs @@ -10,7 +10,7 @@ use umide_core::{buffer::rope_text::RopeText, mode::Mode}; use serde::{Deserialize, Serialize}; use super::{EditorData, view::changes_colors_screen}; -use crate::config::{LapceConfig, color::LapceColor}; +use crate::config::{UmideConfig, color::UmideColor}; pub struct EditorGutterView { id: ViewId, @@ -40,7 +40,7 @@ impl EditorGutterView { e_data: &EditorData, viewport: Rect, is_normal: bool, - config: &LapceConfig, + config: &UmideConfig, ) { if !is_normal { return; @@ -76,7 +76,7 @@ impl EditorGutterView { &self, cx: &mut PaintCx, is_normal: bool, - config: &LapceConfig, + config: &UmideConfig, ) { if !is_normal { return; @@ -97,12 +97,12 @@ impl EditorGutterView { .inflate(25.0, 0.0); cx.fill( &sticky_area_rect, - config.color(LapceColor::LAPCE_DROPDOWN_SHADOW), + config.color(UmideColor::LAPCE_DROPDOWN_SHADOW), 3.0, ); cx.fill( &sticky_area_rect, - config.color(LapceColor::EDITOR_STICKY_HEADER_BACKGROUND), + config.color(UmideColor::EDITOR_STICKY_HEADER_BACKGROUND), 0.0, ); } @@ -149,13 +149,13 @@ impl View for EditorGutterView { FamilyOwned::parse_list(&config.editor.font_family).collect(); let attrs = Attrs::new() .family(&family) - .color(config.color(LapceColor::EDITOR_DIM)) + .color(config.color(UmideColor::EDITOR_DIM)) .font_size(config.editor.font_size() as f32); let attrs_list = AttrsList::new(attrs.clone()); let current_line_attrs_list = AttrsList::new( attrs .clone() - .color(config.color(LapceColor::EDITOR_FOREGROUND)), + .color(config.color(UmideColor::EDITOR_FOREGROUND)), ); let show_relative = config.core.modal && config.editor.modal_mode_relative_line_numbers diff --git a/crates/umide/src/editor/view.rs b/crates/umide/src/editor/view.rs index 528f0558..6b5cb2d4 100644 --- a/crates/umide/src/editor/view.rs +++ b/crates/umide/src/editor/view.rs @@ -54,13 +54,13 @@ use super::{DocSignal, EditorData, gutter::editor_gutter_view}; use crate::{ app::clickable_icon, command::InternalCommand, - config::{LapceConfig, color::LapceColor, editor::WrapStyle, icon::LapceIcons}, - debug::{DapData, LapceBreakpoint}, + config::{UmideConfig, color::UmideColor, editor::WrapStyle, icon::UmideIcons}, + debug::{DapData, UmideBreakpoint}, doc::DocContent, editor::gutter::FoldingDisplayItem, text_input::TextInputBuilder, window_tab::{CommonData, Focus, WindowTabData}, - workspace::LapceWorkspace, + workspace::UmideWorkspace, }; #[derive(Clone, Debug, Default)] @@ -70,7 +70,7 @@ pub struct StickyHeaderInfo { pub y_diff: f64, } -fn editor_wrap(config: &LapceConfig) -> WrapMethod { +fn editor_wrap(config: &UmideConfig) -> WrapMethod { /// Minimum width that we'll allow the view to be wrapped at. const MIN_WRAPPED_WIDTH: f32 = 100.0; @@ -84,7 +84,7 @@ fn editor_wrap(config: &LapceConfig) -> WrapMethod { } pub fn editor_style( - config: ReadSignal>, + config: ReadSignal>, doc: DocSignal, s: Style, ) -> Style { @@ -95,28 +95,28 @@ pub fn editor_style( IndentStyleProp, doc.buffer.with_untracked(Buffer::indent_style), ) - .set(CursorColor, config.color(LapceColor::EDITOR_CARET)) - .set(SelectionColor, config.color(LapceColor::EDITOR_SELECTION)) + .set(CursorColor, config.color(UmideColor::EDITOR_CARET)) + .set(SelectionColor, config.color(UmideColor::EDITOR_SELECTION)) .set( CurrentLineColor, - config.color(LapceColor::EDITOR_CURRENT_LINE), + config.color(UmideColor::EDITOR_CURRENT_LINE), ) .set( VisibleWhitespaceColor, - config.color(LapceColor::EDITOR_VISIBLE_WHITESPACE), + config.color(UmideColor::EDITOR_VISIBLE_WHITESPACE), ) .set( IndentGuideColor, - config.color(LapceColor::EDITOR_INDENT_GUIDE), + config.color(UmideColor::EDITOR_INDENT_GUIDE), ) .set(ScrollBeyondLastLine, config.editor.scroll_beyond_last_line) - .color(config.color(LapceColor::EDITOR_FOREGROUND)) - .set(TextColor, config.color(LapceColor::EDITOR_FOREGROUND)) - .set(PhantomColor, config.color(LapceColor::EDITOR_DIM)) - .set(PlaceholderColor, config.color(LapceColor::EDITOR_DIM)) + .color(config.color(UmideColor::EDITOR_FOREGROUND)) + .set(TextColor, config.color(UmideColor::EDITOR_FOREGROUND)) + .set(PhantomColor, config.color(UmideColor::EDITOR_DIM)) + .set(PlaceholderColor, config.color(UmideColor::EDITOR_DIM)) .set( PreeditUnderlineColor, - config.color(LapceColor::EDITOR_FOREGROUND), + config.color(UmideColor::EDITOR_FOREGROUND), ) .set(ShowIndentGuide, config.editor.show_indent_guide) .set(Modal, config.core.modal) @@ -295,7 +295,7 @@ impl EditorView { cx: &mut PaintCx, viewport: Rect, screen_lines: &ScreenLines, - config: &LapceConfig, + config: &UmideConfig, ) { let Some(diff_sections) = &screen_lines.diff_sections else { return; @@ -322,7 +322,7 @@ impl EditorView { (section.y_idx * config.editor.line_height()) as f64, )), config - .color(LapceColor::SOURCE_CONTROL_ADDED) + .color(UmideColor::SOURCE_CONTROL_ADDED) .multiply_alpha(0.2), 0.0, ); @@ -340,7 +340,7 @@ impl EditorView { (section.y_idx * config.editor.line_height()) as f64, )), config - .color(LapceColor::SOURCE_CONTROL_REMOVED) + .color(UmideColor::SOURCE_CONTROL_REMOVED) .multiply_alpha(0.2), 0.0, ); @@ -355,7 +355,7 @@ impl EditorView { viewport: Rect, start_line: usize, height: usize, - config: &LapceConfig, + config: &UmideConfig, ) { let line_height = config.editor.line_height(); let height = (height * line_height) as f64; @@ -391,7 +391,7 @@ impl EditorView { let p1 = Point::new(x as f64 - height, y + height); cx.stroke( &Line::new(p0, p1), - config.color(LapceColor::EDITOR_DIM), + config.color(UmideColor::EDITOR_DIM), &Stroke::new(1.0), ); } @@ -439,7 +439,7 @@ impl EditorView { cx.fill( &rect, - config.color(LapceColor::EDITOR_DEBUG_BREAK_LINE), + config.color(UmideColor::EDITOR_DEBUG_BREAK_LINE), 0.0, ); } @@ -498,7 +498,7 @@ impl EditorView { let config = config.get_untracked(); let line_height = config.editor.line_height() as f64; - let color = config.color(LapceColor::EDITOR_FOREGROUND); + let color = config.color(UmideColor::EDITOR_FOREGROUND); let start = ed.offset_of_line(min_line); let end = ed.offset_of_line(max_line + 1); @@ -669,12 +669,12 @@ impl EditorView { cx.fill( &sticky_area_rect, - config.color(LapceColor::LAPCE_DROPDOWN_SHADOW), + config.color(UmideColor::LAPCE_DROPDOWN_SHADOW), 3.0, ); cx.fill( &sticky_area_rect, - config.color(LapceColor::EDITOR_STICKY_HEADER_BACKGROUND), + config.color(UmideColor::EDITOR_STICKY_HEADER_BACKGROUND), 0.0, ); self.editor.sticky_header_info.get_untracked(); @@ -715,7 +715,7 @@ impl EditorView { cx: &mut PaintCx, viewport: Rect, is_local: bool, - config: Arc, + config: Arc, ) { const BAR_WIDTH: f64 = 10.0; @@ -731,7 +731,7 @@ impl EditorView { viewport.y0, )) .inflate(0.0, 10.0), - config.color(LapceColor::LAPCE_SCROLL_BAR), + config.color(UmideColor::LAPCE_SCROLL_BAR), 0.0, ); @@ -805,7 +805,7 @@ impl EditorView { cx.stroke( &rect, - config.color(LapceColor::EDITOR_FOREGROUND), + config.color(UmideColor::EDITOR_FOREGROUND), &Stroke::new(1.0), ); } @@ -826,7 +826,7 @@ impl EditorView { let doc = self.editor.doc(); let config = self.editor.common.config.get_untracked(); let line_height = config.editor.line_height() as f64; - let brush = config.color(LapceColor::EDITOR_FOREGROUND); + let brush = config.color(UmideColor::EDITOR_FOREGROUND); if start == end { if let Some(line_info) = screen_lines.info(start) { @@ -1162,7 +1162,7 @@ fn get_sticky_header_info( editor_data: &EditorData, viewport: RwSignal, sticky_header_height_signal: RwSignal, - config: &LapceConfig, + config: &UmideConfig, ) -> StickyHeaderInfo { let editor = &editor_data.editor; let doc = editor_data.doc(); @@ -1273,7 +1273,7 @@ fn get_sticky_header_info( pub fn editor_container_view( window_tab_data: Rc, - workspace: Arc, + workspace: Arc, is_active: impl Fn(bool) -> bool + 'static + Copy, editor: RwSignal, ) -> impl View { @@ -1321,7 +1321,7 @@ pub fn editor_container_view( // .box_shadow_blur(5.0) // .border_bottom(1.0) // .border_color( - // config.get_color(LapceColor::LAPCE_BORDER), + // config.get_color(UmideColor::LAPCE_BORDER), // ) .apply_if( !config.editor.sticky_header @@ -1376,7 +1376,7 @@ fn editor_gutter_breakpoint_view( i: usize, doc: DocSignal, daps: RwSignal>, - breakpoints: RwSignal>>, + breakpoints: RwSignal>>, screen_lines: RwSignal, common: Rc, icon_padding: f32, @@ -1384,12 +1384,12 @@ fn editor_gutter_breakpoint_view( let hovered = RwSignal::new(false); let config = common.config; Container::new( - svg(move || config.get().ui_svg(LapceIcons::DEBUG_BREAKPOINT)).style( + svg(move || config.get().ui_svg(UmideIcons::DEBUG_BREAKPOINT)).style( move |s| { let config = config.get(); let size = config.ui.icon_size() as f32 + 2.0; s.size(size, size) - .color(config.color(LapceColor::DEBUG_BREAKPOINT_HOVER)) + .color(config.color(UmideColor::DEBUG_BREAKPOINT_HOVER)) .apply_if(!hovered.get(), |s| s.hide()) }, ), @@ -1410,7 +1410,7 @@ fn editor_gutter_breakpoint_view( if let std::collections::btree_map::Entry::Vacant(e) = breakpoints.entry(line) { - e.insert(LapceBreakpoint { + e.insert(UmideBreakpoint { id: None, verified: false, message: None, @@ -1545,15 +1545,15 @@ fn editor_gutter_breakpoints( let active = breakpoint.active; Container::new( svg(move || { - config.get().ui_svg(LapceIcons::DEBUG_BREAKPOINT) + config.get().ui_svg(UmideIcons::DEBUG_BREAKPOINT) }) .style(move |s| { let config = config.get(); let size = config.ui.icon_size() as f32 + 2.0; let color = if active { - LapceColor::DEBUG_BREAKPOINT + UmideColor::DEBUG_BREAKPOINT } else { - LapceColor::EDITOR_DIM + UmideColor::EDITOR_DIM }; let color = config.color(color); s.size(size, size).color(color) @@ -1581,7 +1581,7 @@ fn editor_gutter_breakpoints( .style(move |s| { s.absolute() .size_pct(100.0, 100.0) - .background(config.get().color(LapceColor::EDITOR_BACKGROUND)) + .background(config.get().color(UmideColor::EDITOR_BACKGROUND)) }) } @@ -1595,11 +1595,11 @@ fn editor_gutter_code_lens_view( ) -> impl View { let config = window_tab_data.common.config; let view = Container::new( - svg(move || config.get().ui_svg(LapceIcons::START)).style(move |s| { + svg(move || config.get().ui_svg(UmideIcons::START)).style(move |s| { let config = config.get(); let size = config.ui.icon_size() as f32; s.size(size, size) - .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + .color(config.color(UmideColor::LAPCE_ICON_ACTIVE)) }), ) .style(move |s| { @@ -1608,11 +1608,11 @@ fn editor_gutter_code_lens_view( .border_radius(6.0) .hover(|s| { s.cursor(CursorStyle::Pointer) - .background(config.color(LapceColor::PANEL_HOVERED_BACKGROUND)) + .background(config.color(UmideColor::PANEL_HOVERED_BACKGROUND)) }) .active(|s| { s.background( - config.color(LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND), + config.color(UmideColor::PANEL_HOVERED_ACTIVE_BACKGROUND), ) }) }) @@ -1648,9 +1648,9 @@ fn editor_gutter_folding_view( let view = Container::new( svg(move || { let icon_str = match folding_display_item { - FoldingDisplayItem::UnfoldStart(_) => LapceIcons::FOLD_DOWN, - FoldingDisplayItem::Folded(_) => LapceIcons::FOLD, - FoldingDisplayItem::UnfoldEnd(_) => LapceIcons::FOLD_UP, + FoldingDisplayItem::UnfoldStart(_) => UmideIcons::FOLD_DOWN, + FoldingDisplayItem::Folded(_) => UmideIcons::FOLD, + FoldingDisplayItem::UnfoldEnd(_) => UmideIcons::FOLD_UP, }; config.get().ui_svg(icon_str) }) @@ -1658,7 +1658,7 @@ fn editor_gutter_folding_view( let config = config.get(); let size = config.ui.icon_size() as f32; s.size(size, size) - .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + .color(config.color(UmideColor::LAPCE_ICON_ACTIVE)) }), ) .style(move |s| { @@ -1667,11 +1667,11 @@ fn editor_gutter_folding_view( .border_radius(6.0) .hover(|s| { s.cursor(CursorStyle::Pointer) - .background(config.color(LapceColor::PANEL_HOVERED_BACKGROUND)) + .background(config.color(UmideColor::PANEL_HOVERED_BACKGROUND)) }) .active(|s| { s.background( - config.color(LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND), + config.color(UmideColor::PANEL_HOVERED_ACTIVE_BACKGROUND), ) }) }); @@ -1816,12 +1816,12 @@ fn editor_gutter_code_actions( Container::new( Container::new( - svg(move || config.get().ui_svg(LapceIcons::LIGHTBULB)).style( + svg(move || config.get().ui_svg(UmideIcons::LIGHTBULB)).style( move |s| { let config = config.get(); let size = config.ui.icon_size() as f32; s.size(size, size) - .color(config.color(LapceColor::LAPCE_WARN)) + .color(config.color(UmideColor::LAPCE_WARN)) }, ), ) @@ -1834,12 +1834,12 @@ fn editor_gutter_code_actions( .border_radius(6.0) .hover(|s| { s.cursor(CursorStyle::Pointer).background( - config.color(LapceColor::PANEL_HOVERED_BACKGROUND), + config.color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }) .active(|s| { s.background( - config.color(LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND), + config.color(UmideColor::PANEL_HOVERED_ACTIVE_BACKGROUND), ) }) }), @@ -1933,9 +1933,9 @@ fn editor_gutter( } fn editor_breadcrumbs( - workspace: Arc, + workspace: Arc, e_data: EditorData, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { let doc = e_data.doc_signal(); let doc_path = Memo::new(move |_| { @@ -1983,7 +1983,7 @@ fn editor_breadcrumbs( svg(move || { config .get() - .ui_svg(LapceIcons::BREADCRUMB_SEPARATOR) + .ui_svg(UmideIcons::BREADCRUMB_SEPARATOR) }) .style(move |s| { let config = config.get(); @@ -1992,7 +1992,7 @@ fn editor_breadcrumbs( .size(size, size) .color( config.color( - LapceColor::LAPCE_ICON_ACTIVE, + UmideColor::LAPCE_ICON_ACTIVE, ), ) }), @@ -2032,7 +2032,7 @@ fn editor_breadcrumbs( s.absolute() .size_pct(100.0, 100.0) .border_bottom(1.0) - .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + .border_color(config.get().color(UmideColor::LAPCE_BORDER)) .items_center() }), ) @@ -2224,7 +2224,7 @@ fn search_editor_view( }) .style(|s| s.width_pct(100.0)), clickable_icon( - || LapceIcons::SEARCH_CASE_SENSITIVE, + || UmideIcons::SEARCH_CASE_SENSITIVE, move || { let new = match case_matching.get_untracked() { CaseMatching::Exact => CaseMatching::CaseInsensitive, @@ -2239,7 +2239,7 @@ fn search_editor_view( ) .style(|s| s.padding_vert(4.0)), clickable_icon( - || LapceIcons::SEARCH_WHOLE_WORD, + || UmideIcons::SEARCH_WHOLE_WORD, move || { whole_word.update(|whole_word| { *whole_word = !*whole_word; @@ -2252,7 +2252,7 @@ fn search_editor_view( ) .style(|s| s.padding_left(6.0)), clickable_icon( - || LapceIcons::SEARCH_REGEX, + || UmideIcons::SEARCH_REGEX, move || { is_regex.update(|is_regex| { *is_regex = !*is_regex; @@ -2271,8 +2271,8 @@ fn search_editor_view( .items_center() .border(1.0) .border_radius(6.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) - .background(config.color(LapceColor::EDITOR_BACKGROUND)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) + .background(config.color(UmideColor::EDITOR_BACKGROUND)) }) } @@ -2313,8 +2313,8 @@ fn replace_editor_view( .items_center() .border(1.0) .border_radius(6.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) - .background(config.color(LapceColor::EDITOR_BACKGROUND)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) + .background(config.color(UmideColor::EDITOR_BACKGROUND)) }) } @@ -2358,9 +2358,9 @@ fn find_view( clickable_icon( move || { if replace_active.get() { - LapceIcons::ITEM_OPENED + UmideIcons::ITEM_OPENED } else { - LapceIcons::ITEM_CLOSED + UmideIcons::ITEM_CLOSED } }, move || { @@ -2388,7 +2388,7 @@ fn find_view( }) .style(|s| s.margin_left(6.0).min_width(70.0)), clickable_icon( - || LapceIcons::SEARCH_BACKWARD, + || UmideIcons::SEARCH_BACKWARD, move || { editor.get_untracked().search_backward(Modifiers::empty()); }, @@ -2399,7 +2399,7 @@ fn find_view( ) .style(|s| s.padding_left(6.0)), clickable_icon( - || LapceIcons::SEARCH_FORWARD, + || UmideIcons::SEARCH_FORWARD, move || { editor.get_untracked().search_forward(Modifiers::empty()); }, @@ -2410,7 +2410,7 @@ fn find_view( ) .style(|s| s.padding_left(6.0)), clickable_icon( - || LapceIcons::CLOSE, + || UmideIcons::CLOSE, move || { editor.get_untracked().clear_search(); }, @@ -2436,7 +2436,7 @@ fn find_view( find_focus, ), clickable_icon( - || LapceIcons::SEARCH_REPLACE, + || UmideIcons::SEARCH_REPLACE, move || { let text = replace_doc .get_untracked() @@ -2451,7 +2451,7 @@ fn find_view( ) .style(|s| s.padding_left(6.0)), clickable_icon( - || LapceIcons::SEARCH_REPLACE_ALL, + || UmideIcons::SEARCH_REPLACE_ALL, move || { let text = replace_doc .get_untracked() @@ -2475,10 +2475,10 @@ fn find_view( .style(move |s| { let config = config.get(); s.margin_right(50.0) - .background(config.color(LapceColor::PANEL_BACKGROUND)) + .background(config.color(UmideColor::PANEL_BACKGROUND)) .border_radius(6.0) .border(1.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) .padding_vert(4.0) .cursor(CursorStyle::Default) .flex_col() @@ -2518,7 +2518,7 @@ fn find_view( /// Iterator over (len, color, modified) for each change in the diff fn changes_color_iter<'a>( changes: &'a im::Vector, - config: &'a LapceConfig, + config: &'a UmideConfig, ) -> impl Iterator, bool)> + 'a { let mut last_change = None; changes.iter().map(move |change| { @@ -2530,16 +2530,16 @@ fn changes_color_iter<'a>( let mut modified = false; let color = match change { DiffLines::Left(_range) => { - Some(config.color(LapceColor::SOURCE_CONTROL_REMOVED)) + Some(config.color(UmideColor::SOURCE_CONTROL_REMOVED)) } DiffLines::Right(_range) => { if let Some(DiffLines::Left(_)) = last_change.as_ref() { modified = true; } if modified { - Some(config.color(LapceColor::SOURCE_CONTROL_MODIFIED)) + Some(config.color(UmideColor::SOURCE_CONTROL_MODIFIED)) } else { - Some(config.color(LapceColor::SOURCE_CONTROL_ADDED)) + Some(config.color(UmideColor::SOURCE_CONTROL_ADDED)) } } _ => None, @@ -2556,7 +2556,7 @@ fn changes_color_iter<'a>( /// Get the position and coloring information for over the entire current [`ScreenLines`] /// Returns `(y, height_idx, removed, color)` pub fn changes_colors_screen( - config: &LapceConfig, + config: &UmideConfig, editor: &Editor, changes: im::Vector, ) -> Vec<(f64, usize, bool, Color)> { @@ -2610,7 +2610,7 @@ pub fn changes_colors_screen( /// Get the position and coloring information for over the entire current [`ScreenLines`] /// Returns `(y, height_idx, removed, color)` pub fn changes_colors_all( - config: &LapceConfig, + config: &UmideConfig, ed: &Editor, changes: im::Vector, ) -> Vec<(f64, usize, bool, Color)> { diff --git a/crates/umide/src/editor_tab.rs b/crates/umide/src/editor_tab.rs index b83cbd17..433edaca 100644 --- a/crates/umide/src/editor_tab.rs +++ b/crates/umide/src/editor_tab.rs @@ -18,7 +18,7 @@ use umide_rpc::plugin::VoltID; use serde::{Deserialize, Serialize}; use crate::{ - config::{LapceConfig, color::LapceColor, icon::LapceIcons}, + config::{UmideConfig, color::UmideColor, icon::UmideIcons}, doc::{Doc, DocContent}, editor::{ EditorData, EditorInfo, @@ -202,7 +202,7 @@ impl EditorTabChild { editors: Editors, diff_editors: RwSignal>, plugin: PluginData, - config: ReadSignal>, + config: ReadSignal>, ) -> Memo { match self.clone() { EditorTabChild::Editor(editor_id) => Memo::new(move |_| { @@ -243,8 +243,8 @@ impl EditorTabChild { ) } None => ( - config.ui_svg(LapceIcons::FILE), - Some(config.color(LapceColor::LAPCE_ICON_ACTIVE)), + config.ui_svg(UmideIcons::FILE), + Some(config.color(UmideColor::LAPCE_ICON_ACTIVE)), "local".to_string(), RwSignal::new(true), true, @@ -325,8 +325,8 @@ impl EditorTabChild { ) } [None, None] => ( - config.ui_svg(LapceIcons::FILE), - Some(config.color(LapceColor::LAPCE_ICON_ACTIVE)), + config.ui_svg(UmideIcons::FILE), + Some(config.color(UmideColor::LAPCE_ICON_ACTIVE)), "local".to_string(), true, ), @@ -343,8 +343,8 @@ impl EditorTabChild { EditorTabChild::Settings(_) => Memo::new(move |_| { let config = config.get(); EditorTabChildViewInfo { - icon: config.ui_svg(LapceIcons::SETTINGS), - color: Some(config.color(LapceColor::LAPCE_ICON_ACTIVE)), + icon: config.ui_svg(UmideIcons::SETTINGS), + color: Some(config.color(UmideColor::LAPCE_ICON_ACTIVE)), name: "Settings".to_string(), path: None, confirmed: None, @@ -354,8 +354,8 @@ impl EditorTabChild { EditorTabChild::ThemeColorSettings(_) => Memo::new(move |_| { let config = config.get(); EditorTabChildViewInfo { - icon: config.ui_svg(LapceIcons::SYMBOL_COLOR), - color: Some(config.color(LapceColor::LAPCE_ICON_ACTIVE)), + icon: config.ui_svg(UmideIcons::SYMBOL_COLOR), + color: Some(config.color(UmideColor::LAPCE_ICON_ACTIVE)), name: "Theme Colors".to_string(), path: None, confirmed: None, @@ -365,8 +365,8 @@ impl EditorTabChild { EditorTabChild::Keymap(_) => Memo::new(move |_| { let config = config.get(); EditorTabChildViewInfo { - icon: config.ui_svg(LapceIcons::KEYBOARD), - color: Some(config.color(LapceColor::LAPCE_ICON_ACTIVE)), + icon: config.ui_svg(UmideIcons::KEYBOARD), + color: Some(config.color(UmideColor::LAPCE_ICON_ACTIVE)), name: "Keyboard Shortcuts".to_string(), path: None, confirmed: None, @@ -389,8 +389,8 @@ impl EditorTabChild { }) .unwrap_or_else(|| id.name.clone()); EditorTabChildViewInfo { - icon: config.ui_svg(LapceIcons::EXTENSIONS), - color: Some(config.color(LapceColor::LAPCE_ICON_ACTIVE)), + icon: config.ui_svg(UmideIcons::EXTENSIONS), + color: Some(config.color(UmideColor::LAPCE_ICON_ACTIVE)), name: display_name, path: None, confirmed: None, diff --git a/crates/umide/src/file_explorer/data.rs b/crates/umide/src/file_explorer/data.rs index 14c66e26..0872ebd6 100644 --- a/crates/umide/src/file_explorer/data.rs +++ b/crates/umide/src/file_explorer/data.rs @@ -25,8 +25,8 @@ use umide_rpc::{ }; use crate::{ - command::{CommandExecuted, CommandKind, InternalCommand, LapceCommand}, - config::LapceConfig, + command::{CommandExecuted, CommandKind, InternalCommand, UmideCommand}, + config::UmideConfig, editor::EditorData, keypress::{KeyPressFocus, condition::Condition}, main_split::Editors, @@ -65,7 +65,7 @@ impl KeyPressFocus for FileExplorerData { fn run_command( &self, - command: &LapceCommand, + command: &UmideCommand, count: Option, mods: Modifiers, ) -> CommandExecuted { @@ -386,7 +386,7 @@ impl FileExplorerData { self.naming.set(Naming::None); } - pub fn click(&self, path: &Path, config: ReadSignal>) { + pub fn click(&self, path: &Path, config: ReadSignal>) { if self.is_dir(path) { self.toggle_expand(path); } else if !config.get_untracked().core.file_explorer_double_click { @@ -454,7 +454,7 @@ impl FileExplorerData { pub fn double_click( &self, path: &Path, - config: ReadSignal>, + config: ReadSignal>, ) -> EventPropagation { if self.is_dir(path) { EventPropagation::Continue diff --git a/crates/umide/src/file_explorer/view.rs b/crates/umide/src/file_explorer/view.rs index 4b498116..e18c3e47 100644 --- a/crates/umide/src/file_explorer/view.rs +++ b/crates/umide/src/file_explorer/view.rs @@ -19,7 +19,7 @@ use super::{data::FileExplorerData, node::FileNodeVirtualList}; use crate::{ app::clickable_icon, command::InternalCommand, - config::{LapceConfig, color::LapceColor, icon::LapceIcons}, + config::{UmideConfig, color::UmideColor, icon::UmideIcons}, editor_tab::{EditorTabChild, EditorTabData}, panel::{ data::PanelSection, kind::PanelKind, position::PanelPosition, @@ -117,7 +117,7 @@ fn initialize_naming_editor( } fn file_node_text_color( - config: ReadSignal>, + config: ReadSignal>, node: FileNodeViewData, source_control: SourceControlData, ) -> Color { @@ -138,11 +138,11 @@ fn file_node_text_color( let color = match diff { Some(FileDiffKind::Modified | FileDiffKind::Renamed) => { - LapceColor::SOURCE_CONTROL_MODIFIED + UmideColor::SOURCE_CONTROL_MODIFIED } - Some(FileDiffKind::Added) => LapceColor::SOURCE_CONTROL_ADDED, - Some(FileDiffKind::Deleted) => LapceColor::SOURCE_CONTROL_REMOVED, - None => LapceColor::PANEL_FOREGROUND, + Some(FileDiffKind::Added) => UmideColor::SOURCE_CONTROL_ADDED, + Some(FileDiffKind::Deleted) => UmideColor::SOURCE_CONTROL_REMOVED, + None => UmideColor::PANEL_FOREGROUND, }; config.get().color(color) @@ -182,7 +182,7 @@ fn file_node_text_view( .color( config .get() - .color(LapceColor::PANEL_FOREGROUND_DIM), + .color(UmideColor::PANEL_FOREGROUND_DIM), ) .selectable(false) }, @@ -256,7 +256,7 @@ fn file_node_input_view(data: FileExplorerData, err: Option) -> Containe .margin(0.0) .border_radius(6.0) .border(1.0) - .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + .border_color(config.get().color(UmideColor::LAPCE_BORDER)) }); let text_input_id = text_input_view.id(); @@ -270,9 +270,9 @@ fn file_node_input_view(data: FileExplorerData, err: Option) -> Containe let config = config.get(); let editor_background_color = - config.color(LapceColor::PANEL_CURRENT_BACKGROUND); + config.color(UmideColor::PANEL_CURRENT_BACKGROUND); let error_background_color = - config.color(LapceColor::ERROR_LENS_ERROR_BACKGROUND); + config.color(UmideColor::ERROR_LENS_ERROR_BACKGROUND); let background_color = blend_colors( editor_background_color, @@ -282,7 +282,7 @@ fn file_node_input_view(data: FileExplorerData, err: Option) -> Containe s.position(Position::Absolute) .inset_top(ui_line_height.get()) .width_full() - .color(config.color(LapceColor::ERROR_LENS_ERROR_FOREGROUND)) + .color(config.color(UmideColor::ERROR_LENS_ERROR_FOREGROUND)) .background(background_color) .z_index(100) }), @@ -327,8 +327,8 @@ fn file_explorer_view( svg(move || { let config = config.get(); let svg_str = match open { - true => LapceIcons::ITEM_OPENED, - false => LapceIcons::ITEM_CLOSED, + true => UmideIcons::ITEM_OPENED, + false => UmideIcons::ITEM_CLOSED, }; config.ui_svg(svg_str) }) @@ -337,7 +337,7 @@ fn file_explorer_view( let size = config.ui.icon_size() as f32; let color = if is_dir { - config.color(LapceColor::LAPCE_ICON_ACTIVE) + config.color(UmideColor::LAPCE_ICON_ACTIVE) } else { Color::TRANSPARENT }; @@ -354,14 +354,14 @@ fn file_explorer_view( let config = config.get(); if is_dir { let svg_str = match open { - true => LapceIcons::DIRECTORY_OPENED, - false => LapceIcons::DIRECTORY_CLOSED, + true => UmideIcons::DIRECTORY_OPENED, + false => UmideIcons::DIRECTORY_CLOSED, }; config.ui_svg(svg_str) } else if let Some(path) = kind.path() { config.file_svg(path).0 } else { - config.ui_svg(LapceIcons::FILE) + config.ui_svg(UmideIcons::FILE) } }) .style(move |s| { @@ -373,7 +373,7 @@ fn file_explorer_view( .margin_horiz(6.0) .apply_if(is_dir, |s| { s.color( - config.color(LapceColor::LAPCE_ICON_ACTIVE), + config.color(UmideColor::LAPCE_ICON_ACTIVE), ) }) .apply_if(!is_dir, |s| { @@ -399,7 +399,7 @@ fn file_explorer_view( s.background( config .get() - .color(LapceColor::PANEL_HOVERED_BACKGROUND), + .color(UmideColor::PANEL_HOVERED_BACKGROUND), ) .cursor(CursorStyle::Pointer) }) @@ -408,7 +408,7 @@ fn file_explorer_view( |x| { x.background( config.get().color( - LapceColor::PANEL_CURRENT_BACKGROUND, + UmideColor::PANEL_CURRENT_BACKGROUND, ), ) }, @@ -507,9 +507,9 @@ fn open_editors_view(window_tab_data: Rc) -> impl View { clickable_icon( move || { if hovered.get() || info.with(|info| info.is_pristine) { - LapceIcons::CLOSE + UmideIcons::CLOSE } else { - LapceIcons::UNSAVED + UmideIcons::UNSAVED } }, move || { @@ -562,12 +562,12 @@ fn open_editors_view(window_tab_data: Rc) -> impl View { == child_index.get(), |s| { s.background( - config.color(LapceColor::PANEL_CURRENT_BACKGROUND), + config.color(UmideColor::PANEL_CURRENT_BACKGROUND), ) }, ) .hover(|s| { - s.background(config.color(LapceColor::PANEL_HOVERED_BACKGROUND)) + s.background(config.color(UmideColor::PANEL_HOVERED_BACKGROUND)) }) }) .on_event_cont(EventListener::PointerDown, move |_| { diff --git a/crates/umide/src/global_search.rs b/crates/umide/src/global_search.rs index 69646f38..66806177 100644 --- a/crates/umide/src/global_search.rs +++ b/crates/umide/src/global_search.rs @@ -57,7 +57,7 @@ impl KeyPressFocus for GlobalSearchData { fn run_command( &self, - command: &crate::command::LapceCommand, + command: &crate::command::UmideCommand, count: Option, mods: Modifiers, ) -> CommandExecuted { diff --git a/crates/umide/src/inline_completion.rs b/crates/umide/src/inline_completion.rs index 65277e2f..2c0d5f98 100644 --- a/crates/umide/src/inline_completion.rs +++ b/crates/umide/src/inline_completion.rs @@ -9,7 +9,7 @@ use umide_core::{ }; use lsp_types::InsertTextFormat; -use crate::{config::LapceConfig, doc::Doc, editor::EditorData, snippet::Snippet}; +use crate::{config::UmideConfig, doc::Doc, editor::EditorData, snippet::Snippet}; // TODO: we could integrate completion lens with this, so it is considered at the same time @@ -189,7 +189,7 @@ impl InlineCompletionData { pub fn update_inline_completion( &self, - config: &LapceConfig, + config: &UmideConfig, doc: &Doc, cursor_offset: usize, ) { diff --git a/crates/umide/src/keymap.rs b/crates/umide/src/keymap.rs index 94267801..f364c48c 100644 --- a/crates/umide/src/keymap.rs +++ b/crates/umide/src/keymap.rs @@ -10,8 +10,8 @@ use floem::{ use umide_core::mode::Modes; use crate::{ - command::LapceCommand, - config::{LapceConfig, color::LapceColor}, + command::UmideCommand, + config::{UmideConfig, color::UmideColor}, keypress::{ KeyPressData, keymap::{KeyMap, KeyMapPress}, @@ -23,14 +23,14 @@ use crate::{ #[derive(Clone)] pub struct KeymapPicker { - cmd: RwSignal>, + cmd: RwSignal>, keymap: RwSignal>, keys: RwSignal>, } -struct KeymapList(im::Vector<(usize, (LapceCommand, Option))>); +struct KeymapList(im::Vector<(usize, (UmideCommand, Option))>); -impl VirtualVector<(usize, (LapceCommand, Option))> for KeymapList { +impl VirtualVector<(usize, (UmideCommand, Option))> for KeymapList { fn total_len(&self) -> usize { self.0.len() } @@ -38,7 +38,7 @@ impl VirtualVector<(usize, (LapceCommand, Option))> for KeymapList { fn slice( &mut self, range: Range, - ) -> impl Iterator))> { + ) -> impl Iterator))> { self.0 .iter() .skip(range.start) @@ -100,7 +100,7 @@ pub fn keymap_view(editors: Editors, common: Rc) -> impl View { None } }) - .collect::)>>(); + .collect::)>>(); items.extend(keypress.commands_without_keymap.iter().filter_map(|cmd| { let match_pattern = cmd.kind.str().replace('_', " ").contains(&pattern) || cmd @@ -116,12 +116,12 @@ pub fn keymap_view(editors: Editors, common: Rc) -> impl View { let items = items .into_iter() .enumerate() - .collect::))>>(); + .collect::))>>(); KeymapList(items) }; let view_fn = - move |(i, (cmd, keymap)): (usize, (LapceCommand, Option))| { + move |(i, (cmd, keymap)): (usize, (UmideCommand, Option))| { let local_keymap = keymap.clone(); let local_cmd = cmd.clone(); Stack::new(( @@ -147,7 +147,7 @@ pub fn keymap_view(editors: Editors, common: Rc) -> impl View { .flex_basis(0.0) .flex_grow(1.0) .border_right(1.0) - .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + .border_color(config.get().color(UmideColor::LAPCE_BORDER)) }), { let keymap = keymap.clone(); @@ -174,7 +174,7 @@ pub fn keymap_view(editors: Editors, common: Rc) -> impl View { .border(1.0) .border_radius(3.0) .border_color( - config.get().color(LapceColor::LAPCE_BORDER), + config.get().color(UmideColor::LAPCE_BORDER), ) }) }, @@ -186,7 +186,7 @@ pub fn keymap_view(editors: Editors, common: Rc) -> impl View { .height_pct(100.0) .border_right(1.0) .border_color( - config.get().color(LapceColor::LAPCE_BORDER), + config.get().color(UmideColor::LAPCE_BORDER), ) }) }, @@ -223,7 +223,7 @@ pub fn keymap_view(editors: Editors, common: Rc) -> impl View { .border(1.0) .border_radius(3.0) .border_color( - config.get().color(LapceColor::LAPCE_BORDER), + config.get().color(UmideColor::LAPCE_BORDER), ) }) }, @@ -235,7 +235,7 @@ pub fn keymap_view(editors: Editors, common: Rc) -> impl View { .height_pct(100.0) .border_right(1.0) .border_color( - config.get().color(LapceColor::LAPCE_BORDER), + config.get().color(UmideColor::LAPCE_BORDER), ) .apply_if(!modal.get(), |s| s.hide()) }) @@ -286,10 +286,10 @@ pub fn keymap_view(editors: Editors, common: Rc) -> impl View { .height(ui_line_height() as f32) .width_pct(100.0) .apply_if(i % 2 > 0, |s| { - s.background(config.color(LapceColor::EDITOR_CURRENT_LINE)) + s.background(config.color(UmideColor::EDITOR_CURRENT_LINE)) }) .border_bottom(1.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) }) }; @@ -302,7 +302,7 @@ pub fn keymap_view(editors: Editors, common: Rc) -> impl View { s.width_pct(100.0) .border_radius(6.0) .border(1.0) - .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + .border_color(config.get().color(UmideColor::LAPCE_BORDER)) .focusable(true) }), ) @@ -318,7 +318,7 @@ pub fn keymap_view(editors: Editors, common: Rc) -> impl View { .flex_basis(0.0) .flex_grow(1.0) .border_right(1.0) - .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + .border_color(config.get().color(UmideColor::LAPCE_BORDER)) }), Label::new("Key Binding").style(move |s| { s.width(200.0) @@ -326,7 +326,7 @@ pub fn keymap_view(editors: Editors, common: Rc) -> impl View { .padding_horiz(10.0) .height_pct(100.0) .border_right(1.0) - .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + .border_color(config.get().color(UmideColor::LAPCE_BORDER)) }), Label::new("Modes").style(move |s| { s.width(200.0) @@ -334,7 +334,7 @@ pub fn keymap_view(editors: Editors, common: Rc) -> impl View { .padding_horiz(10.0) .height_pct(100.0) .border_right(1.0) - .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + .border_color(config.get().color(UmideColor::LAPCE_BORDER)) .apply_if(!modal.get(), |s| s.hide()) }), Container::new(Label::new("When").style(move |s| { @@ -355,8 +355,8 @@ pub fn keymap_view(editors: Editors, common: Rc) -> impl View { .width_pct(100.0) .border_top(1.0) .border_bottom(1.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) - .background(config.color(LapceColor::EDITOR_CURRENT_LINE)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) + .background(config.color(UmideColor::EDITOR_CURRENT_LINE)) }), Container::new( Scroll::new( @@ -364,7 +364,7 @@ pub fn keymap_view(editors: Editors, common: Rc) -> impl View { items, |(i, (cmd, keymap)): &( usize, - (LapceCommand, Option), + (UmideCommand, Option), )| { (*i, cmd.kind.str(), keymap.clone()) }, view_fn, ) @@ -389,7 +389,7 @@ pub fn keymap_view(editors: Editors, common: Rc) -> impl View { fn keyboard_picker_view( picker: KeymapPicker, ui_line_height: Memo, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { let picker_cmd = picker.cmd; let view = Container::new( @@ -427,7 +427,7 @@ fn keyboard_picker_view( .border(1.0) .border_radius(6.0) .border_color( - config.get().color(LapceColor::LAPCE_BORDER), + config.get().color(UmideColor::LAPCE_BORDER), ) }) }, @@ -441,8 +441,8 @@ fn keyboard_picker_view( .height((ui_line_height.get() as f32) * 1.2) .border(1.0) .border_radius(6.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) - .background(config.color(LapceColor::EDITOR_BACKGROUND)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) + .background(config.color(UmideColor::EDITOR_BACKGROUND)) }), Stack::new(( Label::new("Save") @@ -453,16 +453,16 @@ fn keyboard_picker_view( .padding_vert(8.0) .border(1.0) .border_radius(6.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) .hover(|s| { s.cursor(CursorStyle::Pointer).background( config - .color(LapceColor::PANEL_HOVERED_BACKGROUND), + .color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }) .active(|s| { s.background(config.color( - LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND, + UmideColor::PANEL_HOVERED_ACTIVE_BACKGROUND, )) }) }) @@ -489,16 +489,16 @@ fn keyboard_picker_view( .padding_vert(8.0) .border(1.0) .border_radius(6.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) .hover(|s| { s.cursor(CursorStyle::Pointer).background( config - .color(LapceColor::PANEL_HOVERED_BACKGROUND), + .color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }) .active(|s| { s.background(config.color( - LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND, + UmideColor::PANEL_HOVERED_ACTIVE_BACKGROUND, )) }) }) @@ -512,7 +512,7 @@ fn keyboard_picker_view( .justify_center() .width_pct(100.0) .margin_top(20.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) }), )) .on_event_stop(EventListener::PointerDown, |_| {}) @@ -524,8 +524,8 @@ fn keyboard_picker_view( .width(400.0) .border(1.0) .border_radius(6.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) - .background(config.color(LapceColor::PANEL_BACKGROUND)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) + .background(config.color(UmideColor::PANEL_BACKGROUND)) }), ) diff --git a/crates/umide/src/keypress.rs b/crates/umide/src/keypress.rs index dd6747e7..15c9484c 100644 --- a/crates/umide/src/keypress.rs +++ b/crates/umide/src/keypress.rs @@ -23,8 +23,8 @@ use self::{ loader::KeyMapLoader, }; use crate::{ - command::{CommandExecuted, CommandKind, LapceCommand, lapce_internal_commands}, - config::LapceConfig, + command::{CommandExecuted, CommandKind, UmideCommand, lapce_internal_commands}, + config::UmideConfig, keypress::{ condition::{CheckCondition, Condition}, keymap::KeymapMatch, @@ -46,7 +46,7 @@ pub trait KeyPressFocus: std::fmt::Debug { fn run_command( &self, - command: &LapceCommand, + command: &UmideCommand, count: Option, mods: Modifiers, ) -> CommandExecuted; @@ -72,7 +72,7 @@ impl KeyPressFocus for () { fn run_command( &self, - _command: &LapceCommand, + _command: &UmideCommand, _count: Option, _mods: Modifiers, ) -> CommandExecuted { @@ -100,7 +100,7 @@ impl KeyPressFocus for Box { fn run_command( &self, - command: &LapceCommand, + command: &UmideCommand, count: Option, mods: Modifiers, ) -> CommandExecuted { @@ -148,15 +148,15 @@ pub struct KeyPressHandle { pub struct KeyPressData { count: RwSignal>, pending_keypress: RwSignal<(Vec, Option)>, - pub commands: Rc>, + pub commands: Rc>, pub keymaps: Rc, Vec>>, pub command_keymaps: Rc>>, pub commands_with_keymap: Rc>, - pub commands_without_keymap: Rc>, + pub commands_without_keymap: Rc>, } impl KeyPressData { - pub fn new(cx: Scope, config: &LapceConfig) -> Self { + pub fn new(cx: Scope, config: &UmideConfig) -> Self { let (keymaps, command_keymaps) = Self::get_keymaps(config).unwrap_or((IndexMap::new(), IndexMap::new())); let mut keypress = Self { @@ -172,7 +172,7 @@ impl KeyPressData { keypress } - pub fn update_keymaps(&mut self, config: &LapceConfig) { + pub fn update_keymaps(&mut self, config: &UmideConfig) { if let Ok((new_keymaps, new_command_keymaps)) = Self::get_keymaps(config) { self.keymaps = Rc::new(new_keymaps); self.command_keymaps = Rc::new(new_command_keymaps); @@ -421,7 +421,7 @@ impl KeyPressData { #[cfg(not(target_os = "macos"))] { mods.set(Modifiers::SHIFT, false); - mods.set(Modifiers::ALTGR, false); + mods.set(Modifiers::ALT, false); } if mods.is_empty() { if let KeyInput::Keyboard { logical: Key::Character(c), .. } = &keypress.key { @@ -551,7 +551,7 @@ impl KeyPressData { #[allow(clippy::type_complexity)] fn get_keymaps( - config: &LapceConfig, + config: &UmideConfig, ) -> Result<( IndexMap, Vec>, IndexMap>, @@ -586,7 +586,7 @@ impl KeyPressData { } pub fn file() -> Option { - LapceConfig::keymaps_file() + UmideConfig::keymaps_file() } fn get_file_array() -> Option { diff --git a/crates/umide/src/keypress/condition.rs b/crates/umide/src/keypress/condition.rs index 4a3f9729..2ecd57bd 100644 --- a/crates/umide/src/keypress/condition.rs +++ b/crates/umide/src/keypress/condition.rs @@ -97,7 +97,7 @@ mod test { fn run_command( &self, - _command: &crate::command::LapceCommand, + _command: &crate::command::UmideCommand, _count: Option, _mods: Modifiers, ) -> crate::command::CommandExecuted { diff --git a/crates/umide/src/markdown.rs b/crates/umide/src/markdown.rs index ecef9279..547c4bcd 100644 --- a/crates/umide/src/markdown.rs +++ b/crates/umide/src/markdown.rs @@ -1,13 +1,13 @@ use floem::text::{ Attrs, AttrsList, FamilyOwned, LineHeightValue, Style, TextLayout, Weight, }; -use umide_core::{language::LapceLanguage, syntax::Syntax}; +use umide_core::{language::UmideLanguage, syntax::Syntax}; use lapce_xi_rope::Rope; use lsp_types::MarkedString; use pulldown_cmark::{CodeBlockKind, CowStr, Event, Options, Parser, Tag}; use smallvec::SmallVec; -use crate::config::{LapceConfig, color::LapceColor}; +use crate::config::{UmideConfig, color::UmideColor}; #[derive(Clone)] pub enum MarkdownContent { @@ -19,7 +19,7 @@ pub enum MarkdownContent { pub fn parse_markdown( text: &str, line_height: f64, - config: &LapceConfig, + config: &UmideConfig, ) -> Vec { let mut res = Vec::new(); @@ -28,7 +28,7 @@ pub fn parse_markdown( FamilyOwned::parse_list(&config.editor.font_family).collect(); let default_attrs = Attrs::new() - .color(config.color(LapceColor::EDITOR_FOREGROUND)) + .color(config.color(UmideColor::EDITOR_FOREGROUND)) .font_size(config.ui.font_size() as f32) .line_height(LineHeightValue::Normal(line_height as f32)); let mut attr_list = AttrsList::new(default_attrs.clone()); @@ -165,7 +165,7 @@ pub fn parse_markdown( default_attrs .clone() .family(&code_font_family) - .color(config.color(LapceColor::MARKDOWN_BLOCKQUOTE)), + .color(config.color(UmideColor::MARKDOWN_BLOCKQUOTE)), ); current_text.push_str(&text); pos += text.len(); @@ -203,7 +203,7 @@ fn attribute_for_tag<'a>( default_attrs: Attrs<'a>, tag: &Tag, code_font_family: &'a [FamilyOwned], - config: &LapceConfig, + config: &UmideConfig, ) -> Option> { use pulldown_cmark::HeadingLevel; match tag { @@ -233,7 +233,7 @@ fn attribute_for_tag<'a>( Tag::BlockQuote(_block_quote) => Some( default_attrs .style(Style::Italic) - .color(config.color(LapceColor::MARKDOWN_BLOCKQUOTE)), + .color(config.color(UmideColor::MARKDOWN_BLOCKQUOTE)), ), Tag::CodeBlock(_) => Some(default_attrs.family(code_font_family)), Tag::Emphasis => Some(default_attrs.style(Style::Italic)), @@ -246,7 +246,7 @@ fn attribute_for_tag<'a>( id: _, } => { // TODO: Link support - Some(default_attrs.color(config.color(LapceColor::EDITOR_LINK))) + Some(default_attrs.color(config.color(UmideColor::EDITOR_LINK))) } // All other tags are currently ignored _ => None, @@ -267,19 +267,19 @@ fn should_skip_text_in_tag(tag: &Tag) -> bool { matches!(tag, Tag::Image { .. }) } -fn md_language_to_lapce_language(lang: &str) -> Option { +fn md_language_to_lapce_language(lang: &str) -> Option { // TODO: There are many other names commonly used that should be supported - LapceLanguage::from_name(lang) + UmideLanguage::from_name(lang) } /// Highlight the text in a richtext builder like it was a markdown codeblock pub fn highlight_as_code( attr_list: &mut AttrsList, default_attrs: Attrs, - language: Option, + language: Option, text: &str, start_offset: usize, - config: &LapceConfig, + config: &UmideConfig, ) { let syntax = language.map(Syntax::from_language); @@ -308,7 +308,7 @@ pub fn highlight_as_code( pub fn from_marked_string( text: MarkedString, - config: &LapceConfig, + config: &UmideConfig, ) -> Vec { match text { MarkedString::String(text) => parse_markdown(&text, 1.8, config), @@ -328,7 +328,7 @@ pub fn from_marked_string( pub fn from_plaintext( text: &str, line_height: f64, - config: &LapceConfig, + config: &UmideConfig, ) -> Vec { let mut text_layout = TextLayout::new(); text_layout.set_text( diff --git a/crates/umide/src/palette.rs b/crates/umide/src/palette.rs index 8d5329b3..e0f85134 100644 --- a/crates/umide/src/palette.rs +++ b/crates/umide/src/palette.rs @@ -22,7 +22,7 @@ use floem::{ use im::Vector; use itertools::Itertools; use umide_core::{ - buffer::rope_text::RopeText, command::FocusCommand, cursor::CursorAffinity, language::LapceLanguage, line_ending::LineEnding, mode::Mode, movement::Movement, selection::Selection, syntax::Syntax + buffer::rope_text::RopeText, command::FocusCommand, cursor::CursorAffinity, language::UmideLanguage, line_ending::LineEnding, mode::Mode, movement::Movement, selection::Selection, syntax::Syntax }; use umide_rpc::proxy::ProxyResponse; use lapce_xi_rope::Rope; @@ -37,9 +37,9 @@ use self::{ }; use crate::{ command::{ - CommandExecuted, CommandKind, InternalCommand, LapceCommand, WindowCommand, + CommandExecuted, CommandKind, InternalCommand, UmideCommand, WindowCommand, }, - db::LapceDb, + db::UmideDb, debug::{RunDebugConfigs, RunDebugMode}, editor::{ EditorData, @@ -50,7 +50,7 @@ use crate::{ main_split::MainSplitData, source_control::SourceControlData, window_tab::{CommonData, Focus}, - workspace::{LapceWorkspace, LapceWorkspaceType, SshHost}, + workspace::{UmideWorkspace, UmideWorkspaceType, SshHost}, }; pub mod item; @@ -83,7 +83,7 @@ impl PaletteInput { pub struct PaletteData { run_id_counter: Arc, pub run_id: RwSignal, - pub workspace: Arc, + pub workspace: Arc, pub status: RwSignal, pub index: RwSignal, pub preselect_index: RwSignal>, @@ -115,7 +115,7 @@ impl std::fmt::Debug for PaletteData { impl PaletteData { pub fn new( cx: Scope, - workspace: Arc, + workspace: Arc, main_split: MainSplitData, keypress: ReadSignal, source_control: SourceControlData, @@ -597,7 +597,7 @@ impl PaletteData { /// Initialize the palette with all the available workspaces, local and remote. fn get_workspaces(&self) { - let db: Arc = Context::get().unwrap(); + let db: Arc = Context::get().unwrap(); let workspaces = db.recent_workspaces().unwrap_or_default(); let items = workspaces @@ -605,12 +605,12 @@ impl PaletteData { .filter_map(|w| { let text = w.path.as_ref()?.to_str()?.to_string(); let filter_text = match &w.kind { - LapceWorkspaceType::Local => text, - LapceWorkspaceType::RemoteSSH(remote) => { + UmideWorkspaceType::Local => text, + UmideWorkspaceType::RemoteSSH(remote) => { format!("[{remote}] {text}") } #[cfg(windows)] - LapceWorkspaceType::RemoteWSL(remote) => { + UmideWorkspaceType::RemoteWSL(remote) => { format!("[{remote}] {text}") } }; @@ -796,11 +796,11 @@ impl PaletteData { } fn get_ssh_hosts(&self) { - let db: Arc = Context::get().unwrap(); + let db: Arc = Context::get().unwrap(); let workspaces = db.recent_workspaces().unwrap_or_default(); let mut hosts = HashSet::new(); for workspace in workspaces.iter() { - if let LapceWorkspaceType::RemoteSSH(host) = &workspace.kind { + if let UmideWorkspaceType::RemoteSSH(host) = &workspace.kind { hosts.insert(host.clone()); } } @@ -849,7 +849,7 @@ impl PaletteData { vec![] }; - let db: Arc = use_context().unwrap(); + let db: Arc = Context::get().unwrap(); let workspaces = db.recent_workspaces().unwrap_or_default(); let mut hosts = HashSet::new(); for distro in distros { @@ -857,7 +857,7 @@ impl PaletteData { } for workspace in workspaces.iter() { - if let LapceWorkspaceType::RemoteWSL(host) = &workspace.kind { + if let UmideWorkspaceType::RemoteWSL(host) = &workspace.kind { hosts.insert(host.host.clone()); } } @@ -1005,7 +1005,7 @@ impl PaletteData { } fn get_languages(&self) { - let langs = LapceLanguage::languages(); + let langs = UmideLanguage::languages(); let items = langs .iter() .map(|lang| PaletteItem { @@ -1125,7 +1125,7 @@ impl PaletteData { if let Some(item) = items.get(index) { match &item.content { PaletteItemContent::PaletteHelp { cmd } => { - let cmd = LapceCommand { + let cmd = UmideCommand { kind: CommandKind::Workbench(cmd.clone()), data: None, }; @@ -1202,8 +1202,8 @@ impl PaletteData { PaletteItemContent::SshHost { host } => { self.common.window_common.window_command.send( WindowCommand::SetWorkspace { - workspace: LapceWorkspace { - kind: LapceWorkspaceType::RemoteSSH(host.clone()), + workspace: UmideWorkspace { + kind: UmideWorkspaceType::RemoteSSH(host.clone()), path: None, last_open: 0, }, @@ -1214,8 +1214,8 @@ impl PaletteData { PaletteItemContent::WslHost { host } => { self.common.window_common.window_command.send( WindowCommand::SetWorkspace { - workspace: LapceWorkspace { - kind: LapceWorkspaceType::RemoteWSL(host.clone()), + workspace: UmideWorkspace { + kind: UmideWorkspaceType::RemoteWSL(host.clone()), path: None, last_open: 0, }, @@ -1291,7 +1291,7 @@ impl PaletteData { if name.is_empty() || name.to_lowercase().eq("plain text") { doc.set_syntax(Syntax::plaintext()) } else { - let lang = match LapceLanguage::from_name(name) { + let lang = match UmideLanguage::from_name(name) { Some(v) => v, None => return, }; @@ -1313,9 +1313,9 @@ impl PaletteData { PaletteItemContent::SCMReference { name } => { self.common .lapce_command - .send(crate::command::LapceCommand { + .send(crate::command::UmideCommand { kind: CommandKind::Workbench( - crate::command::LapceWorkbenchCommand::CheckoutReference, + crate::command::UmideWorkbenchCommand::CheckoutReference, ), data: Some(serde_json::json!(name.to_owned())), }); @@ -1332,8 +1332,8 @@ impl PaletteData { let ssh = SshHost::from_string(&input); self.common.window_common.window_command.send( WindowCommand::SetWorkspace { - workspace: LapceWorkspace { - kind: LapceWorkspaceType::RemoteSSH(ssh), + workspace: UmideWorkspace { + kind: UmideWorkspaceType::RemoteSSH(ssh), path: None, last_open: 0, }, @@ -1671,7 +1671,7 @@ impl KeyPressFocus for PaletteData { fn run_command( &self, - command: &crate::command::LapceCommand, + command: &crate::command::UmideCommand, count: Option, mods: Modifiers, ) -> CommandExecuted { diff --git a/crates/umide/src/palette/item.rs b/crates/umide/src/palette/item.rs index 8fcfd9fe..0af7dbe7 100644 --- a/crates/umide/src/palette/item.rs +++ b/crates/umide/src/palette/item.rs @@ -5,10 +5,10 @@ use umide_rpc::dap_types::RunDebugConfig; use lsp_types::{Range, SymbolKind}; use crate::{ - command::{LapceCommand, LapceWorkbenchCommand}, + command::{UmideCommand, UmideWorkbenchCommand}, debug::RunDebugMode, editor::location::EditorLocation, - workspace::{LapceWorkspace, SshHost}, + workspace::{UmideWorkspace, SshHost}, }; #[derive(Clone, Debug, PartialEq)] @@ -22,7 +22,7 @@ pub struct PaletteItem { #[derive(Clone, Debug, PartialEq)] pub enum PaletteItemContent { PaletteHelp { - cmd: LapceWorkbenchCommand, + cmd: UmideWorkbenchCommand, }, File { path: PathBuf, @@ -33,10 +33,10 @@ pub enum PaletteItemContent { content: String, }, Command { - cmd: LapceCommand, + cmd: UmideCommand, }, Workspace { - workspace: LapceWorkspace, + workspace: UmideWorkspace, }, Reference { path: PathBuf, diff --git a/crates/umide/src/palette/kind.rs b/crates/umide/src/palette/kind.rs index 1a1b8941..f4fc05c3 100644 --- a/crates/umide/src/palette/kind.rs +++ b/crates/umide/src/palette/kind.rs @@ -1,6 +1,6 @@ use strum_macros::EnumIter; -use crate::command::LapceWorkbenchCommand; +use crate::command::UmideWorkbenchCommand; #[derive(Clone, Copy, Debug, PartialEq, Eq, EnumIter)] pub enum PaletteKind { @@ -68,41 +68,41 @@ impl PaletteKind { } } - /// Get the [`LapceWorkbenchCommand`] that opens this palette kind, if one exists. - pub fn command(self) -> Option { + /// Get the [`UmideWorkbenchCommand`] that opens this palette kind, if one exists. + pub fn command(self) -> Option { match self { - PaletteKind::PaletteHelp => Some(LapceWorkbenchCommand::PaletteHelp), - PaletteKind::Line => Some(LapceWorkbenchCommand::PaletteLine), + PaletteKind::PaletteHelp => Some(UmideWorkbenchCommand::PaletteHelp), + PaletteKind::Line => Some(UmideWorkbenchCommand::PaletteLine), PaletteKind::DocumentSymbol => { - Some(LapceWorkbenchCommand::PaletteSymbol) + Some(UmideWorkbenchCommand::PaletteSymbol) } PaletteKind::WorkspaceSymbol => { - Some(LapceWorkbenchCommand::PaletteWorkspaceSymbol) + Some(UmideWorkbenchCommand::PaletteWorkspaceSymbol) } - PaletteKind::Workspace => Some(LapceWorkbenchCommand::PaletteWorkspace), - PaletteKind::Command => Some(LapceWorkbenchCommand::PaletteCommand), - PaletteKind::File => Some(LapceWorkbenchCommand::Palette), + PaletteKind::Workspace => Some(UmideWorkbenchCommand::PaletteWorkspace), + PaletteKind::Command => Some(UmideWorkbenchCommand::PaletteCommand), + PaletteKind::File => Some(UmideWorkbenchCommand::Palette), PaletteKind::HelpAndFile => { - Some(LapceWorkbenchCommand::PaletteHelpAndFile) + Some(UmideWorkbenchCommand::PaletteHelpAndFile) } PaletteKind::Reference => None, // InternalCommand::PaletteReferences - PaletteKind::SshHost => Some(LapceWorkbenchCommand::ConnectSshHost), + PaletteKind::SshHost => Some(UmideWorkbenchCommand::ConnectSshHost), #[cfg(windows)] - PaletteKind::WslHost => Some(LapceWorkbenchCommand::ConnectWslHost), + PaletteKind::WslHost => Some(UmideWorkbenchCommand::ConnectWslHost), PaletteKind::RunAndDebug => { - Some(LapceWorkbenchCommand::PaletteRunAndDebug) + Some(UmideWorkbenchCommand::PaletteRunAndDebug) } - PaletteKind::ColorTheme => Some(LapceWorkbenchCommand::ChangeColorTheme), - PaletteKind::IconTheme => Some(LapceWorkbenchCommand::ChangeIconTheme), - PaletteKind::Language => Some(LapceWorkbenchCommand::ChangeFileLanguage), + PaletteKind::ColorTheme => Some(UmideWorkbenchCommand::ChangeColorTheme), + PaletteKind::IconTheme => Some(UmideWorkbenchCommand::ChangeIconTheme), + PaletteKind::Language => Some(UmideWorkbenchCommand::ChangeFileLanguage), PaletteKind::LineEnding => { - Some(LapceWorkbenchCommand::ChangeFileLineEnding) + Some(UmideWorkbenchCommand::ChangeFileLineEnding) } PaletteKind::SCMReferences => { - Some(LapceWorkbenchCommand::PaletteSCMReferences) + Some(UmideWorkbenchCommand::PaletteSCMReferences) } PaletteKind::TerminalProfile => None, // InternalCommand::NewTerminal - PaletteKind::DiffFiles => Some(LapceWorkbenchCommand::DiffFiles), + PaletteKind::DiffFiles => Some(UmideWorkbenchCommand::DiffFiles), } } diff --git a/crates/umide/src/panel/call_hierarchy_view.rs b/crates/umide/src/panel/call_hierarchy_view.rs index 72a2dc0a..b81fdf3a 100644 --- a/crates/umide/src/panel/call_hierarchy_view.rs +++ b/crates/umide/src/panel/call_hierarchy_view.rs @@ -14,7 +14,7 @@ use lsp_types::{CallHierarchyItem, Range}; use super::position::PanelPosition; use crate::{ command::InternalCommand, - config::{color::LapceColor, icon::LapceIcons}, + config::{color::UmideColor, icon::UmideIcons}, editor::location::EditorLocation, window_tab::{CommonData, WindowTabData}, }; @@ -143,8 +143,8 @@ pub fn show_hierarchy_panel( svg(move || { let config = config.get(); let svg_str = match open.get() { - true => LapceIcons::ITEM_OPENED, - false => LapceIcons::ITEM_CLOSED, + true => UmideIcons::ITEM_OPENED, + false => UmideIcons::ITEM_CLOSED, }; config.ui_svg(svg_str) }) @@ -152,7 +152,7 @@ pub fn show_hierarchy_panel( let config = config.get(); let size = config.ui.icon_size() as f32; s.size(size, size) - .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + .color(config.color(UmideColor::LAPCE_ICON_ACTIVE)) }) ) .style(|s| s.padding(4.0).margin_left(6.0).margin_right(2.0)) @@ -175,7 +175,7 @@ pub fn show_hierarchy_panel( let config = config.get(); config .symbol_svg(&kind) - .unwrap_or_else(|| config.ui_svg(LapceIcons::FILE)) + .unwrap_or_else(|| config.ui_svg(UmideIcons::FILE)) }).style(move |s| { let config = config.get(); let size = config.ui.icon_size() as f32; @@ -183,7 +183,7 @@ pub fn show_hierarchy_panel( .size(size, size) .margin_right(5.0) .color(config.symbol_color(&kind).unwrap_or_else(|| { - config.color(LapceColor::LAPCE_ICON_ACTIVE) + config.color(UmideColor::LAPCE_ICON_ACTIVE) })) }), data.item.name.clone().into_view(), @@ -191,7 +191,7 @@ pub fn show_hierarchy_panel( Label::new({ data.item.detail.clone().unwrap_or_default().replace('\n', "↵") }).style(move |s| s.margin_left(6.0) - .color(config.get().color(LapceColor::EDITOR_DIM)) + .color(config.get().color(UmideColor::EDITOR_DIM)) ).into_any() } else { Empty::new().into_any() @@ -206,7 +206,7 @@ pub fn show_hierarchy_panel( s.background( config .get() - .color(LapceColor::PANEL_HOVERED_BACKGROUND), + .color(UmideColor::PANEL_HOVERED_BACKGROUND), ) .cursor(CursorStyle::Pointer) }) diff --git a/crates/umide/src/panel/data.rs b/crates/umide/src/panel/data.rs index eeb997e8..c4876cf7 100644 --- a/crates/umide/src/panel/data.rs +++ b/crates/umide/src/panel/data.rs @@ -14,7 +14,7 @@ use super::{ style::PanelStyle, }; use crate::{ - db::LapceDb, + db::UmideDb, window_tab::{CommonData, Focus}, }; @@ -389,7 +389,7 @@ impl PanelData { style.shown = true; }); - let db: Arc = Context::get().unwrap(); + let db: Arc = Context::get().unwrap(); db.save_panel_orders(self.panels.get_untracked()); } diff --git a/crates/umide/src/panel/debug_view.rs b/crates/umide/src/panel/debug_view.rs index f92ed677..e4c91df7 100644 --- a/crates/umide/src/panel/debug_view.rs +++ b/crates/umide/src/panel/debug_view.rs @@ -20,7 +20,7 @@ use super::{data::PanelSection, position::PanelPosition, view::PanelBuilder}; use crate::{ app::clickable_icon, command::InternalCommand, - config::{LapceConfig, color::LapceColor, icon::LapceIcons}, + config::{UmideConfig, color::UmideColor, icon::UmideIcons}, debug::{DapVariable, RunDebugMode, StackTraceData}, editor::location::{EditorLocation, EditorPosition}, listener::Listener, @@ -70,7 +70,7 @@ fn debug_process_icons( dap_id: DapId, mode: RunDebugMode, stopped: bool, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { let paused = move || { let stopped = terminal @@ -84,7 +84,7 @@ fn debug_process_icons( { let terminal = terminal.clone(); clickable_icon( - || LapceIcons::DEBUG_RESTART, + || UmideIcons::DEBUG_RESTART, move || { terminal.restart_run_debug(term_id); }, @@ -98,7 +98,7 @@ fn debug_process_icons( { let terminal = terminal.clone(); clickable_icon( - || LapceIcons::DEBUG_STOP, + || UmideIcons::DEBUG_STOP, move || { terminal.stop_run_debug(term_id); }, @@ -112,7 +112,7 @@ fn debug_process_icons( { let terminal = terminal.clone(); clickable_icon( - || LapceIcons::CLOSE, + || UmideIcons::CLOSE, move || { terminal.close_terminal(&term_id); }, @@ -128,7 +128,7 @@ fn debug_process_icons( { let terminal = terminal.clone(); clickable_icon( - || LapceIcons::DEBUG_CONTINUE, + || UmideIcons::DEBUG_CONTINUE, move || { terminal.dap_continue(term_id); }, @@ -142,7 +142,7 @@ fn debug_process_icons( { let terminal = terminal.clone(); clickable_icon( - || LapceIcons::DEBUG_PAUSE, + || UmideIcons::DEBUG_PAUSE, move || { terminal.dap_pause(term_id); }, @@ -156,7 +156,7 @@ fn debug_process_icons( { let terminal = terminal.clone(); clickable_icon( - || LapceIcons::DEBUG_STEP_OVER, + || UmideIcons::DEBUG_STEP_OVER, move || { terminal.dap_step_over(term_id); }, @@ -170,7 +170,7 @@ fn debug_process_icons( { let terminal = terminal.clone(); clickable_icon( - || LapceIcons::DEBUG_STEP_INTO, + || UmideIcons::DEBUG_STEP_INTO, move || { terminal.dap_step_into(term_id); }, @@ -184,7 +184,7 @@ fn debug_process_icons( { let terminal = terminal.clone(); clickable_icon( - || LapceIcons::DEBUG_STEP_OUT, + || UmideIcons::DEBUG_STEP_OUT, move || { terminal.dap_step_out(term_id); }, @@ -198,7 +198,7 @@ fn debug_process_icons( { let terminal = terminal.clone(); clickable_icon( - || LapceIcons::DEBUG_RESTART, + || UmideIcons::DEBUG_RESTART, move || { terminal.restart_run_debug(term_id); }, @@ -212,7 +212,7 @@ fn debug_process_icons( { let terminal = terminal.clone(); clickable_icon( - || LapceIcons::DEBUG_STOP, + || UmideIcons::DEBUG_STOP, move || { terminal.stop_run_debug(term_id); }, @@ -226,7 +226,7 @@ fn debug_process_icons( { let terminal = terminal.clone(); clickable_icon( - || LapceIcons::CLOSE, + || UmideIcons::CLOSE, move || { terminal.close_terminal(&term_id); }, @@ -243,7 +243,7 @@ fn debug_process_icons( fn debug_processes( terminal: TerminalPanelData, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { Scroll::new({ let terminal = terminal.clone(); @@ -260,11 +260,11 @@ fn debug_processes( Stack::new(( { let svg_str = match (&p.mode, p.stopped) { - (RunDebugMode::Run, false) => LapceIcons::START, - (RunDebugMode::Run, true) => LapceIcons::RUN_ERRORS, - (RunDebugMode::Debug, false) => LapceIcons::DEBUG, + (RunDebugMode::Run, false) => UmideIcons::START, + (RunDebugMode::Run, true) => UmideIcons::RUN_ERRORS, + (RunDebugMode::Debug, false) => UmideIcons::DEBUG, (RunDebugMode::Debug, true) => { - LapceIcons::DEBUG_DISCONNECT + UmideIcons::DEBUG_DISCONNECT } }; svg(move || config.get().ui_svg(svg_str)).style(move |s| { @@ -273,7 +273,7 @@ fn debug_processes( s.size(size, size) .margin_vert(5.0) .margin_horiz(10.0) - .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + .color(config.color(UmideColor::LAPCE_ICON_ACTIVE)) }) }, Label::new(p.config.name.clone()).style(|s| { @@ -311,12 +311,12 @@ fn debug_processes( .items_center() .apply_if(is_active(), |s| { s.background( - config.color(LapceColor::PANEL_CURRENT_BACKGROUND), + config.color(UmideColor::PANEL_CURRENT_BACKGROUND), ) }) .hover(|s| { s.cursor(CursorStyle::Pointer).background( - (config.color(LapceColor::PANEL_HOVERED_BACKGROUND)) + (config.color(UmideColor::PANEL_HOVERED_BACKGROUND)) .multiply_alpha(0.3), ) }) @@ -374,8 +374,8 @@ fn variables_view(window_tab_data: Rc) -> impl View { svg(move || { let config = config.get(); let svg_str = match node.expanded { - true => LapceIcons::ITEM_OPENED, - false => LapceIcons::ITEM_CLOSED, + true => UmideIcons::ITEM_OPENED, + false => UmideIcons::ITEM_CLOSED, }; config.ui_svg(svg_str) }) @@ -384,7 +384,7 @@ fn variables_view(window_tab_data: Rc) -> impl View { let size = config.ui.icon_size() as f32; let color = if reference > 0 { - config.color(LapceColor::LAPCE_ICON_ACTIVE) + config.color(UmideColor::LAPCE_ICON_ACTIVE) } else { Color::TRANSPARENT }; @@ -435,7 +435,7 @@ fn variables_view(window_tab_data: Rc) -> impl View { s.apply_if(reference > 0, |s| { s.background( config.get().color( - LapceColor::PANEL_HOVERED_BACKGROUND, + UmideColor::PANEL_HOVERED_BACKGROUND, ), ) }) @@ -457,7 +457,7 @@ fn debug_stack_frames( stack_trace: StackTraceData, stopped: RwSignal, internal_command: Listener, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { let expanded = stack_trace.expanded; Stack::new(( @@ -470,7 +470,7 @@ fn debug_stack_frames( .style(move |s| { s.padding_horiz(10.0).min_width_pct(100.0).hover(move |s| { s.cursor(CursorStyle::Pointer).background( - config.get().color(LapceColor::PANEL_HOVERED_BACKGROUND), + config.get().color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }) }), @@ -506,13 +506,13 @@ fn debug_stack_frames( s.background( config .get() - .color(LapceColor::PANEL_HOVERED_BACKGROUND), + .color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }) }), Label::new(source_path.clone()).style(move |s| { s.margin_left(10.0) - .color(config.get().color(LapceColor::EDITOR_DIM)) + .color(config.get().color(UmideColor::EDITOR_DIM)) .font_style(FontStyle::Italic) .apply_if(!has_source, |s| s.hide()) }), @@ -545,11 +545,11 @@ fn debug_stack_frames( .padding_right(10.0) .min_width_pct(100.0) .apply_if(!has_source, |s| { - s.color(config.color(LapceColor::EDITOR_DIM)) + s.color(config.color(UmideColor::EDITOR_DIM)) }) .hover(|s| { s.background( - config.color(LapceColor::PANEL_HOVERED_BACKGROUND), + config.color(UmideColor::PANEL_HOVERED_BACKGROUND), ) .apply_if(has_source, |s| s.cursor(CursorStyle::Pointer)) }) @@ -564,7 +564,7 @@ fn debug_stack_frames( fn debug_stack_traces( terminal: TerminalPanelData, internal_command: Listener, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { Container::new( Scroll::new({ @@ -664,7 +664,7 @@ fn breakpoints_view(window_tab_data: Rc) -> impl View { Stack::new(( clickable_icon( - move || LapceIcons::CLOSE, + move || UmideIcons::CLOSE, move || { breakpoints.update(|breakpoints| { if let Some(breakpoints) = @@ -713,7 +713,7 @@ fn breakpoints_view(window_tab_data: Rc) -> impl View { s.text_ellipsis() .flex_grow(1.0) .flex_basis(0.0) - .color(config.get().color(LapceColor::EDITOR_DIM)) + .color(config.get().color(UmideColor::EDITOR_DIM)) .min_width(0.0) .margin_left(6.0) .apply_if(folder_empty, |s| s.hide()) @@ -725,7 +725,7 @@ fn breakpoints_view(window_tab_data: Rc) -> impl View { s.background( config .get() - .color(LapceColor::PANEL_HOVERED_BACKGROUND), + .color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }, ) diff --git a/crates/umide/src/panel/document_symbol.rs b/crates/umide/src/panel/document_symbol.rs index 0fb9463c..88856d5f 100644 --- a/crates/umide/src/panel/document_symbol.rs +++ b/crates/umide/src/panel/document_symbol.rs @@ -15,7 +15,7 @@ use lsp_types::{DocumentSymbol, SymbolKind}; use super::position::PanelPosition; use crate::{ command::InternalCommand, - config::{color::LapceColor, icon::LapceIcons}, + config::{color::UmideColor, icon::UmideIcons}, editor::location::EditorLocation, window_tab::WindowTabData, }; @@ -225,15 +225,15 @@ pub fn symbol_panel( svg(move || { let config = config.get(); let svg_str = match open.get() { - true => LapceIcons::ITEM_OPENED, - false => LapceIcons::ITEM_CLOSED, + true => UmideIcons::ITEM_OPENED, + false => UmideIcons::ITEM_CLOSED, }; config.ui_svg(svg_str) }) .style(move |s| { let config = config.get(); let color = if has_child { - config.color(LapceColor::LAPCE_ICON_ACTIVE) + config.color(UmideColor::LAPCE_ICON_ACTIVE) } else { Color::TRANSPARENT }; @@ -255,7 +255,7 @@ pub fn symbol_panel( let config = config.get(); config .symbol_svg(&kind) - .unwrap_or_else(|| config.ui_svg(LapceIcons::FILE)) + .unwrap_or_else(|| config.ui_svg(UmideIcons::FILE)) }).style(move |s| { let config = config.get(); let size = config.ui.icon_size() as f32; @@ -263,7 +263,7 @@ pub fn symbol_panel( .size(size, size) .margin_right(5.0) .color(config.symbol_color(&kind).unwrap_or_else(|| { - config.color(LapceColor::LAPCE_ICON_ACTIVE) + config.color(UmideColor::LAPCE_ICON_ACTIVE) })) }), Label::new({ @@ -275,7 +275,7 @@ pub fn symbol_panel( Label::new({ data.detail.clone().unwrap_or_default() }).style(move |s| s.margin_left(6.0) - .color(config.get().color(LapceColor::EDITOR_DIM)) + .color(config.get().color(UmideColor::EDITOR_DIM)) .selectable(false) .apply_if( data.item.detail.clone().is_none(), @@ -291,7 +291,7 @@ pub fn symbol_panel( s.background( config .get() - .color(LapceColor::PANEL_HOVERED_BACKGROUND), + .color(UmideColor::PANEL_HOVERED_BACKGROUND), ) .cursor(CursorStyle::Pointer) }) diff --git a/crates/umide/src/panel/emulator_view.rs b/crates/umide/src/panel/emulator_view.rs index 171246bc..57a400ff 100644 --- a/crates/umide/src/panel/emulator_view.rs +++ b/crates/umide/src/panel/emulator_view.rs @@ -1,8 +1,9 @@ use std::{rc::Rc, sync::Arc}; use floem::{ - View, ViewId, prelude::{SignalGet, SignalUpdate}, reactive::{RwSignal, Effect}, + View, ViewId, prelude::{SignalGet, SignalUpdate}, + reactive::{RwSignal, Effect}, views::{Decorators, Label, Scroll, Stack, dyn_stack, Container}, - context::{PaintCx, UpdateCx, ComputeLayoutCx}, + context::{UpdateCx, ComputeLayoutCx}, peniko::kurbo::Rect, }; @@ -10,29 +11,90 @@ use crate::{ app::clickable_icon, panel::{position::PanelPosition, view::PanelBuilder}, window_tab::WindowTabData, - config::{icon::LapceIcons, color::LapceColor}, + config::{icon::UmideIcons, color::UmideColor}, }; use umide_emulator::{ - list_all_devices, launch_device, stop_device, DeviceInfo, DevicePlatform, DeviceState, - native_view::NativeEmulatorView, + list_all_devices, launch_device, stop_device, + DeviceInfo, DevicePlatform, DeviceState, + decoder::DecodedFrame, }; +#[cfg(target_os = "macos")] +use umide_emulator::native_view::NativeEmulatorView; +#[cfg(target_os = "macos")] use umide_native::emulator::EmulatorPlatform; +#[cfg(not(target_os = "macos"))] +#[derive(Clone, Copy)] +enum EmulatorPlatform { + Android, + Ios, +} + +#[cfg(not(target_os = "macos"))] +struct NativeEmulatorView; + +#[cfg(not(target_os = "macos"))] +impl NativeEmulatorView { + fn new( + _handle: T, + _x: i32, + _y: i32, + _width: u32, + _height: u32, + _platform: EmulatorPlatform, + ) -> Result { + Err("Native emulator embedding is only supported on macOS".to_string()) + } + + fn resize(&self, _x: i32, _y: i32, _width: u32, _height: u32) {} + fn show(&self) {} + fn hide(&self) {} + fn attach_device(&mut self, _device_id: &str) {} + fn is_android(&self) -> bool { + false + } + fn start_grpc_stream(&mut self, _grpc_endpoint: &str) {} +} + struct NativeEmulatorWidget { id: ViewId, - native_view: Option, + native_view: Rc>>, running_device: RwSignal>, + is_visible: RwSignal, #[allow(dead_code)] current_device_id: RwSignal, + /// Track the last device ID we initialized for, to detect changes + last_device_id: Option, + /// Floem frame signal (for panel data, not used for rendering directly) + #[allow(dead_code)] + frame_signal: RwSignal>>, } impl NativeEmulatorWidget { - pub fn new(running_device: RwSignal>, current_device_id: RwSignal) -> Self { + pub fn new( + running_device: RwSignal>, + is_visible: RwSignal, + current_device_id: RwSignal, + frame_signal: RwSignal>>, + ) -> Self { Self { id: ViewId::new(), - native_view: None, + native_view: Rc::new(std::cell::RefCell::new(None)), running_device, + is_visible, current_device_id, + last_device_id: None, + frame_signal, + } + } + + /// Cleanup the native view + fn cleanup(&mut self) { + let mut view_lock = self.native_view.borrow_mut(); + if view_lock.is_some() { + tracing::info!("Cleaning up native emulator view"); + *view_lock = None; + self.last_device_id = None; } } } @@ -46,59 +108,144 @@ impl View for NativeEmulatorWidget { "NativeEmulatorWidget".into() } - fn update(&mut self, _cx: &mut UpdateCx, _state: Box) { - // Handle updates if needed + fn update(&mut self, _cx: &mut floem::context::UpdateCx, _state: Box) { + let current_device = self.running_device.get_untracked(); + let is_visible = self.is_visible.get_untracked(); + + let mut should_cleanup = false; + + if !is_visible || current_device.is_none() { + should_cleanup = true; + } else if let Some(ref dev) = current_device { + if let Some(ref last_id) = self.last_device_id { + if dev.id != *last_id { + should_cleanup = true; + } + } + } + + if should_cleanup { + let has_view = self.native_view.borrow().is_some(); + if has_view { + if let Some(ref view) = *self.native_view.borrow() { + view.hide(); + } + self.cleanup(); + } + } else if is_visible { + if let Some(ref view) = *self.native_view.borrow() { + view.show(); + } + } } fn compute_layout(&mut self, _cx: &mut ComputeLayoutCx) -> Option { - // Get layout after it's been computed - if let Some(layout) = self.id.get_layout() { - let width = layout.size.width as u32; - let height = layout.size.height as u32; + let is_visible = self.is_visible.get_untracked(); + + if !is_visible { + if self.native_view.borrow().is_some() { + self.cleanup(); + } + return None; + } + + let current_device = self.running_device.get_untracked(); + if current_device.is_none() && self.native_view.borrow().is_some() { + self.cleanup(); + return None; + } + + None + } + + fn paint(&mut self, _cx: &mut floem::context::PaintCx) { + let is_visible = self.is_visible.get_untracked(); + let current_device = self.running_device.get_untracked(); + + // Cleanup if hidden or no device + if !is_visible || current_device.is_none() { + let has_view = self.native_view.borrow().is_some(); + if has_view { + if let Some(ref view) = *self.native_view.borrow() { + view.hide(); + } + self.cleanup(); + } + return; + } + + let window_origin = self.id.get_window_origin(); + let size = self.id.get_layout().map(|l| (l.size.width as u32, l.size.height as u32)); + + if let Some((width, height)) = size { + if width == 0 || height == 0 { + return; + } - if let Some(view) = &self.native_view { - view.resize(width, height); - } else { - // Initialize the native view if we have a window handle - use floem::window::WindowIdExt; - - if let Some(window_id) = self.id.window_id() { - if let Some(handle) = window_id.raw_window_handle() { - // Determine the platform from the running device signal - if let Some(device) = self.running_device.get_untracked() { + // Use the widget's own layout position — Floem already accounts for + // the toolbar, header, and sidebar in the layout tree + let x = window_origin.x as i32; + let y = window_origin.y as i32; + let device_name = current_device.as_ref().map(|d| d.name.as_str()).unwrap_or("unknown"); + + tracing::debug!( + "NativeEmulatorWidget [{}]: origin=({},{}) size={}x{}", + device_name, x, y, width, height + ); + + let has_view = self.native_view.borrow().is_some(); + if has_view { + if let Some(view) = &*self.native_view.borrow() { + view.resize(x, y, width, height); + view.show(); + } + } else if is_visible { + if let Some(device) = current_device { + use floem::window::WindowIdExt; + + if let Some(window_id) = self.id.window_id() { + if let Some(handle) = window_id.raw_window_handle() { let platform = match device.platform { umide_emulator::common::DevicePlatform::Android => EmulatorPlatform::Android, umide_emulator::common::DevicePlatform::Ios => EmulatorPlatform::Ios, }; - match NativeEmulatorView::new(handle, width, height, platform) { - Ok(view) => { - tracing::info!("Successfully created native emulator view for device: {}", device.name); - - // Attach device if ID is available + tracing::info!( + "Creating native emulator view for device: {} at ({},{}) size {}x{}", + device.name, x, y, width, height + ); + + match NativeEmulatorView::new( + handle, + x, + y, + width, + height, + platform + ) { + Ok(mut view) => { if !device.id.is_empty() { view.attach_device(&device.id); } - self.native_view = Some(view); + // Android: start gRPC frame streaming (headless, no window) + // iOS: uses ScreenCaptureKit via attach_device (no gRPC needed) + if view.is_android() { + view.start_grpc_stream("http://localhost:8554"); + } + + *self.native_view.borrow_mut() = Some(view); + self.last_device_id = Some(device.id.clone()); } Err(e) => { tracing::error!("Failed to create native emulator view: {}", e); } } - } else { - // Should not happen if view is visible only when running, but handle gracefully - tracing::warn!("NativeEmulatorWidget layout called but no device is running"); } } } } } - None - } - - fn paint(&mut self, _cx: &mut PaintCx) { - // Native view handles painting on its own layer/surface } } @@ -107,9 +254,10 @@ fn platform_panel( platform: DevicePlatform, devices: RwSignal>, running_device: RwSignal>, - frame_signal: RwSignal>>, // Kept for API compat, likely unused + is_visible: RwSignal, + frame_signal: RwSignal>>, current_device_id: RwSignal, - config: floem::reactive::ReadSignal>, + config: floem::reactive::ReadSignal>, ) -> impl View { let platform_name = match &platform { DevicePlatform::Android => "Android", @@ -121,31 +269,62 @@ fn platform_panel( move |device: DeviceInfo| { let device_cloned_start = device.clone(); let device_cloned_stop = device.clone(); + let device_cloned_resume = device.clone(); let is_running = device.state == DeviceState::Running; let is_starting = device.state == DeviceState::Starting; let is_disconnected = device.state == DeviceState::Disconnected; Stack::new(( Label::new(device.name.clone()) - .style(|s| s.flex_grow(1.0).padding_horiz(6.0)), + .style(|s| s.flex_grow(1.0).padding_horiz(6.0).text_ellipsis()), + // Start/Resume/Show button clickable_icon( - || LapceIcons::DEBUG_CONTINUE, + || UmideIcons::DEBUG_CONTINUE, move || { + // Check if this device is already running but hidden + if let Some(ref running) = running_device.get_untracked() { + if running.id == device_cloned_resume.id { + // Just show it again + current_device_id.set(device_cloned_resume.id.clone()); + is_visible.set(true); + return; + } + } + // Start new device let _ = launch_device(&device_cloned_start); let mut d = device_cloned_start.clone(); d.state = DeviceState::Running; running_device.set(Some(d)); + current_device_id.set(device_cloned_start.id.clone()); + is_visible.set(true); }, || false, - move || !is_disconnected, - || "Start", + move || { + // Visible if: + // 1. Device is disconnected (to Start) + // 2. OR Device is running AND hidden (to Show/Resume) + // So hidden if: device is running AND visible + if is_running { + // If running, hide "Start" button unless view is hidden + is_visible.get() + } else { + // If not running, show "Start" button unless starting? + // Original logic: !is_disconnected && !is_running -> hidden. + // Wait, is_disconnected means state == Disconnected. + // If state == Starting, is_disconnected = false, is_running = false. + // Then hidden = true. Correct (don't show start while starting). + !is_disconnected + } + }, + move || if is_running { "Show" } else { "Start" }, config, ), clickable_icon( - || LapceIcons::DEBUG_STOP, + || UmideIcons::DEBUG_STOP, move || { let _ = stop_device(&device_cloned_stop); running_device.set(None); + is_visible.set(false); frame_signal.set(None); current_device_id.set(String::new()); }, @@ -164,41 +343,60 @@ fn platform_panel( .items_center() .padding_vert(5.0) .border_bottom(1.0) + .gap(2.0) }) } }; Stack::new(( - // Header + // Header with device name (ABOVE native view so always visible) Container::new( - Label::new(platform_name.to_string()) - .style(move |s| { - s.font_size(12.0) - .font_bold() - .padding(6.0) + Stack::horizontal(( + Label::new(platform_name.to_string()) + .style(move |s| { + s.font_size(12.0) + .font_bold() + .padding(6.0) + }), + // Show running device name in header + Label::derived(move || { + if let Some(device) = running_device.get() { + if is_visible.get() { + format!(" - {}", device.name) + } else { + format!(" - {} (hidden)", device.name) + } + } else { + String::new() + } }) + .style(|s| s.font_size(10.0).flex_grow(1.0).padding_right(6.0)), + )) + .style(|s| s.width_full().items_center()) ) .style(move |s| { let config = config.get(); s.width_full() .border_bottom(1.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) }), - // Content: Device list + // Content: Device list OR Emulator view Stack::new(( + // Device list (shown when no device or hidden) Scroll::new( dyn_stack( move || { - // Only show list if no device running (or can show generic list) - // Simplified: Show list always, but maybe disable items? - // logic from before: hide if running. - if running_device.get().is_some() { - return Vec::new(); + let visible = is_visible.get(); + let has_running = running_device.get().is_some(); + + // Show list if not visible or no device running + if has_running && visible { + return Vec::new(); } - let platform_filter = platform.clone(); + devices.get().into_iter() - .filter(|d| d.platform == platform_filter) + .filter(|d| d.platform == platform) .collect::>() }, |d| format!("{}-{}", d.id, d.state as u32), @@ -206,44 +404,200 @@ fn platform_panel( ).style(|s| s.flex_col().width_full()) ) .style(move |s| { + let visible = is_visible.get(); + let has_running = running_device.get().is_some(); s.flex_grow(1.0) .width_full() - .apply_if(running_device.get().is_some(), |s| s.hide()) + .min_width(0.0) + .min_height(0.0) + .apply_if(has_running && visible, |s| s.hide()) }), - // Native Emulator View - Stack::new(( - NativeEmulatorWidget::new(running_device, current_device_id), - clickable_icon( - || LapceIcons::CLOSE, - move || { - running_device.set(None); - frame_signal.set(None); - current_device_id.set(String::new()); - }, - || false, - || false, - || "Back to list", - config, - ).style(|s| s.absolute().margin_left(5.0).margin_top(5.0)) - )) + // Native Emulator View + Sidebar (shown when device running AND visible) + Stack::horizontal({ + let native_widget = NativeEmulatorWidget::new(running_device, is_visible, current_device_id, frame_signal); + let widget_id = native_widget.id(); + + + + // Effect to force an update when signals change + Effect::new(move |_| { + let _ = is_visible.get(); + let _ = running_device.get(); + widget_id.update_state(()); + widget_id.request_paint(); + }); + + ( + // Emulator display + native_widget + .style(|s| s.flex_grow(1.0).width_full().height_full()), + // Emulator sidebar controls + emulator_sidebar(platform, running_device, is_visible, frame_signal, current_device_id, config), + ) + }) .style(move |s| { - s.flex_col() + let visible = is_visible.get(); + let has_running = running_device.get().is_some(); + s.flex_grow(1.0) .width_full() - .flex_grow(1.0) - .min_height(300.0) - .apply_if(running_device.get().is_none(), |s| s.hide()) + .height_full() + .min_width(0.0) + .min_height(0.0) + .apply_if(!has_running || !visible, |s| s.hide()) }) )) - .style(|s| s.flex_col().flex_grow(1.0).width_full()), + .style(|s| s.flex_col().flex_grow(1.0).width_full().height_full().min_width(0.0).min_height(0.0)), )) .style(move |s| { let config = config.get(); s.flex_col() .flex_grow(1.0) - .min_width(180.0) + .flex_basis(0.0) + .min_width(0.0) + .min_height(0.0) + .height_full() .border(1.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) + }) +} + +/// Helper to create a sidebar button that executes an arbitrary shell command +fn action_button( + label: &'static str, + _tooltip: &'static str, + device_id: RwSignal, + cmd_builder: impl Fn(String) -> String + 'static + Send + Sync, + config: floem::reactive::ReadSignal>, +) -> impl View { + let label_text = label.to_string(); + Stack::new(( + Label::new(label_text) + .style(|s| s.font_size(14.0)), + )) + .on_click_stop(move |_| { + let id = device_id.get_untracked(); + if id.is_empty() { return; } + + let cmd = cmd_builder(id); + std::thread::spawn(move || { + let env_path = std::env::var("PATH").unwrap_or_default(); + let _ = std::process::Command::new("sh") + .env("PATH", format!("/opt/homebrew/bin:/usr/local/bin:{}", env_path)) + .arg("-c") + .arg(&cmd) + .output(); + }); + }) + .style(move |s| { + let config_val = config.get(); + s.width(28.0) + .height(28.0) + .items_center() + .justify_center() + .border_radius(4.0) + .cursor(floem::style::CursorStyle::Pointer) + .border(1.0) + .border_color(config_val.color(UmideColor::LAPCE_BORDER)) + .hover(|s| s.background(floem::peniko::Color::from_rgba8(255, 255, 255, 20))) + }) +} + +/// Emulator sidebar with control buttons (Stop/Hide for all, hardware buttons for Android) +fn emulator_sidebar( + platform: DevicePlatform, + running_device: RwSignal>, + is_visible: RwSignal, + frame_signal: RwSignal>>, + current_device_id: RwSignal, + config: floem::reactive::ReadSignal>, +) -> impl View { + let is_android = matches!(platform, DevicePlatform::Android); + + Stack::new(( + // Generic controls (both platforms) + Stack::new(( + // Stop button + clickable_icon( + || UmideIcons::DEBUG_STOP, + move || { + if let Some(device) = running_device.get_untracked() { + tracing::info!("Stopping device: {}", device.name); + if let Err(e) = stop_device(&device) { + tracing::error!("Failed to stop device {}: {}", device.name, e); + } + } + running_device.set(None); + is_visible.set(false); + frame_signal.set(None); + current_device_id.set(String::new()); + }, + || false, + || false, + || "Stop", + config, + ), + Label::new("Stop").style(|s| s.font_size(10.0)), + // Separator + Label::new("").style(|s| s.height(8.0)), + // Hide button + clickable_icon( + || UmideIcons::CLOSE, + move || { + tracing::info!("Hiding emulator view (device still running)"); + is_visible.set(false); + }, + || false, + || false, + || "Hide", + config, + ), + Label::new("Hide").style(|s| s.font_size(10.0)), + // Separator + Label::new("").style(|s| s.height(8.0)), + )) + .style(|s| s.flex_col().items_center().gap(2.0)), + + // Android hardware controls + Stack::new(( + action_button("🏠", "Home", current_device_id, |_id| "adb shell input keyevent 3".to_string(), config), + action_button("◀", "Back", current_device_id, |_id| "adb shell input keyevent 4".to_string(), config), + action_button("▦", "Overview", current_device_id, |_id| "adb shell input keyevent 187".to_string(), config), + Label::new("").style(|s| s.height(8.0)), + action_button("🔊", "Vol+", current_device_id, |_id| "adb shell input keyevent 24".to_string(), config), + action_button("🔉", "Vol-", current_device_id, |_id| "adb shell input keyevent 25".to_string(), config), + Label::new("").style(|s| s.height(8.0)), + action_button("⏻", "Power", current_device_id, |_id| "adb shell input keyevent 26".to_string(), config), + Label::new("").style(|s| s.height(8.0)), + action_button("📷", "Screenshot", current_device_id, |_id| "adb exec-out screencap -p > ~/Desktop/umide_screenshot_$(date +%s).png".to_string(), config), + )) + .style(move |s| { + s.flex_col() + .items_center() + .gap(4.0) + .apply_if(!is_android, |s| s.hide()) + }), + + // iOS hardware controls + Stack::new(( + action_button("🏠", "Home", current_device_id, |id| format!("idb ui button --udid {} HOME", id), config), + Label::new("").style(|s| s.height(8.0)), + action_button("📷", "Screenshot", current_device_id, |id| format!("idb screenshot --udid {} ~/Desktop/umide_screenshot_$(date +%s).png", id), config), + )) + .style(move |s| { + s.flex_col() + .items_center() + .gap(4.0) + .apply_if(is_android, |s| s.hide()) // Hide if android + }) + )) + .style(move |s| { + let config_val = config.get(); + s.flex_col() + .items_center() + .padding(4.0) + .border_left(1.0) + .border_color(config_val.color(UmideColor::LAPCE_BORDER)) }) } @@ -258,6 +612,10 @@ pub fn emulator_panel( let running_android = RwSignal::new(None::); let running_ios = RwSignal::new(None::); + // Visibility signals (separate from running state for hide/resume) + let android_visible = RwSignal::new(false); + let ios_visible = RwSignal::new(false); + // Track current device IDs for capture management let current_android_id = RwSignal::new(String::new()); let current_ios_id = RwSignal::new(String::new()); @@ -266,7 +624,7 @@ pub fn emulator_panel( let android_frame = window_tab_data.panel.android_frame; let ios_frame = window_tab_data.panel.ios_frame; - // Effect to fetch devices + // Effect to fetch devices and update running state Effect::new(move |_| { let dev_list = list_all_devices(); @@ -277,11 +635,17 @@ pub fn emulator_panel( DevicePlatform::Android => { if running_android.get().is_none() { running_android.set(Some(device.clone())); + current_android_id.set(device.id.clone()); + // Don't auto-show, let user click "Show" + // android_visible.set(true); } } DevicePlatform::Ios => { if running_ios.get().is_none() { running_ios.set(Some(device.clone())); + current_ios_id.set(device.id.clone()); + // Don't auto-show, let user click "Show" + // ios_visible.set(true); } } } @@ -291,28 +655,74 @@ pub fn emulator_panel( devices.set(dev_list); }); + let android_panel_visible = RwSignal::new(true); + let ios_panel_visible = RwSignal::new(cfg!(target_os = "macos")); + let show_ios_ui = cfg!(target_os = "macos"); + + let toggle_btn = move |label: &'static str, visible_sig: RwSignal| { + Label::derived(move || { + if visible_sig.get() { + format!("☑ {}", label) + } else { + format!("☐ {}", label) + } + }) + .on_click_stop(move |_| { + visible_sig.update(|v| *v = !*v); + }) + .style(move |s| { + s.cursor(floem::style::CursorStyle::Pointer) + .padding_right(15.0) + .font_size(12.0) + .apply_if(label == "iOS" && !show_ios_ui, |s| s.hide()) + }) + }; + + let toggle_bar = Stack::horizontal(( + toggle_btn("Android", android_panel_visible), + toggle_btn("iOS", ios_panel_visible), + )) + .style(move |s| { + let config_val = config.get(); + s.width_full() + .padding(5.0) + .border_bottom(1.0) + .border_color(config_val.color(UmideColor::LAPCE_BORDER)) + }); + PanelBuilder::new(config, position) .add( "Emulators", - Stack::horizontal(( - platform_panel( - DevicePlatform::Android, - devices, - running_android, - android_frame, - current_android_id, - config, - ), - platform_panel( - DevicePlatform::Ios, - devices, - running_ios, - ios_frame, - current_ios_id, - config, - ), + Stack::new(( + toggle_bar, + Stack::horizontal(( + platform_panel( + DevicePlatform::Android, + devices, + running_android, + android_visible, + android_frame, + current_android_id, + config, + ).style(move |s| s.apply_if(!android_panel_visible.get(), |s| s.hide())), + platform_panel( + DevicePlatform::Ios, + devices, + running_ios, + ios_visible, + ios_frame, + current_ios_id, + config, + ).style(move |s| s.apply_if(!ios_panel_visible.get() || !show_ios_ui, |s| s.hide())), + )) + .style(|s| { + s.flex_row() + .size_full() + .gap(5.0) + .padding(5.0) + }), )) - .style(|s| s.flex_row().size_full().gap(5.0).padding(5.0)), + .style(|s| s.flex_col().size_full()), window_tab_data.panel.section_open(crate::panel::data::PanelSection::Process), ) .build() diff --git a/crates/umide/src/panel/global_search_view.rs b/crates/umide/src/panel/global_search_view.rs index 004b6830..5b9536db 100644 --- a/crates/umide/src/panel/global_search_view.rs +++ b/crates/umide/src/panel/global_search_view.rs @@ -14,14 +14,14 @@ use super::{kind::PanelKind, position::PanelPosition}; use crate::{ app::clickable_icon, command::InternalCommand, - config::{LapceConfig, color::LapceColor, icon::LapceIcons}, + config::{UmideConfig, color::UmideColor, icon::UmideIcons}, editor::location::{EditorLocation, EditorPosition}, focus_text::focus_text, global_search::{GlobalSearchData, SearchMatchData}, listener::Listener, text_input::TextInputBuilder, window_tab::{Focus, WindowTabData}, - workspace::LapceWorkspace, + workspace::UmideWorkspace, }; struct SearchMatchList(im::Vector); @@ -60,7 +60,7 @@ pub fn global_search_panel( .build_editor(editor.clone()) .style(|s| s.width_pct(100.0)), clickable_icon( - || LapceIcons::SEARCH_CASE_SENSITIVE, + || UmideIcons::SEARCH_CASE_SENSITIVE, move || { let new = match case_matching.get_untracked() { CaseMatching::Exact => CaseMatching::CaseInsensitive, @@ -75,7 +75,7 @@ pub fn global_search_panel( ) .style(|s| s.padding_vert(4.0)), clickable_icon( - || LapceIcons::SEARCH_WHOLE_WORD, + || UmideIcons::SEARCH_WHOLE_WORD, move || { whole_word.update(|whole_word| { *whole_word = !*whole_word; @@ -88,7 +88,7 @@ pub fn global_search_panel( ) .style(|s| s.padding_left(6.0)), clickable_icon( - || LapceIcons::SEARCH_REGEX, + || UmideIcons::SEARCH_REGEX, move || { is_regex.update(|is_regex| { *is_regex = !*is_regex; @@ -110,7 +110,7 @@ pub fn global_search_panel( .items_center() .border(1.0) .border_radius(6.0) - .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + .border_color(config.get().color(UmideColor::LAPCE_BORDER)) }), ) .style(|s| s.width_pct(100.0).padding(10.0)), @@ -121,10 +121,10 @@ pub fn global_search_panel( } fn search_result( - workspace: Arc, + workspace: Arc, global_search_data: GlobalSearchData, internal_command: Listener, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { let ui_line_height = global_search_data.common.ui_line_height; Container::new({ @@ -162,9 +162,9 @@ fn search_result( Stack::new(( svg(move || { config.get().ui_svg(if expanded.get() { - LapceIcons::ITEM_OPENED + UmideIcons::ITEM_OPENED } else { - LapceIcons::ITEM_CLOSED + UmideIcons::ITEM_CLOSED }) }) .style(move |s| { @@ -175,7 +175,7 @@ fn search_result( .size(size, size) .min_size(size, size) .color( - config.color(LapceColor::LAPCE_ICON_ACTIVE), + config.color(UmideColor::LAPCE_ICON_ACTIVE), ) }), svg(move || config.get().file_svg(&path).0).style( @@ -197,7 +197,7 @@ fn search_result( }), Label::new(folder.clone()).style(move |s| { s.color( - config.get().color(LapceColor::EDITOR_DIM), + config.get().color(UmideColor::EDITOR_DIM), ) .min_width(0.0) .text_ellipsis() @@ -215,7 +215,7 @@ fn search_result( .hover(|s| { s.cursor(CursorStyle::Pointer).background( config.get().color( - LapceColor::PANEL_HOVERED_BACKGROUND, + UmideColor::PANEL_HOVERED_BACKGROUND, ), ) }) @@ -268,7 +268,7 @@ fn search_result( .collect() }, move || { - config.get().color(LapceColor::EDITOR_FOCUS) + config.get().color(UmideColor::EDITOR_FOCUS) }, ) .style(move |s| { @@ -278,7 +278,7 @@ fn search_result( |s| { s.cursor(CursorStyle::Pointer) .background(config.color( - LapceColor::PANEL_HOVERED_BACKGROUND, + UmideColor::PANEL_HOVERED_BACKGROUND, )) }, ) diff --git a/crates/umide/src/panel/implementation_view.rs b/crates/umide/src/panel/implementation_view.rs index 3c08f86c..77140e4c 100644 --- a/crates/umide/src/panel/implementation_view.rs +++ b/crates/umide/src/panel/implementation_view.rs @@ -17,7 +17,7 @@ use lsp_types::{Location, SymbolKind, request::GotoImplementationResponse}; use super::position::PanelPosition; use crate::{ command::InternalCommand, - config::{color::LapceColor, icon::LapceIcons}, + config::{color::UmideColor, icon::UmideIcons}, editor::location::EditorLocation, window_tab::WindowTabData, }; @@ -49,8 +49,8 @@ pub fn common_reference_panel( svg(move || { let config = config.get(); let svg_str = match open.get() { - true => LapceIcons::ITEM_OPENED, - false => LapceIcons::ITEM_CLOSED, + true => UmideIcons::ITEM_OPENED, + false => UmideIcons::ITEM_CLOSED, }; config.ui_svg(svg_str) }) @@ -58,7 +58,7 @@ pub fn common_reference_panel( let config = config.get(); let size = config.ui.icon_size() as f32; s.size(size, size).color( - config.color(LapceColor::LAPCE_ICON_ACTIVE), + config.color(UmideColor::LAPCE_ICON_ACTIVE), ) }), ) @@ -74,7 +74,7 @@ pub fn common_reference_panel( let config = config.get(); config .symbol_svg(&SymbolKind::FILE) - .unwrap_or_else(|| config.ui_svg(LapceIcons::FILE)) + .unwrap_or_else(|| config.ui_svg(UmideIcons::FILE)) }) .style(move |s| { let config = config.get(); @@ -87,14 +87,14 @@ pub fn common_reference_panel( .symbol_color(&SymbolKind::FILE) .unwrap_or_else(|| { config - .color(LapceColor::LAPCE_ICON_ACTIVE) + .color(UmideColor::LAPCE_ICON_ACTIVE) }), ) }), Label::derived(move || format!("{:?}", path)) .style(move |s| { s.margin_left(6.0).color( - config.get().color(LapceColor::EDITOR_DIM), + config.get().color(UmideColor::EDITOR_DIM), ) }) .into_any(), @@ -108,7 +108,7 @@ pub fn common_reference_panel( s.background( config .get() - .color(LapceColor::PANEL_HOVERED_BACKGROUND), + .color(UmideColor::PANEL_HOVERED_BACKGROUND), ) .cursor(CursorStyle::Pointer) }) @@ -117,7 +117,7 @@ pub fn common_reference_panel( Label::derived(move || format!("{} {}", file_line.position.line + 1, file_line.content)) .style(move |s| { s.margin_left(6.0).color( - config.get().color(LapceColor::EDITOR_DIM), + config.get().color(UmideColor::EDITOR_DIM), ) }) .into_any(), @@ -131,7 +131,7 @@ pub fn common_reference_panel( s.background( config .get() - .color(LapceColor::PANEL_HOVERED_BACKGROUND), + .color(UmideColor::PANEL_HOVERED_BACKGROUND), ) .cursor(CursorStyle::Pointer) }) @@ -167,7 +167,7 @@ pub fn common_reference_panel( s.background( config .get() - .color(LapceColor::PANEL_HOVERED_BACKGROUND), + .color(UmideColor::PANEL_HOVERED_BACKGROUND), ) .cursor(CursorStyle::Pointer) }) diff --git a/crates/umide/src/panel/kind.rs b/crates/umide/src/panel/kind.rs index d6e474a5..e4f53310 100644 --- a/crates/umide/src/panel/kind.rs +++ b/crates/umide/src/panel/kind.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use strum_macros::EnumIter; use super::{data::PanelOrder, position::PanelPosition}; -use crate::config::icon::LapceIcons; +use crate::config::icon::UmideIcons; #[derive( Clone, Copy, PartialEq, Serialize, Deserialize, Hash, Eq, Debug, EnumIter, @@ -26,19 +26,19 @@ pub enum PanelKind { impl PanelKind { pub fn svg_name(&self) -> &'static str { match &self { - PanelKind::Terminal => LapceIcons::TERMINAL, - PanelKind::FileExplorer => LapceIcons::FILE_EXPLORER, - PanelKind::SourceControl => LapceIcons::SCM, - PanelKind::Plugin => LapceIcons::EXTENSIONS, - PanelKind::Search => LapceIcons::SEARCH, - PanelKind::Problem => LapceIcons::PROBLEM, - PanelKind::Debug => LapceIcons::DEBUG, - PanelKind::CallHierarchy => LapceIcons::TYPE_HIERARCHY, - PanelKind::DocumentSymbol => LapceIcons::DOCUMENT_SYMBOL, - PanelKind::References => LapceIcons::REFERENCES, - PanelKind::Implementation => LapceIcons::IMPLEMENTATION, - PanelKind::Emulator => LapceIcons::EMULATOR, - PanelKind::Video => LapceIcons::DEBUG_CONSOLE, + PanelKind::Terminal => UmideIcons::TERMINAL, + PanelKind::FileExplorer => UmideIcons::FILE_EXPLORER, + PanelKind::SourceControl => UmideIcons::SCM, + PanelKind::Plugin => UmideIcons::EXTENSIONS, + PanelKind::Search => UmideIcons::SEARCH, + PanelKind::Problem => UmideIcons::PROBLEM, + PanelKind::Debug => UmideIcons::DEBUG, + PanelKind::CallHierarchy => UmideIcons::TYPE_HIERARCHY, + PanelKind::DocumentSymbol => UmideIcons::DOCUMENT_SYMBOL, + PanelKind::References => UmideIcons::REFERENCES, + PanelKind::Implementation => UmideIcons::IMPLEMENTATION, + PanelKind::Emulator => UmideIcons::EMULATOR, + PanelKind::Video => UmideIcons::DEBUG_CONSOLE, } } diff --git a/crates/umide/src/panel/plugin_view.rs b/crates/umide/src/panel/plugin_view.rs index ac0a6107..5a23efe4 100644 --- a/crates/umide/src/panel/plugin_view.rs +++ b/crates/umide/src/panel/plugin_view.rs @@ -25,7 +25,7 @@ use super::{ use crate::{ app::not_clickable_icon, command::InternalCommand, - config::{color::LapceColor, icon::LapceIcons}, + config::{color::UmideColor, icon::UmideIcons}, plugin::{AvailableVoltData, InstalledVoltData, PluginData, VoltIcon}, text_input::TextInputBuilder, window_tab::{Focus, WindowTabData}, @@ -159,7 +159,7 @@ fn installed_view(plugin: PluginData) -> impl View { .min_width(0.0) }), not_clickable_icon( - || LapceIcons::SETTINGS, + || UmideIcons::SETTINGS, || false, || false, || "Options", @@ -186,7 +186,7 @@ fn installed_view(plugin: PluginData) -> impl View { .cursor(CursorStyle::Pointer) .hover(|s| { s.background( - config.get().color(LapceColor::PANEL_HOVERED_BACKGROUND), + config.get().color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }) }) @@ -240,9 +240,9 @@ fn available_view(plugin: PluginData, core_rpc: CoreRpcHandler) -> impl View { }) .style(move |s| { let config = config.get(); - s.color(config.color(LapceColor::LAPCE_BUTTON_PRIMARY_FOREGROUND)) + s.color(config.color(UmideColor::LAPCE_BUTTON_PRIMARY_FOREGROUND)) .background( - config.color(LapceColor::LAPCE_BUTTON_PRIMARY_BACKGROUND), + config.color(UmideColor::LAPCE_BUTTON_PRIMARY_BACKGROUND), ) .margin_left(6.0) .padding_horiz(6.0) @@ -250,18 +250,18 @@ fn available_view(plugin: PluginData, core_rpc: CoreRpcHandler) -> impl View { .hover(|s| { s.cursor(CursorStyle::Pointer).background( config - .color(LapceColor::LAPCE_BUTTON_PRIMARY_BACKGROUND) + .color(UmideColor::LAPCE_BUTTON_PRIMARY_BACKGROUND) .multiply_alpha(0.8), ) }) .active(|s| { s.background( config - .color(LapceColor::LAPCE_BUTTON_PRIMARY_BACKGROUND) + .color(UmideColor::LAPCE_BUTTON_PRIMARY_BACKGROUND) .multiply_alpha(0.6), ) }) - .disabled(|s| s.background(config.color(LapceColor::EDITOR_DIM))) + .disabled(|s| s.background(config.color(UmideColor::EDITOR_DIM))) .set_disabled({ let a: bool = installed.get(); let b: bool= installing.get(); @@ -331,7 +331,7 @@ fn available_view(plugin: PluginData, core_rpc: CoreRpcHandler) -> impl View { .cursor(CursorStyle::Pointer) .hover(|s| { s.background( - config.get().color(LapceColor::PANEL_HOVERED_BACKGROUND), + config.get().color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }) }) @@ -372,10 +372,10 @@ fn available_view(plugin: PluginData, core_rpc: CoreRpcHandler) -> impl View { s.width_pct(100.0) .cursor(CursorStyle::Text) .items_center() - .background(config.color(LapceColor::EDITOR_BACKGROUND)) + .background(config.color(UmideColor::EDITOR_BACKGROUND)) .border(1.0) .border_radius(6.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) }) }) .style(|s| s.padding(10.0).width_pct(100.0)), diff --git a/crates/umide/src/panel/problem_view.rs b/crates/umide/src/panel/problem_view.rs index ddb6de60..68e0ef1c 100644 --- a/crates/umide/src/panel/problem_view.rs +++ b/crates/umide/src/panel/problem_view.rs @@ -15,13 +15,13 @@ use lsp_types::{DiagnosticRelatedInformation, DiagnosticSeverity}; use super::{data::PanelSection, position::PanelPosition, view::PanelBuilder}; use crate::{ command::InternalCommand, - config::{LapceConfig, color::LapceColor, icon::LapceIcons}, + config::{UmideConfig, color::UmideColor, icon::UmideIcons}, doc::{DiagnosticData, EditorDiagnostic}, editor::location::{EditorLocation, EditorPosition}, listener::Listener, lsp::path_from_url, window_tab::WindowTabData, - workspace::LapceWorkspace, + workspace::UmideWorkspace, }; pub fn problem_panel( @@ -36,7 +36,7 @@ pub fn problem_panel( problem_section(window_tab_data.clone(), DiagnosticSeverity::ERROR), window_tab_data.panel.section_open(PanelSection::Error), move |s| { - s.border_color(config.get().color(LapceColor::LAPCE_BORDER)) + s.border_color(config.get().color(UmideColor::LAPCE_BORDER)) .apply_if(is_bottom, |s| s.border_right(1.0)) .apply_if(!is_bottom, |s| s.border_bottom(1.0)) }, @@ -81,12 +81,12 @@ fn problem_section( } fn file_view( - workspace: Arc, + workspace: Arc, path: PathBuf, diagnostic_data: DiagnosticData, severity: DiagnosticSeverity, internal_command: Listener, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { let collapsed = RwSignal::new(false); @@ -137,14 +137,14 @@ fn file_view( let style_path = path.clone(); let icon = match severity { - DiagnosticSeverity::ERROR => LapceIcons::ERROR, - _ => LapceIcons::WARNING, + DiagnosticSeverity::ERROR => UmideIcons::ERROR, + _ => UmideIcons::WARNING, }; let icon_color = move || { let config = config.get(); match severity { - DiagnosticSeverity::ERROR => config.color(LapceColor::LAPCE_ERROR), - _ => config.color(LapceColor::LAPCE_WARN), + DiagnosticSeverity::ERROR => config.color(UmideColor::LAPCE_ERROR), + _ => config.color(UmideColor::LAPCE_WARN), } }; @@ -171,7 +171,7 @@ fn file_view( .selectable(false) }), Label::new( folder.clone()).style(move |s| { - s.color(config.get().color(LapceColor::EDITOR_DIM)) + s.color(config.get().color(UmideColor::EDITOR_DIM)) .min_width(0.0) .text_ellipsis() .selectable(false) @@ -190,16 +190,16 @@ fn file_view( .padding_right(10.0) .hover(|s| { s.cursor(CursorStyle::Pointer).background( - config.color(LapceColor::PANEL_HOVERED_BACKGROUND), + config.color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }) }), Stack::new(( svg(move || { config.get().ui_svg(if collapsed.get() { - LapceIcons::ITEM_CLOSED + UmideIcons::ITEM_CLOSED } else { - LapceIcons::ITEM_OPENED + UmideIcons::ITEM_OPENED }) }) .style(move |s| { @@ -207,7 +207,7 @@ fn file_view( let size = config.ui.icon_size() as f32; s.margin_right(6.0) .size(size, size) - .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + .color(config.color(UmideColor::LAPCE_ICON_ACTIVE)) }), svg(move || config.get().file_svg(&path).0).style(move |s| { let config = config.get(); @@ -258,7 +258,7 @@ fn item_view( icon: &'static str, icon_color: impl Fn() -> Color + 'static, internal_command: Listener, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { let related = d.diagnostic.related_information.unwrap_or_default(); let position = if let Some((start, _)) = d.range { @@ -301,7 +301,7 @@ fn item_view( .style(move |s| { s.width_pct(100.0).min_width(0.0).hover(|s| { s.cursor(CursorStyle::Pointer).background( - config.get().color(LapceColor::PANEL_HOVERED_BACKGROUND), + config.get().color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }) }) @@ -320,7 +320,7 @@ fn item_view( fn related_view( related: Vec, internal_command: Listener, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { let is_empty = related.is_empty(); Stack::new(( @@ -367,7 +367,7 @@ fn related_view( .min_width(0.0) .hover(|s| { s.cursor(CursorStyle::Pointer).background( - config.color(LapceColor::PANEL_HOVERED_BACKGROUND), + config.color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }) }) @@ -375,11 +375,11 @@ fn related_view( ) .style(|s| s.width_pct(100.0).min_width(0.0).flex_col()), Stack::new(( - svg(move || config.get().ui_svg(LapceIcons::LINK)).style(move |s| { + svg(move || config.get().ui_svg(UmideIcons::LINK)).style(move |s| { let config = config.get(); let size = config.ui.icon_size() as f32; s.size(size, size) - .color(config.color(LapceColor::EDITOR_DIM)) + .color(config.color(UmideColor::EDITOR_DIM)) }), Label::new(" ".to_string()).style(move |s| s.selectable(false)), )) @@ -393,7 +393,7 @@ fn related_view( s.width_pct(100.0) .min_width(0.0) .items_start() - .color(config.get().color(LapceColor::EDITOR_DIM)) + .color(config.get().color(UmideColor::EDITOR_DIM)) .apply_if(is_empty, |s| s.hide()) }) } diff --git a/crates/umide/src/panel/source_control_view.rs b/crates/umide/src/panel/source_control_view.rs index 6002ded8..ed155c69 100644 --- a/crates/umide/src/panel/source_control_view.rs +++ b/crates/umide/src/panel/source_control_view.rs @@ -21,8 +21,8 @@ use super::{ view::foldable_panel_section, }; use crate::{ - command::{CommandKind, InternalCommand, LapceCommand, LapceWorkbenchCommand}, - config::{color::LapceColor, icon::LapceIcons}, + command::{CommandKind, InternalCommand, UmideCommand, UmideWorkbenchCommand}, + config::{color::UmideColor, icon::UmideIcons}, editor::view::editor_view, settings::checkbox, source_control::SourceControlData, @@ -71,7 +71,7 @@ pub fn source_control_panel( s.absolute() .items_center() .height(config.editor.line_height() as f32) - .color(config.color(LapceColor::EDITOR_DIM)) + .color(config.color(UmideColor::EDITOR_DIM)) .apply_if(!is_empty.get(), |s| s.hide()) .selectable(false) }), @@ -144,8 +144,8 @@ pub fn source_control_panel( .border(1.0) .padding(-1.0) .border_radius(6.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) - .background(config.color(LapceColor::EDITOR_BACKGROUND)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) + .background(config.color(UmideColor::EDITOR_BACKGROUND)) }), { let source_control = source_control.clone(); @@ -161,16 +161,16 @@ pub fn source_control_panel( .justify_center() .border(1.0) .border_radius(6.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) .hover(|s| { s.cursor(CursorStyle::Pointer).background( config - .color(LapceColor::PANEL_HOVERED_BACKGROUND), + .color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }) .active(|s| { s.background(config.color( - LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND, + UmideColor::PANEL_HOVERED_ACTIVE_BACKGROUND, )) }) .selectable(false) @@ -267,17 +267,17 @@ fn file_diffs_view(source_control: SourceControlData) -> impl View { s.text_ellipsis() .flex_grow(1.0) .flex_basis(0.0) - .color(config.get().color(LapceColor::EDITOR_DIM)) + .color(config.get().color(UmideColor::EDITOR_DIM)) .min_width(0.0) .selectable(false) }), Container::new({ svg(move || { let svg = match &diff { - FileDiff::Modified(_) => LapceIcons::SCM_DIFF_MODIFIED, - FileDiff::Added(_) => LapceIcons::SCM_DIFF_ADDED, - FileDiff::Deleted(_) => LapceIcons::SCM_DIFF_REMOVED, - FileDiff::Renamed(_, _) => LapceIcons::SCM_DIFF_RENAMED, + FileDiff::Modified(_) => UmideIcons::SCM_DIFF_MODIFIED, + FileDiff::Added(_) => UmideIcons::SCM_DIFF_ADDED, + FileDiff::Deleted(_) => UmideIcons::SCM_DIFF_REMOVED, + FileDiff::Renamed(_, _) => UmideIcons::SCM_DIFF_RENAMED, }; config.get().ui_svg(svg) }) @@ -285,11 +285,11 @@ fn file_diffs_view(source_control: SourceControlData) -> impl View { let config = config.get(); let size = config.ui.icon_size() as f32; let color = match &diff_for_style { - FileDiff::Modified(_) => LapceColor::SOURCE_CONTROL_MODIFIED, - FileDiff::Added(_) => LapceColor::SOURCE_CONTROL_ADDED, - FileDiff::Deleted(_) => LapceColor::SOURCE_CONTROL_REMOVED, + FileDiff::Modified(_) => UmideColor::SOURCE_CONTROL_MODIFIED, + FileDiff::Added(_) => UmideColor::SOURCE_CONTROL_ADDED, + FileDiff::Deleted(_) => UmideColor::SOURCE_CONTROL_REMOVED, FileDiff::Renamed(_, _) => { - LapceColor::SOURCE_CONTROL_MODIFIED + UmideColor::SOURCE_CONTROL_MODIFIED } }; let color = config.color(color); @@ -313,9 +313,9 @@ fn file_diffs_view(source_control: SourceControlData) -> impl View { let diff_for_menu = diff_for_menu.clone(); let discard = move || { - lapce_command.send(LapceCommand { + lapce_command.send(UmideCommand { kind: CommandKind::Workbench( - LapceWorkbenchCommand::SourceControlDiscardTargetFileChanges, + UmideWorkbenchCommand::SourceControlDiscardTargetFileChanges, ), data: Some(serde_json::json!(diff_for_menu.clone())), }); @@ -336,7 +336,7 @@ fn file_diffs_view(source_control: SourceControlData) -> impl View { .items_center() .cursor(CursorStyle::Pointer) .hover(|s| { - s.background(config.color(LapceColor::PANEL_HOVERED_BACKGROUND)) + s.background(config.color(UmideColor::PANEL_HOVERED_BACKGROUND)) }) }) }; diff --git a/crates/umide/src/panel/terminal_view.rs b/crates/umide/src/panel/terminal_view.rs index 2c9670d4..27574888 100644 --- a/crates/umide/src/panel/terminal_view.rs +++ b/crates/umide/src/panel/terminal_view.rs @@ -10,8 +10,8 @@ use umide_rpc::terminal::TermId; use super::kind::PanelKind; use crate::{ app::clickable_icon, - command::{InternalCommand, LapceWorkbenchCommand}, - config::{color::LapceColor, icon::LapceIcons}, + command::{InternalCommand, UmideWorkbenchCommand}, + config::{color::UmideColor, icon::UmideIcons}, debug::RunDebugMode, listener::Listener, terminal::{ @@ -91,17 +91,17 @@ fn terminal_tab_header(window_tab_data: Rc) -> impl View { run_debug.as_ref().map(|r| (r.mode, r.stopped)) }) { let svg = match (mode, stopped) { - (RunDebugMode::Run, false) => LapceIcons::START, - (RunDebugMode::Run, true) => LapceIcons::RUN_ERRORS, - (RunDebugMode::Debug, false) => LapceIcons::DEBUG, + (RunDebugMode::Run, false) => UmideIcons::START, + (RunDebugMode::Run, true) => UmideIcons::RUN_ERRORS, + (RunDebugMode::Debug, false) => UmideIcons::DEBUG, (RunDebugMode::Debug, true) => { - LapceIcons::DEBUG_DISCONNECT + UmideIcons::DEBUG_DISCONNECT } }; return svg; } } - LapceIcons::TERMINAL + UmideIcons::TERMINAL }; Stack::new(( Container::new({ @@ -113,7 +113,7 @@ fn terminal_tab_header(window_tab_data: Rc) -> impl View { let size = config.ui.icon_size() as f32; s.size(size, size).color( config.color( - LapceColor::LAPCE_ICON_ACTIVE, + UmideColor::LAPCE_ICON_ACTIVE, ), ) }), @@ -127,7 +127,7 @@ fn terminal_tab_header(window_tab_data: Rc) -> impl View { .selectable(false) }), clickable_icon( - || LapceIcons::CLOSE, + || UmideIcons::CLOSE, move || { terminal.close_tab(Some(terminal_tab_id)); }, @@ -143,14 +143,14 @@ fn terminal_tab_header(window_tab_data: Rc) -> impl View { .height(header_height.get() - 15.0) .border_right(1.0) .border_color( - config.get().color(LapceColor::LAPCE_BORDER), + config.get().color(UmideColor::LAPCE_BORDER), ) .pointer_events_none() }), )) .style(move |s| { s.items_center().width(200.0).border_color( - config.get().color(LapceColor::LAPCE_BORDER), + config.get().color(UmideColor::LAPCE_BORDER), ) }) }) @@ -167,9 +167,9 @@ fn terminal_tab_header(window_tab_data: Rc) -> impl View { if focus.get() == Focus::Panel(PanelKind::Terminal) { - LapceColor::LAPCE_TAB_ACTIVE_UNDERLINE + UmideColor::LAPCE_TAB_ACTIVE_UNDERLINE } else { - LapceColor::LAPCE_TAB_INACTIVE_UNDERLINE + UmideColor::LAPCE_TAB_INACTIVE_UNDERLINE }, )) }) @@ -215,9 +215,9 @@ fn terminal_tab_header(window_tab_data: Rc) -> impl View { s.size(size.width, size.height).pointer_events_none() }), Container::new(clickable_icon( - || LapceIcons::ADD, + || UmideIcons::ADD, move || { - workbench_command.send(LapceWorkbenchCommand::NewTerminalTab); + workbench_command.send(UmideWorkbenchCommand::NewTerminalTab); }, || false, || false, @@ -252,7 +252,7 @@ fn terminal_tab_header(window_tab_data: Rc) -> impl View { s.width_pct(100.0) .items_center() .border_bottom(1.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) }) } @@ -326,7 +326,7 @@ fn terminal_tab_split( index.get() > 0, |s| { s.border_left(1.0).border_color( - config.get().color(LapceColor::LAPCE_BORDER), + config.get().color(UmideColor::LAPCE_BORDER), ) }, ) diff --git a/crates/umide/src/panel/view.rs b/crates/umide/src/panel/view.rs index aa8f3fed..62e3c817 100644 --- a/crates/umide/src/panel/view.rs +++ b/crates/umide/src/panel/view.rs @@ -22,7 +22,7 @@ use super::{ }; use crate::{ app::{clickable_icon, clickable_icon_base}, - config::{LapceConfig, color::LapceColor, icon::LapceIcons}, + config::{UmideConfig, color::UmideColor, icon::UmideIcons}, file_explorer::view::file_explorer_panel, panel::{ call_hierarchy_view::show_hierarchy_panel, document_symbol::symbol_panel, @@ -36,16 +36,16 @@ pub fn foldable_panel_section( header: impl View + 'static, child: impl View + 'static, open: RwSignal, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { Stack::new(( Stack::horizontal(( clickable_icon_base( move || { if open.get() { - LapceIcons::PANEL_FOLD_DOWN + UmideIcons::PANEL_FOLD_DOWN } else { - LapceIcons::PANEL_FOLD_UP + UmideIcons::PANEL_FOLD_UP } }, None::>, @@ -60,7 +60,7 @@ pub fn foldable_panel_section( .padding_vert(6.0) .width_pct(100.0) .cursor(CursorStyle::Pointer) - .background(config.get().color(LapceColor::EDITOR_BACKGROUND)) + .background(config.get().color(UmideColor::EDITOR_BACKGROUND)) }) .on_click_stop(move |_| { open.update(|open| *open = !*open); @@ -72,12 +72,12 @@ pub fn foldable_panel_section( /// A builder for creating a foldable panel out of sections pub struct PanelBuilder { views: Vec, - config: ReadSignal>, + config: ReadSignal>, position: PanelPosition, } impl PanelBuilder { pub fn new( - config: ReadSignal>, + config: ReadSignal>, position: PanelPosition, ) -> Self { Self { @@ -252,7 +252,7 @@ pub fn panel_container_view( s.background( config .get() - .color(LapceColor::EDITOR_DRAG_DROP_BACKGROUND), + .color(UmideColor::EDITOR_DRAG_DROP_BACKGROUND), ) }) }) @@ -359,7 +359,7 @@ pub fn panel_container_view( s.width(4.0).margin_left(-2.0).height_pct(100.0) }) .apply_if(is_dragging, |s| { - s.background(config.color(LapceColor::EDITOR_CARET)) + s.background(config.color(UmideColor::EDITOR_CARET)) .apply_if( position == PanelContainerPosition::Bottom, |s| s.cursor(CursorStyle::RowResize), @@ -371,7 +371,7 @@ pub fn panel_container_view( .z_index(2) }) .hover(|s| { - s.background(config.color(LapceColor::EDITOR_CARET)) + s.background(config.color(UmideColor::EDITOR_CARET)) .apply_if( position == PanelContainerPosition::Bottom, |s| s.cursor(CursorStyle::RowResize), @@ -429,17 +429,17 @@ pub fn panel_container_view( s.border_right(1.0) .width(size as f32) .height_pct(100.0) - .background(config.color(LapceColor::PANEL_BACKGROUND)) + .background(config.color(UmideColor::PANEL_BACKGROUND)) }) .apply_if(position == PanelContainerPosition::Right, |s| { s.border_left(1.0) .width(size as f32) .height_pct(100.0) - .background(config.color(LapceColor::PANEL_BACKGROUND)) + .background(config.color(UmideColor::PANEL_BACKGROUND)) }) .apply_if(!is_bottom, |s| s.flex_col()) - .border_color(config.color(LapceColor::LAPCE_BORDER)) - .color(config.color(LapceColor::PANEL_FOREGROUND)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) + .color(config.color(UmideColor::PANEL_FOREGROUND)) }) .debug_name(format!("{:?} Pannel Container View", position)) } @@ -523,13 +523,13 @@ fn panel_view( pub fn panel_header( header: String, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { Container::new(Label::new(header.clone())).style(move |s| { s.padding_horiz(10.0) .padding_vert(6.0) .width_pct(100.0) - .background(config.get().color(LapceColor::EDITOR_BACKGROUND)) + .background(config.get().color(UmideColor::EDITOR_BACKGROUND)) }) } @@ -602,11 +602,11 @@ fn panel_picker( let config = config.get(); s.border(1.0) .border_radius(6.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) .padding(6.0) .background( config - .color(LapceColor::PANEL_BACKGROUND) + .color(UmideColor::PANEL_BACKGROUND) .multiply_alpha(0.7), ) }) @@ -633,7 +633,7 @@ fn panel_picker( .border_color( config .get() - .color(LapceColor::LAPCE_TAB_ACTIVE_UNDERLINE), + .color(UmideColor::LAPCE_TAB_ACTIVE_UNDERLINE), ) }), ))) @@ -641,7 +641,7 @@ fn panel_picker( }, ) .style(move |s| { - s.border_color(config.get().color(LapceColor::LAPCE_BORDER)) + s.border_color(config.get().color(UmideColor::LAPCE_BORDER)) .apply_if( panels.with(|p| { p.get(&position).map(|p| p.is_empty()).unwrap_or(true) diff --git a/crates/umide/src/plugin.rs b/crates/umide/src/plugin.rs index 14eed065..6583ddbc 100644 --- a/crates/umide/src/plugin.rs +++ b/crates/umide/src/plugin.rs @@ -35,8 +35,8 @@ use sha2::{Digest, Sha256}; use crate::{ command::{CommandExecuted, CommandKind}, - config::{LapceConfig, color::LapceColor}, - db::LapceDb, + config::{UmideConfig, color::UmideColor}, + db::UmideDb, editor::EditorData, keypress::{KeyPressFocus, condition::Condition}, main_split::Editors, @@ -120,7 +120,7 @@ impl KeyPressFocus for PluginData { fn run_command( &self, - command: &crate::command::LapceCommand, + command: &crate::command::UmideCommand, count: Option, mods: Modifiers, ) -> CommandExecuted { @@ -313,7 +313,7 @@ impl PluginData { self.disabled.update(|d| { d.remove(&id); }); - let db: Arc = Context::get().unwrap(); + let db: Arc = Context::get().unwrap(); db.save_disabled_volts( self.disabled.get_untracked().into_iter().collect(), ); @@ -323,7 +323,7 @@ impl PluginData { self.workspace_disabled.update(|d| { d.remove(&id); }); - let db: Arc = Context::get().unwrap(); + let db: Arc = Context::get().unwrap(); db.save_workspace_disabled_volts( self.common.workspace.clone(), self.workspace_disabled @@ -451,7 +451,7 @@ impl PluginData { fn download_readme( volt: &VoltInfo, - config: &LapceConfig, + config: &UmideConfig, ) -> Result> { let url = format!( "https://plugins.lapce.dev/api/v1/plugins/{}/{}/{}/readme", @@ -535,7 +535,7 @@ impl PluginData { if !self.plugin_disabled(&id) { self.common.proxy.enable_volt(volt); } - let db: Arc = Context::get().unwrap(); + let db: Arc = Context::get().unwrap(); db.save_disabled_volts(self.disabled.get_untracked().into_iter().collect()); } @@ -545,7 +545,7 @@ impl PluginData { d.insert(id); }); self.common.proxy.disable_volt(volt); - let db: Arc = Context::get().unwrap(); + let db: Arc = Context::get().unwrap(); db.save_disabled_volts(self.disabled.get_untracked().into_iter().collect()); } @@ -557,7 +557,7 @@ impl PluginData { if !self.plugin_disabled(&id) { self.common.proxy.enable_volt(volt); } - let db: Arc = Context::get().unwrap(); + let db: Arc = Context::get().unwrap(); db.save_workspace_disabled_volts( self.common.workspace.clone(), self.disabled.get_untracked().into_iter().collect(), @@ -570,7 +570,7 @@ impl PluginData { d.insert(id); }); self.common.proxy.disable_volt(volt); - let db: Arc = Context::get().unwrap(); + let db: Arc = Context::get().unwrap(); db.save_workspace_disabled_volts( self.common.workspace.clone(), self.disabled.get_untracked().into_iter().collect(), @@ -769,17 +769,17 @@ pub fn plugin_info_view(plugin: PluginData, volt: VoltID) -> impl View { .border_radius(6.0) .color( config - .color(LapceColor::LAPCE_BUTTON_PRIMARY_FOREGROUND), + .color(UmideColor::LAPCE_BUTTON_PRIMARY_FOREGROUND), ) .background( config - .color(LapceColor::LAPCE_BUTTON_PRIMARY_BACKGROUND), + .color(UmideColor::LAPCE_BUTTON_PRIMARY_BACKGROUND), ) .hover(|s| { s.cursor(CursorStyle::Pointer).background( config .color( - LapceColor::LAPCE_BUTTON_PRIMARY_BACKGROUND, + UmideColor::LAPCE_BUTTON_PRIMARY_BACKGROUND, ) .multiply_alpha(0.8), ) @@ -788,13 +788,13 @@ pub fn plugin_info_view(plugin: PluginData, volt: VoltID) -> impl View { s.background( config .color( - LapceColor::LAPCE_BUTTON_PRIMARY_BACKGROUND, + UmideColor::LAPCE_BUTTON_PRIMARY_BACKGROUND, ) .multiply_alpha(0.6), ) }) .disabled(|s| { - s.background(config.color(LapceColor::EDITOR_DIM)) + s.background(config.color(UmideColor::EDITOR_DIM)) }) .selectable(false) .set_disabled(installing.map(|i| i.get()).unwrap_or(false)) @@ -891,7 +891,7 @@ pub fn plugin_info_view(plugin: PluginData, volt: VoltID) -> impl View { move || { config .get() - .color(LapceColor::EDITOR_LINK) + .color(UmideColor::EDITOR_LINK) }, internal_command, ), @@ -904,7 +904,7 @@ pub fn plugin_info_view(plugin: PluginData, volt: VoltID) -> impl View { .unwrap_or(""), ) .style(move |s| { - s.color(config.get().color(LapceColor::EDITOR_DIM)) + s.color(config.get().color(UmideColor::EDITOR_DIM)) }), version_view(local_plugin.clone(), plugin_info.clone()), )) @@ -924,7 +924,7 @@ pub fn plugin_info_view(plugin: PluginData, volt: VoltID) -> impl View { s.margin_vert(6) .height(1) .width_full() - .background(config.get().color(LapceColor::LAPCE_BORDER)) + .background(config.get().color(UmideColor::LAPCE_BORDER)) }), { let readme = RwSignal::new(None); @@ -982,7 +982,7 @@ pub fn plugin_info_view(plugin: PluginData, volt: VoltID) -> impl View { .height(1.0) .background( config.get().color( - LapceColor::LAPCE_BORDER, + UmideColor::LAPCE_BORDER, ), ) })) diff --git a/crates/umide/src/proxy.rs b/crates/umide/src/proxy.rs index c56b5ade..9c2ae0f1 100644 --- a/crates/umide/src/proxy.rs +++ b/crates/umide/src/proxy.rs @@ -18,7 +18,7 @@ use tracing::error; use self::{remote::start_remote, ssh::SshRemote}; use crate::{ terminal::event::TermEvent, - workspace::{LapceWorkspace, LapceWorkspaceType}, + workspace::{UmideWorkspace, UmideWorkspaceType}, }; mod remote; @@ -46,7 +46,7 @@ impl ProxyData { } pub fn new_proxy( - workspace: Arc, + workspace: Arc, disabled_volts: Vec, extra_plugin_paths: Vec, plugin_configurations: HashMap>, @@ -74,14 +74,14 @@ pub fn new_proxy( ); match &workspace.kind { - LapceWorkspaceType::Local => { + UmideWorkspaceType::Local => { let core_rpc = core_rpc.clone(); let proxy_rpc = proxy_rpc.clone(); let mut dispatcher = Dispatcher::new(core_rpc, proxy_rpc); let proxy_rpc = dispatcher.proxy_rpc.clone(); proxy_rpc.mainloop(&mut dispatcher); } - LapceWorkspaceType::RemoteSSH(remote) => { + UmideWorkspaceType::RemoteSSH(remote) => { if let Err(e) = start_remote( SshRemote { ssh: remote.clone(), @@ -93,7 +93,7 @@ pub fn new_proxy( } } #[cfg(windows)] - LapceWorkspaceType::RemoteWSL(remote) => { + UmideWorkspaceType::RemoteWSL(remote) => { if let Err(e) = start_remote( wsl::WslRemote { wsl: remote.clone(), diff --git a/crates/umide/src/proxy/remote.rs b/crates/umide/src/proxy/remote.rs index 8514ee3f..e1a0c639 100644 --- a/crates/umide/src/proxy/remote.rs +++ b/crates/umide/src/proxy/remote.rs @@ -123,10 +123,10 @@ pub fn start_remote( .output() .map(|output| { if meta::RELEASE == ReleaseType::Debug { - String::from_utf8_lossy(&output.stdout).starts_with("Lapce-proxy") + String::from_utf8_lossy(&output.stdout).starts_with("Umide-proxy") } else { String::from_utf8_lossy(&output.stdout).trim() - == format!("Lapce-proxy {}", meta::VERSION) + == format!("Umide-proxy {}", meta::VERSION) } }) .unwrap_or(false) diff --git a/crates/umide/src/rename.rs b/crates/umide/src/rename.rs index 271d5c52..56933c52 100644 --- a/crates/umide/src/rename.rs +++ b/crates/umide/src/rename.rs @@ -12,7 +12,7 @@ use lapce_xi_rope::Rope; use lsp_types::Position; use crate::{ - command::{CommandExecuted, CommandKind, InternalCommand, LapceCommand}, + command::{CommandExecuted, CommandKind, InternalCommand, UmideCommand}, editor::EditorData, keypress::{KeyPressFocus, condition::Condition}, main_split::Editors, @@ -41,7 +41,7 @@ impl KeyPressFocus for RenameData { fn run_command( &self, - command: &LapceCommand, + command: &UmideCommand, count: Option, mods: Modifiers, ) -> CommandExecuted { diff --git a/crates/umide/src/settings.rs b/crates/umide/src/settings.rs index 54b5e39a..0b31cfaa 100644 --- a/crates/umide/src/settings.rs +++ b/crates/umide/src/settings.rs @@ -29,8 +29,8 @@ use serde_json::Value; use crate::{ command::CommandExecuted, config::{ - DropdownInfo, LapceConfig, color::LapceColor, core::CoreConfig, - editor::EditorConfig, icon::LapceIcons, terminal::TerminalConfig, + DropdownInfo, UmideConfig, color::UmideColor, core::CoreConfig, + editor::EditorConfig, icon::UmideIcons, terminal::TerminalConfig, ui::UIConfig, }, keypress::KeyPressFocus, @@ -106,7 +106,7 @@ impl KeyPressFocus for SettingsData { fn run_command( &self, - _command: &crate::command::LapceCommand, + _command: &crate::command::UmideCommand, _count: Option, _mods: Modifiers, ) -> crate::command::CommandExecuted { @@ -415,16 +415,16 @@ pub fn settings_view( s.padding_horiz(20.0) .width_pct(100.0) .apply_if(kind == current_kind.get(), |s| { - s.background(config.color(LapceColor::PANEL_CURRENT_BACKGROUND)) + s.background(config.color(UmideColor::PANEL_CURRENT_BACKGROUND)) }) .hover(|s| { s.cursor(CursorStyle::Pointer).background( - config.color(LapceColor::PANEL_HOVERED_BACKGROUND), + config.color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }) .active(|s| { s.background( - config.color(LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND), + config.color(UmideColor::PANEL_HOVERED_ACTIVE_BACKGROUND), ) }) }) @@ -482,7 +482,7 @@ pub fn settings_view( s.height_pct(100.0) .width(200.0) .border_right(1.0) - .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + .border_color(config.get().color(UmideColor::LAPCE_BORDER)) }), Stack::new(( Container::new({ @@ -495,7 +495,7 @@ pub fn settings_view( .border_radius(6.0) .border(1.0) .border_color( - config.get().color(LapceColor::LAPCE_BORDER), + config.get().color(UmideColor::LAPCE_BORDER), ) }) .request_focus(|| {}) @@ -626,7 +626,7 @@ fn settings_item_view( }; if let Some(value) = value { - LapceConfig::update_file( + UmideConfig::update_file( &kind, &field, value, ); } @@ -642,7 +642,7 @@ fn settings_item_view( .style(|s| s.focusable(true)) .style(move |s| { s.width(300.0).border(1.0).border_radius(6.0).border_color( - config.get().color(LapceColor::LAPCE_BORDER), + config.get().color(UmideColor::LAPCE_BORDER), ) }) .into_any() @@ -674,7 +674,7 @@ fn settings_item_view( .width_pct(100.0) .padding_horiz(10.0) .font_size(config.ui.font_size() as f32 + 2.0) - .background(config.color(LapceColor::PANEL_BACKGROUND)) + .background(config.color(UmideColor::PANEL_BACKGROUND)) }) .into_any() } else { @@ -716,7 +716,7 @@ fn settings_item_view( &checked, toml_edit::ser::ValueSerializer::new(), ) { - LapceConfig::update_file(&kind, &field, value); + UmideConfig::update_file(&kind, &field, value); } }); @@ -764,7 +764,7 @@ fn settings_item_view( pub fn checkbox( checked: impl Fn() -> bool + 'static, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { const CHECKBOX_SVG: &str = r#""#; let svg_str = move || if checked() { CHECKBOX_SVG } else { "" }.to_string(); @@ -772,7 +772,7 @@ pub fn checkbox( svg(svg_str).style(move |s| { let config = config.get(); let size = config.ui.font_size() as f32; - let color = config.color(LapceColor::EDITOR_FOREGROUND); + let color = config.color(UmideColor::EDITOR_FOREGROUND); s.min_width(size) .size(size, size) @@ -914,14 +914,14 @@ fn color_section_list( .ok(); if let Some(value) = value { - LapceConfig::update_file( + UmideConfig::update_file( &format!("color-theme.{kind}"), &field, value, ); } } else { - LapceConfig::reset_setting( + UmideConfig::reset_setting( &format!("color-theme.{kind}"), &field, ); @@ -947,7 +947,7 @@ fn color_section_list( .border(1) .border_radius(6) .border_color( - config.get().color(LapceColor::LAPCE_BORDER), + config.get().color(UmideColor::LAPCE_BORDER), ) }), Empty::new().style(move |s| { @@ -963,9 +963,9 @@ fn color_section_list( .border_radius(6) .size(size, size) .margin_left(10) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) .background(color.unwrap_or_else(|| { - config.color(LapceColor::EDITOR_FOREGROUND) + config.color(UmideColor::EDITOR_FOREGROUND) })) }), { @@ -975,7 +975,7 @@ fn color_section_list( let local_kind = kind.clone(); Label::new("Reset") .on_click_stop(move |_| { - LapceConfig::reset_setting( + UmideConfig::reset_setting( &format!("color-theme.{local_kind}"), &local_key, ); @@ -1008,13 +1008,13 @@ fn color_section_list( .border(1) .border_radius(6) .border_color( - config.color(LapceColor::LAPCE_BORDER), + config.color(UmideColor::LAPCE_BORDER), ) .apply_if(same, |s| s.hide()) .active(|s| { s.background( config - .color(LapceColor::PANEL_BACKGROUND), + .color(UmideColor::PANEL_BACKGROUND), ) }) }) @@ -1092,7 +1092,7 @@ pub fn theme_color_settings_view( .border_radius(6.0) .border(1.0) .border_color( - config.get().color(LapceColor::LAPCE_BORDER), + config.get().color(UmideColor::LAPCE_BORDER), ) }) .request_focus(|| {}) @@ -1184,7 +1184,7 @@ fn dropdown_view( dropdown: &DropdownInfo, expanded: RwSignal, window_size: RwSignal, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View + use<> { let window_origin = RwSignal::new(Point::ZERO); let size = RwSignal::new(Size::ZERO); @@ -1231,16 +1231,16 @@ fn dropdown_view( Container::new( svg(move || { if expanded.get() { - config.get().ui_svg(LapceIcons::CLOSE) + config.get().ui_svg(UmideIcons::CLOSE) } else { - config.get().ui_svg(LapceIcons::DROPDOWN_ARROW) + config.get().ui_svg(UmideIcons::DROPDOWN_ARROW) } }) .style(move |s| { let config = config.get(); let size = config.ui.icon_size() as f32; s.size(size, size) - .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + .color(config.color(UmideColor::LAPCE_ICON_ACTIVE)) }), ) .style(|s| s.padding_right(4.0)), @@ -1262,7 +1262,7 @@ fn dropdown_view( .style(move |s| { s.items_center() .cursor(CursorStyle::Pointer) - .border_color(config.get().color(LapceColor::LAPCE_BORDER)) + .border_color(config.get().color(UmideColor::LAPCE_BORDER)) .border(1.0) .border_radius(6.0) .width(250.0) @@ -1296,7 +1296,7 @@ fn dropdown_scroll_view( window_origin: RwSignal, input_size: RwSignal, window_size: RwSignal, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View + use<> { dropdown_scroll_focus.set(true); @@ -1313,14 +1313,14 @@ fn dropdown_scroll_view( &item_string, toml_edit::ser::ValueSerializer::new(), ) { - LapceConfig::update_file(&kind, &field, value); + UmideConfig::update_file(&kind, &field, value); } expanded.set(false); }) .style(move |s| { s.text_ellipsis().padding_horiz(10.0).hover(|s| { s.cursor(CursorStyle::Pointer).background( - config.get().color(LapceColor::PANEL_HOVERED_BACKGROUND), + config.get().color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }) }) @@ -1380,16 +1380,16 @@ fn dropdown_scroll_view( .line_height(1.8) .font_size(config.ui.font_size() as f32) .font_family(config.ui.font_family.clone()) - .color(config.color(LapceColor::EDITOR_FOREGROUND)) - .background(config.color(LapceColor::EDITOR_BACKGROUND)) + .color(config.color(UmideColor::EDITOR_FOREGROUND)) + .background(config.color(UmideColor::EDITOR_BACKGROUND)) .class(floem::views::scroll::Handle, |s| { - s.background(config.color(LapceColor::LAPCE_SCROLL_BAR)) + s.background(config.color(UmideColor::LAPCE_SCROLL_BAR)) }) .border(1) .border_radius(6.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) .box_shadow_blur(3.0) - .box_shadow_color(config.color(LapceColor::LAPCE_DROPDOWN_SHADOW)) + .box_shadow_color(config.color(UmideColor::LAPCE_DROPDOWN_SHADOW)) .inset_left(x) .inset_top(y) }) diff --git a/crates/umide/src/source_control.rs b/crates/umide/src/source_control.rs index c1a5aeb4..518eb131 100644 --- a/crates/umide/src/source_control.rs +++ b/crates/umide/src/source_control.rs @@ -41,7 +41,7 @@ impl KeyPressFocus for SourceControlData { fn run_command( &self, - command: &crate::command::LapceCommand, + command: &crate::command::UmideCommand, count: Option, mods: Modifiers, ) -> CommandExecuted { diff --git a/crates/umide/src/status.rs b/crates/umide/src/status.rs index 6ee0f75c..c9efb58e 100644 --- a/crates/umide/src/status.rs +++ b/crates/umide/src/status.rs @@ -18,8 +18,8 @@ use lsp_types::{DiagnosticSeverity, ProgressToken}; use crate::{ app::clickable_icon, - command::LapceWorkbenchCommand, - config::{LapceConfig, color::LapceColor, icon::LapceIcons}, + command::UmideWorkbenchCommand, + config::{UmideConfig, color::UmideColor, icon::UmideIcons}, editor::EditorData, listener::Listener, palette::kind::PaletteKind, @@ -31,9 +31,9 @@ use crate::{ pub fn status( window_tab_data: Rc, source_control: SourceControlData, - workbench_command: Listener, + workbench_command: Listener, status_height: RwSignal, - _config: ReadSignal>, + _config: ReadSignal>, ) -> impl View { let config = window_tab_data.common.config; let diagnostics = window_tab_data.main_split.diagnostics; @@ -96,20 +96,20 @@ pub fn status( let (bg, fg) = match mode.get() { Mode::Normal => ( - LapceColor::STATUS_MODAL_NORMAL_BACKGROUND, - LapceColor::STATUS_MODAL_NORMAL_FOREGROUND, + UmideColor::STATUS_MODAL_NORMAL_BACKGROUND, + UmideColor::STATUS_MODAL_NORMAL_FOREGROUND, ), Mode::Insert => ( - LapceColor::STATUS_MODAL_INSERT_BACKGROUND, - LapceColor::STATUS_MODAL_INSERT_FOREGROUND, + UmideColor::STATUS_MODAL_INSERT_BACKGROUND, + UmideColor::STATUS_MODAL_INSERT_FOREGROUND, ), Mode::Visual(_) => ( - LapceColor::STATUS_MODAL_VISUAL_BACKGROUND, - LapceColor::STATUS_MODAL_VISUAL_FOREGROUND, + UmideColor::STATUS_MODAL_VISUAL_BACKGROUND, + UmideColor::STATUS_MODAL_VISUAL_FOREGROUND, ), Mode::Terminal => ( - LapceColor::STATUS_MODAL_TERMINAL_BACKGROUND, - LapceColor::STATUS_MODAL_TERMINAL_FOREGROUND, + UmideColor::STATUS_MODAL_TERMINAL_BACKGROUND, + UmideColor::STATUS_MODAL_TERMINAL_FOREGROUND, ), }; @@ -125,15 +125,15 @@ pub fn status( .selectable(false) }), Stack::new(( - svg(move || config.get().ui_svg(LapceIcons::SCM)).style(move |s| { + svg(move || config.get().ui_svg(UmideIcons::SCM)).style(move |s| { let config = config.get(); let icon_size = config.ui.icon_size() as f32; s.size(icon_size, icon_size) - .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + .color(config.color(UmideColor::LAPCE_ICON_ACTIVE)) }), Label::derived(branch).style(move |s| { s.margin_left(10.0) - .color(config.get().color(LapceColor::STATUS_FOREGROUND)) + .color(config.get().color(UmideColor::STATUS_FOREGROUND)) .selectable(false) }), )) @@ -148,7 +148,7 @@ pub fn status( .align_items(Some(AlignItems::Center)) .hover(|s| { s.cursor(CursorStyle::Pointer).background( - config.get().color(LapceColor::PANEL_HOVERED_BACKGROUND), + config.get().color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }) }) @@ -160,7 +160,7 @@ pub fn status( move |_| { if pointer_down.get() { workbench_command - .send(LapceWorkbenchCommand::PaletteSCMReferences); + .send(UmideWorkbenchCommand::PaletteSCMReferences); } pointer_down.set(false); EventPropagation::Continue @@ -169,12 +169,12 @@ pub fn status( { let panel = panel.clone(); Stack::new(( - svg(move || config.get().ui_svg(LapceIcons::ERROR)).style( + svg(move || config.get().ui_svg(UmideIcons::ERROR)).style( move |s| { let config = config.get(); let size = config.ui.icon_size() as f32; s.size(size, size) - .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + .color(config.color(UmideColor::LAPCE_ICON_ACTIVE)) }, ), Label::derived(move || diagnostic_count.get().0.to_string()).style( @@ -183,18 +183,18 @@ pub fn status( .color( config .get() - .color(LapceColor::STATUS_FOREGROUND), + .color(UmideColor::STATUS_FOREGROUND), ) .selectable(false) }, ), - svg(move || config.get().ui_svg(LapceIcons::WARNING)).style( + svg(move || config.get().ui_svg(UmideIcons::WARNING)).style( move |s| { let config = config.get(); let size = config.ui.icon_size() as f32; s.size(size, size) .margin_left(5.0) - .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + .color(config.color(UmideColor::LAPCE_ICON_ACTIVE)) }, ), Label::derived(move || diagnostic_count.get().1.to_string()).style( @@ -203,7 +203,7 @@ pub fn status( .color( config .get() - .color(LapceColor::STATUS_FOREGROUND), + .color(UmideColor::STATUS_FOREGROUND), ) .selectable(false) }, @@ -220,7 +220,7 @@ pub fn status( s.cursor(CursorStyle::Pointer).background( config .get() - .color(LapceColor::PANEL_HOVERED_BACKGROUND), + .color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }) }) @@ -243,9 +243,9 @@ pub fn status( if panel .is_container_shown(&PanelContainerPosition::Left, true) { - LapceIcons::SIDEBAR_LEFT + UmideIcons::SIDEBAR_LEFT } else { - LapceIcons::SIDEBAR_LEFT_OFF + UmideIcons::SIDEBAR_LEFT_OFF } } }; @@ -269,9 +269,9 @@ pub fn status( &PanelContainerPosition::Bottom, true, ) { - LapceIcons::LAYOUT_PANEL + UmideIcons::LAYOUT_PANEL } else { - LapceIcons::LAYOUT_PANEL_OFF + UmideIcons::LAYOUT_PANEL_OFF } } }; @@ -295,9 +295,9 @@ pub fn status( if panel .is_container_shown(&PanelContainerPosition::Right, true) { - LapceIcons::SIDEBAR_RIGHT + UmideIcons::SIDEBAR_RIGHT } else { - LapceIcons::SIDEBAR_RIGHT_OFF + UmideIcons::SIDEBAR_RIGHT_OFF } } }; @@ -316,7 +316,7 @@ pub fn status( .style(move |s| { s.height_pct(100.0) .items_center() - .color(config.get().color(LapceColor::STATUS_FOREGROUND)) + .color(config.get().color(UmideColor::STATUS_FOREGROUND)) }), Stack::new({ let palette_clone = palette.clone(); @@ -398,8 +398,8 @@ pub fn status( .style(move |s| { let config = config.get(); s.border_top(1.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) - .background(config.color(LapceColor::STATUS_BACKGROUND)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) + .background(config.color(UmideColor::STATUS_BACKGROUND)) .flex_basis(config.ui.status_height() as f32) .flex_grow(0.0) .flex_shrink(0.0) @@ -409,7 +409,7 @@ pub fn status( } fn progress_view( - config: ReadSignal>, + config: ReadSignal>, progresses: RwSignal>, ) -> impl View { let id = AtomicU64::new(0); @@ -430,7 +430,7 @@ fn progress_view( .text_ellipsis() .selectable(false) .items_center() - .color(config.get().color(LapceColor::STATUS_FOREGROUND)) + .color(config.get().color(UmideColor::STATUS_FOREGROUND)) }) }, ) @@ -438,7 +438,7 @@ fn progress_view( } fn status_text( - config: ReadSignal>, + config: ReadSignal>, editor: Memo>, text: impl Fn() -> S + 'static, ) -> impl View { @@ -463,10 +463,10 @@ fn status_text( .height_full() .padding_horiz(10.0) .items_center() - .color(config.color(LapceColor::STATUS_FOREGROUND)) + .color(config.color(UmideColor::STATUS_FOREGROUND)) .hover(|s| { s.cursor(CursorStyle::Pointer) - .background(config.color(LapceColor::PANEL_HOVERED_BACKGROUND)) + .background(config.color(UmideColor::PANEL_HOVERED_BACKGROUND)) }) .selectable(false) }) diff --git a/crates/umide/src/terminal/data.rs b/crates/umide/src/terminal/data.rs index 1395c23b..5e283026 100644 --- a/crates/umide/src/terminal/data.rs +++ b/crates/umide/src/terminal/data.rs @@ -35,14 +35,14 @@ use crate::{ debug::{RunDebugMode, RunDebugProcess}, keypress::{KeyPressFocus, condition::Condition}, window_tab::CommonData, - workspace::LapceWorkspace, + workspace::UmideWorkspace, }; #[derive(Clone, Debug)] pub struct TerminalData { pub scope: Scope, pub term_id: TermId, - pub workspace: Arc, + pub workspace: Arc, pub title: RwSignal, pub launch_error: RwSignal>, pub mode: RwSignal, @@ -63,7 +63,7 @@ impl KeyPressFocus for TerminalData { fn run_command( &self, - command: &crate::command::LapceCommand, + command: &crate::command::UmideCommand, count: Option, _mods: Modifiers, ) -> crate::command::CommandExecuted { @@ -306,7 +306,7 @@ impl KeyPressFocus for TerminalData { impl TerminalData { pub fn new( cx: Scope, - workspace: Arc, + workspace: Arc, profile: Option, common: Rc, ) -> Self { @@ -315,7 +315,7 @@ impl TerminalData { pub fn new_run_debug( cx: Scope, - workspace: Arc, + workspace: Arc, run_debug: Option, profile: Option, common: Rc, @@ -360,7 +360,7 @@ impl TerminalData { } fn new_raw_terminal( - workspace: &LapceWorkspace, + workspace: &UmideWorkspace, term_id: TermId, run_debug: Option<&RunDebugProcess>, profile: Option, @@ -765,7 +765,7 @@ pub struct ExpandedRunDebug { } impl ExpandedRunDebug { pub fn expand( - workspace: &LapceWorkspace, + workspace: &UmideWorkspace, run_debug: &RunDebugConfig, is_prelaunch: bool, ) -> anyhow::Result { @@ -837,7 +837,7 @@ impl ExpandedRunDebug { } fn expand_work_dir( - workspace: &LapceWorkspace, + workspace: &UmideWorkspace, run_debug: &RunDebugConfig, ) -> Option { let path = run_debug.cwd.as_ref()?; diff --git a/crates/umide/src/terminal/panel.rs b/crates/umide/src/terminal/panel.rs index e03c9e28..6c7489e5 100644 --- a/crates/umide/src/terminal/panel.rs +++ b/crates/umide/src/terminal/panel.rs @@ -24,7 +24,7 @@ use crate::{ main_split::MainSplitData, panel::kind::PanelKind, window_tab::{CommonData, Focus}, - workspace::LapceWorkspace, + workspace::UmideWorkspace, }; pub struct TerminalTabInfo { @@ -35,7 +35,7 @@ pub struct TerminalTabInfo { #[derive(Clone)] pub struct TerminalPanelData { pub cx: Scope, - pub workspace: Arc, + pub workspace: Arc, pub tab_info: RwSignal, pub debug: RunDebugData, pub breakline: Memo>, @@ -45,7 +45,7 @@ pub struct TerminalPanelData { impl TerminalPanelData { pub fn new( - workspace: Arc, + workspace: Arc, profile: Option, common: Rc, main_split: MainSplitData, diff --git a/crates/umide/src/terminal/tab.rs b/crates/umide/src/terminal/tab.rs index 08551fa8..611e7514 100644 --- a/crates/umide/src/terminal/tab.rs +++ b/crates/umide/src/terminal/tab.rs @@ -6,7 +6,7 @@ use umide_rpc::terminal::TerminalProfile; use super::data::TerminalData; use crate::{ debug::RunDebugProcess, id::TerminalTabId, window_tab::CommonData, - workspace::LapceWorkspace, + workspace::UmideWorkspace, }; #[derive(Clone)] @@ -19,7 +19,7 @@ pub struct TerminalTabData { impl TerminalTabData { pub fn new( - workspace: Arc, + workspace: Arc, profile: Option, common: Rc, ) -> Self { @@ -28,7 +28,7 @@ impl TerminalTabData { /// Create the information for a terminal tab, which can contain multiple terminals. pub fn new_run_debug( - workspace: Arc, + workspace: Arc, run_debug: Option, profile: Option, common: Rc, diff --git a/crates/umide/src/terminal/view.rs b/crates/umide/src/terminal/view.rs index 1b8dab52..2577bc62 100644 --- a/crates/umide/src/terminal/view.rs +++ b/crates/umide/src/terminal/view.rs @@ -31,13 +31,13 @@ use unicode_width::UnicodeWidthChar; use super::{panel::TerminalPanelData, raw::RawTerminal}; use crate::{ command::InternalCommand, - config::{LapceConfig, color::LapceColor}, + config::{UmideConfig, color::UmideColor}, debug::RunDebugProcess, editor::location::{EditorLocation, EditorPosition}, listener::Listener, panel::kind::PanelKind, window_tab::Focus, - workspace::LapceWorkspace, + workspace::UmideWorkspace, }; /// Threshold used for double_click/triple_click. @@ -64,12 +64,12 @@ pub struct TerminalView { mode: ReadSignal, size: Size, is_focused: bool, - config: ReadSignal>, + config: ReadSignal>, run_config: ReadSignal>, proxy: ProxyRpcHandler, launch_error: RwSignal>, internal_command: Listener, - workspace: Arc, + workspace: Arc, hyper_regs: Vec, previous_mouse_action: MouseAction, current_mouse_action: MouseAction, @@ -84,7 +84,7 @@ pub fn terminal_view( terminal_panel_data: TerminalPanelData, launch_error: RwSignal>, internal_command: Listener, - workspace: Arc, + workspace: Arc, ) -> TerminalView { let id = ViewId::new(); @@ -329,9 +329,9 @@ impl TerminalView { content: RenderableContent, line_height: f64, char_size: Size, - config: &LapceConfig, + config: &UmideConfig, ) { - let term_bg = config.color(LapceColor::TERMINAL_BACKGROUND); + let term_bg = config.color(UmideColor::TERMINAL_BACKGROUND); let font_size = config.terminal_font_size(); let font_family = config.terminal_font_family(); @@ -429,7 +429,7 @@ impl TerminalView { line_content: &TerminalLineContent, line_height: f64, char_width: f64, - config: &LapceConfig, + config: &UmideConfig, ) { for (start, end, bg) in &line_content.bg { let rect = Size::new( @@ -459,12 +459,12 @@ impl TerminalView { if self.run_config.with_untracked(|run_config| { run_config.as_ref().map(|r| r.stopped).unwrap_or(false) }) { - config.color(LapceColor::LAPCE_ERROR) + config.color(UmideColor::LAPCE_ERROR) } else { - config.color(LapceColor::TERMINAL_CURSOR) + config.color(UmideColor::TERMINAL_CURSOR) } } else { - config.color(LapceColor::EDITOR_CARET) + config.color(UmideColor::EDITOR_CARET) }; if self.is_focused { cx.fill(&rect, cursor_color, 0.0); @@ -644,7 +644,7 @@ impl View for TerminalView { text_layout.set_text( &format!("Terminal failed to launch. Error: {error}"), AttrsList::new( - attrs.color(config.color(LapceColor::EDITOR_FOREGROUND)), + attrs.color(config.color(UmideColor::EDITOR_FOREGROUND)), ), None, ); @@ -692,7 +692,7 @@ impl View for TerminalView { let y1 = y0 + line_height; cx.fill( &Rect::new(x0, y0, x1, y1), - config.color(LapceColor::EDITOR_SELECTION), + config.color(UmideColor::EDITOR_SELECTION), 0.0, ); } @@ -702,7 +702,7 @@ impl View for TerminalView { * line_height; cx.fill( &Rect::new(0.0, y, self.size.width, y + line_height), - config.color(LapceColor::EDITOR_CURRENT_LINE), + config.color(UmideColor::EDITOR_CURRENT_LINE), 0.0, ); } @@ -750,7 +750,7 @@ impl View for TerminalView { // )); // cx.stroke( // &rect, - // config.get_color(LapceColor::TERMINAL_FOREGROUND), + // config.get_color(UmideColor::TERMINAL_FOREGROUND), // 1.0, // ); // start = *m.end(); diff --git a/crates/umide/src/text_area.rs b/crates/umide/src/text_area.rs index 9d3c1fce..ca54df6f 100644 --- a/crates/umide/src/text_area.rs +++ b/crates/umide/src/text_area.rs @@ -9,7 +9,7 @@ use floem::{ }; use umide_core::buffer::rope_text::RopeText; -use crate::{config::color::LapceColor, editor::EditorData}; +use crate::{config::color::UmideColor, editor::EditorData}; pub fn text_area( editor: EditorData, @@ -26,7 +26,7 @@ pub fn text_area( let config = config.get(); let font_size = config.ui.font_size(); let font_family = config.ui.font_family(); - let color = config.color(LapceColor::EDITOR_FOREGROUND); + let color = config.color(UmideColor::EDITOR_FOREGROUND); let attrs = Attrs::new() .color(color) .family(&font_family) @@ -49,7 +49,7 @@ pub fn text_area( let config = config.get_untracked(); let font_size = config.ui.font_size(); let font_family = config.ui.font_family(); - let color = config.color(LapceColor::EDITOR_FOREGROUND); + let color = config.color(UmideColor::EDITOR_FOREGROUND); let attrs = Attrs::new() .color(color) .family(&font_family) @@ -103,7 +103,7 @@ pub fn text_area( .margin_left(cursor_pos.x as f32 - 1.0) .margin_top(cursor_pos.y as f32) .border_left(2.0) - .border_color(config.get().color(LapceColor::EDITOR_CARET)) + .border_color(config.get().color(UmideColor::EDITOR_CARET)) .apply_if(!is_active(), |s| s.hide()) }), )) @@ -115,7 +115,7 @@ pub fn text_area( let config = config.get(); s.border(1.0) .border_radius(6.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) - .background(config.color(LapceColor::EDITOR_BACKGROUND)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) + .background(config.color(UmideColor::EDITOR_BACKGROUND)) }) } diff --git a/crates/umide/src/text_input.rs b/crates/umide/src/text_input.rs index 76ba471e..b84bd445 100644 --- a/crates/umide/src/text_input.rs +++ b/crates/umide/src/text_input.rs @@ -22,7 +22,7 @@ use umide_core::{ use lapce_xi_rope::Rope; use crate::{ - config::{LapceConfig, color::LapceColor}, + config::{UmideConfig, color::UmideColor}, doc::Doc, editor::{DocSignal, EditorData, view::editor_style}, keypress::KeyPressFocus, @@ -317,7 +317,7 @@ pub struct TextInput { cursor_pos: Point, on_cursor_pos: Option>, hide_cursor: RwSignal, - config: ReadSignal>, + config: ReadSignal>, style: Extractor, } @@ -719,7 +719,7 @@ impl View for TextInput { &Rect::ZERO .with_size(Size::new(max - min, height)) .with_origin(Point::new(min + point.x, point.y)), - config.color(LapceColor::EDITOR_SELECTION), + config.color(UmideColor::EDITOR_SELECTION), 0.0, ); } @@ -754,7 +754,7 @@ impl View for TextInput { ); cx.stroke( &line, - config.color(LapceColor::EDITOR_FOREGROUND), + config.color(UmideColor::EDITOR_FOREGROUND), &Stroke::new(1.0), ); } @@ -782,7 +782,7 @@ impl View for TextInput { cx.stroke( &line, - self.config.get_untracked().color(LapceColor::EDITOR_CARET), + self.config.get_untracked().color(UmideColor::EDITOR_CARET), &Stroke::new(2.0), ); } diff --git a/crates/umide/src/title.rs b/crates/umide/src/title.rs index 31be655c..7548535e 100644 --- a/crates/umide/src/title.rs +++ b/crates/umide/src/title.rs @@ -16,20 +16,20 @@ use umide_rpc::proxy::ProxyStatus; use crate::{ app::{clickable_icon, not_clickable_icon, tooltip_label, window_menu}, - command::{LapceCommand, LapceWorkbenchCommand, WindowCommand}, - config::{LapceConfig, color::LapceColor, icon::LapceIcons}, + command::{UmideCommand, UmideWorkbenchCommand, WindowCommand}, + config::{UmideConfig, color::UmideColor, icon::UmideIcons}, listener::Listener, main_split::MainSplitData, update::ReleaseInfo, window_tab::WindowTabData, - workspace::LapceWorkspace, + workspace::UmideWorkspace, }; fn left( - workspace: Arc, - lapce_command: Listener, - workbench_command: Listener, - config: ReadSignal>, + workspace: Arc, + lapce_command: Listener, + workbench_command: Listener, + config: ReadSignal>, proxy_status: RwSignal>, num_window_tabs: Memo, ) -> impl View { @@ -44,16 +44,16 @@ fn left( }; s.width(75.0).apply_if(should_hide, |s| s.hide()) }), - Container::new(svg(move || config.get().ui_svg(LapceIcons::LOGO)).style( + Container::new(svg(move || config.get().ui_svg(UmideIcons::LOGO)).style( move |s| { let config = config.get(); s.size(16.0, 16.0) - .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + .color(config.color(UmideColor::LAPCE_ICON_ACTIVE)) }, )) .style(move |s| s.margin_horiz(10.0).apply_if(is_macos, |s| s.hide())), not_clickable_icon( - || LapceIcons::MENU, + || UmideIcons::MENU, || false, || false, || "Menu", @@ -67,16 +67,16 @@ fn left( }), tooltip_label( config, - Container::new(svg(move || config.get().ui_svg(LapceIcons::REMOTE)).style( + Container::new(svg(move || config.get().ui_svg(UmideIcons::REMOTE)).style( move |s| { let config = config.get(); let size = (config.ui.icon_size() as f32 + 2.0).min(30.0); s.size(size, size).color(if is_local { - config.color(LapceColor::LAPCE_ICON_ACTIVE) + config.color(UmideColor::LAPCE_ICON_ACTIVE) } else { match proxy_status.get() { Some(_) => Color::WHITE, - None => config.color(LapceColor::LAPCE_ICON_ACTIVE), + None => config.color(UmideColor::LAPCE_ICON_ACTIVE), } }) }, @@ -87,7 +87,7 @@ fn left( #[allow(unused_mut)] let mut menu = Menu::new() .item("Connect to SSH Host", |i| i.action(move || { - workbench_command.send(LapceWorkbenchCommand::ConnectSshHost); + workbench_command.send(UmideWorkbenchCommand::ConnectSshHost); })); if !is_local @@ -98,7 +98,7 @@ fn left( menu = menu.item("Disconnect remote", |i| i.action( move || { workbench_command - .send(LapceWorkbenchCommand::DisconnectRemote); + .send(UmideWorkbenchCommand::DisconnectRemote); }, )); } @@ -107,7 +107,7 @@ fn left( menu = menu.item("Connect to WSL Host", |i| i.action( move || { workbench_command - .send(LapceWorkbenchCommand::ConnectWslHost); + .send(UmideWorkbenchCommand::ConnectWslHost); }, )); } @@ -120,13 +120,13 @@ fn left( } else { match proxy_status.get() { Some(ProxyStatus::Connected) => { - config.color(LapceColor::LAPCE_REMOTE_CONNECTED) + config.color(UmideColor::LAPCE_REMOTE_CONNECTED) } Some(ProxyStatus::Connecting) => { - config.color(LapceColor::LAPCE_REMOTE_CONNECTING) + config.color(UmideColor::LAPCE_REMOTE_CONNECTING) } Some(ProxyStatus::Disconnected) => { - config.color(LapceColor::LAPCE_REMOTE_DISCONNECTED) + config.color(UmideColor::LAPCE_REMOTE_DISCONNECTED) } None => Color::TRANSPARENT, } @@ -137,12 +137,12 @@ fn left( .background(color) .hover(|s| { s.cursor(CursorStyle::Pointer).background( - config.color(LapceColor::PANEL_HOVERED_BACKGROUND), + config.color(UmideColor::PANEL_HOVERED_BACKGROUND), ) }) .active(|s| { s.cursor(CursorStyle::Pointer).background( - config.color(LapceColor::PANEL_HOVERED_ACTIVE_BACKGROUND), + config.color(UmideColor::PANEL_HOVERED_ACTIVE_BACKGROUND), ) }) }), @@ -159,10 +159,10 @@ fn left( } fn middle( - workspace: Arc, + workspace: Arc, main_split: MainSplitData, - workbench_command: Listener, - config: ReadSignal>, + workbench_command: Listener, + config: ReadSignal>, ) -> impl View { let local_workspace = workspace.clone(); let can_jump_backward = { @@ -174,9 +174,9 @@ fn middle( let jump_backward = move || { clickable_icon( - || LapceIcons::LOCATION_BACKWARD, + || UmideIcons::LOCATION_BACKWARD, move || { - workbench_command.send(LapceWorkbenchCommand::JumpLocationBackward); + workbench_command.send(UmideWorkbenchCommand::JumpLocationBackward); }, || false, move || !can_jump_backward.get(), @@ -187,9 +187,9 @@ fn middle( }; let jump_forward = move || { clickable_icon( - || LapceIcons::LOCATION_FORWARD, + || UmideIcons::LOCATION_FORWARD, move || { - workbench_command.send(LapceWorkbenchCommand::JumpLocationForward); + workbench_command.send(UmideWorkbenchCommand::JumpLocationForward); }, || false, move || !can_jump_forward.get(), @@ -201,7 +201,7 @@ fn middle( let open_folder = move || { not_clickable_icon( - || LapceIcons::PALETTE_MENU, + || UmideIcons::PALETTE_MENU, || false, || false, || "Open Folder / Recent Workspace", @@ -210,10 +210,10 @@ fn middle( .popout_menu(move || { Menu::new() .item("Open Folder", |i| i.action(move || { - workbench_command.send(LapceWorkbenchCommand::OpenFolder); + workbench_command.send(UmideWorkbenchCommand::OpenFolder); })) .item("Open Recent Workspace", |i| i.action(move || { - workbench_command.send(LapceWorkbenchCommand::PaletteWorkspace); + workbench_command.send(UmideWorkbenchCommand::PaletteWorkspace); })) }) }; @@ -232,12 +232,12 @@ fn middle( }), Container::new( Stack::new(( - svg(move || config.get().ui_svg(LapceIcons::SEARCH)).style( + svg(move || config.get().ui_svg(UmideIcons::SEARCH)).style( move |s| { let config = config.get(); let icon_size = config.ui.icon_size() as f32; s.size(icon_size, icon_size) - .color(config.color(LapceColor::LAPCE_ICON_ACTIVE)) + .color(config.color(UmideColor::LAPCE_ICON_ACTIVE)) }, ), Label::new({ @@ -255,9 +255,9 @@ fn middle( .on_event_stop(EventListener::PointerDown, |_| {}) .on_click_stop(move |_| { if workspace.clone().path.is_some() { - workbench_command.send(LapceWorkbenchCommand::PaletteHelpAndFile); + workbench_command.send(UmideWorkbenchCommand::PaletteHelpAndFile); } else { - workbench_command.send(LapceWorkbenchCommand::PaletteWorkspace); + workbench_command.send(UmideWorkbenchCommand::PaletteWorkspace); } }) .style(move |s| { @@ -270,15 +270,15 @@ fn middle( .justify_content(Some(JustifyContent::Center)) .align_items(Some(AlignItems::Center)) .border(1.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) .border_radius(6.0) - .background(config.color(LapceColor::EDITOR_BACKGROUND)) + .background(config.color(UmideColor::EDITOR_BACKGROUND)) }), Stack::new(( clickable_icon( - || LapceIcons::START, + || UmideIcons::START, move || { - workbench_command.send(LapceWorkbenchCommand::PaletteRunAndDebug) + workbench_command.send(UmideWorkbenchCommand::PaletteRunAndDebug) }, || false, || false, @@ -306,12 +306,12 @@ fn middle( fn right( window_command: Listener, - workbench_command: Listener, + workbench_command: Listener, latest_release: ReadSignal>>, update_in_progress: RwSignal, num_window_tabs: Memo, window_maximized: RwSignal, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { let latest_version = Memo::new(move |_| { let latest_release = latest_release.get(); @@ -333,7 +333,7 @@ fn right( .style(|s| s.height_pct(100.0).flex_basis(0.0).flex_grow(1.0)), Stack::new(( not_clickable_icon( - || LapceIcons::SETTINGS, + || UmideIcons::SETTINGS, || false, || false, || "Settings", @@ -342,22 +342,22 @@ fn right( .popout_menu(move || { Menu::new() .item("Command Palette", |i| i.action(move || { - workbench_command.send(LapceWorkbenchCommand::PaletteCommand) + workbench_command.send(UmideWorkbenchCommand::PaletteCommand) })) .separator() .item("Open Settings", |i| i.action(move || { - workbench_command.send(LapceWorkbenchCommand::OpenSettings) + workbench_command.send(UmideWorkbenchCommand::OpenSettings) })) .item("Open Keyboard Shortcuts", |i| i.action( move || { workbench_command - .send(LapceWorkbenchCommand::OpenKeyboardShortcuts) + .send(UmideWorkbenchCommand::OpenKeyboardShortcuts) }, )) .item("Open Theme Color Settings", |i| i.action( move || { workbench_command - .send(LapceWorkbenchCommand::OpenThemeColorSettings) + .send(UmideWorkbenchCommand::OpenThemeColorSettings) }, )) .separator() @@ -378,7 +378,7 @@ fn right( } else { i.action(move || { workbench_command - .send(LapceWorkbenchCommand::RestartToUpdate) + .send(UmideWorkbenchCommand::RestartToUpdate) }) } } else { @@ -388,17 +388,17 @@ fn right( ) .separator() .item("About UMIDE", |i| i.action(move || { - workbench_command.send(LapceWorkbenchCommand::ShowAbout) + workbench_command.send(UmideWorkbenchCommand::ShowAbout) })) }), Container::new(Label::new("1".to_string()).style(move |s| { let config = config.get(); s.font_size(10.0) - .color(config.color(LapceColor::EDITOR_BACKGROUND)) + .color(config.color(UmideColor::EDITOR_BACKGROUND)) .border_radius(100.0) .margin_left(5.0) .margin_top(10.0) - .background(config.color(LapceColor::EDITOR_CARET)) + .background(config.color(UmideColor::EDITOR_CARET)) })) .style(move |s| { let has_update = has_update(); @@ -475,9 +475,9 @@ pub fn title(window_tab_data: Rc) -> impl View { s.width_pct(100.0) .height(37.0) .items_center() - .background(config.color(LapceColor::PANEL_BACKGROUND)) + .background(config.color(UmideColor::PANEL_BACKGROUND)) .border_bottom(1.0) - .border_color(config.color(LapceColor::LAPCE_BORDER)) + .border_color(config.color(UmideColor::LAPCE_BORDER)) }) .debug_name("Title / Top Bar") } @@ -487,11 +487,11 @@ pub fn window_controls_view( is_title: bool, num_window_tabs: Memo, window_maximized: RwSignal, - config: ReadSignal>, + config: ReadSignal>, ) -> impl View { Stack::new(( clickable_icon( - || LapceIcons::WINDOW_MINIMIZE, + || UmideIcons::WINDOW_MINIMIZE, || { floem::action::minimize_window(); }, @@ -504,9 +504,9 @@ pub fn window_controls_view( clickable_icon( move || { if window_maximized.get() { - LapceIcons::WINDOW_RESTORE + UmideIcons::WINDOW_RESTORE } else { - LapceIcons::WINDOW_MAXIMIZE + UmideIcons::WINDOW_MAXIMIZE } }, move || { @@ -521,7 +521,7 @@ pub fn window_controls_view( ) .style(|s| s.margin_right(16.0)), clickable_icon( - || LapceIcons::WINDOW_CLOSE, + || UmideIcons::WINDOW_CLOSE, move || { window_command.send(WindowCommand::CloseWindow); }, diff --git a/crates/umide/src/update.rs b/crates/umide/src/update.rs index 3982af02..0293926d 100644 --- a/crates/umide/src/update.rs +++ b/crates/umide/src/update.rs @@ -30,7 +30,7 @@ pub fn get_latest_release() -> Result { _ => "https://api.github.com/repos/lapce/lapce/releases/latest", }; - let resp = umide_proxy::get_url(url, Some("Lapce"))?; + let resp = umide_proxy::get_url(url, Some("Umide"))?; if !resp.status().is_success() { return Err(anyhow!("get release info failed {}", resp.text()?)); } diff --git a/crates/umide/src/window.rs b/crates/umide/src/window.rs index b1fe90af..24f13ded 100644 --- a/crates/umide/src/window.rs +++ b/crates/umide/src/window.rs @@ -14,19 +14,19 @@ use serde::{Deserialize, Serialize}; use crate::{ app::AppCommand, command::{InternalCommand, WindowCommand}, - config::LapceConfig, - db::LapceDb, + config::UmideConfig, + db::UmideDb, keypress::EventRef, listener::Listener, update::ReleaseInfo, window_tab::WindowTabData, - workspace::LapceWorkspace, + workspace::UmideWorkspace, }; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TabsInfo { pub active_tab: usize, - pub workspaces: Vec, + pub workspaces: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -57,7 +57,7 @@ pub struct WindowCommonData { /// `WindowData` is the application model for a top-level window. /// /// A top-level window can be independently moved around and -/// resized using your window manager. Normally Lapce has only one +/// resized using your window manager. Normally Umide has only one /// top-level window, but new ones can be created using the "New Window" /// command. /// @@ -77,7 +77,7 @@ pub struct WindowData { pub position: RwSignal, pub root_view_id: RwSignal, pub window_scale: RwSignal, - pub config: RwSignal>, + pub config: RwSignal>, pub ime_enabled: RwSignal, pub common: Rc, } @@ -94,7 +94,7 @@ impl WindowData { ) -> Self { let cx = Scope::new(); let config = - LapceConfig::load(&LapceWorkspace::default(), &[], &extra_plugin_paths); + UmideConfig::load(&UmideWorkspace::default(), &[], &extra_plugin_paths); let config = cx.create_rw_signal(Arc::new(config)); let root_view_id = cx.create_rw_signal(ViewId::new()); @@ -136,7 +136,7 @@ impl WindowData { if window_tabs.with_untracked(|window_tabs| window_tabs.is_empty()) { let window_tab = Rc::new(WindowTabData::new( cx, - Arc::new(LapceWorkspace::default()), + Arc::new(UmideWorkspace::default()), common.clone(), )); window_tabs.update(|window_tabs| { @@ -186,8 +186,8 @@ impl WindowData { } pub fn reload_config(&self) { - let config = LapceConfig::load( - &LapceWorkspace::default(), + let config = UmideConfig::load( + &UmideWorkspace::default(), &[], &self.common.extra_plugin_paths, ); @@ -201,7 +201,7 @@ impl WindowData { pub fn run_window_command(&self, cmd: WindowCommand) { match cmd { WindowCommand::SetWorkspace { workspace } => { - let db: Arc = Context::get().unwrap(); + let db: Arc = Context::get().unwrap(); if let Err(err) = db.update_recent_workspace(&workspace) { tracing::error!("{:?}", err); } @@ -238,7 +238,7 @@ impl WindowData { }) } WindowCommand::NewWorkspaceTab { workspace, end } => { - let db: Arc = Context::get().unwrap(); + let db: Arc = Context::get().unwrap(); if let Err(err) = db.update_recent_workspace(&workspace) { tracing::error!("{:?}", err); } @@ -281,7 +281,7 @@ impl WindowData { if index < window_tabs.len() { let (_, old_window_tab) = window_tabs.remove(index); old_window_tab.proxy.shutdown(); - let db: Arc = Context::get().unwrap(); + let db: Arc = Context::get().unwrap(); if let Err(err) = db.save_window_tab(old_window_tab) { tracing::error!("{:?}", err); } @@ -348,7 +348,7 @@ impl WindowData { } pub fn info(&self) -> WindowInfo { - let workspaces: Vec = self + let workspaces: Vec = self .window_tabs .get_untracked() .iter() diff --git a/crates/umide/src/window_tab.rs b/crates/umide/src/window_tab.rs index 400e8f3b..aa67fe64 100644 --- a/crates/umide/src/window_tab.rs +++ b/crates/umide/src/window_tab.rs @@ -45,13 +45,13 @@ use crate::{ alert::{AlertBoxData, AlertButton}, code_action::{CodeActionData, CodeActionStatus}, command::{ - CommandExecuted, CommandKind, InternalCommand, LapceCommand, - LapceWorkbenchCommand, WindowCommand, + CommandExecuted, CommandKind, InternalCommand, UmideCommand, + UmideWorkbenchCommand, WindowCommand, }, completion::{CompletionData, CompletionStatus}, - config::LapceConfig, - db::LapceDb, - debug::{DapData, LapceBreakpoint, RunDebugMode, RunDebugProcess}, + config::UmideConfig, + db::UmideDb, + debug::{DapData, UmideBreakpoint, RunDebugMode, RunDebugProcess}, doc::DocContent, editor::location::{EditorLocation, EditorPosition}, editor_tab::EditorTabChild, @@ -82,7 +82,7 @@ use crate::{ }, tracing::*, window::WindowCommonData, - workspace::{LapceWorkspace, LapceWorkspaceType, WorkspaceInfo}, + workspace::{UmideWorkspace, UmideWorkspaceType, WorkspaceInfo}, }; #[derive(Debug, Clone, PartialEq, Eq)] @@ -117,7 +117,7 @@ pub struct WorkProgress { #[derive(Clone)] pub struct CommonData { - pub workspace: Arc, + pub workspace: Arc, pub scope: Scope, pub focus: RwSignal, pub keypress: RwSignal, @@ -129,18 +129,18 @@ pub struct CommonData { pub workbench_size: RwSignal, pub window_origin: RwSignal, pub internal_command: Listener, - pub lapce_command: Listener, - pub workbench_command: Listener, + pub lapce_command: Listener, + pub workbench_command: Listener, pub term_tx: Sender<(TermId, TermEvent)>, pub term_notification_tx: Sender, pub proxy: ProxyRpcHandler, pub view_id: RwSignal, pub ui_line_height: Memo, pub dragging: RwSignal>, - pub config: ReadSignal>, + pub config: ReadSignal>, pub proxy_status: RwSignal>, pub mouse_hover_timer: RwSignal, - pub breakpoints: RwSignal>>, + pub breakpoints: RwSignal>>, // the current focused view which will receive keyboard events pub keyboard_focus: RwSignal>, pub window_common: Rc, @@ -158,7 +158,7 @@ impl std::fmt::Debug for CommonData { pub struct WindowTabData { pub scope: Scope, pub window_tab_id: WindowTabId, - pub workspace: Arc, + pub workspace: Arc, pub palette: PaletteData, pub main_split: MainSplitData, pub file_explorer: FileExplorerData, @@ -177,7 +177,7 @@ pub struct WindowTabData { pub title_height: RwSignal, pub status_height: RwSignal, pub proxy: ProxyData, - pub set_config: WriteSignal>, + pub set_config: WriteSignal>, pub update_in_progress: RwSignal, pub progresses: RwSignal>, pub messages: RwSignal>, @@ -212,7 +212,7 @@ impl KeyPressFocus for WindowTabData { fn run_command( &self, - command: &LapceCommand, + command: &UmideCommand, _count: Option, _mods: Modifiers, ) -> CommandExecuted { @@ -272,11 +272,11 @@ impl WindowTabData { #[allow(clippy::too_many_arguments)] pub fn new( cx: Scope, - workspace: Arc, + workspace: Arc, window_common: Rc, ) -> Self { let cx = cx.create_child(); - let db: Arc = Context::get().unwrap(); + let db: Arc = Context::get().unwrap(); let disabled_volts = db.get_disabled_volts().unwrap_or_default(); let workspace_disabled_volts = db @@ -295,7 +295,7 @@ impl WindowTabData { info }; - let config = LapceConfig::load( + let config = UmideConfig::load( &workspace, &all_disabled_volts, &window_common.extra_plugin_paths, @@ -520,7 +520,7 @@ impl WindowTabData { breakpoints .into_iter() .map(|b| (b.line, b)) - .collect::>(), + .collect::>(), ) }) .collect(), @@ -648,7 +648,7 @@ impl WindowTabData { } pub fn reload_config(&self) { - let db: Arc = Context::get().unwrap(); + let db: Arc = Context::get().unwrap(); let disabled_volts = db.get_disabled_volts().unwrap_or_default(); let workspace_disabled_volts = db @@ -657,7 +657,7 @@ impl WindowTabData { let mut all_disabled_volts = disabled_volts; all_disabled_volts.extend(workspace_disabled_volts); - let config = LapceConfig::load( + let config = UmideConfig::load( &self.workspace, &all_disabled_volts, &self.common.window_common.extra_plugin_paths, @@ -707,7 +707,7 @@ impl WindowTabData { } } - pub fn run_lapce_command(&self, cmd: LapceCommand) { + pub fn run_lapce_command(&self, cmd: UmideCommand) { match cmd.kind { CommandKind::Workbench(command) => { self.run_workbench_command(command, cmd.data); @@ -733,10 +733,10 @@ impl WindowTabData { pub fn run_workbench_command( &self, - cmd: LapceWorkbenchCommand, + cmd: UmideWorkbenchCommand, data: Option, ) { - use LapceWorkbenchCommand::*; + use UmideWorkbenchCommand::*; match cmd { // ==== Modal ==== EnableModal => { @@ -760,8 +760,8 @@ impl WindowTabData { }; open_file(options, move |file| { if let Some(mut file) = file { - let workspace = LapceWorkspace { - kind: LapceWorkspaceType::Local, + let workspace = UmideWorkspace { + kind: UmideWorkspaceType::Local, path: Some(if let Some(path) = file.path.pop() { path } else { @@ -782,8 +782,8 @@ impl WindowTabData { CloseFolder => { if !self.workspace.kind.is_remote() { let window_command = self.common.window_common.window_command; - let workspace = LapceWorkspace { - kind: LapceWorkspaceType::Local, + let workspace = UmideWorkspace { + kind: UmideWorkspaceType::Local, path: None, last_open: 0, }; @@ -859,7 +859,7 @@ impl WindowTabData { self.main_split.open_settings(); } OpenSettingsFile => { - if let Some(path) = LapceConfig::settings_file() { + if let Some(path) = UmideConfig::settings_file() { self.main_split.jump_to_location( EditorLocation { path, @@ -884,7 +884,7 @@ impl WindowTabData { self.main_split.open_keymap(); } OpenKeyboardShortcutsFile => { - if let Some(path) = LapceConfig::keymaps_file() { + if let Some(path) = UmideConfig::keymaps_file() { self.main_split.jump_to_location( EditorLocation { path, @@ -969,7 +969,7 @@ impl WindowTabData { NewWindowTab => { self.common.window_common.window_command.send( WindowCommand::NewWorkspaceTab { - workspace: LapceWorkspace::default(), + workspace: UmideWorkspace::default(), end: false, }, ); @@ -1111,8 +1111,8 @@ impl WindowTabData { DisconnectRemote => { self.common.window_common.window_command.send( WindowCommand::SetWorkspace { - workspace: LapceWorkspace { - kind: LapceWorkspaceType::Local, + workspace: UmideWorkspace { + kind: UmideWorkspaceType::Local, path: None, last_open: 0, }, @@ -1190,7 +1190,7 @@ impl WindowTabData { } self.common.window_common.window_scale.set(scale); - LapceConfig::update_file( + UmideConfig::update_file( "ui", "scale", toml_edit::Value::from(scale), @@ -1205,7 +1205,7 @@ impl WindowTabData { } self.common.window_common.window_scale.set(scale); - LapceConfig::update_file( + UmideConfig::update_file( "ui", "scale", toml_edit::Value::from(scale), @@ -1214,7 +1214,7 @@ impl WindowTabData { ZoomReset => { self.common.window_common.window_scale.set(1.0); - LapceConfig::update_file( + UmideConfig::update_file( "ui", "scale", toml_edit::Value::from(1.0), @@ -1943,7 +1943,7 @@ impl WindowTabData { InternalCommand::SetColorTheme { name, save } => { if save { // The config file is watched - LapceConfig::update_file( + UmideConfig::update_file( "core", "color-theme", toml_edit::Value::from(name), @@ -1958,7 +1958,7 @@ impl WindowTabData { InternalCommand::SetIconTheme { name, save } => { if save { // The config file is watched - LapceConfig::update_file( + UmideConfig::update_file( "core", "icon-theme", toml_edit::Value::from(name), @@ -1971,7 +1971,7 @@ impl WindowTabData { } } InternalCommand::SetModal { modal } => { - LapceConfig::update_file( + UmideConfig::update_file( "core", "modal", toml_edit::Value::from(modal), @@ -2835,7 +2835,7 @@ impl WindowTabData { for folder in folders { self.common.window_common.window_command.send( WindowCommand::NewWorkspaceTab { - workspace: LapceWorkspace { + workspace: UmideWorkspace { kind: self.workspace.kind.clone(), path: Some(folder.path.clone()), last_open: 0, diff --git a/crates/umide/src/workspace.rs b/crates/umide/src/workspace.rs index 7181ac03..a16d8f3a 100644 --- a/crates/umide/src/workspace.rs +++ b/crates/umide/src/workspace.rs @@ -2,7 +2,7 @@ use std::{collections::HashMap, fmt::Display, path::PathBuf}; use serde::{Deserialize, Serialize}; -use crate::{debug::LapceBreakpoint, main_split::SplitInfo, panel::data::PanelInfo}; +use crate::{debug::UmideBreakpoint, main_split::SplitInfo, panel::data::PanelInfo}; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)] pub struct SshHost { @@ -63,20 +63,20 @@ impl Display for WslHost { } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub enum LapceWorkspaceType { +pub enum UmideWorkspaceType { Local, RemoteSSH(SshHost), #[cfg(windows)] RemoteWSL(WslHost), } -impl LapceWorkspaceType { +impl UmideWorkspaceType { pub fn is_local(&self) -> bool { - matches!(self, LapceWorkspaceType::Local) + matches!(self, UmideWorkspaceType::Local) } pub fn is_remote(&self) -> bool { - use LapceWorkspaceType::*; + use UmideWorkspaceType::*; #[cfg(not(windows))] return matches!(self, RemoteSSH(_)); @@ -86,15 +86,15 @@ impl LapceWorkspaceType { } } -impl std::fmt::Display for LapceWorkspaceType { +impl std::fmt::Display for UmideWorkspaceType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - LapceWorkspaceType::Local => f.write_str("Local"), - LapceWorkspaceType::RemoteSSH(remote) => { + UmideWorkspaceType::Local => f.write_str("Local"), + UmideWorkspaceType::RemoteSSH(remote) => { write!(f, "ssh://{remote}") } #[cfg(windows)] - LapceWorkspaceType::RemoteWSL(remote) => { + UmideWorkspaceType::RemoteWSL(remote) => { write!(f, "{remote} (WSL)") } } @@ -102,13 +102,13 @@ impl std::fmt::Display for LapceWorkspaceType { } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct LapceWorkspace { - pub kind: LapceWorkspaceType, +pub struct UmideWorkspace { + pub kind: UmideWorkspaceType, pub path: Option, pub last_open: u64, } -impl LapceWorkspace { +impl UmideWorkspace { pub fn display(&self) -> Option { let path = self.path.as_ref()?; let path = path @@ -117,12 +117,12 @@ impl LapceWorkspace { .to_string_lossy() .to_string(); let remote = match &self.kind { - LapceWorkspaceType::Local => String::new(), - LapceWorkspaceType::RemoteSSH(remote) => { + UmideWorkspaceType::Local => String::new(), + UmideWorkspaceType::RemoteSSH(remote) => { format!(" [SSH: {}]", remote.host) } #[cfg(windows)] - LapceWorkspaceType::RemoteWSL(remote) => { + UmideWorkspaceType::RemoteWSL(remote) => { format!(" [WSL: {}]", remote.host) } }; @@ -130,17 +130,17 @@ impl LapceWorkspace { } } -impl Default for LapceWorkspace { +impl Default for UmideWorkspace { fn default() -> Self { Self { - kind: LapceWorkspaceType::Local, + kind: UmideWorkspaceType::Local, path: None, last_open: 0, } } } -impl std::fmt::Display for LapceWorkspace { +impl std::fmt::Display for UmideWorkspace { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, @@ -155,5 +155,5 @@ impl std::fmt::Display for LapceWorkspace { pub struct WorkspaceInfo { pub split: SplitInfo, pub panel: PanelInfo, - pub breakpoints: HashMap>, + pub breakpoints: HashMap>, } diff --git a/crates/umide_emulator/proto/emulator_controller.proto b/crates/umide_emulator/proto/emulator_controller.proto index 73f96794..9f40ed97 100644 --- a/crates/umide_emulator/proto/emulator_controller.proto +++ b/crates/umide_emulator/proto/emulator_controller.proto @@ -1,80 +1,97 @@ // Android Emulator gRPC Protocol -// Based on AOSP android/android-grpc/android/emulation/control/emulator_controller.proto -// Simplified version with screenshot streaming and touch input +// Based on AOSP emulator_controller.proto (field numbers must match exactly) +// https://android.googlesource.com/platform/prebuilts/android-emulator syntax = "proto3"; package android.emulation.control; +import "google/protobuf/empty.proto"; + option java_multiple_files = true; option java_package = "com.android.emulator.control"; // The EmulatorController service provides methods to control the emulator service EmulatorController { // Stream a series of screenshots from the emulator - // This will return a new frame whenever the emulated device produces one rpc streamScreenshot(ImageFormat) returns (stream Image) {} // Get a single screenshot from the emulator rpc getScreenshot(ImageFormat) returns (Image) {} // Send a touch event to the emulator - rpc sendTouch(TouchEvent) returns (Empty) {} + rpc sendTouch(TouchEvent) returns (google.protobuf.Empty) {} // Send a key event to the emulator - rpc sendKey(KeyboardEvent) returns (Empty) {} + rpc sendKey(KeyboardEvent) returns (google.protobuf.Empty) {} // Get the status of the emulator - rpc getStatus(Empty) returns (EmulatorStatus) {} + rpc getStatus(google.protobuf.Empty) returns (EmulatorStatus) {} } -// Empty message for methods that don't need parameters -message Empty {} +// Rotation information for the device display +message Rotation { + enum SkinRotation { + PORTRAIT = 0; + LANDSCAPE = 1; + REVERSE_PORTRAIT = 2; + REVERSE_LANDSCAPE = 3; + } + SkinRotation rotation = 1; +} // Image format specification for screenshots +// Field numbers MUST match AOSP emulator_controller.proto exactly message ImageFormat { - // Format of the image enum ImgFormat { PNG = 0; - RGB888 = 1; - RGBA8888 = 2; + RGBA8888 = 1; // 4 bytes per pixel + RGB888 = 2; // 3 bytes per pixel } + // The (desired) format of the resulting bytes ImgFormat format = 1; - // Optional width/height for resized images - // If not specified, uses native resolution - uint32 width = 2; - uint32 height = 3; + // [Output Only] The rotation of the image + Rotation rotation = 2; + + // The (desired) width of the image (0 = native resolution) + uint32 width = 3; + + // The (desired) height of the image (0 = native resolution) + uint32 height = 4; + + // The display id (0 = main display) + uint32 display = 5; } // The screenshot image returned by the emulator message Image { - // Image format + // Image format (contains actual width/height in AOSP) ImageFormat format = 1; - // Width of the image in pixels + // Deprecated in AOSP but still present for backwards compat uint32 width = 2; - - // Height of the image in pixels uint32 height = 3; - // The actual image data (raw bytes) + // The actual image data (raw bytes, bottom-up, left-to-right) bytes image = 4; - // Sequence number for frame ordering + // Monotonically increasing sequence number uint32 seq = 5; - // Timestamp in microseconds + // Unix timestamp in microseconds when frame was generated uint64 timestampUs = 6; } -// Touch event types +// Touch event containing a list of touch contacts message TouchEvent { - // List of touches (supports multi-touch) repeated Touch touches = 1; + // Display where the touch occurred (0 = main display) + int32 display = 2; } +// A single touch contact point message Touch { // X coordinate in device pixels int32 x = 1; @@ -82,45 +99,46 @@ message Touch { // Y coordinate in device pixels int32 y = 2; - // Touch identifier for multi-touch + // Touch identifier for multi-touch tracking int32 identifier = 3; - // Pressure (0-1) - float pressure = 4; + // Pressure: non-zero when touching, 0 to release. + // Must send pressure=0 to release a touch identifier! + int32 pressure = 4; - // Touch type - enum TouchType { - DOWN = 0; - UP = 1; - MOVE = 2; - } - TouchType type = 5; + // Optional touch major axis + int32 touch_major = 5; + + // Optional touch minor axis + int32 touch_minor = 6; } // Keyboard event message KeyboardEvent { - // Key code - int32 keycode = 1; + enum KeyCodeType { + Usb = 0; + Evdev = 1; + XKB = 2; + Win = 3; + Mac = 4; + } - // Event type enum KeyEventType { - DOWN = 0; - UP = 1; + keydown = 0; + keyup = 1; + keypress = 2; } - KeyEventType type = 2; + + KeyCodeType codeType = 1; + KeyEventType eventType = 2; + int32 keyCode = 3; + string key = 4; + string text = 5; } // Emulator status information message EmulatorStatus { - // Whether the emulator is running - bool running = 1; - - // The AVD name - string avd_name = 2; - - // Display width - uint32 width = 3; - - // Display height - uint32 height = 4; + string version = 1; + uint64 uptime = 2; + bool booted = 3; } diff --git a/crates/umide_emulator/src/android.rs b/crates/umide_emulator/src/android.rs index d6026088..79ec9673 100644 --- a/crates/umide_emulator/src/android.rs +++ b/crates/umide_emulator/src/android.rs @@ -16,6 +16,57 @@ impl AndroidEmulator { } } + /// Get list of currently running emulator serials from adb devices + pub fn get_running_serials() -> Vec { + let output = match Command::new("adb") + .arg("devices") + .output() { + Ok(out) => out, + Err(_) => return Vec::new(), + }; + + if !output.status.success() { + return Vec::new(); + } + + let stdout = String::from_utf8_lossy(&output.stdout); + stdout + .lines() + .skip(1) // Skip "List of devices" header + .filter_map(|line| { + let parts: Vec<&str> = line.split_whitespace().collect(); + if parts.len() >= 2 && parts[0].starts_with("emulator-") && parts[1] == "device" { + Some(parts[0].to_string()) + } else { + None + } + }) + .collect() + } + + /// Check if an AVD is currently running + pub fn is_running(avd_name: &str) -> bool { + let running = Self::get_running_serials(); + if running.is_empty() { + return false; + } + + // Check if any running emulator corresponds to this AVD + // We need to query each emulator for its AVD name + for serial in &running { + if let Ok(output) = Command::new("adb") + .args(["-s", serial, "emu", "avd", "name"]) + .output() + { + let name = String::from_utf8_lossy(&output.stdout); + if name.trim() == avd_name || name.lines().next().map(|l| l.trim()) == Some(avd_name) { + return true; + } + } + } + false + } + pub fn list_devices() -> Result> { let output = Command::new("emulator") .arg("-list-avds") @@ -41,68 +92,138 @@ impl AndroidEmulator { } pub fn launch(avd_name: &str) -> Result<()> { - Command::new("emulator") + tracing::info!("Launching Android emulator for AVD: {}", avd_name); + + // Check if already running + if Self::is_running(avd_name) { + tracing::info!("AVD {} is already running", avd_name); + return Ok(()); + } + + // Launch emulator headless — no window, frames arrive via gRPC streaming + // GPU mode "auto" picks the best available backend (Metal on macOS) + // -no-window: run headless, no macOS window (we render via gRPC frames) + // -grpc 8554: expose gRPC endpoint for frame streaming and input + let child = Command::new("emulator") .arg("-avd") .arg(avd_name) - .arg("-no-window") // Headless mode - no external window + .arg("-gpu") + .arg("auto") + .arg("-no-boot-anim") + .arg("-no-skin") + .arg("-no-window") // Headless: no desktop window, frames via gRPC .arg("-grpc") - .arg("5556") + .arg("8554") // gRPC endpoint for streamScreenshot + sendTouch .stdout(Stdio::null()) - .stderr(Stdio::null()) + .stderr(Stdio::piped()) .stdin(Stdio::null()) - .spawn()?; - Ok(()) + .spawn(); + + match child { + Ok(_child) => { + tracing::info!("Emulator process spawned for AVD: {}", avd_name); + + // Wait for the emulator to become reachable via ADB + // Poll up to 30 seconds for the emulator to appear in adb devices + let mut ready = false; + for attempt in 0..60 { + std::thread::sleep(std::time::Duration::from_millis(500)); + let serials = Self::get_running_serials(); + if !serials.is_empty() { + // Verify this AVD is the one that booted + if Self::is_running(avd_name) { + tracing::info!( + "AVD {} is now running (detected after {}ms)", + avd_name, (attempt + 1) * 500 + ); + ready = true; + break; + } + } + if attempt % 10 == 0 && attempt > 0 { + tracing::debug!("Still waiting for AVD {} to boot... ({}s)", avd_name, (attempt + 1) / 2); + } + } + + if !ready { + tracing::warn!("AVD {} may not be fully booted yet after 30s, proceeding anyway", avd_name); + } + + Ok(()) + } + Err(e) => { + tracing::error!("Failed to spawn emulator for AVD {}: {}", avd_name, e); + Err(anyhow!("Failed to launch emulator: {}", e)) + } + } } pub fn stop(avd_name: &str) -> Result<()> { - // First, try to find the emulator by AVD name in adb devices - let output = Command::new("adb") - .arg("devices") - .arg("-l") - .output()?; - - if !output.status.success() { - return Err(anyhow!("Failed to list adb devices")); + tracing::info!("Attempting to stop Android emulator for AVD: {}", avd_name); + + // Get all running emulator serials + let running_serials = Self::get_running_serials(); + + if running_serials.is_empty() { + tracing::warn!("No running emulators found"); + return Err(anyhow!("No running emulators found")); } - - let stdout = String::from_utf8_lossy(&output.stdout); - // Look for emulator serial that matches AVD name - for line in stdout.lines() { - if line.contains(avd_name) || line.contains(&avd_name.to_lowercase()) { - if let Some(serial) = line.split_whitespace().next() { - if serial.starts_with("emulator-") { - let result = Command::new("adb") - .arg("-s") - .arg(serial) - .arg("emu") - .arg("kill") - .output(); - - if result.is_ok() { - return Ok(()); + // Find the emulator that matches this AVD name + for serial in &running_serials { + // Query the AVD name for this emulator + if let Ok(output) = Command::new("adb") + .args(["-s", serial, "emu", "avd", "name"]) + .output() + { + let name = String::from_utf8_lossy(&output.stdout); + let name_trimmed = name.lines().next().map(|l| l.trim()).unwrap_or(""); + + tracing::debug!("Emulator {} has AVD name: '{}'", serial, name_trimmed); + + if name_trimmed == avd_name { + tracing::info!("Found matching emulator {} for AVD {}, sending kill command", serial, avd_name); + + // Kill this emulator + let result = Command::new("adb") + .args(["-s", serial, "emu", "kill"]) + .output(); + + match result { + Ok(output) => { + if output.status.success() { + tracing::info!("Successfully killed emulator {}", serial); + return Ok(()); + } else { + let stderr = String::from_utf8_lossy(&output.stderr); + tracing::error!("Failed to kill emulator {}: {}", serial, stderr); + } + } + Err(e) => { + tracing::error!("Failed to execute adb kill command: {}", e); } } } } } - // Fallback: kill first running emulator - for line in stdout.lines() { - if let Some(serial) = line.split_whitespace().next() { - if serial.starts_with("emulator-") && line.contains("device") { - let _ = Command::new("adb") - .arg("-s") - .arg(serial) - .arg("emu") - .arg("kill") - .output(); + // If we didn't find a matching AVD, try to kill by partial name match + tracing::warn!("No exact AVD match found, trying partial match..."); + for serial in &running_serials { + // Just kill the first one as fallback + let result = Command::new("adb") + .args(["-s", serial, "emu", "kill"]) + .output(); + + if let Ok(output) = result { + if output.status.success() { + tracing::info!("Killed emulator {} as fallback", serial); return Ok(()); } } } - Err(anyhow!("Could not find running emulator for AVD: {}", avd_name)) + Err(anyhow!("Could not find or stop emulator for AVD: {}", avd_name)) } pub async fn stream_video(&mut self) -> Result>> { diff --git a/crates/umide_emulator/src/common.rs b/crates/umide_emulator/src/common.rs index 64dfdab0..64be583e 100644 --- a/crates/umide_emulator/src/common.rs +++ b/crates/umide_emulator/src/common.rs @@ -2,7 +2,7 @@ use anyhow::Result; use async_trait::async_trait; use serde::{Deserialize, Serialize}; -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)] pub enum DevicePlatform { Android, Ios, diff --git a/crates/umide_emulator/src/grpc_client.rs b/crates/umide_emulator/src/grpc_client.rs index 75424b0f..1e55de19 100644 --- a/crates/umide_emulator/src/grpc_client.rs +++ b/crates/umide_emulator/src/grpc_client.rs @@ -17,7 +17,6 @@ use emulator_proto::{ emulator_controller_client::EmulatorControllerClient, ImageFormat, Image, TouchEvent, Touch, image_format::ImgFormat, - touch::TouchType, }; use crate::decoder::{DecodedFrame, GpuFrame}; @@ -49,24 +48,53 @@ impl EmulatorGrpcClient { .await .map_err(|e| GrpcError::ConnectionFailed(e.to_string()))?; - let client = EmulatorControllerClient::new(channel); + // Raw RGBA frames at device resolution can be large (1080x2400x4 = ~10MB) + // Default tonic limit is 4MB — increase to 50MB + let client = EmulatorControllerClient::new(channel) + .max_decoding_message_size(50 * 1024 * 1024); info!("Connected to Android emulator gRPC"); Ok(Self { client }) } - /// Connect to default emulator endpoint (localhost:5556) + /// Connect to default emulator endpoint (localhost:8554) pub async fn connect_default() -> Result { - Self::connect("http://localhost:5556").await + Self::connect("http://localhost:8554").await + } + + /// Connect with retry and exponential backoff. + /// The emulator takes time to boot and expose gRPC, so we retry patiently. + pub async fn connect_with_retry(endpoint: &str, max_duration: std::time::Duration) -> Result { + let start = std::time::Instant::now(); + let mut delay = std::time::Duration::from_millis(200); + let max_delay = std::time::Duration::from_secs(2); + + loop { + match Self::connect(endpoint).await { + Ok(client) => return Ok(client), + Err(e) => { + if start.elapsed() >= max_duration { + return Err(GrpcError::ConnectionFailed(format!( + "Failed to connect after {:?}: {}", max_duration, e + ))); + } + warn!("gRPC connection failed (retrying in {:?}): {}", delay, e); + tokio::time::sleep(delay).await; + delay = (delay * 2).min(max_delay); + } + } + } } /// Get a single screenshot pub async fn get_screenshot(&mut self) -> Result { let format = ImageFormat { format: ImgFormat::Rgba8888 as i32, - width: 0, // Native resolution + rotation: None, + width: 0, // Native resolution height: 0, + display: 0, // Main display }; let response = self.client @@ -86,8 +114,10 @@ impl EmulatorGrpcClient { ) -> Result<(), GrpcError> { let format = ImageFormat { format: ImgFormat::Rgba8888 as i32, - width: 0, + rotation: None, + width: 0, // Native resolution height: 0, + display: 0, }; info!("Starting screenshot stream..."); @@ -130,17 +160,68 @@ impl EmulatorGrpcClient { } /// Send a touch event to the emulator - pub async fn send_touch(&mut self, x: i32, y: i32, touch_type: TouchType) -> Result<(), GrpcError> { + /// pressure > 0 means touching, pressure = 0 means release + pub async fn send_touch_down(&mut self, x: i32, y: i32) -> Result<(), GrpcError> { + let touch = Touch { + x, + y, + identifier: 0, + pressure: 1, // Non-zero = touching + touch_major: 0, + touch_minor: 0, + }; + + let event = TouchEvent { + touches: vec![touch], + display: 0, + }; + + self.client + .send_touch(event) + .await + .map_err(|e| GrpcError::StreamError(e.to_string()))?; + + Ok(()) + } + + /// Move a touch to new coordinates (pressure = 1) + pub async fn send_touch_move(&mut self, x: i32, y: i32) -> Result<(), GrpcError> { let touch = Touch { x, y, identifier: 0, - pressure: 1.0, - r#type: touch_type as i32, + pressure: 1, // Non-zero = touching + touch_major: 0, + touch_minor: 0, }; let event = TouchEvent { touches: vec![touch], + display: 0, + }; + + self.client + .send_touch(event) + .await + .map_err(|e| GrpcError::StreamError(e.to_string()))?; + + Ok(()) + } + + /// Release a touch at coordinates (pressure = 0) + pub async fn send_touch_up(&mut self, x: i32, y: i32) -> Result<(), GrpcError> { + let touch = Touch { + x, + y, + identifier: 0, + pressure: 0, // 0 = release + touch_major: 0, + touch_minor: 0, + }; + + let event = TouchEvent { + touches: vec![touch], + display: 0, }; self.client @@ -153,29 +234,82 @@ impl EmulatorGrpcClient { /// Send a tap (down + up) at coordinates pub async fn tap(&mut self, x: i32, y: i32) -> Result<(), GrpcError> { - self.send_touch(x, y, TouchType::Down).await?; + self.send_touch_down(x, y).await?; tokio::time::sleep(std::time::Duration::from_millis(50)).await; - self.send_touch(x, y, TouchType::Up).await?; + self.send_touch_up(x, y).await?; + Ok(()) + } + + /// Send a key event using a key string (e.g. "GoHome", "GoBack", "Power", "AppSwitch") + pub async fn send_key(&mut self, key: &str) -> Result<(), GrpcError> { + use emulator_proto::{KeyboardEvent, keyboard_event::{KeyEventType, KeyCodeType}}; + + let event = KeyboardEvent { + code_type: KeyCodeType::Evdev as i32, + event_type: KeyEventType::Keypress as i32, + key_code: 0, + key: key.to_string(), + text: String::new(), + }; + + self.client + .send_key(event) + .await + .map_err(|e| GrpcError::StreamError(e.to_string()))?; + + Ok(()) + } + + /// Send a key event using an Evdev keycode (e.g. 115=Vol+, 114=Vol-) + pub async fn send_key_code(&mut self, code: i32) -> Result<(), GrpcError> { + use emulator_proto::{KeyboardEvent, keyboard_event::{KeyEventType, KeyCodeType}}; + + let event = KeyboardEvent { + code_type: KeyCodeType::Evdev as i32, + event_type: KeyEventType::Keypress as i32, + key_code: code, + key: String::new(), + text: String::new(), + }; + + self.client + .send_key(event) + .await + .map_err(|e| GrpcError::StreamError(e.to_string()))?; + Ok(()) } /// Convert gRPC Image to DecodedFrame fn image_to_frame(&self, image: Image) -> Result { - let width = image.width; - let height = image.height; + // AOSP: width/height can be in Image (deprecated) or Image.format + // Try format first, fall back to deprecated fields + let (width, height) = if let Some(ref fmt) = image.format { + let w = if fmt.width > 0 { fmt.width } else { image.width }; + let h = if fmt.height > 0 { fmt.height } else { image.height }; + (w, h) + } else { + (image.width, image.height) + }; + let data = image.image; if data.is_empty() { return Err(GrpcError::DecodeError("Empty image data".to_string())); } + if width == 0 || height == 0 { + return Err(GrpcError::DecodeError(format!( + "Invalid dimensions: {}x{}", width, height + ))); + } + // Image data should be RGBA8888 let expected_size = (width * height * 4) as usize; if data.len() != expected_size { return Err(GrpcError::DecodeError(format!( - "Image size mismatch: expected {} bytes, got {}", - expected_size, - data.len() + "Image size mismatch: expected {} ({}x{}x4), got {}", + expected_size, width, height, data.len() ))); } diff --git a/crates/umide_emulator/src/ios.rs b/crates/umide_emulator/src/ios.rs index 94abb309..f8dcc938 100644 --- a/crates/umide_emulator/src/ios.rs +++ b/crates/umide_emulator/src/ios.rs @@ -13,6 +13,45 @@ impl IosSimulator { Self { udid } } + /// Get list of currently booted simulator UDIDs + pub fn get_booted_udids() -> Vec { + let output = match Command::new("xcrun") + .args(["simctl", "list", "--json", "devices", "booted"]) + .output() { + Ok(out) => out, + Err(_) => return Vec::new(), + }; + + if !output.status.success() { + return Vec::new(); + } + + let stdout = String::from_utf8_lossy(&output.stdout); + let v: Value = match serde_json::from_str(&stdout) { + Ok(v) => v, + Err(_) => return Vec::new(), + }; + + let mut udids = Vec::new(); + if let Some(runtimes) = v.get("devices").and_then(|d| d.as_object()) { + for (_runtime, devices) in runtimes { + if let Some(devices) = devices.as_array() { + for device in devices { + if let Some(udid) = device.get("udid").and_then(|u| u.as_str()) { + udids.push(udid.to_string()); + } + } + } + } + } + udids + } + + /// Check if a simulator is currently booted + pub fn is_running(udid: &str) -> bool { + Self::get_booted_udids().contains(&udid.to_string()) + } + pub fn list_devices() -> Result> { let output = Command::new("xcrun") .arg("simctl") @@ -61,16 +100,67 @@ impl IosSimulator { } pub fn launch(udid: &str) -> Result<()> { - // Boot the simulator (no external window) - Command::new("xcrun") - .arg("simctl") - .arg("boot") - .arg(udid) - .spawn()?; - - // Note: We don't open Simulator.app - we capture screenshots directly - // via simctl without needing the visible window + tracing::info!("Launching iOS Simulator for UDID: {}", udid); + + // Check if already booted + if Self::is_running(udid) { + tracing::info!("Simulator {} is already booted", udid); + // Still open Simulator.app to ensure window is visible + let _ = Command::new("open") + .args(["-a", "Simulator"]) + .output(); + return Ok(()); + } + + // Boot the simulator synchronously — wait for it to complete + let output = Command::new("xcrun") + .args(["simctl", "boot", udid]) + .output()?; + + if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr); + // Ignore "already booted" errors + if !stderr.contains("current state: Booted") { + tracing::error!("Failed to boot simulator {}: {}", udid, stderr); + return Err(anyhow!("Failed to boot simulator: {}", stderr)); + } + tracing::info!("Simulator {} was already booted", udid); + } else { + tracing::info!("Simulator {} booted successfully", udid); + } + + // Open Simulator.app so the window is visible for ScreenCaptureKit capture + let _ = Command::new("open") + .args(["-a", "Simulator"]) + .output()?; + + // Wait for the Simulator.app window to appear + // ScreenCaptureKit needs the window to be on-screen + tracing::info!("Waiting for Simulator.app window to appear..."); + for attempt in 0..20 { + std::thread::sleep(std::time::Duration::from_millis(500)); + // Check if any simulator window exists + let check = Command::new("osascript") + .args([ + "-e", + r#"tell application "System Events" to count windows of application process "Simulator""#, + ]) + .output(); + if let Ok(out) = check { + let count_str = String::from_utf8_lossy(&out.stdout).trim().to_string(); + if let Ok(count) = count_str.parse::() { + if count > 0 { + tracing::info!("Simulator window appeared after {}ms", (attempt + 1) * 500); + // Give the window a moment to fully render + std::thread::sleep(std::time::Duration::from_millis(500)); + return Ok(()); + } + } + } + } + + tracing::warn!("Simulator window may not have appeared after 10s, proceeding anyway"); Ok(()) } diff --git a/crates/umide_emulator/src/lib.rs b/crates/umide_emulator/src/lib.rs index 2304f45e..72a786c3 100644 --- a/crates/umide_emulator/src/lib.rs +++ b/crates/umide_emulator/src/lib.rs @@ -12,16 +12,33 @@ pub use decoder::create_decoder; pub use grpc_client::{EmulatorGrpcClient, GrpcError}; pub use ios::IosSimulator; +/// List all available devices with their current state pub fn list_all_devices() -> Vec { let mut devices = Vec::new(); if let Ok(mut android_devices) = AndroidEmulator::list_devices() { + // Update states based on actual running status + let running_serials = AndroidEmulator::get_running_serials(); + for device in &mut android_devices { + if AndroidEmulator::is_running(&device.id) || + running_serials.iter().any(|s| s.contains(&device.id) || device.id.contains(s)) { + device.state = DeviceState::Running; + } + } devices.append(&mut android_devices); } #[cfg(target_os = "macos")] { if let Ok(mut ios_devices) = IosSimulator::list_devices() { + // iOS devices already have correct state from list_devices + // but let's double-check with booted list + let booted = IosSimulator::get_booted_udids(); + for device in &mut ios_devices { + if booted.contains(&device.id) { + device.state = DeviceState::Running; + } + } devices.append(&mut ios_devices); } } @@ -29,6 +46,23 @@ pub fn list_all_devices() -> Vec { devices } +/// Check if a specific device is currently running +pub fn is_device_running(device: &DeviceInfo) -> bool { + match device.platform { + DevicePlatform::Android => AndroidEmulator::is_running(&device.id), + DevicePlatform::Ios => IosSimulator::is_running(&device.id), + } +} + +/// Refresh the state of a single device +pub fn refresh_device_state(device: &mut DeviceInfo) { + device.state = if is_device_running(device) { + DeviceState::Running + } else { + DeviceState::Disconnected + }; +} + pub fn launch_device(device: &DeviceInfo) -> anyhow::Result<()> { match device.platform { DevicePlatform::Android => AndroidEmulator::launch(&device.id), @@ -42,3 +76,4 @@ pub fn stop_device(device: &DeviceInfo) -> anyhow::Result<()> { DevicePlatform::Ios => IosSimulator::stop(&device.id), } } + diff --git a/crates/umide_emulator/src/native_view.rs b/crates/umide_emulator/src/native_view.rs index dd6a86a4..0711faed 100644 --- a/crates/umide_emulator/src/native_view.rs +++ b/crates/umide_emulator/src/native_view.rs @@ -1,20 +1,81 @@ -use std::ffi::{CString}; -use raw_window_handle::{RawWindowHandle}; +use std::ffi::{CString, c_void}; +use std::sync::Arc; +use std::sync::atomic::{AtomicBool, Ordering}; +use raw_window_handle::RawWindowHandle; use umide_native::emulator::{ umide_native_create_emulator, umide_native_destroy_emulator, umide_native_resize_emulator, - umide_native_send_input, umide_native_attach_device, - NativeEmulator, EmulatorPlatform, EmulatorInputEvent + umide_native_send_input, umide_native_attach_device, umide_native_push_frame, + umide_native_show_emulator, umide_native_hide_emulator, + umide_native_set_input_callback, NativeEmulator, EmulatorPlatform, EmulatorInputEvent, EmulatorInputType }; +/// Commands to send to the gRPC command client +enum GrpcCommand { + Key(String), + KeyCode(i32), + TouchDown(i32, i32), + TouchMove(i32, i32), + TouchUp(i32, i32), + Scroll(i32, i32), +} + +/// Context passed to the C++ callback +struct CallbackCtx { + is_android: bool, + handle: *mut NativeEmulator, + grpc_cmd_tx: Option>, +} + +extern "C" fn input_callback(event_type: i32, x: i32, y: i32, user_data: *mut c_void) { + if user_data.is_null() { return; } + let ctx = unsafe { &*(user_data as *mut CallbackCtx) }; + + if ctx.is_android { + if let Some(tx) = &ctx.grpc_cmd_tx { + let cmd = match event_type { + 0 => GrpcCommand::TouchDown(x, y), + 1 => GrpcCommand::TouchMove(x, y), + 2 => GrpcCommand::TouchUp(x, y), + 3 => GrpcCommand::Scroll(x, y), // y is deltaY + _ => return, + }; + let _ = tx.send(cmd); + } + } else { + // iOS: send event directly back to C++ `send_input` handler where CGEventPost happens + let ev_type = match event_type { + 0 => EmulatorInputType::TouchDown, + 1 => EmulatorInputType::TouchMove, + 2 => EmulatorInputType::TouchUp, + 3 => EmulatorInputType::Scroll, + _ => return, + }; + let ev = EmulatorInputEvent { + event_type: ev_type, + x, + y, + key_code: 0, + }; + unsafe { umide_native_send_input(ctx.handle, &ev); } + } +} + pub struct NativeEmulatorView { handle: *mut NativeEmulator, + is_android: bool, + /// Cancellation flag for the gRPC streaming task + stream_cancel: Arc, + /// Channel to send commands to the gRPC command client + grpc_cmd_tx: Option>, + /// Pointer to the callback context (so we can drop it) + callback_ctx: *mut CallbackCtx, } unsafe impl Send for NativeEmulatorView {} unsafe impl Sync for NativeEmulatorView {} impl NativeEmulatorView { - pub fn new(window_handle: RawWindowHandle, width: u32, height: u32, platform: EmulatorPlatform) -> Result { + pub fn new(window_handle: RawWindowHandle, x: i32, y: i32, width: u32, height: u32, platform: EmulatorPlatform) -> Result { let parent_ptr = match window_handle { #[cfg(target_os = "macos")] RawWindowHandle::AppKit(handle) => handle.ns_view.as_ptr(), @@ -22,19 +83,39 @@ impl NativeEmulatorView { }; let handle = unsafe { - umide_native_create_emulator(parent_ptr, width, height, platform) + umide_native_create_emulator(parent_ptr, x, y, width, height, platform) }; if handle.is_null() { Err("Failed to create native emulator instance".to_string()) } else { - Ok(Self { handle }) + let is_android = matches!(platform, EmulatorPlatform::Android); + let (_grpc_cmd_tx, _) = std::sync::mpsc::channel::(); // placeholder, replaced in start_grpc_stream + + let ctx = Box::new(CallbackCtx { + is_android, + handle, + grpc_cmd_tx: None, + }); + let ctx_ptr = Box::into_raw(ctx); + + unsafe { + umide_native_set_input_callback(handle, Some(input_callback), ctx_ptr as *mut c_void); + } + + Ok(Self { + handle, + is_android, + stream_cancel: Arc::new(AtomicBool::new(false)), + grpc_cmd_tx: None, + callback_ctx: ctx_ptr, + }) } } - pub fn resize(&self, width: u32, height: u32) { + pub fn resize(&self, x: i32, y: i32, width: u32, height: u32) { unsafe { - umide_native_resize_emulator(self.handle, width, height); + umide_native_resize_emulator(self.handle, x, y, width, height); } } @@ -43,18 +124,301 @@ impl NativeEmulatorView { unsafe { umide_native_attach_device(self.handle, c_str.as_ptr()); } + + if !self.is_android { + self.ensure_idb_installed(); + } + } + + /// Silently checks and installs `idb` via Homebrew and pip if it is missing on the host. + /// This is strictly required for iOS interactability (taps/swipes). + fn ensure_idb_installed(&self) { + std::thread::spawn(move || { + // Check if idb exists + let output = std::process::Command::new("which") + .arg("idb") + .output(); + + let needs_install = match output { + Ok(out) => !out.status.success() || out.stdout.is_empty(), + Err(_) => true, + }; + + if needs_install { + tracing::info!("'idb' not found. Auto-installing iOS interaction dependencies..."); + + // 1. Install idb-companion via brew + let _ = std::process::Command::new("brew") + .args(["tap", "facebook/fb"]) + .output(); + let _ = std::process::Command::new("brew") + .args(["install", "idb-companion"]) + .output(); + + // 2. Install fb-idb via pip3 + let _ = std::process::Command::new("pip3") + .args(["install", "fb-idb"]) + .output(); + + tracing::info!("Finished installing iOS idb dependencies."); + } + }); + } + + + + /// Push RGBA frame data for display (used by gRPC streaming for Android) + pub fn push_frame(&self, rgba_data: &[u8], width: u32, height: u32) { + unsafe { + umide_native_push_frame(self.handle, rgba_data.as_ptr(), width, height); + } } - pub fn send_input(&self, event: EmulatorInputEvent) { + pub fn show(&self) { unsafe { - umide_native_send_input(self.handle, &event); + umide_native_show_emulator(self.handle); } } + + pub fn hide(&self) { + unsafe { + umide_native_hide_emulator(self.handle); + } + } + + /// Send a key event to the Android emulator via gRPC (e.g. "GoHome", "GoBack", "Power") + pub fn send_key(&self, key: &str) { + if let Some(tx) = &self.grpc_cmd_tx { + let _ = tx.send(GrpcCommand::Key(key.to_string())); + } + } + + /// Send a key code to the Android emulator via gRPC (e.g. 115=Vol+, 114=Vol-) + pub fn send_key_code(&self, code: i32) { + if let Some(tx) = &self.grpc_cmd_tx { + let _ = tx.send(GrpcCommand::KeyCode(code)); + } + } + + /// Send a touch down event to the Android emulator via gRPC + pub fn send_touch_down(&self, x: i32, y: i32) { + if let Some(tx) = &self.grpc_cmd_tx { + let _ = tx.send(GrpcCommand::TouchDown(x, y)); + } + } + + /// Send a touch move event to the Android emulator via gRPC + pub fn send_touch_move(&self, x: i32, y: i32) { + if let Some(tx) = &self.grpc_cmd_tx { + let _ = tx.send(GrpcCommand::TouchMove(x, y)); + } + } + + /// Send a touch up event to the Android emulator via gRPC + pub fn send_touch_up(&self, x: i32, y: i32) { + if let Some(tx) = &self.grpc_cmd_tx { + let _ = tx.send(GrpcCommand::TouchUp(x, y)); + } + } + + /// Start gRPC frame streaming for Android emulator. + /// Uses TWO separate gRPC clients: one for streaming frames, one for commands. + /// This avoids the deadlock where stream_screenshots holds a mutex forever. + pub fn start_grpc_stream(&mut self, grpc_endpoint: &str) { + if !self.is_android { + tracing::warn!("gRPC streaming is only for Android emulators"); + return; + } + + // Cancel any existing stream + self.stream_cancel.store(true, Ordering::SeqCst); + let cancel = Arc::new(AtomicBool::new(false)); + self.stream_cancel = cancel.clone(); + + let endpoint = grpc_endpoint.to_string(); + let handle_addr = self.handle as usize; + let cancel_flag = cancel.clone(); + + // Create a sync channel for commands (key presses, touch events) + let (cmd_tx, cmd_rx) = std::sync::mpsc::channel::(); + self.grpc_cmd_tx = Some(cmd_tx.clone()); + + // Update the callback context so the C++ callback can send to this channel + unsafe { + if !self.callback_ctx.is_null() { + let ctx = &mut *self.callback_ctx; + ctx.grpc_cmd_tx = Some(cmd_tx); + } + } + + // Spawn the streaming task on a background thread with its own tokio runtime + std::thread::spawn(move || { + let rt = match tokio::runtime::Runtime::new() { + Ok(rt) => rt, + Err(e) => { + tracing::error!("Failed to create tokio runtime for gRPC stream: {}", e); + return; + } + }; + + rt.block_on(async move { + use crate::grpc_client::EmulatorGrpcClient; + use tokio::sync::mpsc; + + tracing::info!("Android gRPC stream: connecting to {}...", endpoint); + + // Connect STREAMING client with retry + let mut stream_client = match EmulatorGrpcClient::connect_with_retry( + &endpoint, + std::time::Duration::from_secs(60), + ).await { + Ok(c) => { + tracing::info!("Android gRPC stream: streaming client connected!"); + c + } + Err(e) => { + tracing::error!("Android gRPC stream: failed to connect streaming client: {}", e); + return; + } + }; + + if cancel_flag.load(Ordering::SeqCst) { + tracing::info!("Android gRPC stream: cancelled before streaming started"); + return; + } + + // Connect COMMAND client (separate connection, no lock contention) + let cmd_endpoint = endpoint.clone(); + let cmd_cancel = cancel_flag.clone(); + tokio::spawn(async move { + let mut cmd_client = match EmulatorGrpcClient::connect_with_retry( + &cmd_endpoint, + std::time::Duration::from_secs(10), + ).await { + Ok(c) => { + tracing::info!("Android gRPC: command client connected!"); + c + } + Err(e) => { + tracing::error!("Android gRPC: failed to connect command client: {}", e); + return; + } + }; + + loop { + if cmd_cancel.load(Ordering::SeqCst) { + break; + } + match cmd_rx.try_recv() { + Ok(cmd) => { + match cmd { + GrpcCommand::Key(key) => { + if let Err(e) = cmd_client.send_key(&key).await { + tracing::warn!("gRPC send_key error: {}", e); + } + } + GrpcCommand::KeyCode(code) => { + if let Err(e) = cmd_client.send_key_code(code).await { + tracing::warn!("gRPC send_key_code error: {}", e); + } + } + GrpcCommand::TouchDown(x, y) => { + if let Err(e) = cmd_client.send_touch_down(x, y).await { + tracing::warn!("gRPC touch_down error: {}", e); + } + } + GrpcCommand::TouchMove(x, y) => { + if let Err(e) = cmd_client.send_touch_down(x, y).await { + tracing::warn!("gRPC touch_move error: {}", e); + } + } + GrpcCommand::TouchUp(x, y) => { + if let Err(e) = cmd_client.send_touch_up(x, y).await { + tracing::warn!("gRPC touch_up error: {}", e); + } + } + GrpcCommand::Scroll(x, delta_y) => { + let start_y = 500; + let end_y = start_y - delta_y * 5; + let _ = cmd_client.send_touch_down(x, start_y).await; + tokio::time::sleep(std::time::Duration::from_millis(15)).await; + let _ = cmd_client.send_touch_move(x, end_y).await; + tokio::time::sleep(std::time::Duration::from_millis(15)).await; + let _ = cmd_client.send_touch_up(x, end_y).await; + } + } + } + Err(std::sync::mpsc::TryRecvError::Empty) => { + tokio::time::sleep(std::time::Duration::from_millis(10)).await; + } + Err(std::sync::mpsc::TryRecvError::Disconnected) => { + break; + } + } + } + }); + + // Start streaming frames (this runs until cancelled or error) + let (tx, mut rx) = mpsc::channel(2); + let stream_cancel = cancel_flag.clone(); + tokio::spawn(async move { + if let Err(e) = stream_client.stream_screenshots(tx).await { + if !stream_cancel.load(Ordering::SeqCst) { + tracing::error!("Android gRPC stream error: {}", e); + } + } + }); + + // Push frames to native view + while let Some(frame) = rx.recv().await { + if cancel_flag.load(Ordering::SeqCst) { + tracing::info!("Android gRPC stream: cancelled"); + break; + } + + if let Some(rgba_data) = frame.to_rgba() { + let ptr = handle_addr as *mut NativeEmulator; + unsafe { + umide_native_push_frame( + ptr, + rgba_data.as_ptr(), + frame.width, + frame.height, + ); + } + } + } + + tracing::info!("Android gRPC stream: ended"); + }); + }); + } + + /// Stop the gRPC streaming task + pub fn stop_stream(&self) { + self.stream_cancel.store(true, Ordering::SeqCst); + } + + /// Check if this is an Android emulator + pub fn is_android(&self) -> bool { + self.is_android + } + + } impl Drop for NativeEmulatorView { fn drop(&mut self) { + // Cancel any running stream first + self.stream_cancel.store(true, Ordering::SeqCst); + // Drop the command channel + self.grpc_cmd_tx = None; + // Give the stream thread a moment to notice cancellation + std::thread::sleep(std::time::Duration::from_millis(50)); unsafe { + if !self.callback_ctx.is_null() { + let _ = Box::from_raw(self.callback_ctx); + } umide_native_destroy_emulator(self.handle); } } diff --git a/crates/umide_emulator/src/video/mod.rs b/crates/umide_emulator/src/video/mod.rs index 2b6def84..b97c0f62 100644 --- a/crates/umide_emulator/src/video/mod.rs +++ b/crates/umide_emulator/src/video/mod.rs @@ -1,5 +1,6 @@ pub mod macos; pub mod openh264; +#[cfg(target_os = "macos")] pub mod macos_hardware; pub mod fallback; pub mod h264_source; diff --git a/crates/umide_native/cpp/include/umide_native_api.h b/crates/umide_native/cpp/include/umide_native_api.h index fad1fe90..e6cd65f6 100644 --- a/crates/umide_native/cpp/include/umide_native_api.h +++ b/crates/umide_native/cpp/include/umide_native_api.h @@ -24,6 +24,7 @@ typedef enum { EMULATOR_INPUT_TOUCH_UP = 2, EMULATOR_INPUT_KEY_DOWN = 3, EMULATOR_INPUT_KEY_UP = 4, + EMULATOR_INPUT_SCROLL = 5, } EmulatorInputType; typedef struct { @@ -37,13 +38,13 @@ typedef struct { // Create a new emulator view hosted within the given parent window. // parent_window: On macOS, this is a void* pointer to an NSView. // On Windows, an HWND. Linux, XID/Wayland surface. -NativeEmulator* umide_native_create_emulator(void* parent_window, uint32_t width, uint32_t height, EmulatorPlatform platform); +NativeEmulator* umide_native_create_emulator(void* parent_window, int32_t x, int32_t y, uint32_t width, uint32_t height, EmulatorPlatform platform); // Destroy the emulator view void umide_native_destroy_emulator(NativeEmulator* emulator); -// Resize the emulator view -void umide_native_resize_emulator(NativeEmulator* emulator, uint32_t width, uint32_t height); +// Resize and move the emulator view +void umide_native_resize_emulator(NativeEmulator* emulator, int32_t x, int32_t y, uint32_t width, uint32_t height); // Send input to the emulator void umide_native_send_input(NativeEmulator* emulator, const EmulatorInputEvent* event); @@ -52,6 +53,17 @@ void umide_native_send_input(NativeEmulator* emulator, const EmulatorInputEvent* // device_id: serial for ADB, UDID for iOS void umide_native_attach_device(NativeEmulator* emulator, const char* device_id); +// Push an RGBA frame for display (used by gRPC streaming for Android) +// rgba_data: pointer to RGBA8888 pixel data +// width/height: dimensions in pixels +void umide_native_push_frame(NativeEmulator* emulator, const uint8_t* rgba_data, uint32_t width, uint32_t height); + +// Input callback definition: event_type, x, y, user_data +typedef void (*EmulatorInputCallback)(int32_t event_type, int32_t x, int32_t y, void* user_data); + +// Set input callback to route touch/mouse/scroll events back to Rust +void umide_native_set_input_callback(NativeEmulator* emulator, EmulatorInputCallback callback, void* user_data); + #ifdef __cplusplus } #endif diff --git a/crates/umide_native/cpp/src/emulator.h b/crates/umide_native/cpp/src/emulator.h index 3453df8a..736cfbb5 100644 --- a/crates/umide_native/cpp/src/emulator.h +++ b/crates/umide_native/cpp/src/emulator.h @@ -11,17 +11,30 @@ class Emulator { virtual ~Emulator() = default; // Initialize the native surface/window attachment - virtual bool initialize(void* parent_window, uint32_t width, uint32_t height) = 0; + virtual bool initialize(void* parent_window, int32_t x, int32_t y, uint32_t width, uint32_t height) = 0; - // Handle resizing - virtual void resize(uint32_t width, uint32_t height) = 0; + // Handle resizing and moving + virtual void resize(int32_t x, int32_t y, uint32_t width, uint32_t height) = 0; // Attach a specific emulator instance virtual void attach_device(const std::string& device_id) = 0; + // Show the emulator + virtual void show() = 0; + + // Hide the emulator + virtual void hide() = 0; + // Handle input virtual void send_input(const EmulatorInputEvent& event) = 0; + + // Push an RGBA frame for display (used by gRPC streaming for Android) + virtual void push_frame(const uint8_t* rgba_data, uint32_t width, uint32_t height) = 0; + + // Set input callback to route native NSView events back to Rust + virtual void set_input_callback(void (*callback)(int32_t, int32_t, int32_t, void*), void* user_data) = 0; + // Factory method static Emulator* create(EmulatorPlatform platform); }; diff --git a/crates/umide_native/cpp/src/emulator_api.cpp b/crates/umide_native/cpp/src/emulator_api.cpp index e0e5ba93..602b35cd 100644 --- a/crates/umide_native/cpp/src/emulator_api.cpp +++ b/crates/umide_native/cpp/src/emulator_api.cpp @@ -6,7 +6,7 @@ using namespace umide; extern "C" { -NativeEmulator* umide_native_create_emulator(void* parent_window, uint32_t width, uint32_t height, EmulatorPlatform platform) { +NativeEmulator* umide_native_create_emulator(void* parent_window, int32_t x, int32_t y, uint32_t width, uint32_t height, EmulatorPlatform platform) { if (!parent_window) { std::cerr << "Error: parent_window is null" << std::endl; return nullptr; @@ -18,7 +18,7 @@ NativeEmulator* umide_native_create_emulator(void* parent_window, uint32_t width return nullptr; } - if (!emulator->initialize(parent_window, width, height)) { + if (!emulator->initialize(parent_window, x, y, width, height)) { std::cerr << "Error: Failed to initialize emulator" << std::endl; delete emulator; return nullptr; @@ -33,9 +33,9 @@ void umide_native_destroy_emulator(NativeEmulator* emulator) { } } -void umide_native_resize_emulator(NativeEmulator* emulator, uint32_t width, uint32_t height) { +void umide_native_resize_emulator(NativeEmulator* emulator, int32_t x, int32_t y, uint32_t width, uint32_t height) { if (emulator) { - reinterpret_cast(emulator)->resize(width, height); + reinterpret_cast(emulator)->resize(x, y, width, height); } } @@ -45,10 +45,34 @@ void umide_native_send_input(NativeEmulator* emulator, const EmulatorInputEvent* } } +void umide_native_show_emulator(NativeEmulator* emulator) { + if (emulator) { + reinterpret_cast(emulator)->show(); + } +} + +void umide_native_hide_emulator(NativeEmulator* emulator) { + if (emulator) { + reinterpret_cast(emulator)->hide(); + } +} + void umide_native_attach_device(NativeEmulator* emulator, const char* device_id) { if (emulator && device_id) { reinterpret_cast(emulator)->attach_device(std::string(device_id)); } } +void umide_native_push_frame(NativeEmulator* emulator, const uint8_t* rgba_data, uint32_t width, uint32_t height) { + if (emulator && rgba_data && width > 0 && height > 0) { + reinterpret_cast(emulator)->push_frame(rgba_data, width, height); + } +} + +void umide_native_set_input_callback(NativeEmulator* emulator, EmulatorInputCallback callback, void* user_data) { + if (emulator) { + reinterpret_cast(emulator)->set_input_callback(callback, user_data); + } +} + } // extern "C" diff --git a/crates/umide_native/cpp/src/macos/macos_emulator.mm b/crates/umide_native/cpp/src/macos/macos_emulator.mm index 2edbca48..c840d8ea 100644 --- a/crates/umide_native/cpp/src/macos/macos_emulator.mm +++ b/crates/umide_native/cpp/src/macos/macos_emulator.mm @@ -1,115 +1,800 @@ #import #import #import +#import +#import +#import #include "src/emulator.h" #include +#include +#include +#include + // Forward declaration of the C++ class to use in ObjC namespace umide { class MacOSEmulator; } -// define a custom NSView to handle rendering/input? -@interface UmideHostView : NSView +// Input callback type: platform, eventType (0=down,1=move,2=up), x, y +typedef void (^UmideInputCallback)(int eventType, int x, int y); + +// Custom view that captures and displays an external window's content using ScreenCaptureKit +API_AVAILABLE(macos(12.3)) +@interface UmideEmulatorView : NSView { + SCStream* captureStream; + CGImageRef latestFrame; + BOOL isCapturing; + dispatch_queue_t captureQueue; + CIContext* ciContext; + volatile BOOL isBeingDestroyed; + // Track the captured image dimensions for coordinate mapping +@public + CGFloat capturedWidth; + CGFloat capturedHeight; +} +@property (nonatomic, copy) UmideInputCallback inputCallback; +- (void)startCapturingWindowWithID:(CGWindowID)windowID; +- (void)stopCapturing; +- (void)showStatus:(NSString*)status; +- (void)pushFrameWithData:(const uint8_t*)rgbaData width:(uint32_t)width height:(uint32_t)height; @end -@implementation UmideHostView -- (void)drawRect:(NSRect)dirtyRect { - [[NSColor blackColor] setFill]; - NSRectFill(dirtyRect); +API_AVAILABLE(macos(12.3)) +@implementation UmideEmulatorView + +- (instancetype)initWithFrame:(NSRect)frameRect { + self = [super initWithFrame:frameRect]; + if (self) { + captureStream = nil; + latestFrame = NULL; + isCapturing = NO; + isBeingDestroyed = NO; + capturedWidth = 0; + capturedHeight = 0; + captureQueue = dispatch_queue_create("com.umide.screencapture", DISPATCH_QUEUE_SERIAL); + ciContext = [CIContext context]; + [self setWantsLayer:YES]; + self.layer.backgroundColor = [[NSColor blackColor] CGColor]; + // Ensure CoreAnimation scales the video frames automatically while maintaining aspect ratio + self.layer.contentsGravity = kCAGravityResizeAspect; + } + return self; +} + +- (void)startCapturingWindowWithID:(CGWindowID)windowID { + if (isCapturing) return; + + NSLog(@"UmideEmulatorView: Requesting capture for window ID %u", windowID); + + // Find the SCWindow matching our windowID + [SCShareableContent getShareableContentWithCompletionHandler:^(SCShareableContent * _Nullable content, NSError * _Nullable error) { + if (error) { + NSLog(@"UmideEmulatorView: Failed to get shareable content: %@", error); + NSLog(@"UmideEmulatorView: Make sure Screen Recording permission is granted in System Settings > Privacy & Security"); + return; + } + + // Find the window with matching ID + SCWindow* targetWindow = nil; + for (SCWindow* window in content.windows) { + if (window.windowID == windowID) { + targetWindow = window; + break; + } + } + + if (!targetWindow) { + NSLog(@"UmideEmulatorView: Could not find window with ID %u among %lu windows", + windowID, (unsigned long)content.windows.count); + for (SCWindow* window in content.windows) { + NSLog(@" Available window: ID=%u app='%@' title='%@'", + window.windowID, window.owningApplication.applicationName, window.title); + } + return; + } + + NSLog(@"UmideEmulatorView: Found window '%@' (app: '%@') size=%.0fx%.0f for capture", + targetWindow.title, targetWindow.owningApplication.applicationName, + targetWindow.frame.size.width, targetWindow.frame.size.height); + + // Configure stream for window capture + SCContentFilter* filter = [[SCContentFilter alloc] initWithDesktopIndependentWindow:targetWindow]; + + SCStreamConfiguration* config = [[SCStreamConfiguration alloc] init]; + config.width = (size_t)MAX(targetWindow.frame.size.width, 1); + config.height = (size_t)MAX(targetWindow.frame.size.height, 1); + config.minimumFrameInterval = CMTimeMake(1, 60); // 60 FPS + config.pixelFormat = kCVPixelFormatType_32BGRA; + config.showsCursor = NO; + config.capturesAudio = NO; + + // Remove massive macOS window drop shadow from the capture if supported (macOS 14+) + if ([config respondsToSelector:NSSelectorFromString(@"setIgnoreShadowsSingleWindow:")]) { + [config setValue:@YES forKey:@"ignoreShadowsSingleWindow"]; + } + + self->captureStream = [[SCStream alloc] initWithFilter:filter configuration:config delegate:self]; + + NSError* addOutputError; + BOOL added = [self->captureStream addStreamOutput:self type:SCStreamOutputTypeScreen sampleHandlerQueue:self->captureQueue error:&addOutputError]; + if (!added) { + NSLog(@"UmideEmulatorView: Failed to add stream output: %@", addOutputError); + return; + } + + [self->captureStream startCaptureWithCompletionHandler:^(NSError * _Nullable startError) { + if (startError) { + NSLog(@"UmideEmulatorView: Failed to start capture: %@ (code: %ld)", + startError.localizedDescription, (long)startError.code); + } else { + self->isCapturing = YES; + NSLog(@"UmideEmulatorView: Started capturing window at %zux%zu @ 60fps", + config.width, config.height); + } + }]; + }]; +} + +- (void)stopCapturing { + if (!isCapturing || !captureStream) return; + + isCapturing = NO; + SCStream* streamToStop = captureStream; + captureStream = nil; + + [streamToStop stopCaptureWithCompletionHandler:^(NSError * _Nullable error) { + if (error) { + NSLog(@"UmideEmulatorView: Error stopping capture: %@", error); + } else { + NSLog(@"UmideEmulatorView: Capture stopped cleanly"); + } + }]; + + if (latestFrame) { + CGImageRelease(latestFrame); + latestFrame = NULL; + } +} + +- (void)showStatus:(NSString*)status { + NSLog(@"UmideEmulatorView: Status: %@", status); + [self setNeedsDisplay:YES]; +} + +// SCStreamOutput delegate method - called for each frame +- (void)stream:(SCStream *)stream didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer ofType:(SCStreamOutputType)type { + if (type != SCStreamOutputTypeScreen) return; + if (isBeingDestroyed) return; + + CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); + if (!imageBuffer) return; + + // Use cached CIContext to avoid per-frame allocation + CIImage* ciImage = [CIImage imageWithCVPixelBuffer:imageBuffer]; + CGImageRef newFrame = [ciContext createCGImage:ciImage fromRect:ciImage.extent]; + + if (newFrame) { + CGFloat imgW = (CGFloat)CGImageGetWidth(newFrame); + CGFloat imgH = (CGFloat)CGImageGetHeight(newFrame); + + dispatch_async(dispatch_get_main_queue(), ^{ + if (self->isBeingDestroyed) { + CGImageRelease(newFrame); + return; + } + if (self->latestFrame) { + CGImageRelease(self->latestFrame); + } + self->latestFrame = newFrame; + self->capturedWidth = imgW; + self->capturedHeight = imgH; + + // Render directly through the layer tree instead of relying on drawRect: + // This grants hardware-accelerated kCAGravityResizeAspect perfect fit + self.layer.contents = (__bridge id)self->latestFrame; + }); + } +} + +// SCStreamDelegate method - called on stream errors +- (void)stream:(SCStream *)stream didStopWithError:(NSError *)error { + NSLog(@"UmideEmulatorView: Stream stopped with error: %@ (code: %ld)", + error.localizedDescription, (long)error.code); + isCapturing = NO; + + if (!isBeingDestroyed) { + NSLog(@"UmideEmulatorView: Will not auto-restart — device may have been stopped"); + } +} + +// Calculate the aspect-fit drawing rect for the current frame +- (NSRect)aspectFitRect { + if (capturedWidth <= 0 || capturedHeight <= 0) return self.bounds; + + NSRect bounds = self.bounds; + CGFloat scaleX = bounds.size.width / capturedWidth; + CGFloat scaleY = bounds.size.height / capturedHeight; + CGFloat scale = MIN(scaleX, scaleY); + + CGFloat drawW = capturedWidth * scale; + CGFloat drawH = capturedHeight * scale; + CGFloat drawX = (bounds.size.width - drawW) / 2.0; + CGFloat drawY = (bounds.size.height - drawH) / 2.0; + + return NSMakeRect(drawX, drawY, drawW, drawH); +} + +// Map a view point to emulator coordinates (0..capturedWidth, 0..capturedHeight) +- (NSPoint)viewPointToEmulatorPoint:(NSPoint)viewPoint { + NSRect drawRect = [self aspectFitRect]; + if (drawRect.size.width <= 0 || drawRect.size.height <= 0) return NSMakePoint(-1, -1); + + // Map from view-space draw rect to image-space + CGFloat relX = (viewPoint.x - drawRect.origin.x) / drawRect.size.width; + CGFloat relY = (viewPoint.y - drawRect.origin.y) / drawRect.size.height; + + // Clamp to valid range + if (relX < 0 || relX > 1 || relY < 0 || relY > 1) return NSMakePoint(-1, -1); + + // NSView is bottom-up, emulator is top-down — flip Y + CGFloat emuX = relX * capturedWidth; + CGFloat emuY = (1.0 - relY) * capturedHeight; + + return NSMakePoint(emuX, emuY); +} + +// Mouse event handling for interaction +- (BOOL)acceptsFirstResponder { + return YES; +} + +- (BOOL)acceptsFirstMouse:(NSEvent *)event { + return YES; +} + +- (void)mouseDown:(NSEvent *)event { + NSPoint viewPoint = [self convertPoint:[event locationInWindow] fromView:nil]; + NSPoint emuPoint = [self viewPointToEmulatorPoint:viewPoint]; + if (emuPoint.x >= 0 && self.inputCallback) { + self.inputCallback(0, (int)emuPoint.x, (int)emuPoint.y); + } +} - // Draw a placeholder text - NSString* text = @"Native Emulator Host"; - NSDictionary* attrs = @{ - NSForegroundColorAttributeName: [NSColor whiteColor], - NSFontAttributeName: [NSFont systemFontOfSize:24] - }; - [text drawAtPoint:NSMakePoint(dirtyRect.size.width/2 - 100, dirtyRect.size.height/2) withAttributes:attrs]; +- (void)mouseDragged:(NSEvent *)event { + NSPoint viewPoint = [self convertPoint:[event locationInWindow] fromView:nil]; + NSPoint emuPoint = [self viewPointToEmulatorPoint:viewPoint]; + if (emuPoint.x >= 0 && self.inputCallback) { + self.inputCallback(1, (int)emuPoint.x, (int)emuPoint.y); + } +} + +- (void)mouseUp:(NSEvent *)event { + NSPoint viewPoint = [self convertPoint:[event locationInWindow] fromView:nil]; + NSPoint emuPoint = [self viewPointToEmulatorPoint:viewPoint]; + if (emuPoint.x >= 0 && self.inputCallback) { + self.inputCallback(2, (int)emuPoint.x, (int)emuPoint.y); + } +} + +- (void)scrollWheel:(NSEvent *)event { + NSPoint viewPoint = [self convertPoint:[event locationInWindow] fromView:nil]; + NSPoint emuPoint = [self viewPointToEmulatorPoint:viewPoint]; + if (emuPoint.x >= 0 && self.inputCallback) { + // Event type 3 = scroll, pass deltaY as the y coordinate + int deltaY = (int)([event scrollingDeltaY] * 3); // Amplify for emulator + self.inputCallback(3, (int)emuPoint.x, deltaY); + } } + +// Removed manual drawRect: - replaced by CALayer rendering + +- (void)dealloc { + isBeingDestroyed = YES; + [self stopCapturing]; +} + +// Push RGBA frame data from gRPC (Android native resolution) +- (void)pushFrameWithData:(const uint8_t*)rgbaData width:(uint32_t)width height:(uint32_t)height { + if (!rgbaData || width == 0 || height == 0) return; + if (isBeingDestroyed) return; + + // Create CGImage from RGBA data + size_t bytesPerRow = width * 4; + size_t dataSize = bytesPerRow * height; + + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CFDataRef cfData = CFDataCreate(NULL, rgbaData, dataSize); + CGDataProviderRef provider = CGDataProviderCreateWithCFData(cfData); + + CGImageRef newFrame = CGImageCreate( + width, height, + 8, // bits per component + 32, // bits per pixel + bytesPerRow, + colorSpace, + kCGBitmapByteOrderDefault | kCGImageAlphaLast, // RGBA + provider, + NULL, // decode + false, // shouldInterpolate + kCGRenderingIntentDefault + ); + + CGDataProviderRelease(provider); + CFRelease(cfData); + CGColorSpaceRelease(colorSpace); + + if (newFrame) { + // Must update UI on main thread + if ([NSThread isMainThread]) { + if (latestFrame) CGImageRelease(latestFrame); + latestFrame = newFrame; + capturedWidth = width; + capturedHeight = height; + + // Render directly through the layer tree instead of relying on drawRect: + self.layer.contents = (__bridge id)self->latestFrame; + } else { + dispatch_async(dispatch_get_main_queue(), ^{ + if (self->isBeingDestroyed) { + CGImageRelease(newFrame); + return; + } + if (self->latestFrame) CGImageRelease(self->latestFrame); + self->latestFrame = newFrame; + self->capturedWidth = width; + self->capturedHeight = height; + + // Render directly through the layer tree instead of relying on drawRect: + self.layer.contents = (__bridge id)self->latestFrame; + }); + } + } +} + @end +// Helper for safe main thread execution +static void runOnMainThread(void (^block)(void)) { + if ([NSThread isMainThread]) { + block(); + } else { + dispatch_sync(dispatch_get_main_queue(), block); + } +} + +// Find window ID by process name and optional window title +static CGWindowID findWindowByProcessName(const std::string& processName, const std::string& titleContains = "") { + CFArrayRef windowList = CGWindowListCopyWindowInfo( + kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, + kCGNullWindowID + ); + + if (!windowList) return 0; + + CGWindowID foundWindowID = 0; + CGWindowID bestMatch = 0; + CFIndex count = CFArrayGetCount(windowList); + + NSLog(@"findWindowByProcessName: Looking for process='%s' title='%s' among %ld windows", + processName.c_str(), titleContains.c_str(), (long)count); + + for (CFIndex i = 0; i < count; i++) { + CFDictionaryRef windowInfo = (CFDictionaryRef)CFArrayGetValueAtIndex(windowList, i); + + // Get owner name (process name) + CFStringRef ownerName = (CFStringRef)CFDictionaryGetValue(windowInfo, kCGWindowOwnerName); + if (!ownerName) continue; + + char ownerBuffer[256]; + if (!CFStringGetCString(ownerName, ownerBuffer, sizeof(ownerBuffer), kCFStringEncodingUTF8)) { + continue; + } + + // Check if process name matches + std::string owner(ownerBuffer); + if (owner.find(processName) == std::string::npos) { + continue; + } + + // Get window layer — skip menu bar items and status items (layer != 0) + CFNumberRef layerRef = (CFNumberRef)CFDictionaryGetValue(windowInfo, kCGWindowLayer); + int32_t layer = 0; + if (layerRef) { + CFNumberGetValue(layerRef, kCFNumberSInt32Type, &layer); + } + if (layer != 0) continue; // Only normal windows (layer 0) + + // Get window ID + CFNumberRef windowIDRef = (CFNumberRef)CFDictionaryGetValue(windowInfo, kCGWindowNumber); + CGWindowID windowID = 0; + if (windowIDRef) { + CFNumberGetValue(windowIDRef, kCGWindowIDCFNumberType, &windowID); + } + if (windowID == 0) continue; + + // Get window title + CFStringRef windowName = (CFStringRef)CFDictionaryGetValue(windowInfo, kCGWindowName); + char titleBuffer[512] = ""; + if (windowName) { + CFStringGetCString(windowName, titleBuffer, sizeof(titleBuffer), kCFStringEncodingUTF8); + } + + NSLog(@" Candidate: process='%s' title='%s' windowID=%u layer=%d", + ownerBuffer, titleBuffer, windowID, layer); + + // If title filter specified, prefer windows matching it + if (!titleContains.empty()) { + if (strlen(titleBuffer) > 0 && std::string(titleBuffer).find(titleContains) != std::string::npos) { + NSLog(@" -> Title match! Using window %u", windowID); + foundWindowID = windowID; + break; + } + // Save as fallback in case no title match + if (bestMatch == 0) { + bestMatch = windowID; + } + } else { + // No title filter, take the first match + foundWindowID = windowID; + break; + } + } + + CFRelease(windowList); + + // Use best match if no exact title match was found + if (foundWindowID == 0 && bestMatch != 0) { + NSLog(@"findWindowByProcessName: No title match, using fallback window %u", bestMatch); + foundWindowID = bestMatch; + } + + return foundWindowID; +} + namespace umide { class MacOSEmulator : public Emulator { private: - UmideHostView* hostView = nil; - NSView* parentView = nil; // Weak ref + NSWindow* childWindow = nil; + UmideEmulatorView* emulatorView = nil; + NSView* parentView = nil; + CGWindowID embeddedWindowID = 0; + std::string currentDeviceId; + EmulatorPlatform platform; + volatile bool destroyed = false; + uint32_t viewWidth = 400; + uint32_t viewHeight = 860; + + // State tracking for iOS idb touches + int lastTouchX = 0; + int lastTouchY = 0; + std::chrono::steady_clock::time_point lastMoveTime; public: - MacOSEmulator() {} + MacOSEmulator(EmulatorPlatform p) : platform(p) {} ~MacOSEmulator() override { - if (hostView) { - dispatch_sync(dispatch_get_main_queue(), ^{ - [hostView removeFromSuperview]; - // hostView is autoreleased or strong ref depending on usage, - // but removeFromSuperview releases the parent's hold. - hostView = nil; + destroyed = true; + if (childWindow) { + runOnMainThread(^{ + if (emulatorView) { + [emulatorView stopCapturing]; + } + NSWindow* parent = [childWindow parentWindow]; + if (parent) { + [parent removeChildWindow:childWindow]; + } + [childWindow orderOut:nil]; + [childWindow close]; + childWindow = nil; + emulatorView = nil; }); } } - bool initialize(void* parent_window, uint32_t width, uint32_t height) override { + void (*inputCallbackFn)(int32_t, int32_t, int32_t, void*) = nullptr; + void* inputCallbackUserData = nullptr; + + bool initialize(void* parent_window, int32_t x, int32_t y, uint32_t width, uint32_t height) override { parentView = (__bridge NSView*)parent_window; - // Ensure we run UI updates on main thread __block bool success = false; - // We block here because init is expected to be synchronous for safety - dispatch_sync(dispatch_get_main_queue(), ^{ - hostView = [[UmideHostView alloc] initWithFrame:NSMakeRect(0, 0, width, height)]; - if (!hostView) return; - - // Auto resize with parent - [hostView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + runOnMainThread(^{ + NSWindow* parentWin = [parentView window]; + if (!parentWin) { + std::cerr << "MacOSEmulator: Parent view has no window!" << std::endl; + return; + } - // Add to parent - [parentView addSubview:hostView]; - - // Use a CALayer for potential Metal backing - [hostView setWantsLayer:YES]; - hostView.layer.backgroundColor = [[NSColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:1.0] CGColor]; + // Calculate exact screen coordinates for initialization to avoid 0x0 bugs + NSRect windowFrame = [parentWin frame]; + NSRect contentRect = [parentWin contentLayoutRect]; + CGFloat screenX = windowFrame.origin.x + x; + CGFloat screenTop = windowFrame.origin.y + windowFrame.size.height - contentRect.origin.y - y; + CGFloat screenY = screenTop - height; + NSRect initialChildFrame = NSMakeRect(screenX, screenY, width, height); + // Create a borderless child window sized precisely + childWindow = [[NSPanel alloc] initWithContentRect:initialChildFrame + styleMask:NSWindowStyleMaskBorderless + backing:NSBackingStoreBuffered + defer:NO]; + + [childWindow setReleasedWhenClosed:NO]; + [childWindow setHidesOnDeactivate:NO]; + [childWindow setCanHide:NO]; + [childWindow setOpaque:YES]; + [childWindow setBackgroundColor:[NSColor blackColor]]; + + emulatorView = [[UmideEmulatorView alloc] initWithFrame:NSMakeRect(0, 0, width, height)]; + + // Wire up input callback to forward mouse events to Rust + emulatorView.inputCallback = ^(int eventType, int emuX, int emuY) { + if (this->inputCallbackFn) { + this->inputCallbackFn(eventType, emuX, emuY, this->inputCallbackUserData); + } + }; + + [childWindow setContentView:emulatorView]; + + // Make the child window accept mouse events for interaction + [childWindow setIgnoresMouseEvents:NO]; + + // Attach to parent window + [parentWin addChildWindow:childWindow ordered:NSWindowAbove]; + + // Initial positioning + this->resize(x, y, width, height); + + NSLog(@"MacOSEmulator: Initialized child window for %s platform", + platform == EMULATOR_PLATFORM_ANDROID ? "Android" : "iOS"); + success = true; }); return success; } - void resize(uint32_t width, uint32_t height) override { - // Auto-resizing mask should handle frame changes if parent changes, - // but if we need explicit sizing: - dispatch_async(dispatch_get_main_queue(), ^{ - if (hostView) { - [hostView setFrameSize:NSMakeSize(width, height)]; - } - }); + void set_input_callback(void (*callback)(int32_t, int32_t, int32_t, void*), void* user_data) override { + inputCallbackFn = callback; + inputCallbackUserData = user_data; + } + + void resize(int32_t x, int32_t y, uint32_t width, uint32_t height) override { + if (destroyed) return; + + runOnMainThread(^{ + if (parentView && childWindow) { + NSWindow* parentWin = [parentView window]; + if (!parentWin) return; + + NSRect windowFrame = [parentWin frame]; + NSRect contentRect = [parentWin contentLayoutRect]; + + CGFloat screenX = windowFrame.origin.x + x; + CGFloat screenTop = windowFrame.origin.y + windowFrame.size.height - contentRect.origin.y - y; + + // CLAMP : ne jamais dépasser le bas de la fenêtre parente + CGFloat parentBottom = windowFrame.origin.y; + CGFloat maxHeight = screenTop - parentBottom; + CGFloat clampedHeight = MIN((CGFloat)height, maxHeight); + + CGFloat screenY = screenTop - clampedHeight; + + NSRect rectInScreen = NSMakeRect(screenX, screenY, width, clampedHeight); + [childWindow setFrame:rectInScreen display:YES]; + + viewWidth = width; + viewHeight = height; // Keep original requested dimensions for logical sizing if needed later + + // CRITICAL: Explicitly update the content view's frame + // The NSPanel starts at NSZeroRect, so autoresizingMask from 0x0 stays 0x0 + // We must manually set the view frame to match the window's content area + if (emulatorView) { + [emulatorView setFrame:NSMakeRect(0, 0, width, clampedHeight)]; + NSLog(@"MacOSEmulator::resize: window=%dx%d view=%dx%d", + (int)width, (int)clampedHeight, + (int)emulatorView.frame.size.width, (int)emulatorView.frame.size.height); + } + } + }); } void attach_device(const std::string& device_id) override { - std::cout << "MacOSEmulator: Attaching device " << device_id << std::endl; - //TODO: Implement Simctl/Metal surface attachment here + currentDeviceId = device_id; + NSLog(@"MacOSEmulator: Attaching device '%s' (platform=%s)", + device_id.c_str(), + platform == EMULATOR_PLATFORM_ANDROID ? "Android" : "iOS"); + + if (platform == EMULATOR_PLATFORM_ANDROID) { + // Android: emulator runs headless (-no-window), frames arrive via gRPC pushFrame. + // No window to find, no ScreenCaptureKit, no AppleScript. + // The Rust side handles gRPC connection and frame streaming. + NSLog(@"MacOSEmulator: Android device attached (headless mode, frames via gRPC)"); + + dispatch_async(dispatch_get_main_queue(), ^{ + if (!destroyed && emulatorView) { + [emulatorView showStatus:@"Connecting to Android emulator..."]; + } + }); + return; + } + + // iOS Simulator: Find the simulator window and capture via ScreenCaptureKit + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + if (destroyed) return; + + CGWindowID windowID = 0; + + // Poll for the window to appear (max 30 seconds, 300 attempts * 100ms) + int maxAttempts = 300; + for (int attempt = 0; attempt < maxAttempts && windowID == 0; attempt++) { + if (destroyed) return; + + // iOS Simulator — match by device name in window title + // Simulator.app window titles contain the device name, e.g. "iPhone 15 Pro" + windowID = findWindowByProcessName("Simulator", device_id); + + if (windowID == 0) { + if (attempt % 50 == 0) { + NSLog(@"MacOSEmulator: Waiting for Simulator window (attempt %d/%d)...", attempt, maxAttempts); + } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + } + + if (destroyed) return; + + if (windowID != 0) { + embeddedWindowID = windowID; + NSLog(@"MacOSEmulator: Found Simulator window ID %u for device '%s'", windowID, device_id.c_str()); + + dispatch_async(dispatch_get_main_queue(), ^{ + if (!destroyed && emulatorView) { + [emulatorView startCapturingWindowWithID:windowID]; + } + }); + } else { + NSLog(@"MacOSEmulator: ERROR - Could not find Simulator window for device '%s' after %d seconds", + device_id.c_str(), maxAttempts / 10); + + // Show error status in the view + dispatch_async(dispatch_get_main_queue(), ^{ + if (!destroyed && emulatorView) { + [emulatorView showStatus:@"Could not find Simulator window.\nCheck Screen Recording permission."]; + } + }); + } + }); } - void send_input(const EmulatorInputEvent& /*_event*/) override { - // Forward input to backend + void send_input(const EmulatorInputEvent& event) override { + if (destroyed) return; + + if (platform == EMULATOR_PLATFORM_ANDROID) { + // Forward touch events via ADB + if (event.type == EMULATOR_INPUT_TOUCH_DOWN || event.type == EMULATOR_INPUT_TOUCH_UP) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + std::string cmd = std::string("adb shell input tap ") + + std::to_string(event.x) + " " + std::to_string(event.y); + int result = system(cmd.c_str()); + if (result != 0) { + NSLog(@"MacOSEmulator: ADB input command failed with code %d", result); + } + }); + } else if (event.type == EMULATOR_INPUT_KEY_DOWN) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + std::string cmd = std::string("adb shell input keyevent ") + + std::to_string(event.key_code); + system(cmd.c_str()); + }); + } + } else { + // Forward touch events to iOS Simulator using idb + if (embeddedWindowID != 0 && emulatorView != nil) { + + // Convert simulator capture pixels into idb logical points (assume 3.0x retina scale) + int mappedX = (int)(event.x / 3.0f); + int mappedY = (int)(event.y / 3.0f); + + if (event.type == EMULATOR_INPUT_TOUCH_DOWN) { + lastTouchX = mappedX; + lastTouchY = mappedY; + } else if (event.type == EMULATOR_INPUT_TOUCH_UP) { + int startX = lastTouchX; + int startY = lastTouchY; + int endX = mappedX; + int endY = mappedY; + std::string udid = currentDeviceId; + + int dx = abs(endX - startX); + int dy = abs(endY - startY); + + if (dx < 10 && dy < 10) { + // It's a tap + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSLog(@"MacOSEmulator: Sending idb tap to x=%d y=%d", endX, endY); + NSString* cmd = [NSString stringWithFormat:@"idb ui tap --udid %s %d %d", udid.c_str(), endX, endY]; + int result = system([cmd UTF8String]); + if (result != 0) { + NSLog(@"MacOSEmulator: idb tap command failed with code %d", result); + } + }); + } else { + // It's a swipe + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSLog(@"MacOSEmulator: Sending idb swipe from x=%d y=%d to x=%d y=%d", startX, startY, endX, endY); + NSString* cmd = [NSString stringWithFormat:@"idb ui swipe --udid %s --duration 0.2 %d %d %d %d", udid.c_str(), startX, startY, endX, endY]; + system([cmd UTF8String]); + }); + } + } else if (event.type == EMULATOR_INPUT_TOUCH_MOVE) { + // Empty tracking block; we batch swipe invocations to fire cleanly out of TOUCH_UP instead. + } else if (event.type == EMULATOR_INPUT_SCROLL) { + auto now = std::chrono::steady_clock::now(); + auto elapsed = std::chrono::duration_cast(now - lastMoveTime).count(); + + if (elapsed < 100) return; // scroll throttle + lastMoveTime = now; + + int deltaY = event.y; + + // Synthetic swipe originating from center of iOS simulator bounds + int centerX = emulatorView->capturedWidth > 0 ? (emulatorView->capturedWidth / 2) / 3 : 200; + int centerY = emulatorView->capturedHeight > 0 ? (emulatorView->capturedHeight / 2) / 3 : 400; + + int startX = centerX; + int startY = centerY; + int endX = startX; + int endY = startY - (deltaY * 20); // scroll direction translation + + std::string udid = currentDeviceId; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSString* cmd = [NSString stringWithFormat:@"idb ui swipe --udid %s --duration 0.1 %d %d %d %d", udid.c_str(), startX, startY, endX, endY]; + system([cmd UTF8String]); + }); + } + } + } + } + + void show() override { + runOnMainThread(^{ + if (childWindow) { + [childWindow orderFront:nil]; + } + }); } -}; -// Android implementation (stub for now, can share NSView logic on MacOS if we use same hosting strategy) -class AndroidEmulator : public Emulator { - // Android on macOS also ends up being a window we might need to embed via NSView (child window) - // or just a surface. For now, let's reuse MacOSEmulator-like logic or simpler stub. - // Actually, on macOS, Android Emulator runs as a separate process (qemu). - // Embedding it requires ` -qt-hide-window-decorations` and re-parenting the NSWindow using private APIs or - // simply making the emulator render to a shared texture that we draw in our view. - // The "Right" way per roadmap is "Native Surface Handle" -> passed to emulator. - // For now, I'll return a MacOSEmulator for both since we just want to prove embedding. + void hide() override { + runOnMainThread(^{ + if (childWindow) { + [childWindow orderOut:nil]; + } + }); + } + + void push_frame(const uint8_t* rgba_data, uint32_t width, uint32_t height) override { + if (destroyed) return; + + // Copy data — dispatch_async outlives the caller's buffer + size_t dataSize = (size_t)width * height * 4; + uint8_t* dataCopy = (uint8_t*)malloc(dataSize); + if (!dataCopy) return; + memcpy(dataCopy, rgba_data, dataSize); + + dispatch_async(dispatch_get_main_queue(), ^{ + if (!destroyed && emulatorView) { + [emulatorView pushFrameWithData:dataCopy width:width height:height]; + } + free(dataCopy); + }); + } }; -Emulator* Emulator::create(EmulatorPlatform /*_platform*/) { - // For now, return MacOS implementation for both as a test harness - // Real implementation would diverge based on backing (Metal vs Vulkan/GFXStream) - return new MacOSEmulator(); +Emulator* Emulator::create(EmulatorPlatform platform) { + return new MacOSEmulator(platform); } } // namespace umide diff --git a/crates/umide_native/src/emulator.rs b/crates/umide_native/src/emulator.rs index 3280b3f5..9d404881 100644 --- a/crates/umide_native/src/emulator.rs +++ b/crates/umide_native/src/emulator.rs @@ -6,6 +6,7 @@ pub struct NativeEmulator { } #[repr(C)] +#[derive(Copy, Clone)] pub enum EmulatorPlatform { Android = 0, Ios = 1, @@ -18,6 +19,7 @@ pub enum EmulatorInputType { TouchUp = 2, KeyDown = 3, KeyUp = 4, + Scroll = 5, } #[repr(C)] @@ -28,9 +30,13 @@ pub struct EmulatorInputEvent { pub key_code: i32, } +pub type EmulatorInputCallback = Option; + extern "C" { pub fn umide_native_create_emulator( parent_window: *mut c_void, + x: i32, + y: i32, width: u32, height: u32, platform: EmulatorPlatform @@ -38,9 +44,17 @@ extern "C" { pub fn umide_native_destroy_emulator(emulator: *mut NativeEmulator); - pub fn umide_native_resize_emulator(emulator: *mut NativeEmulator, width: u32, height: u32); + pub fn umide_native_resize_emulator(emulator: *mut NativeEmulator, x: i32, y: i32, width: u32, height: u32); pub fn umide_native_send_input(emulator: *mut NativeEmulator, event: *const EmulatorInputEvent); + pub fn umide_native_set_input_callback(emulator: *mut NativeEmulator, callback: EmulatorInputCallback, user_data: *mut c_void); + pub fn umide_native_attach_device(emulator: *mut NativeEmulator, device_id: *const i8); + + pub fn umide_native_push_frame(emulator: *mut NativeEmulator, rgba_data: *const u8, width: u32, height: u32); + + pub fn umide_native_show_emulator(emulator: *mut NativeEmulator); + + pub fn umide_native_hide_emulator(emulator: *mut NativeEmulator); } diff --git a/crates/umide_native/src/macos.rs b/crates/umide_native/src/macos.rs index 9b200c40..16c297dc 100644 --- a/crates/umide_native/src/macos.rs +++ b/crates/umide_native/src/macos.rs @@ -218,9 +218,23 @@ extern "C" fn screen_capture_trampoline(context: *mut c_void, surface: *mut ffi: unsafe { let data = &*(context as *const ScreenCaptureCallbackData); - // Create a temporary MacOSSurface wrapper - // Note: We don't own this surface, it's managed by the C++ side - let surface_ref = &*(surface as *const MacOSSurface); - (data.callback)(surface_ref); + // Construct a temporary MacOSSurface wrapper from the raw pointer + // We need to query width/height if we want them to be valid + // For now, we'll assume the callback uses the surface pointer mainly + // WARNING: This assumes the surface is valid for the duration of the callback + if let Some(ptr) = NonNull::new(surface) { + // Use dummy values or fetch from FFI if needed. + // For safety, we should ideally fetch valid dimensions or change the callback signature. + // But to fix the immediate segfault risk of invalid casting: + + // Note: We used ManuallyDrop to ensure we don't destroy the C++ managed surface + let surface_wrapper = std::mem::ManuallyDrop::new(MacOSSurface { + ptr, + width: 0, // Placeholder + height: 0 // Placeholder + }); + + (data.callback)(&surface_wrapper); + } } } diff --git a/defaults/dark-theme.toml b/defaults/dark-theme.toml index 8d3c6ce0..83c6992d 100644 --- a/defaults/dark-theme.toml +++ b/defaults/dark-theme.toml @@ -1,7 +1,7 @@ #:schema ../extra/schemas/color-theme.json [color-theme] -name = "Lapce Dark" +name = "Umide Dark" [ui] font-family = "" diff --git a/defaults/icon-theme.toml b/defaults/icon-theme.toml index a68c7e66..6a284125 100644 --- a/defaults/icon-theme.toml +++ b/defaults/icon-theme.toml @@ -1,7 +1,7 @@ #:schema ../extra/schemas/icon-theme.json [icon-theme] -name = "Lapce Codicons" +name = "Umide Codicons" [icon-theme.ui] "logo" = "lapce_logo.svg" diff --git a/defaults/light-theme.toml b/defaults/light-theme.toml index 570e6f75..206e802c 100644 --- a/defaults/light-theme.toml +++ b/defaults/light-theme.toml @@ -1,7 +1,7 @@ #:schema ../extra/schemas/color-theme.json [color-theme] -name = "Lapce Light" +name = "Umide Light" [ui] font-family = "" diff --git a/defaults/settings.toml b/defaults/settings.toml index 4b73f81b..9253fae1 100644 --- a/defaults/settings.toml +++ b/defaults/settings.toml @@ -2,8 +2,8 @@ [core] modal = false -color-theme = "Lapce Dark" -icon-theme = "Lapce Codicons" +color-theme = "Umide Dark" +icon-theme = "Umide Codicons" custom-titlebar = true file-explorer-double-click = false auto-reload-plugin = false diff --git a/docs/architecture.md b/docs/architecture.md index 8c8a0f3c..b683786a 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,6 +1,6 @@ # UMIDE Architecture Overview -This document describes the high-level architecture of UMIDE (based on Lapce and Floem) and outlines the plan for integrating mobile emulator features. +This document describes the high-level architecture of UMIDE (based on Umide and Floem) and outlines the plan for integrating mobile emulator features. ## Core Architecture diff --git a/docs/building-from-source.md b/docs/building-from-source.md index 970176e0..dfdf6adf 100644 --- a/docs/building-from-source.md +++ b/docs/building-from-source.md @@ -1,30 +1,37 @@ ## Building from source -It is easy to build Lapce from source on a GNU/Linux distribution. Cargo handles the build process, all you need to do, is ensure the correct dependencies are installed. +It is easy to build Umide from source on a GNU/Linux distribution. Cargo handles the build process, all you need to do, is ensure the correct dependencies are installed. 1. Install the Rust compiler and Cargo using [`rustup.rs`](https://rustup.rs/). If you already have the toolchain, ensure you are using latest Rust version. 2. Install dependencies for your operating system: #### Ubuntu + ```sh sudo apt install clang libxkbcommon-x11-dev pkg-config libvulkan-dev libwayland-dev xorg-dev libxcb-shape0-dev libxcb-xfixes0-dev ``` + #### Fedora + ```sh sudo dnf install clang libxkbcommon-x11-devel libxcb-devel vulkan-loader-devel wayland-devel openssl-devel pkgconf ``` + #### Void Linux + ```sh sudo xbps-install -S base-devel clang libxkbcommon-devel vulkan-loader wayland-devel ``` 3. Clone this repository (this command will clone to your home directory): + ```sh git clone https://github.com/lapce/lapce.git ~/lapce ``` 4. `cd` into the repository, and run the build command with the release flag + ```sh cd ~/lapce ``` @@ -35,14 +42,14 @@ cargo install --path . --bin lapce --profile release-lto --locked > If you use a different distribution, and are having trouble finding appropriate dependencies, let us know in an issue! -Once Lapce is compiled, the executable will be available in `$HOME/.cargo/bin/lapce` and should be available in `PATH` automatically. +Once Umide is compiled, the executable will be available in `$HOME/.cargo/bin/lapce` and should be available in `PATH` automatically. ## Building using Docker or Podman Packages available in releases are built using containers based on multi-stage Dockerfiles. To easily orchestrate builds, there is a `docker-bake.hcl` manifest in root of repository that defines all stages and targets. If you want to build all packages for ubuntu, you can run `RELEASE_TAG_NAME=nightly docker buildx bake ubuntu` (`RELEASE_TAG_NAME` is a required environment variable used to tell what kind of release is being built as well as baking in the version itself). To scope in to specific distribution version, you can define target with it's version counterpart from matrix, e.g. to build only Ubuntu Focal package, you can run `RELEASE_TAG_NAME=nightly docker buildx bake ubuntu-focal`. -Additionally to building multiple OS versions at the same time, Docker-based builds will also try to cross-compile Lapce for other architectures. +Additionally to building multiple OS versions at the same time, Docker-based builds will also try to cross-compile Umide for other architectures. This does not require QEMU installed as it's done via true cross-compilation meaning `HOST` will run your native OS/CPU architecture and `TARGET` will be the wanted architecture, instead of spawning container that's running OS using `TARGET` architecture. > ![WARNING] diff --git a/docs/installing-with-package-manager.md b/docs/installing-with-package-manager.md index 4acd76b5..9974c7d2 100644 --- a/docs/installing-with-package-manager.md +++ b/docs/installing-with-package-manager.md @@ -1,20 +1,19 @@ ## Installation With Package Manager -Lapce is available in below software repositories: +Umide is available in below software repositories: [![Packaging status](https://repology.org/badge/vertical-allrepos/lapce.svg)](https://repology.org/project/lapce/versions) -Lapce is also additionally available via: +Umide is also additionally available via: - [Flatpak](https://flathub.org/apps/details/dev.lapce.lapce) - [Scoop](https://scoop.sh/#/apps?q=lapce) - -For Fedora Linux, Lapce is (unofficially) available via dnf RPM package manager, using nightly as of 2024.01: +For Fedora Linux, Umide is (unofficially) available via dnf RPM package manager, using nightly as of 2024.01: - [copr](https://copr.fedorainfracloud.org/coprs/titaniumtown/lapce/) ```bash -sudo dnf copr enable titaniumtown/lapce +sudo dnf copr enable titaniumtown/lapce sudo dnf install lapce ``` diff --git a/docs/new-release.md b/docs/new-release.md index dcd66a33..6bd63949 100644 --- a/docs/new-release.md +++ b/docs/new-release.md @@ -1,7 +1,7 @@ # Updating versioning for package managers and whatnot - App metainfo: `extra/linux/dev.lapce.lapce.metainfo.xml` -- macOS plist (`CFBundleShortVersionString`): `extra/macos/Lapce.app/Contents/Info.plist` +- macOS plist (`CFBundleShortVersionString`): `extra/macos/Umide.app/Contents/Info.plist` - Rust: `Cargo.toml` - Obviously changelog: `CHANGELOG.md` - RPM spec: `lapce.spec` diff --git a/extra/linux/dev.lapce.lapce.metainfo.xml b/extra/linux/dev.lapce.lapce.metainfo.xml index c0e9fb02..e110d9a3 100644 --- a/extra/linux/dev.lapce.lapce.metainfo.xml +++ b/extra/linux/dev.lapce.lapce.metainfo.xml @@ -1,7 +1,7 @@ dev.lapce.lapce - Lapce + Umide Dongdong Zhou, et al. Lightning-fast and powerful code editor written in Rust MIT @@ -15,7 +15,7 @@

- Lapce is an open source code editor written in Rust. By utilising native GUI and GPU rendering, and with the performance Rust provides, Lapce is one of the fastest code editors out there. + Umide is an open source code editor written in Rust. By utilising native GUI and GPU rendering, and with the performance Rust provides, Umide is one of the fastest code editors out there.

Features:

    @@ -23,14 +23,14 @@
  • Built-in LSP (Language Server Protocol) support to give you code intelligence like code completion, diagnostics and code actions etc.
  • Built-in remote development support (inspired by VSCode Remote Development) for a seamless "local" experience, benefiting from the full power of the remote system.
  • Plugins can be written in programming languages that can compile to the WASI format (C, Rust, AssemblyScript)
  • -
  • Built-in terminal, so you can execute commands in your workspace, without leaving Lapce.
  • +
  • Built-in terminal, so you can execute commands in your workspace, without leaving Umide.
dev.lapce.lapce.desktop - Lapce source project opened in Lapce with Rust source code file opened + Umide source project opened in Umide with Rust source code file opened https://raw.githubusercontent.com/lapce/lapce/refs/tags/v0.4.5/extra/images/linux/code-file-with-highlight.png diff --git a/extra/linux/docker/fedora/Dockerfile b/extra/linux/docker/fedora/Dockerfile index 03dd4260..424ce5ce 100644 --- a/extra/linux/docker/fedora/Dockerfile +++ b/extra/linux/docker/fedora/Dockerfile @@ -130,7 +130,7 @@ URL: https://github.com/lapce/lapce Packager: Jakub Panek %description -Lapce is written in pure Rust with a UI in Floem (which is also written in Rust). +Umide is written in pure Rust with a UI in Floem (which is also written in Rust). It is designed with Rope Science from the Xi-Editor which makes for lightning-fast computation, and leverages OpenGL for rendering. %build diff --git a/extra/proxy.ps1 b/extra/proxy.ps1 index 42bc12ef..ef363b26 100644 --- a/extra/proxy.ps1 +++ b/extra/proxy.ps1 @@ -6,8 +6,8 @@ param( $proxy = (Join-Path $directory 'lapce.exe') -$LapceProcesses = (Get-Process -Name 'lapce' -EA SilentlyContinue).Count -if ($LapceProcesses -ne 0) { +$UmideProcesses = (Get-Process -Name 'lapce' -EA SilentlyContinue).Count +if ($UmideProcesses -ne 0) { Write-Host 'Proxy currently in use. Aborting installation' exit } diff --git a/extra/windows/wix/lapce.wxs b/extra/windows/wix/lapce.wxs index 509bad7b..545c3397 100644 --- a/extra/windows/wix/lapce.wxs +++ b/extra/windows/wix/lapce.wxs @@ -10,8 +10,8 @@ - - + + @@ -19,33 +19,33 @@ - + - + - - - + + + - + - - - + + + - + - + @@ -53,10 +53,10 @@ - + - + diff --git a/lapce.spec b/lapce.spec index 9ec2dedc..b2865fba 100644 --- a/lapce.spec +++ b/lapce.spec @@ -11,7 +11,7 @@ Source: {{{ git_dir_pack }}} BuildRequires: cargo libxkbcommon-x11-devel libxcb-devel vulkan-loader-devel wayland-devel openssl-devel pkgconf libxkbcommon-x11-devel %description -Lapce is written in pure Rust, with a UI in Floem (also written in Rust). +Umide is written in pure Rust, with a UI in Floem (also written in Rust). It is designed with Rope Science from the Xi-Editor, enabling lightning-fast computation, and leverages wgpu for rendering. %prep diff --git a/test_bezel.scpt b/test_bezel.scpt new file mode 100644 index 00000000..0ee68512 --- /dev/null +++ b/test_bezel.scpt @@ -0,0 +1,13 @@ +tell application "System Events" + tell process "Simulator" + if exists menu item "Show Device Bezels" of menu "Window" of menu bar 1 then + set bezelItem to menu item "Show Device Bezels" of menu "Window" of menu bar 1 + if value of attribute "AXMenuItemMarkChar" of bezelItem is not missing value then + click bezelItem + return "Bezels disabled" + else + return "Bezels already disabled" + end if + end if + end tell +end tell diff --git a/test_sc b/test_sc new file mode 100755 index 00000000..cb9dba96 Binary files /dev/null and b/test_sc differ diff --git a/test_sc.m b/test_sc.m new file mode 100644 index 00000000..eed7b85b --- /dev/null +++ b/test_sc.m @@ -0,0 +1,7 @@ +#import +#import + +int main() { + SCStreamConfiguration *cfg = [[SCStreamConfiguration alloc] init]; + return 0; +} diff --git a/umide-core/build.rs b/umide-core/build.rs index d4a7d155..fda6f842 100644 --- a/umide-core/build.rs +++ b/umide-core/build.rs @@ -26,7 +26,7 @@ fn main() -> Result<()> { #[rustfmt::skip] let meta = format!(r#" - pub const NAME: &str = "Lapce-{branch}"; + pub const NAME: &str = "Umide-{branch}"; pub const VERSION: &str = "{version}"; pub const RELEASE: ReleaseType = ReleaseType::{branch}; "#); diff --git a/umide-core/src/directory.rs b/umide-core/src/directory.rs index 42849773..e5bc274d 100644 --- a/umide-core/src/directory.rs +++ b/umide-core/src/directory.rs @@ -13,7 +13,7 @@ impl Directory { #[cfg(not(feature = "portable"))] fn project_dirs() -> Option { - ProjectDirs::from("dev", "lapce", NAME) + ProjectDirs::from("dev", "umide", NAME) } /// Return path adjacent to lapce executable when built as portable @@ -21,7 +21,7 @@ impl Directory { fn project_dirs() -> Option { if let Ok(current_exe) = std::env::current_exe() { if let Some(parent) = current_exe.parent() { - return ProjectDirs::from_path(parent.join("lapce-data")); + return ProjectDirs::from_path(parent.join("umide-data")); } unreachable!("Couldn't obtain current process parent path"); } diff --git a/umide-core/src/language.rs b/umide-core/src/language.rs index b7056cd4..21bdc999 100644 --- a/umide-core/src/language.rs +++ b/umide-core/src/language.rs @@ -98,7 +98,7 @@ macro_rules! comment_properties { pub struct SyntaxProperties { /// An extra check to make sure that the array elements are in the correct order. /// If this id does not match the enum value, a panic will happen with a debug assertion message. - id: LapceLanguage, + id: UmideLanguage, /// All tokens that can be used for comments in language comment: CommentProperties, @@ -168,7 +168,7 @@ struct CommentProperties { } /// NOTE: Keep the enum variants "fieldless" so they can cast to usize as array -/// indices into the LANGUAGES array. See method `LapceLanguage::properties`. +/// indices into the LANGUAGES array. See method `UmideLanguage::properties`. /// /// Do not assign values to the variants because the number of variants and /// number of elements in the LANGUAGES array change as different features @@ -191,7 +191,7 @@ struct CommentProperties { )] #[strum(ascii_case_insensitive)] #[remain::sorted] -pub enum LapceLanguage { +pub enum UmideLanguage { // Do not move #[remain::unsorted] #[default] @@ -449,11 +449,11 @@ pub enum LapceLanguage { } /// NOTE: Elements in the array must be in the same order as the enum variants of -/// `LapceLanguage` as they will be accessed using the enum variants as indices. +/// `UmideLanguage` as they will be accessed using the enum variants as indices. const LANGUAGES: &[SyntaxProperties] = &[ // Undetected/unmatched fallback or just plain file SyntaxProperties { - id: LapceLanguage::PlainText, + id: UmideLanguage::PlainText, indent: Indent::tab(), files: &[], extensions: &["txt"], @@ -462,7 +462,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ }, // Languages SyntaxProperties { - id: LapceLanguage::Ada, + id: UmideLanguage::Ada, indent: Indent::tab(), files: &[], extensions: &[], @@ -470,7 +470,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Adl, + id: UmideLanguage::Adl, indent: Indent::tab(), files: &[], extensions: &[], @@ -478,7 +478,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Agda, + id: UmideLanguage::Agda, indent: Indent::tab(), files: &[], extensions: &[], @@ -486,7 +486,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Astro, + id: UmideLanguage::Astro, indent: Indent::tab(), files: &[], extensions: &[], @@ -494,7 +494,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Bash, + id: UmideLanguage::Bash, indent: Indent::space(2), files: &[], extensions: &["bash", "sh"], @@ -502,7 +502,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Bass, + id: UmideLanguage::Bass, indent: Indent::tab(), files: &[], extensions: &[], @@ -510,7 +510,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Beancount, + id: UmideLanguage::Beancount, indent: Indent::tab(), files: &[], extensions: &[], @@ -518,7 +518,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Bibtex, + id: UmideLanguage::Bibtex, indent: Indent::tab(), files: &[], extensions: &[], @@ -526,7 +526,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Bitbake, + id: UmideLanguage::Bitbake, indent: Indent::tab(), files: &[], extensions: &[], @@ -534,7 +534,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Blade, + id: UmideLanguage::Blade, indent: Indent::tab(), files: &[], extensions: &[], @@ -542,7 +542,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::C, + id: UmideLanguage::C, indent: Indent::space(4), files: &[], extensions: &["c", "h"], @@ -556,7 +556,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ }, }, SyntaxProperties { - id: LapceLanguage::Clojure, + id: UmideLanguage::Clojure, indent: Indent::space(2), files: &[], extensions: &[ @@ -573,7 +573,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Cmake, + id: UmideLanguage::Cmake, indent: Indent::space(2), files: &["cmakelists"], extensions: &["cmake"], @@ -587,7 +587,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ }, }, SyntaxProperties { - id: LapceLanguage::Comment, + id: UmideLanguage::Comment, indent: Indent::tab(), files: &[], extensions: &[], @@ -595,7 +595,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Cpp, + id: UmideLanguage::Cpp, indent: Indent::space(4), files: &[], extensions: &["cpp", "cxx", "cc", "c++", "hpp", "hxx", "hh", "h++"], @@ -613,7 +613,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ }, }, SyntaxProperties { - id: LapceLanguage::Csharp, + id: UmideLanguage::Csharp, indent: Indent::space(2), files: &[], extensions: &["cs", "csx"], @@ -638,7 +638,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ }, }, SyntaxProperties { - id: LapceLanguage::Css, + id: UmideLanguage::Css, indent: Indent::space(2), files: &[], extensions: &["css"], @@ -646,7 +646,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Cue, + id: UmideLanguage::Cue, indent: Indent::tab(), files: &[], extensions: &[], @@ -654,7 +654,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::D, + id: UmideLanguage::D, indent: Indent::space(4), files: &[], extensions: &["d", "di", "dlang"], @@ -668,7 +668,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Dart, + id: UmideLanguage::Dart, indent: Indent::space(2), files: &[], extensions: &["dart"], @@ -697,7 +697,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ }, }, SyntaxProperties { - id: LapceLanguage::Dhall, + id: UmideLanguage::Dhall, indent: Indent::tab(), files: &[], extensions: &[], @@ -705,7 +705,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Diff, + id: UmideLanguage::Diff, indent: Indent::tab(), files: &[], extensions: &["diff", "patch"], @@ -713,7 +713,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Dockerfile, + id: UmideLanguage::Dockerfile, indent: Indent::space(2), files: &["Dockerfile", "Containerfile"], extensions: &["containerfile", "dockerfile"], @@ -721,7 +721,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Dot, + id: UmideLanguage::Dot, indent: Indent::tab(), files: &[], extensions: &[], @@ -729,7 +729,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Elixir, + id: UmideLanguage::Elixir, indent: Indent::space(2), files: &[], extensions: &["ex", "exs", "eex", "heex", "sface"], @@ -743,7 +743,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ }, }, SyntaxProperties { - id: LapceLanguage::Elm, + id: UmideLanguage::Elm, indent: Indent::space(4), files: &[], extensions: &["elm"], @@ -751,7 +751,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Erlang, + id: UmideLanguage::Erlang, indent: Indent::space(4), files: &[], extensions: &["erl", "hrl"], @@ -759,7 +759,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::FSharp, + id: UmideLanguage::FSharp, indent: Indent::tab(), files: &[], extensions: &[], @@ -767,7 +767,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Fish, + id: UmideLanguage::Fish, indent: Indent::tab(), files: &[], extensions: &["fish"], @@ -775,7 +775,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Fluent, + id: UmideLanguage::Fluent, indent: Indent::tab(), files: &[], extensions: &[], @@ -783,7 +783,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Forth, + id: UmideLanguage::Forth, indent: Indent::tab(), files: &[], extensions: &[], @@ -791,7 +791,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Fortran, + id: UmideLanguage::Fortran, indent: Indent::tab(), files: &[], extensions: &[], @@ -799,7 +799,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Gitattributes, + id: UmideLanguage::Gitattributes, indent: Indent::tab(), files: &[], extensions: &[], @@ -807,7 +807,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::GitCommit, + id: UmideLanguage::GitCommit, indent: Indent::tab(), files: &[], extensions: &[], @@ -815,7 +815,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::GitConfig, + id: UmideLanguage::GitConfig, indent: Indent::tab(), files: &[".gitconfig", ".git/config"], extensions: &[], @@ -823,7 +823,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::GitRebase, + id: UmideLanguage::GitRebase, indent: Indent::tab(), files: &[], extensions: &[], @@ -831,7 +831,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Gleam, + id: UmideLanguage::Gleam, indent: Indent::tab(), files: &[], extensions: &[], @@ -839,7 +839,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Glimmer, + id: UmideLanguage::Glimmer, indent: Indent::space(2), files: &[], extensions: &["hbs"], @@ -847,7 +847,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Glsl, + id: UmideLanguage::Glsl, indent: Indent::space(2), files: &[], extensions: &[ @@ -860,7 +860,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Gn, + id: UmideLanguage::Gn, indent: Indent::tab(), files: &[], extensions: &[], @@ -868,7 +868,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Go, + id: UmideLanguage::Go, indent: Indent::tab(), files: &[], extensions: &["go"], @@ -891,7 +891,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ }, }, SyntaxProperties { - id: LapceLanguage::GoMod, + id: UmideLanguage::GoMod, indent: Indent::tab(), files: &[], extensions: &[], @@ -899,7 +899,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::GoTemplate, + id: UmideLanguage::GoTemplate, indent: Indent::tab(), files: &[], extensions: &[], @@ -907,7 +907,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::GoWork, + id: UmideLanguage::GoWork, indent: Indent::tab(), files: &[], extensions: &[], @@ -915,7 +915,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::GraphQl, + id: UmideLanguage::GraphQl, indent: Indent::tab(), files: &[], extensions: &[], @@ -923,7 +923,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Groovy, + id: UmideLanguage::Groovy, indent: Indent::tab(), files: &[], extensions: &[], @@ -931,7 +931,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Hare, + id: UmideLanguage::Hare, indent: Indent::space(8), files: &[], extensions: &["ha"], @@ -939,7 +939,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Haskell, + id: UmideLanguage::Haskell, indent: Indent::space(2), files: &[], extensions: &["hs"], @@ -947,7 +947,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Haxe, + id: UmideLanguage::Haxe, indent: Indent::space(2), files: &[], extensions: &["hx"], @@ -955,7 +955,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Hcl, + id: UmideLanguage::Hcl, indent: Indent::space(2), files: &[], extensions: &["hcl", "tf"], @@ -963,7 +963,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Hosts, + id: UmideLanguage::Hosts, indent: Indent::tab(), files: &[], extensions: &[], @@ -971,7 +971,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Html, + id: UmideLanguage::Html, indent: Indent::space(4), files: &[], extensions: &["html", "htm"], @@ -979,7 +979,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Ini, + id: UmideLanguage::Ini, indent: Indent::tab(), files: &[], extensions: &[], @@ -987,7 +987,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Java, + id: UmideLanguage::Java, indent: Indent::space(4), files: &[], extensions: &["java"], @@ -995,7 +995,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Javascript, + id: UmideLanguage::Javascript, indent: Indent::space(2), files: &[], extensions: &["js", "cjs", "mjs"], @@ -1009,7 +1009,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ }, }, SyntaxProperties { - id: LapceLanguage::Jsdoc, + id: UmideLanguage::Jsdoc, indent: Indent::tab(), files: &[], extensions: &[], @@ -1017,7 +1017,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Json, + id: UmideLanguage::Json, indent: Indent::space(4), files: &[], extensions: &["json", "har"], @@ -1025,7 +1025,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Json5, + id: UmideLanguage::Json5, indent: Indent::tab(), files: &[], extensions: &[], @@ -1033,7 +1033,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Jsonnet, + id: UmideLanguage::Jsonnet, indent: Indent::tab(), files: &[], extensions: &[], @@ -1041,7 +1041,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Jsx, + id: UmideLanguage::Jsx, indent: Indent::space(2), files: &[], extensions: &["jsx"], @@ -1055,7 +1055,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ }, }, SyntaxProperties { - id: LapceLanguage::Julia, + id: UmideLanguage::Julia, indent: Indent::space(4), files: &[], extensions: &["julia", "jl"], @@ -1069,7 +1069,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Just, + id: UmideLanguage::Just, indent: Indent::tab(), files: &["justfile", "Justfile", ".justfile", ".Justfile"], extensions: &["just"], @@ -1077,7 +1077,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Kdl, + id: UmideLanguage::Kdl, indent: Indent::tab(), files: &[], extensions: &[], @@ -1085,7 +1085,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Kotlin, + id: UmideLanguage::Kotlin, indent: Indent::space(2), files: &[], extensions: &["kt"], @@ -1100,7 +1100,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::KotlinBuildScript, + id: UmideLanguage::KotlinBuildScript, indent: Indent::space(2), files: &[], extensions: &["kts"], @@ -1115,7 +1115,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Latex, + id: UmideLanguage::Latex, indent: Indent::space(2), files: &[], extensions: &["tex"], @@ -1123,7 +1123,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Ld, + id: UmideLanguage::Ld, indent: Indent::tab(), files: &[], extensions: &[], @@ -1131,7 +1131,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Llvm, + id: UmideLanguage::Llvm, indent: Indent::tab(), files: &[], extensions: &[], @@ -1139,7 +1139,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::LlvmMir, + id: UmideLanguage::LlvmMir, indent: Indent::tab(), files: &[], extensions: &[], @@ -1147,7 +1147,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Log, + id: UmideLanguage::Log, indent: Indent::tab(), files: &["log.txt"], extensions: &["log"], @@ -1155,7 +1155,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Lua, + id: UmideLanguage::Lua, indent: Indent::space(2), files: &[], extensions: &["lua"], @@ -1163,7 +1163,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Make, + id: UmideLanguage::Make, indent: Indent::tab(), files: &[], extensions: &[], @@ -1171,7 +1171,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Markdown, + id: UmideLanguage::Markdown, indent: Indent::space(4), files: &[], extensions: &["md"], @@ -1179,7 +1179,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::MarkdownInline, + id: UmideLanguage::MarkdownInline, indent: Indent::space(4), // markdown inline is only used as an injection by the Markdown language files: &[], @@ -1194,7 +1194,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ }, }, SyntaxProperties { - id: LapceLanguage::Meson, + id: UmideLanguage::Meson, indent: Indent::tab(), files: &[], extensions: &[], @@ -1202,7 +1202,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Nasm, + id: UmideLanguage::Nasm, indent: Indent::tab(), files: &[], extensions: &[], @@ -1210,7 +1210,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Nix, + id: UmideLanguage::Nix, indent: Indent::space(2), files: &[], extensions: &["nix"], @@ -1225,7 +1225,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Nushell, + id: UmideLanguage::Nushell, indent: Indent::tab(), files: &[], extensions: &[], @@ -1233,7 +1233,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Ocaml, + id: UmideLanguage::Ocaml, indent: Indent::space(2), files: &[], extensions: &["ml"], @@ -1248,7 +1248,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::OcamlInterface, + id: UmideLanguage::OcamlInterface, indent: Indent::space(2), files: &[], extensions: &["mli"], @@ -1256,7 +1256,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Odin, + id: UmideLanguage::Odin, indent: Indent::tab(), files: &[], extensions: &[], @@ -1264,7 +1264,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::OpenCl, + id: UmideLanguage::OpenCl, indent: Indent::tab(), files: &[], extensions: &[], @@ -1272,7 +1272,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Pascal, + id: UmideLanguage::Pascal, indent: Indent::tab(), files: &[], extensions: &[], @@ -1280,7 +1280,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Passwd, + id: UmideLanguage::Passwd, indent: Indent::tab(), files: &[], extensions: &[], @@ -1288,7 +1288,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Pem, + id: UmideLanguage::Pem, indent: Indent::tab(), files: &[], extensions: &[], @@ -1296,7 +1296,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Php, + id: UmideLanguage::Php, indent: Indent::space(2), files: &[], extensions: &["php"], @@ -1331,7 +1331,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ }, }, SyntaxProperties { - id: LapceLanguage::Pkl, + id: UmideLanguage::Pkl, indent: Indent::tab(), files: &[], extensions: &[], @@ -1339,7 +1339,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::PowerShell, + id: UmideLanguage::PowerShell, indent: Indent::space(4), files: &[], extensions: &["ps1", "psm1", "psd1", "ps1xml"], @@ -1353,7 +1353,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Prisma, + id: UmideLanguage::Prisma, indent: Indent::space(4), files: &[], extensions: &["prisma"], @@ -1361,7 +1361,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::ProtoBuf, + id: UmideLanguage::ProtoBuf, indent: Indent::space(2), files: &[], extensions: &["proto"], @@ -1369,7 +1369,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Python, + id: UmideLanguage::Python, indent: Indent::space(4), files: &[], extensions: &["py", "pyi", "pyc", "pyd", "pyw"], @@ -1394,7 +1394,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ }, }, SyntaxProperties { - id: LapceLanguage::Ql, + id: UmideLanguage::Ql, indent: Indent::space(2), files: &[], extensions: &["ql"], @@ -1402,7 +1402,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::R, + id: UmideLanguage::R, indent: Indent::space(2), files: &[], extensions: &["r"], @@ -1410,7 +1410,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Rcl, + id: UmideLanguage::Rcl, indent: Indent::tab(), files: &[], extensions: &[], @@ -1418,7 +1418,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Regex, + id: UmideLanguage::Regex, indent: Indent::tab(), files: &[], extensions: &[], @@ -1426,7 +1426,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Rego, + id: UmideLanguage::Rego, indent: Indent::tab(), files: &[], extensions: &[], @@ -1434,7 +1434,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Ron, + id: UmideLanguage::Ron, indent: Indent::tab(), files: &[], extensions: &[], @@ -1442,7 +1442,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Rst, + id: UmideLanguage::Rst, indent: Indent::tab(), files: &[], extensions: &[], @@ -1450,7 +1450,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Ruby, + id: UmideLanguage::Ruby, indent: Indent::space(2), files: &[], extensions: &["rb"], @@ -1464,7 +1464,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ }, }, SyntaxProperties { - id: LapceLanguage::Rust, + id: UmideLanguage::Rust, indent: Indent::space(4), files: &[], extensions: &["rs"], @@ -1486,7 +1486,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ }, }, SyntaxProperties { - id: LapceLanguage::Scala, + id: UmideLanguage::Scala, indent: Indent::tab(), files: &[], extensions: &[], @@ -1494,7 +1494,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Scheme, + id: UmideLanguage::Scheme, indent: Indent::space(2), files: &[], extensions: &["scm", "ss"], @@ -1502,7 +1502,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Scss, + id: UmideLanguage::Scss, indent: Indent::space(2), files: &[], extensions: &["scss"], @@ -1510,7 +1510,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::ShellScript, + id: UmideLanguage::ShellScript, indent: Indent::space(2), files: &[], extensions: &["sh"], @@ -1518,7 +1518,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Smithy, + id: UmideLanguage::Smithy, indent: Indent::tab(), files: &[], extensions: &[], @@ -1526,7 +1526,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Sql, + id: UmideLanguage::Sql, indent: Indent::space(2), files: &[], extensions: &["sql"], @@ -1534,7 +1534,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::SshClientConfig, + id: UmideLanguage::SshClientConfig, indent: Indent::tab(), files: &[], extensions: &[], @@ -1542,7 +1542,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Strace, + id: UmideLanguage::Strace, indent: Indent::tab(), files: &[], extensions: &[], @@ -1550,7 +1550,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Svelte, + id: UmideLanguage::Svelte, indent: Indent::space(2), files: &[], extensions: &["svelte"], @@ -1558,7 +1558,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Sway, + id: UmideLanguage::Sway, indent: Indent::tab(), files: &[], extensions: &[], @@ -1566,7 +1566,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Swift, + id: UmideLanguage::Swift, indent: Indent::space(2), files: &[], extensions: &["swift"], @@ -1574,7 +1574,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Tcl, + id: UmideLanguage::Tcl, indent: Indent::tab(), files: &[], extensions: &["tcl"], @@ -1582,7 +1582,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Toml, + id: UmideLanguage::Toml, indent: Indent::space(2), files: &["Cargo.lock"], extensions: &["toml"], @@ -1590,7 +1590,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Tsx, + id: UmideLanguage::Tsx, indent: Indent::space(4), files: &[], extensions: &["tsx"], @@ -1604,7 +1604,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ }, }, SyntaxProperties { - id: LapceLanguage::Typescript, + id: UmideLanguage::Typescript, indent: Indent::space(4), files: &[], extensions: &["ts", "cts", "mts"], @@ -1618,7 +1618,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ }, }, SyntaxProperties { - id: LapceLanguage::Typst, + id: UmideLanguage::Typst, indent: Indent::tab(), files: &[], extensions: &[], @@ -1626,7 +1626,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Verilog, + id: UmideLanguage::Verilog, indent: Indent::tab(), files: &[], extensions: &[], @@ -1634,7 +1634,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Vue, + id: UmideLanguage::Vue, indent: Indent::space(2), files: &[], extensions: &["vue"], @@ -1642,7 +1642,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Wasm, + id: UmideLanguage::Wasm, indent: Indent::space(4), files: &[], extensions: &["wasm"], @@ -1650,7 +1650,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Wgsl, + id: UmideLanguage::Wgsl, indent: Indent::space(4), files: &[], extensions: &["wgsl"], @@ -1658,7 +1658,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Wit, + id: UmideLanguage::Wit, indent: Indent::space(4), files: &[], extensions: &["wit"], @@ -1666,7 +1666,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Xml, + id: UmideLanguage::Xml, indent: Indent::space(4), files: &[], extensions: &["xml", "csproj"], @@ -1674,7 +1674,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Yaml, + id: UmideLanguage::Yaml, indent: Indent::space(2), files: &[], extensions: &["yml", "yaml"], @@ -1682,7 +1682,7 @@ const LANGUAGES: &[SyntaxProperties] = &[ tree_sitter: TreeSitterProperties::DEFAULT, }, SyntaxProperties { - id: LapceLanguage::Zig, + id: UmideLanguage::Zig, indent: Indent::space(4), files: &[], extensions: &["zig"], @@ -1691,15 +1691,15 @@ const LANGUAGES: &[SyntaxProperties] = &[ }, ]; -impl LapceLanguage { +impl UmideLanguage { const HIGHLIGHTS_INJECTIONS_FILE_NAME: &'static str = "injections.scm"; const HIGHLIGHTS_QUERIES_FILE_NAME: &'static str = "highlights.scm"; - pub fn from_path(path: &Path) -> LapceLanguage { - Self::from_path_raw(path).unwrap_or(LapceLanguage::PlainText) + pub fn from_path(path: &Path) -> UmideLanguage { + Self::from_path_raw(path).unwrap_or(UmideLanguage::PlainText) } - pub fn from_path_raw(path: &Path) -> Option { + pub fn from_path_raw(path: &Path) -> Option { let filename = path.file_name().and_then(|s| s.to_str()); let extension = path .extension() @@ -1722,11 +1722,11 @@ impl LapceLanguage { None } - pub fn from_name(name: &str) -> Option { - match LapceLanguage::from_str(name.to_lowercase().as_str()) { + pub fn from_name(name: &str) -> Option { + match UmideLanguage::from_str(name.to_lowercase().as_str()) { Ok(v) => Some(v), Err(e) => { - event!(Level::DEBUG, "failed parsing `{name}` LapceLanguage: {e}"); + event!(Level::DEBUG, "failed parsing `{name}` UmideLanguage: {e}"); None } } @@ -1788,7 +1788,7 @@ impl LapceLanguage { return Some(grammar); } Err(err) => { - if self != &LapceLanguage::PlainText { + if self != &UmideLanguage::PlainText { tracing::error!("{:?} {:?}", self, err); } } @@ -2064,11 +2064,11 @@ fn read_grammar_query(queries_dir: &Path, name: &str, kind: &str) -> String { mod tests { use std::path::PathBuf; - use super::LapceLanguage; + use super::UmideLanguage; #[test] fn test_lanaguage_from_path() { - let l = LapceLanguage::from_path(&PathBuf::new().join("test.rs")); - assert_eq!(l, LapceLanguage::Rust); + let l = UmideLanguage::from_path(&PathBuf::new().join("test.rs")); + assert_eq!(l, UmideLanguage::Rust); } } diff --git a/umide-core/src/syntax/highlight.rs b/umide-core/src/syntax/highlight.rs index 4b5fa7c7..fe91b6ce 100644 --- a/umide-core/src/syntax/highlight.rs +++ b/umide-core/src/syntax/highlight.rs @@ -26,10 +26,10 @@ use tree_sitter::{ }; use super::{PARSER, util::RopeProvider}; -use crate::{language::LapceLanguage, style::SCOPES}; +use crate::{language::UmideLanguage, style::SCOPES}; thread_local! { - static HIGHLIGHT_CONFIGS: RefCell, HighlightIssue>>> = Default::default(); + static HIGHLIGHT_CONFIGS: RefCell, HighlightIssue>>> = Default::default(); } pub fn reset_highlight_configs() { @@ -39,7 +39,7 @@ pub fn reset_highlight_configs() { } pub(crate) fn get_highlight_config( - lang: LapceLanguage, + lang: UmideLanguage, ) -> Result, HighlightIssue> { HIGHLIGHT_CONFIGS.with(|configs| { let mut configs = configs.borrow_mut(); diff --git a/umide-core/src/syntax/mod.rs b/umide-core/src/syntax/mod.rs index c4f7c816..65cf67bf 100644 --- a/umide-core/src/syntax/mod.rs +++ b/umide-core/src/syntax/mod.rs @@ -39,7 +39,7 @@ use self::{ }; use crate::{ buffer::{Buffer, rope_text::RopeText}, - language::{self, LapceLanguage}, + language::{self, UmideLanguage}, lens::{Lens, LensBuilder}, style::SCOPES, syntax::highlight::InjectionLanguageMarker, @@ -513,12 +513,12 @@ impl SyntaxLayers { let injection_callback = |language: &InjectionLanguageMarker| { let language = match language { InjectionLanguageMarker::Name(name) => { - LapceLanguage::from_name(name) + UmideLanguage::from_name(name) } InjectionLanguageMarker::Filename(path) => { - LapceLanguage::from_path_raw(path) + UmideLanguage::from_path_raw(path) } - InjectionLanguageMarker::Shebang(id) => LapceLanguage::from_name(id), + InjectionLanguageMarker::Shebang(id) => UmideLanguage::from_name(id), }; language .map(get_highlight_config) @@ -898,7 +898,7 @@ impl SyntaxLayers { #[derive(Clone)] pub struct Syntax { pub rev: u64, - pub language: LapceLanguage, + pub language: UmideLanguage, pub text: Rope, pub layers: Option, pub lens: Lens, @@ -925,15 +925,15 @@ impl std::fmt::Debug for Syntax { impl Syntax { pub fn init(path: &Path) -> Syntax { - let language = LapceLanguage::from_path(path); + let language = UmideLanguage::from_path(path); Syntax::from_language(language) } pub fn plaintext() -> Syntax { - Self::from_language(LapceLanguage::PlainText) + Self::from_language(UmideLanguage::PlainText) } - pub fn from_language(language: LapceLanguage) -> Syntax { + pub fn from_language(language: UmideLanguage) -> Syntax { let highlight = get_highlight_config(language).ok(); Syntax { rev: 0, @@ -1204,7 +1204,7 @@ impl Syntax { } pub fn find_enclosing_pair(&self, offset: usize) -> Option<(usize, usize)> { - if self.language == LapceLanguage::Markdown { + if self.language == UmideLanguage::Markdown { // TODO: fix the issue that sometimes node.prev_sibling can stuck for markdown return None; } diff --git a/umide-proxy/Cargo.toml b/umide-proxy/Cargo.toml index 3160fe71..91bdfc36 100644 --- a/umide-proxy/Cargo.toml +++ b/umide-proxy/Cargo.toml @@ -64,5 +64,4 @@ wasi-common = "14.0.0" path = "../vendor/wasi-experimental-http/crates/wasi-experimental-http-wasmtime" [target.'cfg(target_os = "macos")'.dependencies.locale_config] -git = "https://github.com/lapce/locale_config.git" -branch = "lapce" +path = "../vendor/locale_config" diff --git a/umide-proxy/src/lib.rs b/umide-proxy/src/lib.rs index e0713dde..bc479aac 100644 --- a/umide-proxy/src/lib.rs +++ b/umide-proxy/src/lib.rs @@ -28,7 +28,7 @@ use umide_rpc::{ use tracing::error; #[derive(Parser)] -#[clap(name = "Lapce-proxy")] +#[clap(name = "Umide-proxy")] #[clap(version = meta::VERSION)] struct Cli { #[clap(short, long, action, hide = true)] @@ -145,8 +145,10 @@ pub fn register_lapce_path() -> Result<()> { let current_path = std::env::var("PATH")?; let paths = std::env::split_paths(¤t_path); for path in paths { - if exedir == path.canonicalize()? { - return Ok(()); + if let Ok(path) = path.canonicalize() { + if exedir == path { + return Ok(()); + } } } let paths = std::env::split_paths(¤t_path); diff --git a/umide-proxy/src/plugin/dap.rs b/umide-proxy/src/plugin/dap.rs index 671c4dc2..c2ce74b3 100644 --- a/umide-proxy/src/plugin/dap.rs +++ b/umide-proxy/src/plugin/dap.rs @@ -320,7 +320,7 @@ impl DapClient { pub(crate) fn initialize(&mut self) -> Result<()> { let params = dap_types::InitializeParams { client_id: Some("lapce".to_owned()), - client_name: Some("Lapce".to_owned()), + client_name: Some("Umide".to_owned()), adapter_id: "".to_string(), locale: Some("en-us".to_owned()), lines_start_at_one: Some(true), diff --git a/umide-proxy/src/plugin/wasi.rs b/umide-proxy/src/plugin/wasi.rs index 399e1b72..2d459daa 100644 --- a/umide-proxy/src/plugin/wasi.rs +++ b/umide-proxy/src/plugin/wasi.rs @@ -268,7 +268,7 @@ pub fn load_all_volts( } /// Find all installed volts. -/// `plugin_dev_path` allows launching Lapce with a plugin on your local system for testing +/// `plugin_dev_path` allows launching Umide with a plugin on your local system for testing /// purposes. /// As well, this function skips any volt in the typical plugin directory that match the name /// of the dev plugin so as to support developing a plugin you actively use. diff --git a/umide-rpc/Cargo.toml b/umide-rpc/Cargo.toml index d907cc0d..f3f53c9f 100644 --- a/umide-rpc/Cargo.toml +++ b/umide-rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "umide-rpc" -description = "Data formats between lapce components" +description = "Data formats between umide components" license = { workspace = true } version = { workspace = true } authors = { workspace = true } diff --git a/vendor/locale_config/.gitignore b/vendor/locale_config/.gitignore new file mode 100644 index 00000000..a9d37c56 --- /dev/null +++ b/vendor/locale_config/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/vendor/locale_config/.travis.yml b/vendor/locale_config/.travis.yml new file mode 100644 index 00000000..e4c7c3db --- /dev/null +++ b/vendor/locale_config/.travis.yml @@ -0,0 +1,80 @@ +# TravisCI configuration based on https://github.com/japaric/trust +# +# We don't need binary build, only continuous integration, so we don't use +# the deploy step. We also only build a somewhat representative selection of +# targets. + +# Based on the "trust" template v0.1.1 +# https://github.com/japaric/trust/tree/v0.1.1 + +dist: trusty +language: rust +services: docker +sudo: required + +env: + global: + - CRATE_NAME=locale_config + +matrix: + include: + # Stable channel + # Linux + - env: TARGET=x86_64-unknown-linux-gnu + - env: TARGET=x86_64-unknown-linux-musl + - env: TARGET=i686-unknown-linux-gnu + - env: TARGET=i686-unknown-linux-musl + + # OSX + - env: TARGET=x86_64-apple-darwin + os: osx + + # *BSD + - env: TARGET=i686-unknown-freebsd DISABLE_TESTS=1 + - env: TARGET=x86_64-unknown-netbsd DISABLE_TESTS=1 + + # Other architectures + - env: TARGET=aarch64-unknown-linux-gnu + - env: TARGET=armv7-unknown-linux-gnueabihf + - env: TARGET=mips-unknown-linux-gnu + - env: TARGET=mips64-unknown-linux-gnuabi64 + - env: TARGET=mips64el-unknown-linux-gnuabi64 + - env: TARGET=mipsel-unknown-linux-gnu + - env: TARGET=powerpc-unknown-linux-gnu + - env: TARGET=powerpc64-unknown-linux-gnu + - env: TARGET=powerpc64le-unknown-linux-gnu + - env: TARGET=s390x-unknown-linux-gnu DISABLE_TESTS=1 + + # Asmjs & Wasm + # TODO: Emscripten seems to be broken in cross + # - env: TARGET=asmjs-unknown-emscripten + # - env: TARGET=wasm32-unknown-emscripten + # TODO: wasm-unknown-unknown not yet supported in cross + # - env: TARGET=wasm32-unknown-unknown + + # Testing other channels + - env: TARGET=x86_64-unknown-linux-gnu + rust: nightly + - env: TARGET=i686-unknown-linux-musl + rust: nightly + - env: TARGET=x86_64-apple-darwin + os: osx + rust: nightly + +before_install: set -e + +install: + - sh ci/install.sh + - source ~/.cargo/env || true + +script: + - bash ci/script.sh + +after_script: set +e + +cache: cargo +before_cache: + # Travis can't cache files that are not readable by "others" + - chmod -R a+r $HOME/.cargo + +# vim: set sw=2 sts=2: diff --git a/vendor/locale_config/Cargo.toml b/vendor/locale_config/Cargo.toml new file mode 100644 index 00000000..8df4714a --- /dev/null +++ b/vendor/locale_config/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "locale_config" +version = "0.3.1-alpha.0" +edition = "2021" +description = """ +Maintains locale preferences for process and thread and initialises them by +inspecting the system for user preference. +""" +authors = [ + "Jan Hudec ", +] +license = "MIT" + +documentation = "https://docs.rs/locale_config/" +repository = "https://github.com/rust-locale/locale_config/" +readme = "README.md" +keywords = ["i18n"] +categories = ["os"] +exclude = ["/ci/*", "/.travis.yml", "/appveyor.yml"] + +[package.metadata.release] +upload-doc = true + +[badges] +travis-ci = { repository = "rust-locale/locale_config" } +appveyor = { repository = "rust-locale/locale_config" } + +[dependencies] +lazy_static = "1" +regex = "1" + +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["winnls"] } + +[target.'cfg(target_os = "macos")'.dependencies] +objc2 = "0.5.1" +objc2-foundation = { version = "0.2", features = ["NSLocale", "NSString"] } diff --git a/vendor/locale_config/LICENSE b/vendor/locale_config/LICENSE new file mode 100644 index 00000000..97b3d203 --- /dev/null +++ b/vendor/locale_config/LICENSE @@ -0,0 +1,25 @@ +The MIT License (MIT) + +Copyright (c) 2016–2019 Jan Hudec +Copyright (c) 2016 A.J. Gardner +Copyright (c) 2019, Bastien Orivel +Copyright (c) 2019, Igor Gnatenko +Copyright (c) 2019, Sophie Tauchert <999eagle@999eagle.moe> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/locale_config/README.md b/vendor/locale_config/README.md new file mode 100644 index 00000000..e5014902 --- /dev/null +++ b/vendor/locale_config/README.md @@ -0,0 +1,135 @@ +[![TravisCI Build Status](https://travis-ci.org/rust-locale/locale_config.svg?branch=master)](https://travis-ci.org/rust-locale/locale_config) +[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/13100wtqs80tyink/branch/master?svg=true)](https://ci.appveyor.com/project/jan-hudec/locale-config/branch/master) +[![Crates.io Version](https://img.shields.io/crates/v/locale_config.svg)](https://crates.io/crates/locale_config) +[![Docs.rs](https://docs.rs/locale_config/badge.svg)](https://docs.rs/locale_config/) + +# `locale_config` + +Remembers locale configuration per-thread and per-process and initializes the +values by inspecting the system for user preferences. + +## Installation + +You can depend on this library by adding `locale_config` to your Cargo dependencies: + +```toml +[dependencies] +locale_config = "*" +``` + +Usually it is not recommended to depend on `*`, but in this case it is +important that incompatible version requirements don't cause multiple +versions to be pulled in the final binary, so I do recommend it here and +promise I will maintain good compatibility. Just please don't add traits to +the types defined here to avoid conflicts with potential future methods. + +## Using + +Usually you want to use this indirectly via a localization crate like +`locale`. However if you need to work with the identifier itself, or you need +to override it, use + +```rust +Locale::current() +``` + +to find what you should be using at any given point in the application, + +```rust +Locale::set_current() +``` + +to override it for current thread and + +```rust +Locale::set_global_default() +``` + +to override it for new threads. + +In case you need to access the initial value, you'll find it under + +```rust +Locale::user_default() +``` + +The value may contain language tags specific for various localization +aspects, called categories, and fallbacks. The `Locale::tags_for` method will +take care of selecting relevant tags for you. For preferred language of +translations, use + +```rust +Locale::current().tags_for("messages") +``` + +For formatting, use categories `"numeric"` for numbers, `"time"` for date and +time and `"monetary"` for money amounts. And use `"collate"` for collation. + +Note that this crate does not itself provide any translation, formatting nor +collation functionality. Formatting and collation will be provided by +`locale` crate, translation has multiple available implementations. + +See full documentation on [![Docs.rs](https://docs.rs/locale_config/badge.svg)](https://docs.rs/locale_config/) or [github](https://rust-locale.github.io/locale_config/locale_config/). + +## Supported systems + +* **Unix:** Using the POSIX standard environment variables `LANG`, `LC_*` and + `LANGUAGES`. The variables are recognized on all systems and take + precedence on most of them. + +* **Windows:** Vista and newer + + - Uses API available from Vista and Server 2008 only. + - The `GetUserPreferredUILanguages` is only available for desktop, but + not store applications. Store applications should have equivalent + functionality, but I didn't try accessing it from Rust yet. + - Customization to individual locale elements done in “Regional and + Language options” (digits, calendar, decimal and thousand separator + etc.) are not detected (yet). + - Not well tested. + +* **OS X:** Reads setting from `NSLocale`, can be overridden by setting the + Unix environment variables. + +* **CGI:** The `HTTP_ACCEPT_LANGUAGE` environment variable is used if + detected. Hopefully it is specific enough to the CGI environment that it + can be used whenever detected. + +## Changelog + +### 0.3.0 + + * Support OS X `NSLocale`. + Thanks Sophie Tauchert (@999eagle). + +### 0.2.3 + +* Try support getting locale in emscripten targets in browser. Unfortunately + the emscripten targets seem to have broken in cross meanwhile, so they are not + being tested. +* Update to winapi 0.3. +* Update ro regex 1.0. + +### 0.2.2 + +* Update dependencies: regex 0.2. + +### 0.2.1 + +* Interpret some overrides that can be set on Windows in Region and Language + dialog, namely: group, decimal and list separators, first day of week, + 12/24-hour time, measurement system, (decimal) number system, to an extent + negative monetary value format (only whether to use parenthesized format + or not) and to an extent date format (if ISO-8601 variant is selected). + +### 0.2.0 + +* Changed error handling to proper error type. + +### 0.1.1 + +* Added basic Windows support. + +### 0.1.0 + +* Initial version, with Unix and CGI support. diff --git a/vendor/locale_config/appveyor.yml b/vendor/locale_config/appveyor.yml new file mode 100644 index 00000000..1de9610c --- /dev/null +++ b/vendor/locale_config/appveyor.yml @@ -0,0 +1,58 @@ +# AppVeyor configuration based on https://github.com/japaric/trust +# +# We don't need binary build, only continuous integration, so we don't use +# the deploy step. We also only build subset of the configurations to keep +# the time down. + +# Based on the "trust" template v0.1.1 +# https://github.com/japaric/trust/tree/v0.1.1 + +environment: + global: + RUST_VERSION: stable + CRATE_NAME: locale_config + + matrix: + # MinGW + - TARGET: i686-pc-windows-gnu + - TARGET: x86_64-pc-windows-gnu + + # MSVC + - TARGET: i686-pc-windows-msvc + - TARGET: x86_64-pc-windows-msvc + + # Testing other channels + - TARGET: x86_64-pc-windows-gnu + RUST_VERSION: nightly + - TARGET: i686-pc-windows-msvc + RUST_VERSION: nightly + +install: + - ps: >- + If ($Env:TARGET -eq 'x86_64-pc-windows-gnu') { + $Env:PATH += ';C:\msys64\mingw64\bin' + } ElseIf ($Env:TARGET -eq 'i686-pc-windows-gnu') { + $Env:PATH += ';C:\msys64\mingw32\bin' + } + - curl -sSf -o rustup-init.exe https://win.rustup.rs/ + - rustup-init.exe -y --default-host %TARGET% --default-toolchain %RUST_VERSION% + - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin + - rustc -Vv + - cargo -V + +test_script: + - cargo build --target %TARGET% + - cargo build --target %TARGET% --release + - cargo test --target %TARGET% + - cargo test --target %TARGET% --release + - cargo run --target %TARGET% --example show-user-locale + - cargo run --target %TARGET% --release --example show-user-locale + +cache: + - C:\Users\appveyor\.cargo\registry + - target + +# Building is done in the test phase, so we disable Appveyor's build phase. +build: false + +# vim: set sw=2 sts=2: diff --git a/vendor/locale_config/ci/install.sh b/vendor/locale_config/ci/install.sh new file mode 100644 index 00000000..748ad9a9 --- /dev/null +++ b/vendor/locale_config/ci/install.sh @@ -0,0 +1,27 @@ +set -ex + +main() { + local target= + if [ $TRAVIS_OS_NAME = linux ]; then + target=x86_64-unknown-linux-musl + sort=sort + else + target=x86_64-apple-darwin + sort=gsort # for `sort --sort-version`, from brew's coreutils. + fi + + # This fetches latest stable release + local tag=$(git ls-remote --tags --refs --exit-code https://github.com/japaric/cross \ + | cut -d/ -f3 \ + | grep -E '^v[0.1.0-9.]+$' \ + | $sort --version-sort \ + | tail -n1) + curl -LSfs https://japaric.github.io/trust/install.sh | \ + sh -s -- \ + --force \ + --git japaric/cross \ + --tag $tag \ + --target $target +} + +main diff --git a/vendor/locale_config/ci/script.sh b/vendor/locale_config/ci/script.sh new file mode 100644 index 00000000..0c7c9074 --- /dev/null +++ b/vendor/locale_config/ci/script.sh @@ -0,0 +1,24 @@ +# This script takes care of testing your crate + +set -ex + +# TODO This is the "test phase", tweak it as you see fit +main() { + cross build --target $TARGET + cross build --target $TARGET --release + + if [ ! -z $DISABLE_TESTS ]; then + return + fi + + cross test --target $TARGET + cross test --target $TARGET --release + + cross run --target $TARGET --example show-user-locale + cross run --target $TARGET --release --example show-user-locale +} + +# we don't run the "test phase" when doing deploys +if [ -z $TRAVIS_TAG ]; then + main +fi diff --git a/vendor/locale_config/examples/show-user-locale.rs b/vendor/locale_config/examples/show-user-locale.rs new file mode 100644 index 00000000..646072b6 --- /dev/null +++ b/vendor/locale_config/examples/show-user-locale.rs @@ -0,0 +1,5 @@ +extern crate locale_config; + +pub fn main() { + println!("{}", locale_config::Locale::user_default()); +} diff --git a/vendor/locale_config/src/cgi.rs b/vendor/locale_config/src/cgi.rs new file mode 100644 index 00000000..31126130 --- /dev/null +++ b/vendor/locale_config/src/cgi.rs @@ -0,0 +1,12 @@ +//! Inspect CGI environment variables for locale configuration + +use super::Locale; +use std::env; + +pub fn system_locale() -> Option { + if let Ok(al) = env::var("HTTP_ACCEPT_LANGUAGE") { + Locale::new(al.as_ref()).ok() + } else { + None + } +} diff --git a/vendor/locale_config/src/emscripten.rs b/vendor/locale_config/src/emscripten.rs new file mode 100644 index 00000000..67888da7 --- /dev/null +++ b/vendor/locale_config/src/emscripten.rs @@ -0,0 +1,31 @@ +use std::ffi::CStr; +use std::os::raw::c_char; +use std::os::raw::c_int; + +use super::Locale; + +// Bind some emscripten functions. Copied from webplatform crate. +extern "C" { + pub fn emscripten_asm_const_int(s: *const c_char, ...) -> c_int; +} + +pub fn system_locale() -> Option { + const JS: &'static [u8] = b"\ + try { \ + return allocate(intArrayFromString(navigator.languages.join(',')), 'i8', ALLOC_STACK); \ + } catch(e) {} \ + try { \ + return allocate(intArrayFromString(navigator.language), 'i8', ALLOC_STACK); \ + } catch(e) {} \ + try { \ + return allocate(intArrayFromString(navigator.userLanguage), 'i8', ALLOC_STACK); \ + } catch(e) {} \ + return 0;\0"; + unsafe { + let cptr = emscripten_asm_const_int(&JS[0] as *const _ as *const c_char); + return CStr::from_ptr(cptr as *const c_char) + .to_str() + .ok() + .and_then(|s| Locale::new(s).ok()); + } +} diff --git a/vendor/locale_config/src/lib.rs b/vendor/locale_config/src/lib.rs new file mode 100644 index 00000000..b7d4dfc4 --- /dev/null +++ b/vendor/locale_config/src/lib.rs @@ -0,0 +1,1082 @@ +//! Global locale instances and system inspection. +//! +//! This is an auxiliary crate for i18n solutions that: +//! +//! - Holds the appropriate default instances of locale. +//! - Inspects the system for the initial values. +//! +//! You don't want to use it directly, but instead use an internationalisation crate like [locale]. +//! +//! This crate is separate and intentionally minimal so that multiple i18n crates or multiple +//! versions of one that get into the application still share the current locale setting. +//! +//! [locale]: https://crates.io/crates/locale + +#[macro_use] +extern crate lazy_static; + +#[cfg(target_os = "macos")] +extern crate objc2; + +#[cfg(target_os = "macos")] +extern crate objc2_foundation; + +extern crate regex; + +use regex::Regex; +use std::borrow::{Borrow, Cow}; +use std::cell::RefCell; +use std::convert::AsRef; +use std::fmt::{self, Display}; +use std::sync::Mutex; + +// ------------------------------ LANGUAGE RANGE --------------------------------- + +/// Language and culture identifier. +/// +/// This object holds a [RFC4647] extended language range. +/// +/// The internal data may be owned or shared from object with lifetime `'a`. The lifetime can be +/// extended using the `into_static()` method, which internally clones the data as needed. +/// +/// # Syntax +/// +/// The range is composed of `-`-separated alphanumeric subtags, possibly replaced by `*`s. It +/// might be empty. +/// +/// In agreement with [RFC4647], this object only requires that the tag matches: +/// +/// ```ebnf +/// language_tag = (alpha{1,8} | "*") +/// ("-" (alphanum{1,8} | "*"))* +/// ``` +/// +/// The exact interpretation is up to the downstream localization provider, but it expected that +/// it will be matched against a normalized [RFC5646] language tag, which has the structure: +/// +/// ```ebnf +/// language_tag = language +/// ("-" script)? +/// ("-" region)? +/// ("-" variant)* +/// ("-" extension)* +/// ("-" private)? +/// +/// language = alpha{2,3} ("-" alpha{3}){0,3} +/// +/// script = aplha{4} +/// +/// region = alpha{2} +/// | digit{3} +/// +/// variant = alphanum{5,8} +/// | digit alphanum{3} +/// +/// extension = [0-9a-wyz] ("-" alphanum{2,8})+ +/// +/// private = "x" ("-" alphanum{1,8})+ +/// ``` +/// +/// * `language` is an [ISO639] 2-letter or, where not defined, 3-letter code. A code for +/// macro-language might be followed by code of specific dialect. +/// * `script` is an [ISO15924] 4-letter code. +/// * `region` is either an [ISO3166] 2-letter code or, for areas other than countries, [UN M.49] +/// 3-digit numeric code. +/// * `variant` is a string indicating variant of the language. +/// * `extension` and `private` define additional options. The private part has same structure as +/// the Unicode [`-u-` extension][u_ext]. Available options are documented for the facets that +/// use them. +/// +/// The values obtained by inspecting the system are normalized according to those rules. +/// +/// The content will be case-normalized as recommended in [RFC5646] §2.1.1, namely: +/// +/// * `language` is written in lowercase, +/// * `script` is written with first capital, +/// * `country` is written in uppercase and +/// * all other subtags are written in lowercase. +/// +/// When detecting system configuration, additional options that may be generated under the +/// [`-u-` extension][u_ext] currently are: +/// +/// * `cf` — Currency format (`account` for parenthesized negative values, `standard` for minus +/// sign). +/// * `fw` — First day of week (`mon` to `sun`). +/// * `hc` — Hour cycle (`h12` for 1–12, `h23` for 0–23). +/// * `ms` — Measurement system (`metric` or `ussystem`). +/// * `nu` — Numbering system—only decimal systems are currently used. +/// * `va` — Variant when locale is specified in Unix format and the tag after `@` does not +/// correspond to any variant defined in [Language subtag registry]. +/// +/// And under the `-x-` extension, following options are defined: +/// +/// * `df` — Date format: +/// +/// * `iso`: Short date should be in ISO format of `yyyy-MM-dd`. +/// +/// For example `-df-iso`. +/// +/// * `dm` — Decimal separator for monetary: +/// +/// Followed by one or more Unicode codepoints in hexadecimal. For example `-dm-002d` means to +/// use comma. +/// +/// * `ds` — Decimal separator for numbers: +/// +/// Followed by one or more Unicode codepoints in hexadecimal. For example `-ds-002d` means to +/// use comma. +/// +/// * `gm` — Group (thousand) separator for monetary: +/// +/// Followed by one or more Unicode codepoints in hexadecimal. For example `-dm-00a0` means to +/// use non-breaking space. +/// +/// * `gs` — Group (thousand) separator for numbers: +/// +/// Followed by one or more Unicode codepoints in hexadecimal. For example `-ds-00a0` means to +/// use non-breaking space. +/// +/// * `ls` — List separator: +/// +/// Followed by one or more Unicode codepoints in hexadecimal. For example, `-ds-003b` means to +/// use a semicolon. +/// +/// [RFC5646]: https://www.rfc-editor.org/rfc/rfc5646.txt +/// [RFC4647]: https://www.rfc-editor.org/rfc/rfc4647.txt +/// [ISO639]: https://en.wikipedia.org/wiki/ISO_639 +/// [ISO15924]: https://en.wikipedia.org/wiki/ISO_15924 +/// [ISO3166]: https://en.wikipedia.org/wiki/ISO_3166 +/// [UN M.49]: https://en.wikipedia.org/wiki/UN_M.49 +/// [u_ext]: http://www.unicode.org/reports/tr35/#u_Extension +/// [Language subtag registry]: https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct LanguageRange<'a> { + language: Cow<'a, str>, +} + +lazy_static! { + static ref REGULAR_LANGUAGE_RANGE_REGEX: Regex = Regex::new( + r"(?x) ^ + (?P (?: + [[:alpha:]]{2,3} (?: - [[:alpha:]]{3} ){0,3} + | \* )) + (?P