diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..96b35539c9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,9 @@ +# Auto detect text files and perform normalization +* text=auto eol=lf + +*.rs text diff=rust eol=lf +*.toml text diff=toml eol=lf +Cargo.lock text eol=lf + +*.sh text eol=lf +*.ps1 text eol=crlf diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000000..2dad4588be --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,29 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: 'C-bug' +assignees: '' + +--- + +## Lapce Version + +The Lapce version you are using, which can be found in "About Lapce" 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 + +Other information that can be used to further reproduce or isolate the problem. +This commonly includes: + +- screenshots +- logs +- theories about what might be going wrong +- workarounds that you used diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..aac61aa4ed --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,11 @@ +blank_issues_enabled: false +contact_links: + - name: Lapce community on Discord + url: https://discord.gg/n8tGJ6Rn6D + about: Please ask and answer questions here. + - name: Lapce community on Matrix + url: https://matrix.to/#/#lapce-editor:matrix.org + about: Please ask and answer questions here. + - name: Lapce documentation + url: https://docs.lapce.dev/ + about: Documentation for Lapce diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000000..2464024d03 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,24 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: 'C-feature' +assignees: '' + +--- + +## Is your feature request related to a problem? Please describe. + +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +## Describe the solution you'd like + +A clear and concise description of what you want to happen. + +## Describe alternatives you've considered + +A clear and concise description of any alternative solutions or features you've considered. + +## Additional context + +Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..e3e1d64c45 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1 @@ +- [ ] Added an entry to `CHANGELOG.md` if this change could be valuable to users \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..0a8ff26e31 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +version: 2 +updates: + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'weekly' + + - package-ecosystem: 'cargo' + directory: '/' + schedule: + interval: 'weekly' \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 27e4f79b36..f554569421 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,75 +2,101 @@ on: push: branches: - master + pull_request: + types: [opened, synchronize, reopened, ready_for_review] name: CI +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + jobs: build: - name: Rust (${{ matrix.toolchain }}) on ${{ matrix.os }} + name: Rust on ${{ matrix.os }} + if: github.event.pull_request.draft == false + needs: [fmt, clippy] strategy: fail-fast: false matrix: os: [ ubuntu-latest, windows-latest, macos-latest ] - toolchain: [ stable ] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - name: Checkout repo + uses: actions/checkout@v3 - name: Install dependencies on Ubuntu if: startsWith(matrix.os, 'ubuntu') run: sudo apt-get update && sudo apt-get install cmake pkg-config libgtk-3-dev - - name: Install toolchain - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.toolchain }} + - name: Update toolchain & add llvm-tools + run: | + rustup update + rustup component add llvm-tools-preview - - uses: Swatinem/rust-cache@v1 + - name: Cache Rust dependencies + uses: Swatinem/rust-cache@v2 + + - name: Fetch dependencies + run: cargo fetch --locked - name: Build - uses: actions-rs/cargo@v1 - with: - command: build - - - name: Run tests - uses: actions-rs/cargo@v1 + run: cargo build --frozen + + - name: Install cargo-llvm-cov + uses: taiki-e/install-action@cargo-llvm-cov + + - name: Run tests and coverage + run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info + + - name: Run doc tests + run: cargo test --doc --workspace + + - name: Upload coverage + uses: codecov/codecov-action@v3 with: - command: test - args: --workspace + files: lcov.info + fmt: name: Rustfmt runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - - run: rustup component add rustfmt - - uses: Swatinem/rust-cache@v1 - - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Update toolchain & add rustfmt + run: | + rustup update + rustup component add rustfmt + + - name: Run rustfmt + run: cargo fmt --all --check clippy: - name: Clippy - runs-on: ubuntu-latest + name: Clippy on ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ ubuntu-latest, windows-latest, macos-latest ] + runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - - run: rustup component add clippy + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Update toolchain & add clippy + run: | + rustup update + rustup component add clippy + - name: Install dependencies on Ubuntu + if: startsWith(matrix.os, 'ubuntu') run: sudo apt-get update && sudo apt-get install cmake pkg-config libgtk-3-dev - - uses: Swatinem/rust-cache@v1 - - uses: actions-rs/cargo@v1 - with: - command: clippy - args: -- -D warnings + + - name: Cache Rust dependencies + uses: Swatinem/rust-cache@v2 + + - name: Fetch dependencies + run: cargo fetch --locked + + - name: Run clippy + run: cargo clippy -- -D warnings diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml deleted file mode 100644 index 5ac33a9c4f..0000000000 --- a/.github/workflows/pr.yml +++ /dev/null @@ -1,69 +0,0 @@ -on: - pull_request: - types: [opened, synchronize, reopened, ready_for_review] - -name: Pull request checks - -jobs: - check: - name: Rust (${{ matrix.toolchain }}) on ${{ matrix.os }} - if: github.event.pull_request.draft == false - - strategy: - matrix: - os: [ ubuntu-latest, windows-latest, macos-latest ] - toolchain: [ stable ] - - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v2 - - - name: Install dependencies on Ubuntu - if: startsWith(matrix.os, 'ubuntu') - run: sudo apt-get update && sudo apt-get install cmake pkg-config libgtk-3-dev - - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.toolchain }} - - - uses: Swatinem/rust-cache@v1 - - - uses: actions-rs/cargo@v1 - with: - command: test - args: --workspace - - fmt: - name: Rustfmt - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - - run: rustup component add rustfmt - - uses: Swatinem/rust-cache@v1 - - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check - clippy: - name: Clippy - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - - run: rustup component add clippy - - name: Install dependencies on Ubuntu - run: sudo apt-get update && sudo apt-get install cmake pkg-config libgtk-3-dev - - uses: actions-rs/cargo@v1 - with: - command: clippy - args: -- -D warnings diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4018d8874d..1364f93503 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,29 +1,80 @@ name: Release on: + schedule: + - cron: 0 0 * * * + workflow_dispatch: + inputs: + tag_name: + description: 'Tag name for release' + required: false + default: nightly push: tags: ["v[0-9]+.[0-9]+.[0-9]+*"] + pull_request: + paths: + # trigger release workflow only if this file changed + - .github/workflows/release.yml env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CARGO_TERM_COLOR: always jobs: + tagname: + runs-on: ubuntu-latest + outputs: + tag_name: ${{ steps.tag.outputs.tag }} + steps: + - if: github.event_name == 'workflow_dispatch' + run: echo "TAG_NAME=${{ github.event.inputs.tag_name }}" >> $GITHUB_ENV + + - if: github.event_name == 'schedule' + run: echo 'TAG_NAME=nightly' >> $GITHUB_ENV + + - if: github.event_name == 'push' + run: | + TAG_NAME=${{ github.ref }} + echo "TAG_NAME=${TAG_NAME#refs/tags/}" >> $GITHUB_ENV + + - if: github.event_name == 'pull_request' + run: echo 'TAG_NAME=debug' >> $GITHUB_ENV + + - id: vars + shell: bash + run: echo "sha_short=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT + + - if: env.TAG_NAME == 'nightly' + run: echo 'TAG_NAME=nightly-${{ steps.vars.outputs.sha_short }}' >> $GITHUB_ENV + + - id: tag + run: echo "tag=$TAG_NAME" >> $GITHUB_OUTPUT + windows: runs-on: windows-latest + needs: tagname + env: + RELEASE_TAG_NAME: ${{ needs.tagname.outputs.tag_name }} defaults: run: shell: bash steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 + - name: Update rust run: rustup update + + - name: Fetch dependencies + run: cargo fetch --locked + - name: Build - run: cargo build --profile release-lto + run: cargo build --frozen --profile release-lto + - name: Install WiX run: nuget install WiX + - name: Crate msi installer run: | ./WiX.*/tools/candle.exe -arch "x64" -ext WixUIExtension -ext WixUtilExtension \ @@ -31,95 +82,255 @@ jobs: ./WiX.*/tools/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-ui/portable Compress-Archive ./target/release-lto/lapce.exe ./Lapce-windows-portable.zip - - name: Upload msi installer - uses: svenstaro/upload-release-action@v2 - with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: ./Lapce-windows.msi - file_glob: true - tag: ${{ github.ref }} - overwrite: true - - name: Upload portable - uses: svenstaro/upload-release-action@v2 + + - 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@v3 with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: ./Lapce-windows-portable.zip - file_glob: true - tag: ${{ github.ref }} - overwrite: true + name: lapce-windows + path: | + ./lapce-proxy-windows-*.gz + ./Lapce-windows-portable.zip + ./Lapce-windows.msi + retention-days: 1 linux: - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest + container: ubuntu:18.04 + needs: tagname + env: + RELEASE_TAG_NAME: ${{ needs.tagname.outputs.tag_name }} + DEBIAN_FRONTEND: noninteractive steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies run: | - sudo apt-get install cmake pkg-config libfontconfig-dev libgtk-3-dev - - name: Update rust - run: rustup update + apt-get -y update + apt-get -y install cmake pkg-config libfontconfig-dev libgtk-3-dev + + - name: Install Rust toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + target: x86_64-unknown-linux-gnu + profile: minimal + + - name: Fetch dependencies + run: cargo fetch --locked + - name: Build - run: cargo build --profile release-lto + run: cargo build --frozen --profile release-lto --bin lapce + - name: Gzip run: | mkdir Lapce cp ./target/release-lto/lapce Lapce/ tar -zcvf ./Lapce-linux.tar.gz Lapce - gzip -c "./target/release-lto/lapce-proxy" > ./lapce-proxy-linux.gz - - name: Upload Application - uses: svenstaro/upload-release-action@v2 + + - uses: actions/upload-artifact@v3 + with: + name: lapce-linux + path: | + ./Lapce-linux.tar.gz + retention-days: 1 + + linux-musl: + name: Build lapce-proxy for ${{ matrix.platform }} + runs-on: ubuntu-latest + needs: tagname + env: + RELEASE_TAG_NAME: ${{ needs.tagname.outputs.tag_name }} + CROSS_SYSROOT: /mnt/alpine-${{ matrix.platform }} + PACKAGES: > + zlib-static freetype-static fontconfig-static + libgit2-static libssh2-static openssl-libs-static + libssl3 gtk+3.0-dev http-parser-dev rustup + build-base openssl-dev git lld clang + strategy: + fail-fast: false + matrix: + include: + - triple: x86_64-unknown-linux-musl + platform: x86_64 + - triple: aarch64-unknown-linux-musl + platform: aarch64 + steps: + - uses: actions/checkout@v3 + + - name: Set up Alpine Linux for ${{ matrix.platform }} (target arch) + id: alpine-target + uses: jirutka/setup-alpine@v1 + with: + arch: ${{ matrix.platform }} + branch: edge + packages: ${{ env.PACKAGES }} + shell-name: alpine-target.sh + + - name: Set up Alpine Linux for x86_64 (build arch) + uses: jirutka/setup-alpine@v1 with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: ./Lapce-linux.tar.gz - file_glob: true - tag: ${{ github.ref }} - overwrite: true - - name: Upload Application - uses: svenstaro/upload-release-action@v2 + arch: x86_64 + branch: edge + packages: ${{ env.PACKAGES }} + volumes: ${{ steps.alpine-target.outputs.root-path }}:${{ env.CROSS_SYSROOT }} + shell-name: alpine.sh + + - name: Install Rust stable toolchain via rustup + run: rustup-init --target ${{ matrix.triple }} --default-toolchain stable --profile minimal -y + shell: alpine.sh {0} + + - name: Build ${{ matrix.triple }} + shell: alpine.sh {0} + env: + LIBZ_SYS_STATIC: 1 + LIBSSH2_STATIC: 1 + LIBGIT2_STATIC: 1 + OPENSSL_STATIC: 1 + OPENSSL_DIR: ${{ env.CROSS_SYSROOT }}/usr # static/dynamic lib workaround <3 + OPENSSL_NO_VENDOR: 1 # don't even try to build without it on musl + PKG_CONFIG_ALL_STATIC: 1 + PKG_CONFIG_LIBDIR: ${{ env.CROSS_SYSROOT }}/usr/lib/pkgconfig + RUSTFLAGS: -C target-feature=+crt-static -C linker=/usr/bin/ld.lld # link runtime static, use universal linker + CARGO_BUILD_TARGET: ${{ matrix.triple }} + CARGO_PROFILE_RELEASE_LTO: 'true' + CARGO_PROFILE_RELEASE_STRIP: symbols # remove unneeded debug stuff + CARGO_PROFILE_RELEASE_OPT_LEVEL: 's' # optimise for size + CARGO_PROFILE_RELEASE_CODEGEN_UNITS: '1' # optimise each crate + SYSROOT: /dummy # workaround for https://github.com/rust-lang/pkg-config-rs/issues/102 + CC: clang + run: | + # Workaround for https://github.com/rust-lang/pkg-config-rs/issues/102 + echo -e '#!/bin/sh\nPKG_CONFIG_SYSROOT_DIR=${{ env.CROSS_SYSROOT }} exec pkgconf "$@"' \ + | install -m755 /dev/stdin pkg-config + export PKG_CONFIG="$(pwd)/pkg-config" + cargo fetch --locked + cargo build \ + --frozen \ + --verbose \ + --release \ + --bin lapce-proxy \ + --manifest-path lapce-proxy/Cargo.toml + + - name: Gzip + run: | + gzip -c ./target/${{ matrix.triple }}/release/lapce-proxy > ./lapce-proxy-linux-${{ matrix.platform }}.gz + + - uses: actions/upload-artifact@v3 with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: ./lapce-proxy-linux.gz - file_glob: true - tag: ${{ github.ref }} - overwrite: true + name: lapce-proxy-linux-${{ matrix.platform }} + path: | + ./lapce-proxy-linux-*.gz + retention-days: 1 macos: runs-on: macos-11 - + needs: tagname env: + RELEASE_TAG_NAME: ${{ needs.tagname.outputs.tag_name }} + NOTARIZE_USERNAME: ${{ secrets.NOTARIZE_USERNAME }} NOTARIZE_PASSWORD: ${{ secrets.NOTARIZE_PASSWORD }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 + - name: Install ARM target run: rustup update && rustup target add aarch64-apple-darwin + - name: Import Certificate - uses: apple-actions/import-codesign-certs@v1 + uses: lapce/import-codesign-certs@72dec84923586f8bef2bed09fdb4f9475c8f623d # use updated action, can be dropped once/if upstream is fixed with: p12-file-base64: ${{ secrets.MACOS_CERTIFICATE }} p12-password: ${{ secrets.MACOS_CERTIFICATE_PWD }} + + - name: Fetch dependencies + run: cargo fetch --locked + - name: Make DMG run: make dmg-universal + - name: Rename run: | cp ./target/release-lto/macos/Lapce.dmg ./target/release-lto/macos/Lapce-macos.dmg + + - name: Gzip lapce-proxy + 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 + - name: "Notarize Release Build" run: | npx notarize-cli --file ./target/release-lto/macos/Lapce-macos.dmg --bundle-id io.lapce --asc-provider CYSGAZFR8D + - name: "Staple Release Build" - uses: devbotsxyz/xcode-staple@v1 + uses: lapce/xcode-staple@062485d6eeafe841c18a412f012e80f49e23c517 with: product-path: "./target/release-lto/macos/Lapce-macos.dmg" - - name: Upload Application - uses: svenstaro/upload-release-action@v2 + + - uses: actions/upload-artifact@v3 with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - file: ./target/release-lto/macos/Lapce-macos.dmg - file_glob: true - tag: ${{ github.ref }} - overwrite: true + name: lapce-macos + path: | + ./target/release-lto/macos/lapce-proxy-darwin-*.gz + ./target/release-lto/macos/Lapce-macos.dmg + retention-days: 1 + + publish: + if: github.event_name != 'pull_request' + needs: [linux, linux-musl, windows, macos] + runs-on: ubuntu-latest + env: + GH_REPO: ${{ github.repository }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + permissions: + contents: write + steps: + # Must perform checkout first, since it deletes the target directory + # before running, and would therefore delete the downloaded artifacts + - uses: actions/checkout@v3 + + - uses: actions/download-artifact@v3 + + - if: github.event_name == 'workflow_dispatch' + run: echo "TAG_NAME=${{ github.event.inputs.tag_name }}" >> $GITHUB_ENV + + - if: github.event_name == 'schedule' + run: echo 'TAG_NAME=nightly' >> $GITHUB_ENV + + - if: github.event_name == 'push' + run: | + TAG_NAME=${{ github.ref }} + echo "TAG_NAME=${TAG_NAME#refs/tags/}" >> $GITHUB_ENV + + - if: env.TAG_NAME == 'nightly' + run: | + (echo 'SUBJECT=Lapce development build'; + echo 'PRERELEASE=--prerelease') >> $GITHUB_ENV + gh release delete nightly --yes || true + git push origin :nightly || true + + - if: env.TAG_NAME != 'nightly' + run: | + (echo 'SUBJECT=Lapce release build'; + echo 'PRERELEASE=') >> $GITHUB_ENV + + - name: Publish release + env: + DEBUG: api + run: | + gh release create $TAG_NAME $PRERELEASE --title "$TAG_NAME" --target $GITHUB_SHA lapce-macos/* lapce-linux/* lapce-proxy-linux-*/* lapce-windows/* diff --git a/.gitignore b/.gitignore index 3c15873097..f327728e8a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,10 @@ .vscode .lapce .idea +.fleet +shell.nix lib/ target/ core/languages/ + +.DS_Store diff --git a/.rustfmt.toml b/.rustfmt.toml index 3c67608274..06900d0d9b 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -1 +1,4 @@ max_width = 85 +# below requires nightly +# imports_granularity = "Crate" +# group_imports = "StdExternalCrate" diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..0e8e085f66 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,240 @@ +# Changelog + +## Unreleased + +### Features/Changes + +### Bug Fixes + +## 0.2.6 + +### Breaking changes + +- [#1820](https://github.com/lapce/lapce/pull/1820): Add remote svg icon colour to theme, disable plugin settings when none are available +- [#1988](https://github.com/lapce/lapce/pull/1987): Replace modal status background with background/foreground theme keys + +### Features/Changes +- [#1899](https://github.com/lapce/lapce/pull/1899): Improve sorting files with numbers +- [#1831](https://github.com/lapce/lapce/pull/1831): Plugin settings shown on right click +- [#1830](https://github.com/lapce/lapce/pull/1830): Adds Clojure language support +- [#1835](https://github.com/lapce/lapce/pull/1835): Add mouse keybinds +- [#1856](https://github.com/lapce/lapce/pull/1856): Highlight git/VCS modified files in explorer, palette, and buffer tabs +- [#1574](https://github.com/lapce/lapce/pull/1574): Panel sections can be expanded/collapsed +- [#1938](https://github.com/lapce/lapce/pull/1938): Use dropdown for theme selection in settings +- [#1960](https://github.com/lapce/lapce/pull/1960): Add sticky headers and code lens for PHP +- [#1968](https://github.com/lapce/lapce/pull/1968): Completion lens (disabled by default) + - ![image](https://user-images.githubusercontent.com/13157904/211959283-c3229cfc-28d7-4676-a50d-aec7d47cde9f.png) +- [#1972](https://github.com/lapce/lapce/pull/1972): Add file duplication option in fs tree context menu +- [#1991](https://github.com/lapce/lapce/pull/1991): Implement rendering of images in markdown views +- [#2004](https://github.com/lapce/lapce/pull/2004): Add ToggleHistory command +- [#2033](https://github.com/lapce/lapce/pull/2033): Add setting for double click delay (Currently only works for opening file from the explorer) +- [#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 +- [#2127](https://github.com/lapce/lapce/pull/2127): Extended double-click options with file-only and file + folders mode + +### Bug Fixes +- [#1911](https://github.com/lapce/lapce/pull/1911): Fix movement on selections with left/right arrow keys +- [#1939](https://github.com/lapce/lapce/pull/1939): Fix saving/editing newly saved-as files +- [#1971](https://github.com/lapce/lapce/pull/1971): Fix up/down movement on first/last line +- [#2036](https://github.com/lapce/lapce/pull/2036): Fix movement on selections with up/down arrow keys +- [#2056](https://github.com/lapce/lapce/pull/2056): Fix default directory of remote session file picker +- [#2072](https://github.com/lapce/lapce/pull/2072): Fix connection issues from Windows to lapce proxy +- [#2069](https://github.com/lapce/lapce/pull/2045): Fix not finding git repositories in parent path +- [#2131](https://github.com/lapce/lapce/pull/2131): Fix overwriting symlink +- [#2188](https://github.com/lapce/lapce/pull/2188): Fix auto closing matching pairs in inappropriate inputs + +## 0.2.5 + +### Breaking changes + +- [#1726](https://github.com/lapce/lapce/pull/1726): Add more panel theme keys, apply hover first, then current item colour + +### Features/Changes +- [#1791](https://github.com/lapce/lapce/pull/1791): Add highlighting for scope lines +- [#1767](https://github.com/lapce/lapce/pull/1767): Added CMake tree-sitter syntax highlighting +- [#1759](https://github.com/lapce/lapce/pull/1759): Update C tree-sitter and highlight queries +- [#1758](https://github.com/lapce/lapce/pull/1758): Replaced dlang syntax highlighting +- [#1713](https://github.com/lapce/lapce/pull/1713): Add protobuf syntax and highlighting +- [#1720](https://github.com/lapce/lapce/pull/1720): Display signature/parameter information from LSP +- [#1723](https://github.com/lapce/lapce/pull/1723): In the palette, display the keybind for a command adjacent to it +- [#1722](https://github.com/lapce/lapce/pull/1722): Add 'Save without Formatting'; Add option to disable formatting on autosave +- [#1741](https://github.com/lapce/lapce/pull/1741): Add syntax highlighting for glsl +- [#1756](https://github.com/lapce/lapce/pull/1756): Add support for ssh port with ```[user@]host[:port]``` +- [#1760](https://github.com/lapce/lapce/pull/1760): Add vim motions `cw`, `ce`, `cc`, `S`, and QOL modal bind `gf` +- [#1770](https://github.com/lapce/lapce/pull/1770): Add support for terminal tabs + +### Bug Fixes +- [#1771](https://github.com/lapce/lapce/pull/1771): Update tree-sitter-bash +- [#1737](https://github.com/lapce/lapce/pull/1726): Fix an issue that plugins can't be upgraded +- [#1724](https://github.com/lapce/lapce/pull/1724): Files and hidden folders no longer will be considered when trying to open a plugin base folder +- [#1753](https://github.com/lapce/lapce/pull/1753): Limit proxy search response size in order to avoid issues with absurdly long lines +- [#1805](https://github.com/lapce/lapce/pull/1805): Fix some LSP bugs causing code actions to not show up correctly + +## 0.2.4 + +### Features/Changes +- [#1700](https://github.com/lapce/lapce/pull/1700): Add prisma syntax and highlighting +- [#1702](https://github.com/lapce/lapce/pull/1702): Improved svelte treesitter queries +- [#1690](https://github.com/lapce/lapce/pull/1690): Add codelens and sticky headers for Dart +- [#1711](https://github.com/lapce/lapce/pull/1711): Add zstd support for plugin +- [#1715](https://github.com/lapce/lapce/pull/1715): Add support for requests from plugins + +### Bug Fixes +- [#1710](https://github.com/lapce/lapce/pull/1710): Fix autosave trying to save scratch files +- [#1709](https://github.com/lapce/lapce/pull/1709): Fix search result ordering +- [#1708](https://github.com/lapce/lapce/pull/1708): Fix visual issue when search panel is placed to either side panel + +## 0.2.3 + +### Features/Changes + +- [#1655](https://github.com/lapce/lapce/pull/1655): Add status foreground theme key, use author colour for plugin version +- [#1646](https://github.com/lapce/lapce/pull/1646): Fork the process when started from terminal +- [#1653](https://github.com/lapce/lapce/pull/1653): Paint plugin icons +- [#1644](https://github.com/lapce/lapce/pull/1644): Added "Reveal in File Tree" action to the editor tabs context menu +- [#1645](https://github.com/lapce/lapce/pull/1645): Add plugin search + +### Bug Fixes + +- [#1651](https://github.com/lapce/lapce/pull/1651): Fixed an issue where new windows would never be created after closing all windows on macOS. +- [#1637](https://github.com/lapce/lapce/issues/1637): Fix python using 7 spaces instead of 4 spaces to indent +- [#1669](https://github.com/lapce/lapce/issues/1669): It will now remember panel states when open a new project +- [#1706](https://github.com/lapce/lapce/issues/1706): Fix the issue that color can't be changed in theme settings + +## 0.2.2 + +### Features/Changes + +- [#1643](https://github.com/lapce/lapce/pull/1643): Use https://plugins.lapce.dev/ as the plugin registry +- [#1620](https://github.com/lapce/lapce/pull/1620): Added "Show Hover" keybinding that will trigger the hover at the cursor location +- [#1619](https://github.com/lapce/lapce/pull/1619): + - Add active/inactive tab colours + - Add primary button colour + - Add hover effect in source control panel + - Add colour preview in settings +- [#1617](https://github.com/lapce/lapce/pull/1617): Fixed a stack overflow that would crash lapce when attempting to sort a large number of PaletteItems +- [#1609](https://github.com/lapce/lapce/pull/1609): Add syntax highlighting for erlang +- [#1590](https://github.com/lapce/lapce/pull/1590): Added ability to open file and file diff from source control context menu +- [#1570](https://github.com/lapce/lapce/pull/1570): Added a basic tab context menu with common close actions +- [#1560](https://github.com/lapce/lapce/pull/1560): Added ability to copy active editor remote file path to clipboard +- [#1510](https://github.com/lapce/lapce/pull/1510): Added support to discard changes to a file +- [#1459](https://github.com/lapce/lapce/pull/1459): Implement icon theme system + - **This is a breaking change for colour themes!** + - Colour themes should now use `[color-theme]` table format in theme TOML + - `volt.toml` now use `color-themes` and `icon-themes` keys. `themes` key is not used anymore. +- [#1554](https://github.com/lapce/lapce/pull/1554): Added XML language support +- [#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 +- [#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 +- [#1452](https://github.com/lapce/lapce/pull/1452): Wrap selected text with brackets/quotes +- [#1421](https://github.com/lapce/lapce/pull/1421): Add matching bracket highlighting +- [#1541](https://github.com/lapce/lapce/pull/1541): Order palette items according to last execute time + +### Bug Fixes + +- [#1566](https://github.com/lapce/lapce/pull/1565)|[#1568](https://github.com/lapce/lapce/pull/1568): Use separate colour for drag and drop background +- [#1459](https://github.com/lapce/lapce/pull/1459): Fix opening currently used logfile +- [#1505](https://github.com/lapce/lapce/pull/1505): Fix proxy download for hosts with curl without -Z flag +- [#1483](https://github.com/lapce/lapce/pull/1483): Fix showing the close icon for the first tab when opening multiple tab +- [#1477](https://github.com/lapce/lapce/pull/1477): Now use `esc` to close searchbar regarless of the current focus +- [#1507](https://github.com/lapce/lapce/pull/1507): Fixed a crash when scratch buffer is closed +- [#1547](https://github.com/lapce/lapce/pull/1547): Fix infinite cycle in workspace symbol search +- [#1628](https://github.com/lapce/lapce/pull/1541): Fix kts files not being recognized + +## 0.2.1 + +### Features/Changes + +- [#1050](https://github.com/lapce/lapce/pull/1050): Collapse groups of problems in the problem list panel +- [#1165](https://github.com/lapce/lapce/pull/1165): Command to reveal item in system file explorer +- [#1196](https://github.com/lapce/lapce/pull/1196): Always show close button on focused editor tabs +- [#1208](https://github.com/lapce/lapce/pull/1208): Sticky header breadcrumbs + - This provides a header at the top which tells you information about the current scope! Especially useful for long blocks of code + - ![image](https://user-images.githubusercontent.com/13157904/195404556-2c329ebb-f721-4d55-aa22-56a54f8e8454.png) + - As well, you can see that there is now a breadcrumb path to the current file. + - A language with syntax highlighting can have this added, even without an LSP. Take a look at `language.rs` if your language isn't supported! +- [#1198](https://github.com/lapce/lapce/pull/1198): Focus current theme/language in palette +- [#1244](https://github.com/lapce/lapce/pull/1244); Prettier plugin panel +- [#1238](https://github.com/lapce/lapce/pull/1238): Improved multicursor selection +- [#1291](https://github.com/lapce/lapce/pull/1291): Use link colour for empty editor buttons +- [#1234](https://github.com/lapce/lapce/commit/07390f0c90c0700d1f69409bf48723d15090c474): Automatic line height +- [#1262](https://github.com/lapce/lapce/pull/1262): Add absolute/relative copy path to file explorer +- [#1284](https://github.com/lapce/lapce/pull/1284): Render whitespace (default: none) + - ![image](https://user-images.githubusercontent.com/13157904/195410868-f27db85f-d7d2-4197-84f0-12d6c44e2053.png) +- [#1308](https://github.com/lapce/lapce/pull/1308): Handle LSP ResourceOp +- [#1251](https://github.com/lapce/lapce/pull/1251): Add vim's paste-before `P` command +- [#1319](https://github.com/lapce/lapce/pull/1319): Add information page for plugins +- [#1344](https://github.com/lapce/lapce/pull/1344): Replace the branch-selector menu with a scrollable list +- [#1352](https://github.com/lapce/lapce/pull/1352): Add duplicate line up/down commands +- [#1281](https://github.com/lapce/lapce/pull/1281): Implement logic for displaying plugin installation status +- [#1353](https://github.com/lapce/lapce/pull/1353): Implement syntax aware selection +- [#1358](https://github.com/lapce/lapce/pull/1358): Add autosave implementation +- [#1381](https://github.com/lapce/lapce/pull/1381): Show multiple hover items in the hover box +- [#1040](https://github.com/lapce/lapce/pull/1040): Add keybindings for `Shift-Del`, `Shift-Ins`, and `Ctrl-Ins` +- [#1401](https://github.com/lapce/lapce/pull/1401): Merge semantic and tree-sitter syntax highlighting +- [#1426](https://github.com/lapce/lapce/pull/1426): Add cursor position/current selection in status bar + - ![image](https://user-images.githubusercontent.com/13157904/195414557-dbf6cff1-3ab2-49ec-ba9d-c7507b2fc83a.png) +- [#1420](https://github.com/lapce/lapce/pull/1420): Add LSP `codeAction/resolve` support +- [#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 +- [#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 + +- [#957](https://github.com/lapce/lapce/pull/957): Replace existing tree-sitter syntax highlighting code with part of Helix's better implementation + - This means that syntax highlighting for more languages! Such as fixing markdown support, and making so that languages embedded in others (like JavaScript in HTML) work. + - Note that not all themes have updated themselves to include the extra scopes/colors. +- [#1036](https://github.com/lapce/lapce/pull/1036): Recognize ESM/CJS extensions for JavaScript/TypeScript +- [#1007](https://github.com/lapce/lapce/pull/1007): Add ability to bind a key shortcut for quitting the editor +- [#1104](https://github.com/lapce/lapce/pull/1104): Add syntax highlighting for Dockerfile, C#, and Nix +- [#1118](https://github.com/lapce/lapce/pull/1118): Recognize `pyi, pyc, pyd, pyw` extensions for Python +- [#1122](https://github.com/lapce/lapce/pull/1122): Recognize extensions for DLang +- [#1335](https://github.com/lapce/lapce/pull/1335): Highlighting for DLang +- [#1153](https://github.com/lapce/lapce/pull/1050): Recognize and add highlighting for Dart +- [#1161](https://github.com/lapce/lapce/pull/1161): Recognize and add highlighting for Svelte and LaTeX files +- [#1299](https://github.com/lapce/lapce/pull/1299): Recognize and add highlighting for Kotlin +- [#1326](https://github.com/lapce/lapce/pull/1326): Recognize and add highlighting for Vue +- [#1370](https://github.com/lapce/lapce/pull/1370): Recognize and add highlighting for R +- [#1416](https://github.com/lapce/lapce/pull/1416): Recognize and add highlighting for Scheme +- [#1145](https://github.com/lapce/lapce/pull/1145): Adds/Fixes highlighting for C/C++/TypeScript/JavaScript/Zig/Bash +- [#1272](https://github.com/lapce/lapce/pull/1272): Adds/Fixes highlighting for Elm/JSX/TSX +- [#1450](https://github.com/lapce/lapce/pull/1450): Add `tf` extension for HCL + +### Bug Fixes + +- [#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 +- [#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 +- [#1179](https://github.com/lapce/lapce/pull/1179): Various improvements/fixes to window-tab functionality +- [#1210](https://github.com/lapce/lapce/pull/1210): Fixed closing modified file when closing split +- [#1219](https://github.com/lapce/lapce/pull/1219): Fix append command behavior +- [#1250](https://github.com/lapce/lapce/pull/1250): Fix too long socket path for proxy +- [#1252](https://github.com/lapce/lapce/pull/1252): Check whether the active editor tab index actually exists, avoiding a potential crash +- [#1294](https://github.com/lapce/lapce/pull/1294): Backward word deletion should respect whitespace better +- [#1301](https://github.com/lapce/lapce/pull/1301): Fix incorrect path when going from Url -> PathBuf (such as from an LSP) +- [#1368](https://github.com/lapce/lapce/pull/1368): Fix tabstop for postfix completions +- [#1388](https://github.com/lapce/lapce/pull/1388): Fix regex search within the terminal +- [#1423](https://github.com/lapce/lapce/pull/1423): Fix multiple cursor offset after inserting opening pair +- [#1434](https://github.com/lapce/lapce/pull/1434): Join PATH with correct platform separator +- [#1443](https://github.com/lapce/lapce/pull/1443): Correct terminal font sizing +- [#1453](https://github.com/lapce/lapce/pull/1453): Trim whitespace from search results +- [#1461](https://github.com/lapce/lapce/pull/1461): Load shell environment when launching from GUI +- Many more fixes! + +### Other + +- [#1191](https://github.com/lapce/lapce/pull/1191): Tone down default inlay hint background color in Lapce 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 447f51bd91..59f4b5f963 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,6 +22,8 @@ If you encounter a bug when using Lapce, check the issues to see if anyone else 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). +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. + We are currently in the process of improving the documentation for new developers/code contributors. Feel free to get started, or post a message on [Discord](https://discord.gg/n8tGJ6Rn6D) to see what can be done. ## Contact diff --git a/Cargo.lock b/Cargo.lock index c9acaa7a30..f8a6af8049 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,9 +14,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd" +checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" dependencies = [ "gimli", ] @@ -27,12 +27,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "adler32" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" - [[package]] name = "ahash" version = "0.7.6" @@ -46,18 +40,29 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.18" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" dependencies = [ "memchr", ] [[package]] -name = "alacritty_config_derive" +name = "alacritty_config" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77044c45bdb871e501b5789ad16293ecb619e5733b60f4bb01d1cb31c463c336" +checksum = "b0c9edf2a6899fc12e9f8718485fa70f2c311bc86c25ff329783b16de7227dfd" +dependencies = [ + "log 0.4.17", + "serde", + "serde_yaml", +] + +[[package]] +name = "alacritty_config_derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37164df1dc70b36db94e2df45b121c1f57b2946778d5f7e56f4b0d1c118e1b54" dependencies = [ "proc-macro2", "quote", @@ -66,24 +71,25 @@ dependencies = [ [[package]] name = "alacritty_terminal" -version = "0.16.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02fb5d4af84e39f9754d039ff6de2233c8996dbae0af74910156e559e5766e2f" +checksum = "043d0bc52432b59149ca25e45ea617cc4cfd2e34acc00d2f7ea976b9934be477" dependencies = [ + "alacritty_config", "alacritty_config_derive", - "base64", + "base64 0.13.0", "bitflags", "dirs", "libc", - "log", + "log 0.4.17", "mio 0.6.23", "mio-anonymous-pipes", "mio-extras", "miow 0.3.7", "nix", - "parking_lot", + "parking_lot 0.12.1", "regex-automata", - "serde 1.0.130", + "serde", "serde_yaml", "signal-hook", "signal-hook-mio", @@ -92,6 +98,21 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "ambient-authority" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec8ad6edb4840b78c5c3d88de606b22252d552b55f3a4699fbb10fc070ec3049" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "ansi_term" version = "0.12.1" @@ -103,9 +124,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.43" +version = "1.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" + +[[package]] +name = "arc-swap" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" +checksum = "983cd8b9d4b02a6dc6ffa557262eb5858a27a0038ffffe21a0f133eaa819a164" [[package]] name = "arrayref" @@ -125,6 +152,34 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +[[package]] +name = "async-channel" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14485364214912d3b19cc3435dde4df66065127f05fa0d75c712f36f12c2f28" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-task" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" + +[[package]] +name = "async-trait" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "atk" version = "0.14.0" @@ -149,32 +204,53 @@ dependencies = [ "system-deps", ] +[[package]] +name = "atomic-waker" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi 0.3.9", +] + [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.61" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01" +checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" dependencies = [ "addr2line", "cc", "cfg-if 1.0.0", "libc", - "miniz_oxide 0.4.4", - "object 0.26.2", + "miniz_oxide", + "object", "rustc-demangle", ] [[package]] -name = "base-x" -version = "0.2.8" +name = "base64" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b" +checksum = "7c4a342b450b268e1be8036311e2c613d7f8a7ed31214dff1cc3b60852a3168d" +dependencies = [ + "byteorder", + "safemem", +] [[package]] name = "base64" @@ -183,10 +259,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] -name = "bit-vec" -version = "0.5.1" +name = "bincode" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] [[package]] name = "bit_field" @@ -225,63 +304,65 @@ dependencies = [ ] [[package]] -name = "bstr" -version = "0.2.17" +name = "block-buffer" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" dependencies = [ - "lazy_static", - "memchr", - "regex-automata", + "generic-array", ] [[package]] -name = "bumpalo" -version = "3.7.0" +name = "blocking" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" +checksum = "c6ccb65d468978a086b69884437ded69a90faab3bbe6e67f242173ea728acccc" +dependencies = [ + "async-channel", + "async-task", + "atomic-waker", + "fastrand", + "futures-lite", + "once_cell", +] [[package]] -name = "bytecheck" -version = "0.6.7" +name = "bstr" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "314889ea31cda264cb7c3d6e6e5c9415a987ecb0e72c17c00d36fbb881d34abe" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" dependencies = [ - "bytecheck_derive", - "ptr_meta", + "lazy_static", + "memchr", + "regex-automata", ] [[package]] -name = "bytecheck_derive" -version = "0.6.7" +name = "bumpalo" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a2b3b92c135dae665a6f760205b89187638e83bed17ef3e44e83c712cf30600" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" [[package]] name = "bytecount" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72feb31ffc86498dacdbd0fcebb56138e7177a8cc5cea4516031d15ae85a742e" +checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" [[package]] name = "bytemuck" -version = "1.8.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e851ca7c24871e7336801608a4797d7376545b6928a10d32d75685687141ead" +checksum = "2f5715e491b5a1598fc2bef5a606847b5dc1d48ea625bd3c02c00de8285591da" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.0.1" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e215f8c2f9f79cb53c8335e687ffd07d5bfcb6fe5fc80723762d0be46e7cc54" +checksum = "1b9e1f5fa78f69496407a27ae9ed989e3c3b072310286f5ef385525e4cbc24a9" dependencies = [ "proc-macro2", "quote", @@ -296,9 +377,15 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" + +[[package]] +name = "cache-padded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" [[package]] name = "cairo-rs" @@ -324,11 +411,76 @@ dependencies = [ "system-deps", ] +[[package]] +name = "cap-fs-ext" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "438ca7f5bb15c799ea146429e4f8b7bfd25ff1eb05319024549a7728de45800c" +dependencies = [ + "cap-primitives", + "cap-std", + "io-lifetimes", + "windows-sys", +] + +[[package]] +name = "cap-primitives" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba063daa90ed40882bb288ac4ecaa942d655d15cf74393d41d2267b5d7daf120" +dependencies = [ + "ambient-authority", + "fs-set-times", + "io-extras", + "io-lifetimes", + "ipnet", + "maybe-owned", + "rustix", + "winapi-util", + "windows-sys", + "winx", +] + +[[package]] +name = "cap-rand" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c720808e249f0ae846ec647fe48cef3cea67e4e5026cf869c041c278b7dcae45" +dependencies = [ + "ambient-authority", + "rand", +] + +[[package]] +name = "cap-std" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e3a603c9f3bd2181ed128ab3cd32fbde7cff76afc64a3576662701c4aee7e2b" +dependencies = [ + "cap-primitives", + "io-extras", + "io-lifetimes", + "ipnet", + "rustix", +] + +[[package]] +name = "cap-time-ext" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da76e64f3e46f8c8479e392a7fe3faa2e76b8c1cea4618bae445276fdec12082" +dependencies = [ + "cap-primitives", + "once_cell", + "rustix", + "winx", +] + [[package]] name = "cc" -version = "1.0.69" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" dependencies = [ "jobserver", ] @@ -365,22 +517,63 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.19" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" dependencies = [ - "libc", + "iana-time-zone", + "js-sys", "num-integer", - "num-traits 0.2.14", + "num-traits", "time 0.1.44", + "wasm-bindgen", "winapi 0.3.9", ] +[[package]] +name = "clap" +version = "3.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750" +dependencies = [ + "atty", + "bitflags", + "clap_derive", + "clap_lex", + "indexmap", + "once_cell", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap_derive" +version = "3.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" +dependencies = [ + "heck 0.4.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "cmake" -version = "0.1.45" +version = "0.1.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb6210b637171dfba4cda12e579ac6dc73f5165ad56133e5d72ef3131f320855" +checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a" dependencies = [ "cc", ] @@ -422,29 +615,46 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "concurrent-queue" +version = "1.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af4780a44ab5696ea9e28294517f1fffb421a83a25af521333c838635509db9c" +dependencies = [ + "cache-padded", +] + [[package]] name = "config" -version = "0.11.0" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1b9d958c2b1368a663f05538fc1b5975adce1e19f435acceae987aceeeb369" +checksum = "11f1667b8320afa80d69d8bbe40830df2c8a06003d86f73d8e003b2c48df416d" dependencies = [ + "async-trait", "lazy_static", "nom", - "rust-ini", - "serde 1.0.130", - "serde-hjson", - "serde_json", + "pathdiff", + "serde", "toml", - "yaml-rust", ] [[package]] name = "console_error_panic_hook" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "wasm-bindgen", ] @@ -454,17 +664,11 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed3d0b5ff30645a68f35ece8cea4556ca14ef8a1651455f789a099a0513532a6" -[[package]] -name = "const_fn" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92cfa0fd5690b3cf8c1ef2cabbd9b7ef22fa53cf5e1f92b05103f6d5d1cf6e7" - [[package]] name = "core-foundation" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ "core-foundation-sys", "libc", @@ -472,15 +676,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "core-graphics" -version = "0.22.2" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "269f35f69b542b80e736a20a89a05215c0ce80c2c03c514abb2e318b78379d86" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" dependencies = [ "bitflags", "core-foundation", @@ -513,89 +717,136 @@ dependencies = [ "libc", ] +[[package]] +name = "cpp_demangle" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eeaa953eaad386a53111e47172c2fedba671e5684c8dd601a5f474f4f118710f" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "cpufeatures" -version = "0.2.1" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" dependencies = [ "libc", ] [[package]] name = "cranelift-bforest" -version = "0.76.0" +version = "0.88.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e6bea67967505247f54fa2c85cf4f6e0e31c4e5692c9b70e4ae58e339067333" +checksum = "52056f6d0584484b57fa6c1a65c1fcb15f3780d8b6a758426d9e3084169b2ddd" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.76.0" +version = "0.88.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48194035d2752bdd5bdae429e3ab88676e95f52a2b1355a5d4e809f9e39b1d74" +checksum = "18fed94c8770dc25d01154c3ffa64ed0b3ba9d583736f305fed7beebe5d9cf74" dependencies = [ + "arrayvec 0.7.2", + "bumpalo", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", "cranelift-entity", + "cranelift-isle", "gimli", - "log", - "regalloc", + "log 0.4.17", + "regalloc2", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.76.0" +version = "0.88.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976efb22fcab4f2cd6bd4e9913764616a54d895c1a23530128d04e03633c555f" +checksum = "1c451b81faf237d11c7e4f3165eeb6bac61112762c5cfe7b4c0fb7241474358f" dependencies = [ "cranelift-codegen-shared", - "cranelift-entity", ] [[package]] name = "cranelift-codegen-shared" -version = "0.76.0" +version = "0.88.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dabb5fe66e04d4652e434195b45ae65b5c8172d520247b8f66d8df42b2b45dc" +checksum = "e7c940133198426d26128f08be2b40b0bd117b84771fd36798969c4d712d81fc" [[package]] name = "cranelift-entity" -version = "0.76.0" +version = "0.88.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3329733e4d4b8e91c809efcaa4faee80bf66f20164e3dd16d707346bd3494799" +checksum = "87a0f1b2fdc18776956370cf8d9b009ded3f855350c480c1c52142510961f352" +dependencies = [ + "serde", +] [[package]] name = "cranelift-frontend" -version = "0.76.0" +version = "0.88.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "279afcc0d3e651b773f94837c3d581177b348c8d69e928104b2e9fccb226f921" +checksum = "34897538b36b216cc8dd324e73263596d51b8cf610da6498322838b2546baf8a" dependencies = [ "cranelift-codegen", - "log", + "log 0.4.17", "smallvec", "target-lexicon", ] +[[package]] +name = "cranelift-isle" +version = "0.88.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b2629a569fae540f16a76b70afcc87ad7decb38dc28fa6c648ac73b51e78470" + +[[package]] +name = "cranelift-native" +version = "0.88.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20937dab4e14d3e225c5adfc9c7106bafd4ac669bdb43027b911ff794c6fb318" +dependencies = [ + "cranelift-codegen", + "libc", + "target-lexicon", +] + +[[package]] +name = "cranelift-wasm" +version = "0.88.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80fc2288957a94fd342a015811479de1837850924166d1f1856d8406e6f3609b" +dependencies = [ + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "itertools", + "log 0.4.17", + "smallvec", + "wasmparser", + "wasmtime-types", +] + [[package]] name = "crc32fast" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if 1.0.0", ] [[package]] name = "crossbeam-channel" -version = "0.5.1" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" dependencies = [ "cfg-if 1.0.0", "crossbeam-utils", @@ -603,9 +854,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" dependencies = [ "cfg-if 1.0.0", "crossbeam-epoch", @@ -614,32 +865,43 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.5" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" dependencies = [ + "autocfg", "cfg-if 1.0.0", "crossbeam-utils", - "lazy_static", "memoffset", + "once_cell", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.5" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" dependencies = [ "cfg-if 1.0.0", - "lazy_static", + "once_cell", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", ] [[package]] name = "darling" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d720b8683f8dd83c65155f0530560cba68cd2bf395f6513a483caee57ff7f4" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" dependencies = [ "darling_core", "darling_macro", @@ -647,9 +909,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a340f241d2ceed1deb47ae36c4144b2707ec7dd0b649f894cb39bb595986324" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" dependencies = [ "fnv", "ident_case", @@ -661,9 +923,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c41b3b7352feb3211a0d743dc5700a4e3b60f51bd2b368892d1e0f9a95f44b" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ "darling_core", "quote", @@ -672,35 +934,30 @@ dependencies = [ [[package]] name = "data-url" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d33fe99ccedd6e84bc035f1931bb2e6be79739d6242bd895e7311c886c50dc9c" +checksum = "3a30bfce702bcfa94e906ef82421f2c0e61c076ad76030c16ee5d2e9a32fe193" dependencies = [ "matches", ] [[package]] -name = "deflate" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c86f7e25f518f4b81808a2cf1c50996a61f5c2eb394b2393bd87f2a4780a432f" +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "adler32", + "generic-array", ] -[[package]] -name = "diff" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499" - [[package]] name = "digest" -version = "0.9.0" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" dependencies = [ - "generic-array", + "block-buffer 0.10.3", + "crypto-common", ] [[package]] @@ -712,11 +969,21 @@ dependencies = [ "dirs-sys", ] +[[package]] +name = "directories-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" +dependencies = [ + "cfg-if 1.0.0", + "dirs-sys-next", +] + [[package]] name = "dirs" -version = "3.0.2" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" dependencies = [ "dirs-sys", ] @@ -733,9 +1000,9 @@ dependencies = [ [[package]] name = "dirs-sys" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" dependencies = [ "libc", "redox_users", @@ -753,12 +1020,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "discard" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" - [[package]] name = "dlib" version = "0.5.0" @@ -768,10 +1029,20 @@ dependencies = [ "libloading", ] +[[package]] +name = "dmg" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e565b39e64e4030c75320536cc18cd51f0636811c53d98a05f01ec5deb8dd8f" +dependencies = [ + "log 0.3.9", + "plist", +] + [[package]] name = "druid" version = "0.7.0" -source = "git+https://github.com/lapce/druid?branch=shell_opengl#5a8f806121332581114a2628b9dc9937b70e52c2" +source = "git+https://github.com/lapce/druid?branch=shell_opengl#0b9c00fcda238e392e758382f25166cd748fd305" dependencies = [ "console_error_panic_hook", "druid-derive", @@ -783,7 +1054,7 @@ dependencies = [ "im", "instant", "tracing", - "tracing-subscriber 0.3.6", + "tracing-subscriber", "tracing-wasm", "unic-langid", "unicode-segmentation", @@ -794,7 +1065,7 @@ dependencies = [ [[package]] name = "druid-derive" version = "0.4.0" -source = "git+https://github.com/lapce/druid?branch=shell_opengl#5a8f806121332581114a2628b9dc9937b70e52c2" +source = "git+https://github.com/lapce/druid?branch=shell_opengl#0b9c00fcda238e392e758382f25166cd748fd305" dependencies = [ "proc-macro2", "quote", @@ -804,7 +1075,7 @@ dependencies = [ [[package]] name = "druid-shell" version = "0.7.0" -source = "git+https://github.com/lapce/druid?branch=shell_opengl#5a8f806121332581114a2628b9dc9937b70e52c2" +source = "git+https://github.com/lapce/druid?branch=shell_opengl#0b9c00fcda238e392e758382f25166cd748fd305" dependencies = [ "anyhow", "bitflags", @@ -831,7 +1102,7 @@ dependencies = [ "objc", "piet-wgpu", "scopeguard", - "time 0.3.9", + "time 0.3.14", "tracing", "wasm-bindgen", "web-sys", @@ -839,12 +1110,6 @@ dependencies = [ "wio", ] -[[package]] -name = "dtoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" - [[package]] name = "dwrote" version = "0.11.0" @@ -857,17 +1122,23 @@ dependencies = [ "wio", ] +[[package]] +name = "dyn-clone" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9b0705efd4599c15a38151f4721f7bc388306f61084d3bfd50bd07fbca5cb60" + [[package]] name = "either" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" [[package]] name = "encoding_rs" -version = "0.8.30" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" dependencies = [ "cfg-if 1.0.0", ] @@ -882,47 +1153,65 @@ dependencies = [ ] [[package]] -name = "enumset" -version = "1.0.8" +name = "env_logger" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6216d2c19a6fb5f29d1ada1dc7bc4367a8cbf0fa4af5cf12e07b5bbdde6b5b2c" +checksum = "c90bf5f19754d10198ccb95b70664fc925bd1fc090a0fd9a6ebc54acc8cd6272" dependencies = [ - "enumset_derive", + "atty", + "humantime", + "log 0.4.17", + "regex", + "termcolor", ] [[package]] -name = "enumset_derive" -version = "0.5.5" +name = "errno" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6451128aa6655d880755345d085494cf7561a6bee7c8dc821e5d77e6d267ecd4" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn", + "errno-dragonfly", + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", ] [[package]] name = "euclid" -version = "0.22.6" +version = "0.22.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da96828553a086d7b18dcebfc579bd9628b016f86590d7453c115e490fa74b80" +checksum = "b52c2ef4a78da0ba68fbe1fd920627411096d2ac478f7f4c9f3a54ba6705bade" dependencies = [ - "num-traits 0.2.14", + "num-traits", ] +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + [[package]] name = "exr" -version = "1.4.2" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14cc0e06fb5f67e5d6beadf3a382fec9baca1aa751c6d5368fdeee7e5932c215" +checksum = "c9a7880199e74c6d3fe45579df2f436c5913a71405494cb89d59234d86b47dc5" dependencies = [ "bit_field", - "deflate", "flume", "half", - "inflate", "lebe", + "miniz_oxide", "smallvec", "threadpool", ] @@ -935,20 +1224,20 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fastrand" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" dependencies = [ "instant", ] [[package]] name = "fern" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9a4820f0ccc8a7afd67c39a0f1a0f4b07ca1725164271a64939d7aeb9af065" +checksum = "3bdd7b0849075e79ee9a1836df22c717d1eba30451796fdc631b04565dd11e2a" dependencies = [ - "log", + "log 0.4.17", ] [[package]] @@ -958,19 +1247,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" dependencies = [ "memoffset", - "rustc_version 0.3.3", + "rustc_version", +] + +[[package]] +name = "file-per-thread-logger" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21e16290574b39ee41c71aeb90ae960c504ebaf1e2a1c87bd52aa56ed6e1a02f" +dependencies = [ + "env_logger", + "log 0.4.17", ] [[package]] name = "filetime" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" +checksum = "e94a7bbaa59354bc20dd75b67f23e2797b4490e9d6928203fb105c79e448c86c" dependencies = [ "cfg-if 1.0.0", "libc", "redox_syscall", - "winapi 0.3.9", + "windows-sys", ] [[package]] @@ -981,14 +1280,12 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" [[package]] name = "flate2" -version = "1.0.22" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" dependencies = [ - "cfg-if 1.0.0", "crc32fast", - "libc", - "miniz_oxide 0.4.4", + "miniz_oxide", ] [[package]] @@ -1015,21 +1312,21 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fc612c5837986b7104a87a0df74a5460931f1c5274be12f8d0f40aa2f30d632" dependencies = [ - "num-traits 0.2.14", + "num-traits", ] [[package]] name = "fluent-bundle" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acf044eeb4872d9dbf2667541fbf461f5965c57e343878ad0fb24b5793fa007" +checksum = "e242c601dec9711505f6d5bbff5bedd4b61b2469f2e8bb8e57ee7c9747a87ffd" dependencies = [ "fluent-langneg", "fluent-syntax", "intl-memoizer", "intl_pluralrules", - "ouroboros", "rustc-hash", + "self_cell", "smallvec", "unic-langid", ] @@ -1054,9 +1351,9 @@ dependencies = [ [[package]] name = "flume" -version = "0.10.12" +version = "0.10.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843c03199d0c0ca54bc1ea90ac0d507274c28abcc4f691ae8b4eaa375087c76a" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" dependencies = [ "futures-core", "futures-sink", @@ -1087,7 +1384,7 @@ dependencies = [ "freetype", "lazy_static", "libc", - "log", + "log 0.4.17", "pathfinder_geometry", "pathfinder_simd", "walkdir", @@ -1110,7 +1407,7 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e58903f4f8d5b58c7d300908e4ebe5289c1bfdf5587964330f12023b8ff17fd1" dependencies = [ - "log", + "log 0.4.17", "memmap2 0.2.3", "ttf-parser 0.12.3", ] @@ -1122,9 +1419,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "122fa73a5566372f9df09768a16e8e3dad7ad18abe07835f1f0b71f84078ba4c" dependencies = [ "fontconfig-parser", - "log", - "memmap2 0.5.3", - "ttf-parser 0.15.0", + "log 0.4.17", + "memmap2 0.5.7", + "ttf-parser 0.15.2", ] [[package]] @@ -1144,21 +1441,20 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" dependencies = [ - "matches", "percent-encoding", ] [[package]] name = "fount" version = "0.1.0" -source = "git+https://github.com/lapce/fount#bfe215c0f82595361dc2385bed5a8687a41e5dd2" +source = "git+https://github.com/lapce/fount#3bfdc689c0cfbeb498358c79c7be2cb3beb44efe" dependencies = [ "font-kit", - "memmap2 0.5.3", + "memmap2 0.5.7", "swash", ] @@ -1184,33 +1480,31 @@ dependencies = [ ] [[package]] -name = "fs2" -version = "0.4.3" +name = "fs-set-times" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +checksum = "a267b6a9304912e018610d53fe07115d8b530b160e85db4d2d3a59f3ddde1aec" dependencies = [ - "libc", - "winapi 0.3.9", + "io-lifetimes", + "rustix", + "windows-sys", ] [[package]] -name = "fsevent" -version = "0.4.0" +name = "fs2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" dependencies = [ - "bitflags", - "fsevent-sys 2.0.1", + "libc", + "winapi 0.3.9", ] [[package]] -name = "fsevent-sys" -version = "2.0.1" +name = "fs_extra" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" -dependencies = [ - "libc", -] +checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" [[package]] name = "fsevent-sys" @@ -1237,26 +1531,42 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +[[package]] +name = "futures" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f21eda599937fba36daeb58a22e8f5cee2d14c4a17b5b7739c7c8e5e3b8230c" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" dependencies = [ "futures-core", + "futures-sink", ] [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" [[package]] name = "futures-executor" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab" dependencies = [ "futures-core", "futures-task", @@ -1265,30 +1575,59 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" + +[[package]] +name = "futures-lite" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-macro" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" dependencies = [ + "futures-channel", "futures-core", "futures-io", + "futures-macro", + "futures-sink", "futures-task", "memchr", "pin-project-lite", @@ -1372,20 +1711,11 @@ dependencies = [ "system-deps", ] -[[package]] -name = "generational-arena" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d3b771574f62d0548cee0ad9057857e9fc25d7a3335f140c84f6acd0bf601" -dependencies = [ - "cfg-if 0.1.10", -] - [[package]] name = "generic-array" -version = "0.14.4" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" dependencies = [ "typenum", "version_check", @@ -1402,22 +1732,22 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ "cfg-if 1.0.0", "js-sys", "libc", - "wasi 0.10.0+wasi-snapshot-preview1", + "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", ] [[package]] name = "gif" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a7187e78088aead22ceedeee99779455b23fc231fe13ec443f99bb71694e5b" +checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06" dependencies = [ "color_quant", "weezl", @@ -1425,9 +1755,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.25.0" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" +checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" dependencies = [ "fallible-iterator", "indexmap", @@ -1466,14 +1796,14 @@ dependencies = [ [[package]] name = "git2" -version = "0.14.4" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0155506aab710a86160ddb504a480d2964d7ab5b9e62419be69e0032bc5931c" +checksum = "ccf7f68c2995f392c49fffb4f95ae2c873297830eb25c6bc4c114ce8f4562acc" dependencies = [ "bitflags", "libc", "libgit2-sys", - "log", + "log 0.4.17", "openssl-probe", "openssl-sys", "url", @@ -1486,8 +1816,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" dependencies = [ "khronos_api", - "log", - "xml-rs", + "log 0.4.17", + "xml-rs 0.8.4", ] [[package]] @@ -1561,14 +1891,14 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "globset" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" +checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a" dependencies = [ "aho-corasick", "bstr", "fnv", - "log", + "log 0.4.17", "regex", ] @@ -1615,14 +1945,14 @@ dependencies = [ [[package]] name = "grep-regex" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121553c9768c363839b92fc2d7cdbbad44a3b70e8d6e7b1b72b05c977527bd06" +checksum = "1345f8d33c89f2d5b081f2f2a41175adef9fd0bed2fea6a26c96c2deb027e58e" dependencies = [ "aho-corasick", "bstr", "grep-matcher", - "log", + "log 0.4.17", "regex", "regex-syntax", "thread_local", @@ -1630,17 +1960,17 @@ dependencies = [ [[package]] name = "grep-searcher" -version = "0.1.8" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fbdbde90ba52adc240d2deef7b6ad1f99f53142d074b771fe9b7bede6c4c23d" +checksum = "48852bd08f9b4eb3040ecb6d2f4ade224afe880a9a0909c5563cc59fa67932cc" dependencies = [ "bstr", "bytecount", "encoding_rs", "encoding_rs_io", "grep-matcher", - "log", - "memmap2 0.3.1", + "log 0.4.17", + "memmap2 0.5.7", ] [[package]] @@ -1701,9 +2031,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" +checksum = "5ca32592cf21ac7ccab1825cd87f6c9b3d9022c44d086172ed0966bec8af30be" dependencies = [ "bytes", "fnv", @@ -1733,6 +2063,16 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", + "serde", +] + [[package]] name = "heck" version = "0.3.3" @@ -1758,22 +2098,12 @@ dependencies = [ ] [[package]] -name = "home" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654" -dependencies = [ - "winapi 0.3.9", -] - -[[package]] -name = "hotwatch" -version = "0.4.6" +name = "hermit-abi" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39301670a6f5798b75f36a1b149a379a50df5aa7c71be50f4b41ec6eab445cb8" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" dependencies = [ - "log", - "notify 4.0.17", + "libc", ] [[package]] @@ -1784,7 +2114,7 @@ checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ "bytes", "fnv", - "itoa 1.0.2", + "itoa", ] [[package]] @@ -1800,9 +2130,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" @@ -1810,11 +2140,22 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +[[package]] +name = "human-sort" +version = "0.2.2" +source = "git+https://github.com/dragazo/human-sort#1e74db1e09e8194ba88ad983723cf6f8b0c365da" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "hyper" -version = "0.14.19" +version = "0.14.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f" +checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" dependencies = [ "bytes", "futures-channel", @@ -1825,7 +2166,7 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa 1.0.2", + "itoa", "pin-project-lite", "socket2", "tokio", @@ -1847,6 +2188,19 @@ dependencies = [ "tokio-native-tls", ] +[[package]] +name = "iana-time-zone" +version = "0.1.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd911b35d940d2bd0bea0f9100068e5b97b51a1cbe13d13382f132e0365257a0" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "js-sys", + "wasm-bindgen", + "winapi 0.3.9", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -1855,11 +2209,10 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" dependencies = [ - "matches", "unicode-bidi", "unicode-normalization", ] @@ -1873,7 +2226,7 @@ dependencies = [ "crossbeam-utils", "globset", "lazy_static", - "log", + "log 0.4.17", "memchr", "regex", "same-file", @@ -1884,14 +2237,14 @@ dependencies = [ [[package]] name = "im" -version = "15.0.0" +version = "15.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "111c1983f3c5bb72732df25cddacee9b546d08325fb584b5ebd38148be7b0246" +checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" dependencies = [ "bitmaps", "rand_core", "rand_xoshiro", - "serde 1.0.130", + "serde", "sized-chunks", "typenum", "version_check", @@ -1899,9 +2252,9 @@ dependencies = [ [[package]] name = "image" -version = "0.24.2" +version = "0.24.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28edd9d7bc256be2502e325ac0628bde30b7001b9b52e0abe31a1a9dc2701212" +checksum = "bd8e4fb07cf672b1642304e731ef8a6a4c7891d67bb4fd4f5ce58cd6ed86803c" dependencies = [ "bytemuck", "byteorder", @@ -1909,9 +2262,8 @@ dependencies = [ "exr", "gif", "jpeg-decoder", - "num-iter", "num-rational", - "num-traits 0.2.14", + "num-traits", "png", "scoped_threadpool", "tiff", @@ -1919,9 +2271,9 @@ dependencies = [ [[package]] name = "include_dir" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31a924bd335356c7622dff9ee33d06920afcf7f762a1a991236645e08c8a484b" +checksum = "24b56e147e6187d61e9d0f039f10e070d0c0a887e24fe0bb9ca3f29bfde62cab" dependencies = [ "glob", "include_dir_impl", @@ -1930,9 +2282,9 @@ dependencies = [ [[package]] name = "include_dir_impl" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afae3917f781921d7c7813992ccadff7e816f7e6ecb4b70a9ec3e740d51da3d6" +checksum = "0a0c890c85da4bab7bce4204c707396bbd3c6c8a681716a51c8814cfc2b682df" dependencies = [ "anyhow", "proc-macro-hack", @@ -1943,33 +2295,13 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.7.0" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", - "hashbrown", - "serde 1.0.130", -] - -[[package]] -name = "inflate" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff" -dependencies = [ - "adler32", -] - -[[package]] -name = "inotify" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f" -dependencies = [ - "bitflags", - "inotify-sys", - "libc", + "hashbrown 0.12.3", + "serde", ] [[package]] @@ -1994,9 +2326,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -2004,6 +2336,23 @@ dependencies = [ "web-sys", ] +[[package]] +name = "interprocess" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c58ec7fbda1df9a93f587b780659db3c99f61f4be27f9c82c9b37684ffd0366" +dependencies = [ + "blocking", + "cfg-if 1.0.0", + "futures", + "intmap", + "libc", + "once_cell", + "spinning", + "thiserror", + "winapi 0.3.9", +] + [[package]] name = "intl-memoizer" version = "0.5.1" @@ -2024,6 +2373,32 @@ dependencies = [ "unic-langid", ] +[[package]] +name = "intmap" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae52f28f45ac2bc96edb7714de995cffc174a395fb0abf5bff453587c980d7b9" + +[[package]] +name = "io-extras" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5d8c2ab5becd8720e30fd25f8fa5500d8dc3fceadd8378f05859bd7b46fc49" +dependencies = [ + "io-lifetimes", + "windows-sys", +] + +[[package]] +name = "io-lifetimes" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ea37f355c05dde75b84bba2d767906ad522e97cd9e2eef2be7a4ab7fb442c06" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "iovec" version = "0.1.4" @@ -2040,60 +2415,86 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" [[package]] -name = "itertools" -version = "0.10.3" +name = "is-terminal" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +checksum = "0d508111813f9af3afd2f92758f77e4ed2cc9371b642112c6a48d22eb73105c5" dependencies = [ - "either", + "hermit-abi 0.2.6", + "io-lifetimes", + "rustix", + "windows-sys", ] [[package]] -name = "itoa" -version = "0.4.8" +name = "itertools" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] [[package]] name = "itoa" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" + +[[package]] +name = "ittapi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c4f6ff06169ce7048dac5150b1501c7e3716a929721aeb06b87e51a43e42f4" +dependencies = [ + "anyhow", + "ittapi-sys", + "log 0.4.17", +] + +[[package]] +name = "ittapi-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e078cce01485f418bae3beb34dd604aaedf2065502853c7da17fbce8e64eda" +dependencies = [ + "cc", +] [[package]] name = "jobserver" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" +checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" dependencies = [ "libc", ] [[package]] name = "jpeg-decoder" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744c24117572563a98a7e9168a5ac1ee4a1ca7f702211258797bbe0ed0346c3c" +checksum = "9478aa10f73e7528198d75109c8be5cd7d15fb530238040148d5f9a22d4c5b3b" dependencies = [ "rayon", ] [[package]] name = "js-sys" -version = "0.3.53" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4bf49d50e2961077d9c99f4b7997d770a1114f087c3c2e0069b36c13fc2979d" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" dependencies = [ "wasm-bindgen", ] [[package]] name = "jsonrpc-lite" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a98d245f26984add78277a5306ca0cf774863d4eddb4912b31d94ee3fa1a22d4" +checksum = "bb4128aba82294c14af2998831c4df3c843940e92b5cfc41bac1229d1e63b88c" dependencies = [ - "serde 1.0.130", + "serde", "serde_derive", "serde_json", ] @@ -2125,9 +2526,9 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" [[package]] name = "kqueue" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "058a107a784f8be94c7d35c1300f4facced2e93d2fbe5b1452b44e905ddca4a9" +checksum = "4d6112e8f37b59803ac47a42d14f1f3a59bbf72fc6857ffc5be455e28a691f8e" dependencies = [ "kqueue-sys", "libc", @@ -2150,12 +2551,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a53776d271cfb873b17c618af0298445c88afc52837f3e948fa3fafd131f449" dependencies = [ "arrayvec 0.7.2", - "serde 1.0.130", + "serde", ] [[package]] name = "lapce" -version = "0.1.2" +version = "0.2.6" dependencies = [ "lapce-proxy", "lapce-ui", @@ -2163,200 +2564,246 @@ dependencies = [ [[package]] name = "lapce-core" -version = "0.1.2" +version = "0.2.6" dependencies = [ + "anyhow", + "arc-swap", "bitflags", + "directories", "itertools", "lapce-rpc", - "log", + "lapce-xi-rope", + "log 0.4.17", "lsp-types", - "serde 1.0.130", - "serde_json", - "strum 0.24.0", - "strum_macros 0.24.0", + "once_cell", + "serde", + "slotmap", + "strum", + "strum_macros", "thiserror", "tree-sitter", + "tree-sitter-bash", "tree-sitter-c", + "tree-sitter-c-sharp", + "tree-sitter-clojure", + "tree-sitter-cmake", "tree-sitter-cpp", + "tree-sitter-css", + "tree-sitter-d", + "tree-sitter-dart", + "tree-sitter-dockerfile", "tree-sitter-elixir", "tree-sitter-elm", + "tree-sitter-erlang", "tree-sitter-glimmer", + "tree-sitter-glsl", "tree-sitter-go", + "tree-sitter-hare", "tree-sitter-haskell", "tree-sitter-haxe", "tree-sitter-hcl", - "tree-sitter-highlight", "tree-sitter-html", "tree-sitter-java", "tree-sitter-javascript", "tree-sitter-json", + "tree-sitter-julia", + "tree-sitter-kotlin", + "tree-sitter-latex", + "tree-sitter-lua", "tree-sitter-md", + "tree-sitter-nix", "tree-sitter-ocaml", "tree-sitter-php", + "tree-sitter-prisma-io", + "tree-sitter-protobuf", "tree-sitter-python", "tree-sitter-ql", + "tree-sitter-r", "tree-sitter-ruby", "tree-sitter-rust", + "tree-sitter-scheme", "tree-sitter-scss", + "tree-sitter-sql", + "tree-sitter-svelte", "tree-sitter-swift", "tree-sitter-toml", "tree-sitter-typescript", - "xi-rope", + "tree-sitter-vue", + "tree-sitter-wgsl", + "tree-sitter-xml", + "tree-sitter-yaml", + "tree-sitter-zig", ] [[package]] name = "lapce-data" -version = "0.1.2" +version = "0.2.6" dependencies = [ - "Inflector", "alacritty_terminal", "anyhow", - "base64", - "bit-vec", - "bitflags", "bytemuck", "chrono", + "clap", "config", "crossbeam-channel", - "crossbeam-utils", - "diff", "directories", + "dmg", "druid", - "fern", "flate2", + "fs_extra", "fuzzy-matcher", - "hashbrown", + "hashbrown 0.12.3", "im", "include_dir", "indexmap", + "interprocess", "itertools", - "jsonrpc-lite", "lapce-core", "lapce-proxy", "lapce-rpc", - "lazy_static", - "libloading", - "log", + "lapce-xi-rope", + "log 0.4.17", "lsp-types", - "notify 5.0.0-pre.15", - "parking_lot", + "notify", + "once_cell", + "parking_lot 0.11.2", "pulldown-cmark", "rayon", "regex", "reqwest", - "serde 1.0.130", + "serde", "serde_json", + "sha2 0.10.6", "sled", + "smallvec", "structdesc", - "strum 0.24.0", - "strum_macros 0.24.0", + "strum", + "strum_macros", + "tar", "thiserror", - "toml", - "unicode-segmentation", - "unicode-width", + "toml_edit", + "url", "uuid", - "xi-rope", - "xi-unicode", + "zip", ] [[package]] name = "lapce-proxy" -version = "0.1.2" +version = "0.2.6" dependencies = [ "alacritty_terminal", "anyhow", - "base64", + "clap", + "cocoa", "crossbeam-channel", "directories", + "dyn-clone", + "flate2", "git2", + "globset", "grep-matcher", "grep-regex", "grep-searcher", - "home", - "hotwatch", "ignore", + "indexmap", + "interprocess", "jsonrpc-lite", + "lapce-core", "lapce-rpc", + "lapce-xi-rope", + "libc", "locale_config", + "log 0.4.17", "lsp-types", "mio 0.6.23", - "notify 5.0.0-pre.15", - "parking_lot", + "notify", + "objc", + "once_cell", + "parking_lot 0.11.2", + "psp-types", "regex", "reqwest", - "serde 1.0.130", + "serde", "serde_json", - "toml", - "wasmer", - "wasmer-wasi", + "strum", + "strum_macros", + "tar", + "toml_edit", + "trash", + "url", + "walkdir", + "wasi-common", + "wasi-experimental-http-wasmtime", + "wasmtime", + "wasmtime-wasi", "which", - "xi-rope", + "zstd", ] [[package]] name = "lapce-rpc" -version = "0.1.2" +version = "0.2.6" dependencies = [ "anyhow", "crossbeam-channel", - "jsonrpc-lite", + "human-sort", + "indexmap", + "lapce-xi-rope", + "log 0.4.17", "lsp-types", - "notify 5.0.0-pre.15", - "parking_lot", - "serde 1.0.130", + "parking_lot 0.11.2", + "serde", "serde_json", - "xi-rope", ] [[package]] name = "lapce-ui" -version = "0.1.2" +version = "0.2.6" dependencies = [ "Inflector", "alacritty_terminal", "anyhow", - "base64", - "bit-vec", "chrono", - "config", - "crossbeam-channel", - "crossbeam-utils", - "diff", - "directories", + "clap", "druid", "fern", - "flate2", - "fuzzy-matcher", - "hashbrown", + "hashbrown 0.12.3", "im", "image", "include_dir", "indexmap", "itertools", - "jsonrpc-lite", "lapce-core", "lapce-data", + "lapce-proxy", "lapce-rpc", - "lazy_static", - "libloading", - "log", + "lapce-xi-rope", + "log 0.4.17", + "log-panics", "lsp-types", - "notify 5.0.0-pre.15", - "parking_lot", + "once_cell", + "open", "rayon", "regex", - "serde 1.0.130", + "serde", "serde_json", - "sled", - "structdesc", - "strum 0.24.0", - "strum_macros 0.24.0", - "toml", - "unicode-segmentation", + "smallvec", + "toml_edit", "unicode-width", "winres", - "xi-rope", - "xi-unicode", +] + +[[package]] +name = "lapce-xi-rope" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08ae23edb8cf91f01edd9a87c88623eae3977c8d647a31c57cb12f1a125ca10a" +dependencies = [ + "bytecount", + "memchr", + "regex", + "serde", + "unicode-segmentation", ] [[package]] @@ -2379,34 +2826,21 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "lebe" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7efd1d698db0759e6ef11a7cd44407407399a910c774dd804c64c032da7826ff" - -[[package]] -name = "lexical-core" -version = "0.7.6" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" -dependencies = [ - "arrayvec 0.5.2", - "bitflags", - "cfg-if 1.0.0", - "ryu", - "static_assertions", -] +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "libc" -version = "0.2.121" +version = "0.2.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f" +checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966" [[package]] name = "libgit2-sys" -version = "0.13.4+1.4.2" +version = "0.14.2+1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0fa6563431ede25f5cc7f6d803c6afbc1c5d3ad3d4925d12c882bf2b526f5d1" +checksum = "7f3d95f6b51075fe9810a7ae22c7095f12b98005ab364d8544797a825ce946a4" dependencies = [ "cc", "libc", @@ -2418,9 +2852,9 @@ dependencies = [ [[package]] name = "libloading" -version = "0.7.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a" +checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" dependencies = [ "cfg-if 1.0.0", "winapi 0.3.9", @@ -2428,9 +2862,9 @@ dependencies = [ [[package]] name = "libssh2-sys" -version = "0.2.21" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0186af0d8f171ae6b9c4c90ec51898bad5d08a2d5e470903a50d9ad8959cbee" +checksum = "b094a36eb4b8b8c8a7b4b8ae43b2944502be3e59cd87687595cf6b0a71b3f4ca" dependencies = [ "cc", "libc", @@ -2442,9 +2876,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.3" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de5435b8549c16d423ed0c03dbaafe57cf6c3344744f1242520d59c9d8ecec66" +checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" dependencies = [ "cc", "libc", @@ -2454,9 +2888,15 @@ dependencies = [ [[package]] name = "linked-hash-map" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.0.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d" [[package]] name = "locale_config" @@ -2473,51 +2913,51 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.5" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" dependencies = [ + "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.14" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" dependencies = [ - "cfg-if 1.0.0", + "log 0.4.17", ] [[package]] -name = "loupe" -version = "0.1.3" +name = "log" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ - "indexmap", - "loupe-derive", - "rustversion", + "cfg-if 1.0.0", + "serde", ] [[package]] -name = "loupe-derive" -version = "0.1.3" +name = "log-panics" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" +checksum = "68f9dd8546191c1850ecf67d22f5ff00a935b890d0e84713159a55495cc2ac5f" dependencies = [ - "quote", - "syn", + "backtrace", + "log 0.4.17", ] [[package]] name = "lsp-types" -version = "0.89.2" +version = "0.93.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852e0dedfd52cc32325598b2631e0eba31b7b708959676a9f837042f276b09a2" +checksum = "a3bcfee315dde785ba887edb540b08765fd7df75a7d948844be6bf5712246734" dependencies = [ "bitflags", - "serde 1.0.130", + "serde", "serde_json", "serde_repr", "url", @@ -2525,9 +2965,9 @@ dependencies = [ [[package]] name = "lyon" -version = "0.17.5" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a146a460c58fb5361fc7faf8d7a68b274f11969ee1f6856875c162d679d0306" +checksum = "cf0510ed5e3e2fb80f3db2061ef5ca92d87bfda1a624bb1eacf3bd50226e4cbb" dependencies = [ "lyon_algorithms", "lyon_tessellation", @@ -2535,9 +2975,9 @@ dependencies = [ [[package]] name = "lyon_algorithms" -version = "0.17.5" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea1ebc5107076627bc9e402b09d11ba8ca68e06e3053b923bce9570ef70bf960" +checksum = "8037f716541ba0d84d3de05c0069f8068baf73990d55980558b84d944c8a244a" dependencies = [ "lyon_path", "sid", @@ -2545,34 +2985,32 @@ dependencies = [ [[package]] name = "lyon_geom" -version = "0.17.5" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe153a6ce93cb97c85ba47a007fd437079bbff5592b9c0f77195973b8b169d69" +checksum = "71d89ccbdafd83d259403e22061be27bccc3254bba65cdc5303250c4227c8c8e" dependencies = [ "arrayvec 0.5.2", "euclid", - "num-traits 0.2.14", + "num-traits", ] [[package]] name = "lyon_path" -version = "0.17.6" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ef7433accd4515fc98f59bb3cdf565a9615f0c666f50bfcb96134bbd91ccc04" +checksum = "5b0a59fdf767ca0d887aa61d1b48d4bbf6a124c1a45503593f7d38ab945bfbc0" dependencies = [ "lyon_geom", ] [[package]] name = "lyon_tessellation" -version = "0.17.9" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56799e28a041fa98b0865a93d2e19f64de3c8f2708bfe96b8af5c7d491aef468" +checksum = "7230e08dd0638048e46f387f255dbe7a7344a3e6705beab53242b5af25635760" dependencies = [ - "arrayvec 0.5.2", "float_next_after", "lyon_path", - "sid", ] [[package]] @@ -2599,44 +3037,50 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" +[[package]] +name = "maybe-owned" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4facc753ae494aeb6e3c22f839b158aebd4f9270f55cd3c79906c45476c47ab4" + [[package]] name = "memchr" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] -name = "memmap2" -version = "0.2.3" +name = "memfd" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "723e3ebdcdc5c023db1df315364573789f8857c11b631a2fdfad7c00f5c046b4" +checksum = "480b5a5de855d11ff13195950bdc8b98b5e942ef47afc447f6615cdcc4e15d80" dependencies = [ - "libc", + "rustix", ] [[package]] name = "memmap2" -version = "0.3.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b6c2ebff6180198788f5db08d7ce3bc1d0b617176678831a7510825973e357" +checksum = "723e3ebdcdc5c023db1df315364573789f8857c11b631a2fdfad7c00f5c046b4" dependencies = [ "libc", ] [[package]] name = "memmap2" -version = "0.5.3" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057a3db23999c867821a7a59feb06a578fcb03685e983dff90daf9e7d24ac08f" +checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498" dependencies = [ "libc", ] [[package]] name = "memoffset" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ "autocfg", ] @@ -2648,20 +3092,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" [[package]] -name = "miniz_oxide" -version = "0.4.4" +name = "minimal-lexical" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" -dependencies = [ - "adler", - "autocfg", -] +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.5.1" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" +checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" dependencies = [ "adler", ] @@ -2678,7 +3118,7 @@ dependencies = [ "iovec", "kernel32-sys", "libc", - "log", + "log 0.4.17", "miow 0.2.2", "net2", "slab", @@ -2687,16 +3127,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9" +checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" dependencies = [ "libc", - "log", - "miow 0.3.7", - "ntapi", + "log 0.4.17", "wasi 0.11.0+wasi-snapshot-preview1", - "winapi 0.3.9", + "windows-sys", ] [[package]] @@ -2707,7 +3145,7 @@ checksum = "6bc513025fe5005a3aa561b50fdb2cda5a150b84800ae02acd8aa9ed62ca1a6b" dependencies = [ "mio 0.6.23", "miow 0.3.7", - "parking_lot", + "parking_lot 0.11.2", "spsc-buffer", "winapi 0.3.9", ] @@ -2719,7 +3157,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" dependencies = [ "lazycell", - "log", + "log 0.4.17", "mio 0.6.23", "slab", ] @@ -2756,12 +3194,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "more-asserts" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" - [[package]] name = "nanorand" version = "0.7.0" @@ -2779,7 +3211,7 @@ checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" dependencies = [ "lazy_static", "libc", - "log", + "log 0.4.17", "openssl", "openssl-probe", "openssl-sys", @@ -2802,12 +3234,11 @@ dependencies = [ [[package]] name = "nix" -version = "0.22.3" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf" +checksum = "195cdbc1741b8134346d515b3a56a1c94b0912758009cfd53f99ea0f57b065fc" dependencies = [ "bitflags", - "cc", "cfg-if 1.0.0", "libc", "memoffset", @@ -2815,107 +3246,59 @@ dependencies = [ [[package]] name = "nom" -version = "5.1.2" +version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" dependencies = [ - "lexical-core", "memchr", - "version_check", -] - -[[package]] -name = "notify" -version = "4.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae03c8c853dba7bfd23e571ff0cff7bc9dceb40a4cd684cd1681824183f45257" -dependencies = [ - "bitflags", - "filetime", - "fsevent", - "fsevent-sys 2.0.1", - "inotify 0.7.1", - "libc", - "mio 0.6.23", - "mio-extras", - "walkdir", - "winapi 0.3.9", + "minimal-lexical", ] [[package]] name = "notify" -version = "5.0.0-pre.15" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "553f9844ad0b0824605c20fb55a661679782680410abfb1a8144c2e7e437e7a7" +checksum = "ed2c66da08abae1c024c01d635253e402341b4060a12e99b31c7594063bf490a" dependencies = [ "bitflags", "crossbeam-channel", "filetime", - "fsevent-sys 4.1.0", - "inotify 0.9.6", + "fsevent-sys", + "inotify", "kqueue", "libc", - "mio 0.8.2", - "serde 1.0.130", + "mio 0.8.4", + "serde", "walkdir", "winapi 0.3.9", ] -[[package]] -name = "ntapi" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" -dependencies = [ - "winapi 0.3.9", -] - [[package]] name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg", - "num-traits 0.2.14", -] - -[[package]] -name = "num-iter" -version = "0.1.43" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ "autocfg", - "num-integer", - "num-traits 0.2.14", + "num-traits", ] [[package]] name = "num-rational" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" dependencies = [ "autocfg", "num-integer", - "num-traits 0.2.14", -] - -[[package]] -name = "num-traits" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" -dependencies = [ - "num-traits 0.2.14", + "num-traits", ] [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", ] @@ -2926,7 +3309,7 @@ version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", ] @@ -2970,29 +3353,21 @@ dependencies = [ [[package]] name = "object" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2" -dependencies = [ - "memchr", -] - -[[package]] -name = "object" -version = "0.27.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9" +checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" dependencies = [ "crc32fast", + "hashbrown 0.12.3", "indexmap", "memchr", ] [[package]] name = "once_cell" -version = "1.10.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "opaque-debug" @@ -3000,11 +3375,21 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "open" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4a3100141f1733ea40b53381b0ae3117330735ef22309a190ac57b9576ea716" +dependencies = [ + "pathdiff", + "windows-sys", +] + [[package]] name = "openssl" -version = "0.10.40" +version = "0.10.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb81a6430ac911acb25fe5ac8f1d2af1b4ea8a4fdfda0f1ee4292af2e2d8eb0e" +checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13" dependencies = [ "bitflags", "cfg-if 1.0.0", @@ -3028,24 +3413,24 @@ dependencies = [ [[package]] name = "openssl-probe" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "111.16.0+1.1.1l" +version = "111.22.0+1.1.1q" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab2173f69416cf3ec12debb5823d244127d23a9b127d5a5189aa97c5fa2859f" +checksum = "8f31f0d509d1c1ae9cada2f9539ff8f37933831fd5098879e482aa687d659853" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.74" +version = "0.9.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "835363342df5fba8354c5b453325b110ffd54044e588c539cf2f20a8014e4cb1" +checksum = "5230151e44c0f05157effb743e8d517472843121cf9243e8b81393edb5acd9ce" dependencies = [ "autocfg", "cc", @@ -3056,27 +3441,10 @@ dependencies = [ ] [[package]] -name = "ouroboros" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeff60e3e37407a80ead3e9458145b456e978c4068cddbfea6afb48572962ca" -dependencies = [ - "ouroboros_macro", - "stable_deref_trait", -] - -[[package]] -name = "ouroboros_macro" -version = "0.9.5" +name = "os_str_bytes" +version = "6.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03f2cb802b5bdfdf52f1ffa0b54ce105e4d346e91990dd571f86c91321ad49e2" -dependencies = [ - "Inflector", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] +checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" [[package]] name = "pango" @@ -3103,6 +3471,12 @@ dependencies = [ "system-deps", ] +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" + [[package]] name = "parking_lot" version = "0.11.2" @@ -3111,7 +3485,17 @@ checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", "lock_api", - "parking_lot_core", + "parking_lot_core 0.8.5", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.3", ] [[package]] @@ -3131,22 +3515,47 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "parking_lot_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + [[package]] name = "parley" version = "0.1.0" -source = "git+https://github.com/lapce/parley#6baaa02bbe3ab717822656ad98a95f8121febd53" +source = "git+https://github.com/lapce/parley#c37477b889ff53b9a3033e2180becddf90b9bb17" dependencies = [ "fount", "swash", ] +[[package]] +name = "paste" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" + +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + [[package]] name = "pathfinder_geometry" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b7e7b4ea703700ce73ebf128e1450eb69c3a8329199ffbfb9b2a0418e5ad3" dependencies = [ - "log", + "log 0.4.17", "pathfinder_simd", ] @@ -3156,21 +3565,22 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39fe46acc5503595e5949c17b818714d26fdf9b4920eacf3b2947f0199f4a6ff" dependencies = [ - "rustc_version 0.3.3", + "rustc_version", ] [[package]] name = "percent-encoding" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" -version = "2.1.3" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +checksum = "cb779fcf4bb850fbbb0edc96ff6cf34fd90c4b1a112ce042653280d9a7364048" dependencies = [ + "thiserror", "ucd-trie", ] @@ -3203,21 +3613,22 @@ dependencies = [ [[package]] name = "piet-wgpu" version = "0.1.0" -source = "git+https://github.com/lapce/piet-wgpu?branch=shell_opengl#6e268b3b09a5480c17a241d964c9ef090fd02d98" +source = "git+https://github.com/lapce/piet-wgpu?branch=shell_opengl#2024fe8f241dc95ad38f4024d39898bada8fe802" dependencies = [ "bytemuck", "glam", "glow", - "hashbrown", + "hashbrown 0.11.2", + "image", "include_dir", "linked-hash-map", - "log", + "log 0.4.17", "lyon", "parley", "pathfinder_geometry", "piet", "resvg", - "sha2", + "sha2 0.9.9", "swash", "tiny-skia", "unicode-width", @@ -3226,18 +3637,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" dependencies = [ "proc-macro2", "quote", @@ -3246,9 +3657,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.7" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "pin-utils" @@ -3258,28 +3669,47 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.19" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" + +[[package]] +name = "plist" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +checksum = "c61ac2afed2856590ae79d6f358a24b85ece246d2aa134741a66d589519b7503" +dependencies = [ + "base64 0.8.0", + "byteorder", + "chrono", + "xml-rs 0.7.0", +] [[package]] name = "png" -version = "0.17.5" +version = "0.17.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc38c0ad57efb786dd57b9864e5b18bae478c00c824dc55a38bbc9da95dde3ba" +checksum = "8f0e7f4c94ec26ff209cee506314212639d6c91b80afb82984819fafce9df01c" dependencies = [ "bitflags", "crc32fast", - "deflate", - "miniz_oxide 0.5.1", + "flate2", + "miniz_oxide", ] +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + [[package]] name = "proc-macro-crate" -version = "1.0.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fdbd1df62156fbc5945f4762632564d7d038153091c3fcf1067f6aef7cff92" +checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9" dependencies = [ + "once_cell", "thiserror", "toml", ] @@ -3316,38 +3746,37 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "7bd7356a8122b6c4a24a82b278680c73357984ca2fc79a0f9fa6dea7dced7c58" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] -name = "ptr_meta" -version = "0.1.4" +name = "psm" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" dependencies = [ - "ptr_meta_derive", + "cc", ] [[package]] -name = "ptr_meta_derive" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +name = "psp-types" +version = "0.1.0" +source = "git+https://github.com/lapce/psp-types#b55d2c5c1f9aae89a4f369db5151fe1756d34c08" dependencies = [ - "proc-macro2", - "quote", - "syn", + "lsp-types", + "serde", + "serde_json", ] [[package]] name = "pulldown-cmark" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34f197a544b0c9ab3ae46c359a7ec9cbbb5c7bf97054266fecb7ead794a181d6" +checksum = "2d9cc634bc78768157b5cbfe988ffcd1dcba95cd2b2f03a88316c08c6d00ed63" dependencies = [ "bitflags", "getopts", @@ -3357,33 +3786,57 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.15" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + [[package]] name = "rand_core" -version = "0.5.1" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] [[package]] name = "rand_xoshiro" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9fcdd2e881d02f1d9390ae47ad8e5696a9e4be7b547a1da2afbc61973217004" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" dependencies = [ "rand_core", ] [[package]] name = "rayon" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" dependencies = [ "autocfg", "crossbeam-deque", @@ -3393,14 +3846,13 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" dependencies = [ "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "lazy_static", "num_cpus", ] @@ -3418,39 +3870,41 @@ checksum = "9ae028b272a6e99d9f8260ceefa3caa09300a8d6c8d2b2001316474bc52122e9" [[package]] name = "redox_syscall" -version = "0.2.10" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] [[package]] name = "redox_users" -version = "0.4.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", "redox_syscall", + "thiserror", ] [[package]] -name = "regalloc" -version = "0.0.31" +name = "regalloc2" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "571f7f397d61c4755285cd37853fe8e03271c243424a907415909379659381c5" +checksum = "d43a209257d978ef079f3d446331d0f1794f5e0fc19b306a199983857833a779" dependencies = [ - "log", - "rustc-hash", + "fxhash", + "log 0.4.17", + "slice-group-by", "smallvec", ] [[package]] name = "regex" -version = "1.5.6" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" dependencies = [ "aho-corasick", "memchr", @@ -3468,21 +3922,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" - -[[package]] -name = "region" -version = "3.0.0" +version = "0.6.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76e189c2369884dce920945e2ddf79b3dff49e071a167dd1817fa9c4c00d512e" -dependencies = [ - "bitflags", - "libc", - "mach", - "winapi 0.3.9", -] +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" [[package]] name = "remove_dir_all" @@ -3493,22 +3935,13 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "rend" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" -dependencies = [ - "bytecheck", -] - [[package]] name = "reqwest" -version = "0.11.10" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a1f7aa4f35e5e8b4160449f51afc758f0ce6454315a9fa7d0d113e958c41eb" +checksum = "431949c384f4e2ae07605ccaa56d1d9d2ecdb5cadd4f9577ccfab29f2e5149fc" dependencies = [ - "base64", + "base64 0.13.0", "bytes", "encoding_rs", "futures-core", @@ -3520,18 +3953,19 @@ dependencies = [ "hyper-tls", "ipnet", "js-sys", - "lazy_static", - "log", + "log 0.4.17", "mime", "native-tls", + "once_cell", "percent-encoding", "pin-project-lite", - "serde 1.0.130", + "serde", "serde_json", "serde_urlencoded", "tokio", "tokio-native-tls", "tokio-socks", + "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", @@ -3547,50 +3981,25 @@ checksum = "2e702d1e8e00a3a0717b96244cba840f34f542d8f23097c8903266c4e2975658" dependencies = [ "gif", "jpeg-decoder", - "log", + "log 0.4.17", "pico-args", "png", "rgb", "svgfilters", - "svgtypes 0.8.0", + "svgtypes 0.8.1", "tiny-skia", "usvg 0.22.0", ] [[package]] name = "rgb" -version = "0.8.32" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e74fdc210d8f24a7dbfedc13b04ba5764f5232754ccebfdf5fff1bad791ccbc6" +checksum = "3603b7d71ca82644f79b5a06d1220e9a58ede60bd32255f698cb1af8838b8db3" dependencies = [ "bytemuck", ] -[[package]] -name = "rkyv" -version = "0.7.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "631f7d2a2854abb66724f492ce5256e79685a673dc210ac022194cedd5c914d3" -dependencies = [ - "bytecheck", - "hashbrown", - "ptr_meta", - "rend", - "rkyv_derive", - "seahash", -] - -[[package]] -name = "rkyv_derive" -version = "0.7.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c067e650861a749720952aed722fb344449bc95de33e6456d426f5c7d44f71c0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "roxmltree" version = "0.14.1" @@ -3600,12 +4009,6 @@ dependencies = [ "xmlparser", ] -[[package]] -name = "rust-ini" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" - [[package]] name = "rustc-demangle" version = "0.1.21" @@ -3618,29 +4021,30 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - [[package]] name = "rustc_version" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" dependencies = [ - "semver 0.11.0", + "semver", ] [[package]] -name = "rustversion" -version = "1.0.6" +name = "rustix" +version = "0.35.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" +checksum = "af895b90e5c071badc3136fc10ff0bcfc98747eadbaf43ed8f214e07ba8f8477" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "itoa", + "libc", + "linux-raw-sys", + "once_cell", + "windows-sys", +] [[package]] name = "rustybuzz" @@ -3660,14 +4064,14 @@ dependencies = [ [[package]] name = "rustybuzz" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25ff94f20221325d000e552781713e53b0d85c1d9551b6f420d12daf5a08eace" +checksum = "a617c811f5c9a7060fe511d35d13bf5b9f0463ce36d63ce666d05779df2b4eba" dependencies = [ "bitflags", "bytemuck", "smallvec", - "ttf-parser 0.15.0", + "ttf-parser 0.15.2", "unicode-bidi-mirroring", "unicode-ccc", "unicode-general-category 0.4.0", @@ -3676,9 +4080,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] name = "safe_arch" @@ -3689,6 +4093,12 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "safemem" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" + [[package]] name = "same-file" version = "1.0.6" @@ -3720,17 +4130,11 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "seahash" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" - [[package]] name = "security-framework" -version = "2.4.2" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87" +checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" dependencies = [ "bitflags", "core-foundation", @@ -3741,22 +4145,19 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.4.2" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e" +checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" dependencies = [ "core-foundation-sys", "libc", ] [[package]] -name = "semver" -version = "0.9.0" +name = "self_cell" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser 0.7.0", -] +checksum = "1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8af" [[package]] name = "semver" @@ -3764,15 +4165,9 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" dependencies = [ - "semver-parser 0.10.2", + "semver-parser", ] -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "semver-parser" version = "0.10.2" @@ -3784,45 +4179,18 @@ dependencies = [ [[package]] name = "serde" -version = "0.8.23" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8" - -[[package]] -name = "serde" -version = "1.0.130" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" dependencies = [ "serde_derive", ] -[[package]] -name = "serde-hjson" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a3a4e0ea8a88553209f6cc6cfe8724ecad22e1acf372793c27d995290fe74f8" -dependencies = [ - "lazy_static", - "num-traits 0.1.43", - "regex", - "serde 0.8.23", -] - -[[package]] -name = "serde_bytes" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" -dependencies = [ - "serde 1.0.130", -] - [[package]] name = "serde_derive" -version = "1.0.130" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" dependencies = [ "proc-macro2", "quote", @@ -3831,20 +4199,20 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.67" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950" +checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" dependencies = [ - "itoa 0.4.8", + "itoa", "ryu", - "serde 1.0.130", + "serde", ] [[package]] name = "serde_repr" -version = "0.1.7" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5" +checksum = "1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca" dependencies = [ "proc-macro2", "quote", @@ -3858,65 +4226,79 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa 1.0.2", + "itoa", "ryu", - "serde 1.0.130", + "serde", ] [[package]] name = "serde_yaml" -version = "0.8.21" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c608a35705a5d3cdc9fbe403147647ff34b921f8e833e49306df898f9b20af" +checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" dependencies = [ - "dtoa", "indexmap", - "serde 1.0.130", + "ryu", + "serde", "yaml-rust", ] [[package]] -name = "sha1" -version = "0.6.0" +name = "sha2" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] [[package]] name = "sha2" -version = "0.9.8" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ - "block-buffer", "cfg-if 1.0.0", "cpufeatures", - "digest", - "opaque-debug", + "digest 0.10.5", ] [[package]] name = "sharded-slab" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740223c51853f3145fe7c90360d2d4232f2b62e3449489c207eccde818979982" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" dependencies = [ "lazy_static", ] +[[package]] +name = "shellexpand" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ccc8076840c4da029af4f87e4e8daeb0fca6b87bbb02e10cb60b791450e11e4" +dependencies = [ + "dirs", +] + [[package]] name = "sid" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd5ac56c121948b4879bba9e519852c211bcdd8f014efff766441deff0b91bdb" dependencies = [ - "num-traits 0.2.14", + "num-traits", ] [[package]] name = "signal-hook" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "647c97df271007dcea485bb74ffdb57f2e683f1306c854f468a0c244badabf2d" +checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" dependencies = [ "libc", "signal-hook-registry", @@ -3924,9 +4306,9 @@ dependencies = [ [[package]] name = "signal-hook-mio" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29fd5867f1c4f2c5be079aee7a2adf1152ebb04a4bc4d341f504b7dece607ed4" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" dependencies = [ "libc", "mio 0.6.23", @@ -3949,7 +4331,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a11be7c62927d9427e9f40f3444d5499d868648e2edbc4e2116de69e7ec0e89d" dependencies = [ - "log", + "log 0.4.17", ] [[package]] @@ -3976,9 +4358,12 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] [[package]] name = "sled" @@ -3992,10 +4377,16 @@ dependencies = [ "fs2", "fxhash", "libc", - "log", - "parking_lot", + "log 0.4.17", + "parking_lot 0.11.2", ] +[[package]] +name = "slice-group-by" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03b634d87b960ab1a38c4fe143b508576f075e7c978bfad18217645ebfdfa2ec" + [[package]] name = "slotmap" version = "1.0.6" @@ -4007,15 +4398,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "socket2" -version = "0.4.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" dependencies = [ "libc", "winapi 0.3.9", @@ -4023,9 +4414,18 @@ dependencies = [ [[package]] name = "spin" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c530c2b0d0bf8b69304b39fe2001993e267461948b890cd037d8ad4293fa1a0d" +checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spinning" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d4f0e86297cad2658d92a707320d87bf4e6ae1050287f51d19b67ef3f153a7b" dependencies = [ "lock_api", ] @@ -4042,70 +4442,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" -[[package]] -name = "standback" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" -dependencies = [ - "version_check", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "stdweb" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" -dependencies = [ - "discard", - "rustc_version 0.2.3", - "stdweb-derive", - "stdweb-internal-macros", - "stdweb-internal-runtime", - "wasm-bindgen", -] - -[[package]] -name = "stdweb-derive" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" -dependencies = [ - "proc-macro2", - "quote", - "serde 1.0.130", - "serde_derive", - "syn", -] - -[[package]] -name = "stdweb-internal-macros" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" -dependencies = [ - "base-x", - "proc-macro2", - "quote", - "serde 1.0.130", - "serde_derive", - "serde_json", - "sha1", - "syn", -] - -[[package]] -name = "stdweb-internal-runtime" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" - [[package]] name = "strsim" version = "0.10.0" @@ -4129,12 +4465,6 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2" -[[package]] -name = "strum" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96acfc1b70604b8b2f1ffa4c57e59176c7dbb05d556c71ecd2f5498a1dee7f8" - [[package]] name = "strum_macros" version = "0.21.1" @@ -4148,23 +4478,10 @@ dependencies = [ ] [[package]] -name = "strum_macros" -version = "0.24.0" +name = "svgfilters" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6878079b17446e4d3eba6192bb0a2950d5b14f0ed8424b852310e5a94345d0ef" -dependencies = [ - "heck 0.4.0", - "proc-macro2", - "quote", - "rustversion", - "syn", -] - -[[package]] -name = "svgfilters" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "639abcebc15fdc2df179f37d6f5463d660c1c79cd552c12343a4600827a04bce" +checksum = "639abcebc15fdc2df179f37d6f5463d660c1c79cd552c12343a4600827a04bce" dependencies = [ "float-cmp 0.9.0", "rgb", @@ -4182,9 +4499,9 @@ dependencies = [ [[package]] name = "svgtypes" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dabb3eb59a457c56d5282ab4545609e2cc382b41f6af239bb8d59a7267ef94b3" +checksum = "cc802f68b144cdf4d8ff21301f9a7863e837c627fde46537e29c05e8a18c85c1" dependencies = [ "siphasher 0.3.10", ] @@ -4200,13 +4517,13 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.86" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" +checksum = "e90cde112c4b9690b8cbe810cba9ddd8bc1d7472e2cae317b69e9438c1cba7d2" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -4220,18 +4537,45 @@ dependencies = [ "heck 0.3.3", "itertools", "pkg-config", - "strum 0.21.0", - "strum_macros 0.21.1", + "strum", + "strum_macros", "thiserror", "toml", "version-compare", ] +[[package]] +name = "system-interface" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa85f9e64bd72b222ced152d2694fd306c0ebe43670cb9d187701874b7b89008" +dependencies = [ + "atty", + "bitflags", + "cap-fs-ext", + "cap-std", + "io-lifetimes", + "rustix", + "windows-sys", + "winx", +] + +[[package]] +name = "tar" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" +dependencies = [ + "filetime", + "libc", + "xattr", +] + [[package]] name = "target-lexicon" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9bffcddbc2458fa3e6058414599e3c838a022abae82e5c67b4f7f80298d5bff" +checksum = "c02424087780c9b71cc96799eaeddff35af2bc513278cda5c99fc1f5d026d3c1" [[package]] name = "tempfile" @@ -4247,20 +4591,35 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7b3e525a49ec206798b40326a44121291b530c963cfb01018f63e135bac543d" + [[package]] name = "thiserror" -version = "1.0.28" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "283d5230e63df9608ac7d9691adc1dfb6e701225436eb64d0b9a7f0a5a04f6ec" +checksum = "0a99cb8c4b9a8ef0e7907cd3b617cc8dc04d571c4e73c8ae403d80ac160bb122" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.28" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa3884228611f5cd3608e2d409bf7dce832e4eb3135e3f11addbd7e41bd68e71" +checksum = "3a891860d3c8d66fec8e73ddb3765f90082374dbaaa833407b904a94f1a7eb43" dependencies = [ "proc-macro2", "quote", @@ -4280,9 +4639,9 @@ dependencies = [ [[package]] name = "thread_local" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" dependencies = [ "once_cell", ] @@ -4298,9 +4657,9 @@ dependencies = [ [[package]] name = "tiff" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cfada0986f446a770eca461e8c6566cb879682f7d687c8348aa0c857bd52286" +checksum = "7259662e32d1e219321eb309d5f9d898b779769d81b76e762c07c8e5d38fcb65" dependencies = [ "flate2", "jpeg-decoder", @@ -4320,57 +4679,19 @@ dependencies = [ [[package]] name = "time" -version = "0.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" -dependencies = [ - "const_fn", - "libc", - "standback", - "stdweb", - "time-macros", - "version_check", - "winapi 0.3.9", -] - -[[package]] -name = "time" -version = "0.3.9" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd" +checksum = "3c3f9a28b618c3a6b9251b6908e9c99e04b9e5c02e6581ccbb67d59c34ef7f9b" dependencies = [ "libc", "num_threads", ] -[[package]] -name = "time-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" -dependencies = [ - "proc-macro-hack", - "time-macros-impl", -] - -[[package]] -name = "time-macros-impl" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" -dependencies = [ - "proc-macro-hack", - "proc-macro2", - "quote", - "standback", - "syn", -] - [[package]] name = "tiny-skia" -version = "0.6.3" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bcfd4339bdd4545eabed74b208f2f1555f2e6540fb58135c01f46c0940aa138" +checksum = "d049bfef0eaa2521e75d9ffb5ce86ad54480932ae19b85f78bec6f52c4d30d78" dependencies = [ "arrayref", "arrayvec 0.5.2", @@ -4388,9 +4709,9 @@ checksum = "29738eedb4388d9ea620eeab9384884fc3f06f586a2eddb56bedc5885126c7c1" [[package]] name = "tinyvec" -version = "1.3.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ "tinyvec_macros", ] @@ -4403,21 +4724,36 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.19.2" +version = "1.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439" +checksum = "0020c875007ad96677dcc890298f4b942882c5d4eb7cc8f439fc3bf813dc9c95" dependencies = [ + "autocfg", "bytes", "libc", "memchr", - "mio 0.8.2", + "mio 0.8.4", "num_cpus", "once_cell", + "parking_lot 0.12.1", "pin-project-lite", + "signal-hook-registry", "socket2", + "tokio-macros", "winapi 0.3.9", ] +[[package]] +name = "tokio-macros" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tokio-native-tls" version = "0.3.0" @@ -4442,9 +4778,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" dependencies = [ "bytes", "futures-core", @@ -4456,28 +4792,39 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.8" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +checksum = "5376256e44f2443f8896ac012507c19a012df0fe8758b55246ae51a2279db51f" dependencies = [ + "combine", "indexmap", - "serde 1.0.130", + "itertools", + "serde", ] [[package]] name = "tower-service" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.26" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" +checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" dependencies = [ "cfg-if 1.0.0", - "log", + "log 0.4.17", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -4485,9 +4832,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.15" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2" +checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" dependencies = [ "proc-macro2", "quote", @@ -4496,63 +4843,104 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.26" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" +checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" dependencies = [ - "lazy_static", - "valuable", + "once_cell", ] [[package]] name = "tracing-subscriber" -version = "0.2.20" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9cbe87a2fa7e35900ce5de20220a582a9483a7063811defce79d7cbd59d4cfe" +checksum = "60db860322da191b40952ad9affe65ea23e7dd6a5c442c2c42865810c6ab8e6b" dependencies = [ + "ansi_term", "sharded-slab", "thread_local", "tracing-core", ] [[package]] -name = "tracing-subscriber" -version = "0.3.6" +name = "tracing-wasm" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77be66445c4eeebb934a7340f227bfe7b338173d3f8c00a60a5a58005c9faecf" +checksum = "4575c663a174420fa2d78f4108ff68f65bf2fbb7dd89f33749b6e826b3626e07" dependencies = [ - "ansi_term", - "sharded-slab", - "thread_local", - "tracing-core", + "tracing", + "tracing-subscriber", + "wasm-bindgen", ] [[package]] -name = "tracing-wasm" -version = "0.2.0" +name = "trash" +version = "2.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae741706df70547fca8715f74a8569677666e7be3454313af70f6e158034485" +checksum = "fe090367848cd40c4230ff3ce4e2ff6a2fd511c1e14ae047a4a4c37ef7965236" dependencies = [ - "tracing", - "tracing-subscriber 0.2.20", - "wasm-bindgen", + "chrono", + "libc", + "log 0.4.17", + "objc", + "once_cell", + "scopeguard", + "url", + "windows", ] [[package]] name = "tree-sitter" -version = "0.20.6" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b3b781640108d29892e8b9684642d2cda5ea05951fd58f0fea1db9edeb9b71" +checksum = "d4423c784fe11398ca91e505cdc71356b07b1a924fc8735cfab5333afe3e18bc" dependencies = [ "cc", "regex", ] +[[package]] +name = "tree-sitter-bash" +version = "0.19.0" +source = "git+https://github.com/tree-sitter/tree-sitter-bash?rev=4488aa41406547e478636a4fcfd24f5bbc3f2f74#4488aa41406547e478636a4fcfd24f5bbc3f2f74" +dependencies = [ + "cc", + "tree-sitter", +] + [[package]] name = "tree-sitter-c" -version = "0.20.1" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cca211f4827d4b4dc79f388bf67b6fa3bc8a8cfa642161ef24f99f371ba34c7b" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-c-sharp" +version = "0.20.0" +source = "git+https://github.com/tree-sitter/tree-sitter-c-sharp?rev=5b60f99545fea00a33bbfae5be956f684c4c69e2#5b60f99545fea00a33bbfae5be956f684c4c69e2" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-clojure" +version = "0.1.0" +source = "git+https://github.com/abreumatheus/tree-sitter-clojure?rev=fdc969eb04fc711e38ad74afe441d74b3b5d3091#fdc969eb04fc711e38ad74afe441d74b3b5d3091" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-cmake" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bdc5574c6cbc39c409246caeb1dd4d3c4bd6d30d4e9b399776086c20365fd24" +checksum = "ba8253ba26ab0adc2ae7cc7802d47cda9bba3fa31d07436f829a4c7f2b2442f3" dependencies = [ "cc", "tree-sitter", @@ -4568,10 +4956,46 @@ dependencies = [ "tree-sitter", ] +[[package]] +name = "tree-sitter-css" +version = "0.19.0" +source = "git+https://github.com/syntacti/tree-sitter-css?rev=397aa132b9982fcdd2d473ed69343762a557f10a#397aa132b9982fcdd2d473ed69343762a557f10a" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-d" +version = "0.3.2" +source = "git+https://github.com/ghishadow/tree-sitter-d?rev=36603135ecb37ac6494c520efff91b875815d6f7#36603135ecb37ac6494c520efff91b875815d6f7" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-dart" +version = "0.0.1" +source = "git+https://github.com/syntacti/tree-sitter-dart?rev=78cad4503571d72666f78d5ba8ed6c1417653063#78cad4503571d72666f78d5ba8ed6c1417653063" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-dockerfile" +version = "0.1.0" +source = "git+https://github.com/panekj/tree-sitter-dockerfile?rev=c49d819e07685c90456270f1cc654d9cba640f53#c49d819e07685c90456270f1cc654d9cba640f53" +dependencies = [ + "cc", + "tree-sitter", +] + [[package]] name = "tree-sitter-elixir" version = "0.19.0" -source = "git+https://github.com/elixir-lang/tree-sitter-elixir.git#60863fc6e27d60cf4b1917499ed2259f92c7800e" +source = "git+https://github.com/elixir-lang/tree-sitter-elixir.git?rev=05e3631c6a0701c1fa518b0fee7be95a2ceef5e2#05e3631c6a0701c1fa518b0fee7be95a2ceef5e2" dependencies = [ "cc", "tree-sitter", @@ -4579,9 +5003,18 @@ dependencies = [ [[package]] name = "tree-sitter-elm" -version = "5.6.0" +version = "5.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d4c28acbbdb8a0d72a5eb181e05d29f664e6631c3182f1e3d9974ae900addf3" +checksum = "22b9408ad250aa27774132baf20c4f107faad16841aa45568c6900a27895093b" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-erlang" +version = "0.0.1" +source = "git+https://github.com/WhatsApp/tree-sitter-erlang?rev=a8b8b0e16c4f5552f5e85af3dec976a5d16af8b9#a8b8b0e16c4f5552f5e85af3dec976a5d16af8b9" dependencies = [ "cc", "tree-sitter", @@ -4590,7 +5023,16 @@ dependencies = [ [[package]] name = "tree-sitter-glimmer" version = "0.0.1" -source = "git+https://github.com/VixieTSQ/tree-sitter-glimmer#d8a41791e83d445ef52748429cea6fed974908e7" +source = "git+https://github.com/VixieTSQ/tree-sitter-glimmer?rev=7281caca2ba114e1960c5d944a37860ef0841426#7281caca2ba114e1960c5d944a37860ef0841426" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-glsl" +version = "0.1.3" +source = "git+https://github.com/theHamsta/tree-sitter-glsl?rev=74329feb2605deccd32b1c644af507daa6fb82f1#74329feb2605deccd32b1c644af507daa6fb82f1" dependencies = [ "cc", "tree-sitter", @@ -4607,40 +5049,39 @@ dependencies = [ ] [[package]] -name = "tree-sitter-haskell" -version = "0.14.0" -source = "git+https://github.com/tree-sitter/tree-sitter-haskell#14bf3061a3fbcadab428fb5e50eb2c5b1f9be0c3" +name = "tree-sitter-hare" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cbd59e015721be7de5449fad7b7d5302f0f8544b1589f818d9a38afd4ff198b" dependencies = [ "cc", "tree-sitter", ] [[package]] -name = "tree-sitter-haxe" -version = "0.0.1" -source = "git+https://github.com/VixieTSQ/tree-sitter-haxe#a3e23bc0f84a53371eb5d86229782ec6c21d3729" +name = "tree-sitter-haskell" +version = "0.14.0" +source = "git+https://github.com/tree-sitter/tree-sitter-haskell?rev=e30bdfd53eb28c73f26a68b77d436fd2140af167#e30bdfd53eb28c73f26a68b77d436fd2140af167" dependencies = [ "cc", "tree-sitter", ] [[package]] -name = "tree-sitter-hcl" -version = "0.0.1" -source = "git+https://github.com/VixieTSQ/tree-sitter-hcl#f4aa4553344e03e149ec459549a7f686d6846626" +name = "tree-sitter-haxe" +version = "0.2.2" +source = "git+https://github.com/vantreeseba/tree-sitter-haxe?rev=52e3d2b9c3955aca886bccc38b496ef99b603a09#52e3d2b9c3955aca886bccc38b496ef99b603a09" dependencies = [ "cc", "tree-sitter", ] [[package]] -name = "tree-sitter-highlight" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "042342584c5a7a0b833d9fc4e2bdab3f9868ddc6c4b339a1e01451c6720868bc" +name = "tree-sitter-hcl" +version = "0.0.1" +source = "git+https://github.com/VixieTSQ/tree-sitter-hcl?rev=f4aa4553344e03e149ec459549a7f686d6846626#f4aa4553344e03e149ec459549a7f686d6846626" dependencies = [ - "regex", - "thiserror", + "cc", "tree-sitter", ] @@ -4657,7 +5098,7 @@ dependencies = [ [[package]] name = "tree-sitter-java" version = "0.20.0" -source = "git+https://github.com/tree-sitter/tree-sitter-java.git#e7cb801ef57f74db5c4ebe14df74de852bb451b5" +source = "git+https://github.com/tree-sitter/tree-sitter-java.git?rev=09d650def6cdf7f479f4b78f595e9ef5b58ce31e#09d650def6cdf7f479f4b78f595e9ef5b58ce31e" dependencies = [ "cc", "tree-sitter", @@ -4675,141 +5116,287 @@ dependencies = [ [[package]] name = "tree-sitter-json" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90b04c4e1a92139535eb9fca4ec8fa9666cc96b618005d3ae35f3c957fa92f92" +version = "0.20.0" +source = "git+https://github.com/tree-sitter/tree-sitter-json.git?rev=11e2cc12d9b267766fb11a06e52952792fd8e3f0#11e2cc12d9b267766fb11a06e52952792fd8e3f0" dependencies = [ "cc", "tree-sitter", ] [[package]] -name = "tree-sitter-md" -version = "0.0.1" -source = "git+https://github.com/MDeiml/tree-sitter-markdown.git#6d112e7a9c1694504bb78ee0b92dcd509625e0df" +name = "tree-sitter-julia" +version = "0.19.0" +source = "git+https://github.com/varlad/tree-sitter-julia.git?rev=2ad4c9b79e0f213b61dbb3820754bfc6306e595a#2ad4c9b79e0f213b61dbb3820754bfc6306e595a" dependencies = [ "cc", "tree-sitter", ] [[package]] -name = "tree-sitter-ocaml" -version = "0.20.0" -source = "git+https://github.com/tree-sitter/tree-sitter-ocaml#cc26b1ef111100f26a137bcbcd39fd4e35be9a59" +name = "tree-sitter-kotlin" +version = "0.2.11" +source = "git+https://github.com/fwcd/tree-sitter-kotlin?rev=a4f71eb9b8c9b19ded3e0e9470be4b1b77c2b569#a4f71eb9b8c9b19ded3e0e9470be4b1b77c2b569" dependencies = [ "cc", "tree-sitter", ] [[package]] -name = "tree-sitter-php" -version = "0.19.1" -source = "git+https://github.com/tree-sitter/tree-sitter-php.git#ead3e4cc5f54602a6b54826c5d6881c9a9da15af" +name = "tree-sitter-latex" +version = "0.2.0" +source = "git+https://github.com/latex-lsp/tree-sitter-latex?rev=b3b2cf27f33e71438ebe46934900b1153901c6f2#b3b2cf27f33e71438ebe46934900b1153901c6f2" dependencies = [ "cc", "tree-sitter", ] [[package]] -name = "tree-sitter-python" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c46916553ebc2a5b23763cd2da8d2b104c515c8f828eb678d1477ccd8c379c" +name = "tree-sitter-lua" +version = "0.0.12" +source = "git+https://github.com/syntacti/tree-sitter-lua?rev=a29f646c14ed800aaeef1ca58a9bacc6d92922e8#a29f646c14ed800aaeef1ca58a9bacc6d92922e8" dependencies = [ "cc", "tree-sitter", ] [[package]] -name = "tree-sitter-ql" -version = "0.19.0" -source = "git+https://github.com/tree-sitter/tree-sitter-ql#b2c2364e833cc9f1afa243ac367f1475330fef63" +name = "tree-sitter-md" +version = "0.1.2" +source = "git+https://github.com/MDeiml/tree-sitter-markdown.git?rev=272e080bca0efd19a06a7f4252d746417224959e#272e080bca0efd19a06a7f4252d746417224959e" dependencies = [ "cc", "tree-sitter", ] [[package]] -name = "tree-sitter-ruby" -version = "0.19.0" -source = "git+https://github.com/Liberatys/tree-sitter-ruby.git?branch=chore/allow-range-of-tree-sitter#26086eeb072266abf51273af631a2cb62d0fd1e8" +name = "tree-sitter-nix" +version = "0.0.1" +source = "git+https://github.com/panekj/tree-sitter-nix?rev=59fc47150ab437e8bb356c7ab21e9531e87f7cc8#59fc47150ab437e8bb356c7ab21e9531e87f7cc8" dependencies = [ "cc", "tree-sitter", ] [[package]] -name = "tree-sitter-rust" +name = "tree-sitter-ocaml" version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3df540a493d754015d22eaf57c38f58804be3713a22f6062db983ec15f85c3c9" +source = "git+https://github.com/tree-sitter/tree-sitter-ocaml?rev=cc26b1ef111100f26a137bcbcd39fd4e35be9a59#cc26b1ef111100f26a137bcbcd39fd4e35be9a59" dependencies = [ "cc", "tree-sitter", ] [[package]] -name = "tree-sitter-scss" -version = "0.0.1" -source = "git+https://github.com/VixieTSQ/tree-sitter-scss?branch=patch-1#3aac3391ede5098edbf4cc8a9f6d0cfdfe28e5dc" +name = "tree-sitter-php" +version = "0.19.1" +source = "git+https://github.com/tree-sitter/tree-sitter-php.git?rev=ab2e72179ceb8bb0b249c8ac9162a148e911b3dc#ab2e72179ceb8bb0b249c8ac9162a148e911b3dc" dependencies = [ "cc", "tree-sitter", ] [[package]] -name = "tree-sitter-swift" -version = "0.3.0" +name = "tree-sitter-prisma-io" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090310d23c7a0a96cece88376ad7acf53ce47a036a64145ef2523a336c1d2051" +checksum = "15843349be7dd0281ffb24dd9659c6695d7a3d43a75e175c6a985f8dd6089174" dependencies = [ "cc", "tree-sitter", ] [[package]] -name = "tree-sitter-toml" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca517f578a98b23d20780247cc2688407fa81effad5b627a5a364ec3339b53e8" +name = "tree-sitter-protobuf" +version = "0.0.1" +source = "git+https://github.com/yusdacra/tree-sitter-protobuf?rev=5aef38d655f76a6b0d172340eed3766c93b3124c#5aef38d655f76a6b0d172340eed3766c93b3124c" dependencies = [ "cc", "tree-sitter", ] [[package]] -name = "tree-sitter-typescript" -version = "0.20.0" +name = "tree-sitter-python" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8935efd97c92067c9b2b6d7acb647607590996ba80f3a7be09a197f9c1fdab73" +checksum = "dda114f58048f5059dcf158aff691dffb8e113e6d2b50d94263fd68711975287" dependencies = [ "cc", "tree-sitter", ] [[package]] -name = "try-lock" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +name = "tree-sitter-ql" +version = "0.19.0" +source = "git+https://github.com/tree-sitter/tree-sitter-ql?rev=bd087020f0d8c183080ca615d38de0ec827aeeaf#bd087020f0d8c183080ca615d38de0ec827aeeaf" +dependencies = [ + "cc", + "tree-sitter", +] [[package]] -name = "ttf-parser" -version = "0.9.0" +name = "tree-sitter-r" +version = "0.19.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ddb402ac6c2af6f7a2844243887631c4e94b51585b229fcfddb43958cd55ca" - -[[package]] -name = "ttf-parser" +checksum = "522c13f4cc46213148b19d4ad40a988ffabd51fd90eb7de759844fbde49bda0c" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-ruby" +version = "0.19.0" +source = "git+https://github.com/tree-sitter/tree-sitter-ruby.git?rev=656abef0645caea793e33c1c773570722463e1d8#656abef0645caea793e33c1c773570722463e1d8" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-rust" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13470fafb7327a3acf96f5bc1013b5539a899a182f01c59b5af53f6b93195717" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-scheme" +version = "0.2.0" +source = "git+https://github.com/6cdh/tree-sitter-scheme.git?rev=af0fd1fa452cb2562dc7b5c8a8c55551c39273b9#af0fd1fa452cb2562dc7b5c8a8c55551c39273b9" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-scss" +version = "0.0.1" +source = "git+https://github.com/VixieTSQ/tree-sitter-scss?rev=3aac3391ede5098edbf4cc8a9f6d0cfdfe28e5dc#3aac3391ede5098edbf4cc8a9f6d0cfdfe28e5dc" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-sql" +version = "0.0.2" +source = "git+https://github.com/oknozor/tree-sitter-sql?rev=15dad0f3cae8a094a7dac17d712ea8fb25228011#15dad0f3cae8a094a7dac17d712ea8fb25228011" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-svelte" +version = "0.10.2" +source = "git+https://github.com/Himujjal/tree-sitter-svelte?rev=52e122ae68b316d3aa960a0a422d3645ba717f42#52e122ae68b316d3aa960a0a422d3645ba717f42" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-swift" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe0df6a792c4cd3066239195b65a322066c9ebbff58686a9de3e9ad9f25b510" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-toml" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca517f578a98b23d20780247cc2688407fa81effad5b627a5a364ec3339b53e8" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-typescript" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e8ed0ecb931cdff13c6a13f45ccd615156e2779d9ffb0395864e05505e6e86d" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-vue" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc58c2aaf6d4a5da799f45751719a6ff4b7d38a97479c6b547b442a8cbf8730" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-wgsl" +version = "0.0.1" +source = "git+https://github.com/szebniok/tree-sitter-wgsl?rev=272e89ef2aeac74178edb9db4a83c1ffef80a463#272e89ef2aeac74178edb9db4a83c1ffef80a463" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-xml" +version = "0.0.1" +source = "git+https://github.com/RenjiSann/tree-sitter-xml?rev=422528a43630db6dcc1e222d1c5ee3babd559473#422528a43630db6dcc1e222d1c5ee3babd559473" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-yaml" +version = "0.0.1" +source = "git+https://github.com/panekj/tree-sitter-yaml?rev=80c8d76847f03e772c5c524cf29bafb56858a8d1#80c8d76847f03e772c5c524cf29bafb56858a8d1" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "tree-sitter-zig" +version = "0.0.1" +source = "git+https://github.com/maxxnino/tree-sitter-zig?rev=8d3224c3bd0890fe08358886ebf54fca2ed448a6#8d3224c3bd0890fe08358886ebf54fca2ed448a6" +dependencies = [ + "cc", + "tree-sitter", +] + +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + +[[package]] +name = "ttf-parser" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ddb402ac6c2af6f7a2844243887631c4e94b51585b229fcfddb43958cd55ca" + +[[package]] +name = "ttf-parser" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ae2f58a822f08abdaf668897e96a5656fe72f5a9ce66422423e8849384872e6" [[package]] name = "ttf-parser" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c74c96594835e10fa545e2a51e8709f30b173a092bfd6036ef2cec53376244f3" +checksum = "7b3e06c9b9d80ed6b745c7159c40b311ad2916abb34a49e9be2653b90db0d8dd" [[package]] name = "type-map" @@ -4822,15 +5409,15 @@ dependencies = [ [[package]] name = "typenum" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "ucd-trie" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" +checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" [[package]] name = "unic-bidi" @@ -4912,9 +5499,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.6" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-bidi-mirroring" @@ -4940,26 +5527,32 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07547e3ee45e28326cc23faac56d44f58f16ab23e413db526debce3b0bfd2742" +[[package]] +name = "unicode-ident" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" + [[package]] name = "unicode-normalization" -version = "0.1.19" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] [[package]] name = "unicode-script" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "098ec66172ce21cd55f8bcc786ee209dd20e04eff70acfca30cb79924d173ae9" +checksum = "7d817255e1bed6dfd4ca47258685d14d2bdcfbc64fdc9e3819bd5848057b8ecc" [[package]] name = "unicode-segmentation" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" +checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" [[package]] name = "unicode-vo" @@ -4969,27 +5562,20 @@ checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94" [[package]] name = "unicode-width" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" - -[[package]] -name = "unicode-xid" -version = "0.2.2" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "url" -version = "2.2.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" dependencies = [ "form_urlencoded", "idna", - "matches", "percent-encoding", - "serde 1.0.130", + "serde", ] [[package]] @@ -4998,12 +5584,12 @@ version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef8352f317d8f9a918ba5154797fb2a93e2730244041cf7d5be35148266adfa5" dependencies = [ - "base64", + "base64 0.13.0", "data-url", "flate2", "fontdb 0.5.4", "kurbo", - "log", + "log 0.4.17", "memmap2 0.2.3", "pico-args", "rctree 0.3.3", @@ -5025,21 +5611,21 @@ version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a261d60a7215fa339482047cc3dafd4e22e2bf34396aaebef2b707355bbb39c0" dependencies = [ - "base64", + "base64 0.13.0", "data-url", "flate2", "float-cmp 0.9.0", "fontdb 0.9.1", "kurbo", - "log", + "log 0.4.17", "pico-args", "rctree 0.4.0", "roxmltree", - "rustybuzz 0.5.0", + "rustybuzz 0.5.1", "simplecss", "siphasher 0.3.10", - "svgtypes 0.8.0", - "ttf-parser 0.15.0", + "svgtypes 0.8.1", + "ttf-parser 0.15.2", "unicode-bidi", "unicode-script", "unicode-vo", @@ -5054,19 +5640,13 @@ checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372" [[package]] name = "uuid" -version = "0.8.2" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" dependencies = [ "getrandom", ] -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - [[package]] name = "vcpkg" version = "0.2.15" @@ -5081,9 +5661,9 @@ checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b" [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "vte" @@ -5105,6 +5685,12 @@ dependencies = [ "quote", ] +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + [[package]] name = "walkdir" version = "2.3.2" @@ -5122,7 +5708,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" dependencies = [ - "log", + "log 0.4.17", "try-lock", ] @@ -5138,11 +5724,72 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi-cap-std-sync" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd3298c9cd5b619d74c3ef7130a370da0f677b30110a34ab15985b3b81475bc9" +dependencies = [ + "anyhow", + "async-trait", + "cap-fs-ext", + "cap-rand", + "cap-std", + "cap-time-ext", + "fs-set-times", + "io-extras", + "io-lifetimes", + "is-terminal", + "once_cell", + "rustix", + "system-interface", + "tracing", + "wasi-common", + "windows-sys", +] + +[[package]] +name = "wasi-common" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5eaf4ef6ce85c09254f2ff414e8319b023b60007f3d0eb6164b14a41c56231c" +dependencies = [ + "anyhow", + "bitflags", + "cap-rand", + "cap-std", + "io-extras", + "rustix", + "thiserror", + "tracing", + "wiggle", + "windows-sys", +] + +[[package]] +name = "wasi-experimental-http-wasmtime" +version = "0.10.0" +source = "git+https://github.com/lapce/wasi-experimental-http#5c6d970fe0750932f76979678384bf1c5ab5be2e" +dependencies = [ + "anyhow", + "bytes", + "futures", + "http", + "reqwest", + "thiserror", + "tokio", + "tracing", + "url", + "wasi-common", + "wasmtime", + "wasmtime-wasi", +] + [[package]] name = "wasm-bindgen" -version = "0.2.76" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce9b1b516211d33767048e5d47fa2a381ed8b76fc48d2ce4aa39877f9f183e0" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -5150,13 +5797,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.76" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe8dc78e2326ba5f845f4b5bf548401604fa20b1dd1d365fb73b6c1d6364041" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" dependencies = [ "bumpalo", - "lazy_static", - "log", + "log 0.4.17", + "once_cell", "proc-macro2", "quote", "syn", @@ -5165,9 +5812,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.26" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fded345a6559c2cfee778d562300c581f7d4ff3edb9b0d230d69800d213972" +checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -5177,9 +5824,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.76" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44468aa53335841d9d6b6c023eaab07c0cd4bddbcfdee3e2bb1e8d2cb8069fef" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5187,9 +5834,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.76" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0195807922713af1e67dc66132c7328206ed9766af3858164fb583eedc25fbad" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", @@ -5200,269 +5847,264 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.76" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdb075a845574a1fa5f09fd77e43f7747599301ea3417a9fbffdeedfc1f4a29" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" [[package]] -name = "wasmer" -version = "2.1.1" +name = "wasm-encoder" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23f0188c23fc1b7de9bd7f8b834d0b1cd5edbe66e287452e8ce36d24418114f7" +checksum = "7e7ca71c70a6de5b10968ae4d298e548366d9cd9588176e6ff8866f3c49c96ee" dependencies = [ - "cfg-if 1.0.0", - "indexmap", - "js-sys", - "loupe", - "more-asserts", - "target-lexicon", - "thiserror", - "wasm-bindgen", - "wasmer-compiler", - "wasmer-compiler-cranelift", - "wasmer-derive", - "wasmer-engine", - "wasmer-engine-dylib", - "wasmer-engine-universal", - "wasmer-types", - "wasmer-vm", - "wat", - "winapi 0.3.9", + "leb128", ] [[package]] -name = "wasmer-compiler" -version = "2.1.1" +name = "wasmparser" +version = "0.89.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88c51cc589772c5f90bd329244c2416976d6cb2ee00d59429aaa8f421d9fe447" +checksum = "ab5d3e08b13876f96dd55608d03cd4883a0545884932d5adf11925876c96daef" dependencies = [ - "enumset", - "loupe", - "rkyv", - "serde 1.0.130", - "serde_bytes", - "smallvec", - "target-lexicon", - "thiserror", - "wasmer-types", - "wasmer-vm", - "wasmparser", + "indexmap", ] [[package]] -name = "wasmer-compiler-cranelift" -version = "2.1.1" +name = "wasmtime" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09691e3e323b4e1128d2127f60f9cd988b66ce49afc8184b071c2b5ab16793f2" +checksum = "4ad5af6ba38311282f2a21670d96e78266e8c8e2f38cbcd52c254df6ccbc7731" dependencies = [ - "cranelift-codegen", - "cranelift-entity", - "cranelift-frontend", - "gimli", - "loupe", - "more-asserts", + "anyhow", + "async-trait", + "bincode", + "cfg-if 1.0.0", + "indexmap", + "libc", + "log 0.4.17", + "object", + "once_cell", + "paste", + "psm", "rayon", - "smallvec", + "serde", "target-lexicon", - "tracing", - "wasmer-compiler", - "wasmer-types", - "wasmer-vm", + "wasmparser", + "wasmtime-cache", + "wasmtime-cranelift", + "wasmtime-environ", + "wasmtime-fiber", + "wasmtime-jit", + "wasmtime-runtime", + "wat", + "windows-sys", ] [[package]] -name = "wasmer-derive" -version = "2.1.1" +name = "wasmtime-asm-macros" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f5cb7b09640e09f1215da95d6fb7477d2db572f064b803ff705f39ff079cc5" +checksum = "45de63ddfc8b9223d1adc8f7b2ee5f35d1f6d112833934ad7ea66e4f4339e597" dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn", + "cfg-if 1.0.0", ] [[package]] -name = "wasmer-engine" -version = "2.1.1" +name = "wasmtime-cache" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab20311c354fe2c12bc766417e0a1a45f399c1cd8ff262127d1dc86d0588971a" +checksum = "bcd849399d17d2270141cfe47fa0d91ee52d5f8ea9b98cf7ddde0d53e5f79882" dependencies = [ - "backtrace", - "enumset", - "lazy_static", - "loupe", - "memmap2 0.5.3", - "more-asserts", - "rustc-demangle", - "serde 1.0.130", - "serde_bytes", - "target-lexicon", - "thiserror", - "wasmer-compiler", - "wasmer-types", - "wasmer-vm", + "anyhow", + "base64 0.13.0", + "bincode", + "directories-next", + "file-per-thread-logger", + "log 0.4.17", + "rustix", + "serde", + "sha2 0.9.9", + "toml", + "windows-sys", + "zstd", ] [[package]] -name = "wasmer-engine-dylib" -version = "2.1.1" +name = "wasmtime-cranelift" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dd5b7a74731e1dcccaf10a8ff5f72216c82f12972ce17cc81c6caa1afff75ea" +checksum = "4bd91339b742ff20bfed4532a27b73c86b5bcbfedd6bea2dcdf2d64471e1b5c6" dependencies = [ - "cfg-if 1.0.0", - "enumset", - "leb128", - "libloading", - "loupe", - "rkyv", - "serde 1.0.130", - "tempfile", - "tracing", - "wasmer-compiler", - "wasmer-engine", - "wasmer-object", - "wasmer-types", - "wasmer-vm", - "which", + "anyhow", + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "cranelift-native", + "cranelift-wasm", + "gimli", + "log 0.4.17", + "object", + "target-lexicon", + "thiserror", + "wasmparser", + "wasmtime-environ", ] [[package]] -name = "wasmer-engine-universal" -version = "2.1.1" +name = "wasmtime-environ" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfeae8d5b825ad7abcf9a34e66eb11e1507b21020efe7bbf9897e3dd8d7869e2" +checksum = "ebb881c61f4f627b5d45c54e629724974f8a8890d455bcbe634330cc27309644" dependencies = [ - "cfg-if 1.0.0", - "enumset", - "leb128", - "loupe", - "region", - "rkyv", - "wasmer-compiler", - "wasmer-engine", - "wasmer-types", - "wasmer-vm", - "winapi 0.3.9", + "anyhow", + "cranelift-entity", + "gimli", + "indexmap", + "log 0.4.17", + "object", + "serde", + "target-lexicon", + "thiserror", + "wasmparser", + "wasmtime-types", ] [[package]] -name = "wasmer-object" -version = "2.1.1" +name = "wasmtime-fiber" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d4714e4f3bdc3b2157c24284417d19cd99de036da31d00ec5664712dcb72f7" +checksum = "7e867cf58e31bfa0ab137bd47e207d2e1e38c581d7838b2f258d47c8145db412" dependencies = [ - "object 0.27.1", - "thiserror", - "wasmer-compiler", - "wasmer-types", + "cc", + "cfg-if 1.0.0", + "rustix", + "wasmtime-asm-macros", + "windows-sys", ] [[package]] -name = "wasmer-types" -version = "2.1.1" +name = "wasmtime-jit" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434e1c0177da0a74ecca90b2aa7d5e86198260f07e8ba83be89feb5f0a4aeead" +checksum = "1985c628011fe26adf5e23a5301bdc79b245e0e338f14bb58b39e4e25e4d8681" dependencies = [ - "indexmap", - "loupe", - "rkyv", - "serde 1.0.130", + "addr2line", + "anyhow", + "bincode", + "cfg-if 1.0.0", + "cpp_demangle", + "gimli", + "ittapi", + "log 0.4.17", + "object", + "rustc-demangle", + "rustix", + "serde", + "target-lexicon", "thiserror", + "wasmtime-environ", + "wasmtime-jit-debug", + "wasmtime-runtime", + "windows-sys", ] [[package]] -name = "wasmer-vfs" -version = "2.1.1" +name = "wasmtime-jit-debug" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a3a58a3700781aa4f5344915ea082086e75ba7ebe294f60ae499614db92dd00" +checksum = "f671b588486f5ccec8c5a3dba6b4c07eac2e66ab8c60e6f4e53717c77f709731" dependencies = [ - "libc", - "thiserror", - "tracing", + "object", + "once_cell", + "rustix", ] [[package]] -name = "wasmer-vm" -version = "2.1.1" +name = "wasmtime-runtime" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc8f964ebba70d9f81340228b98a164782591f00239fc7f01e1b67afcf0e0156" +checksum = "ee8f92ad4b61736339c29361da85769ebc200f184361959d1792832e592a1afd" dependencies = [ - "backtrace", + "anyhow", "cc", "cfg-if 1.0.0", "indexmap", "libc", - "loupe", + "log 0.4.17", + "mach", + "memfd", "memoffset", - "more-asserts", - "region", - "rkyv", - "serde 1.0.130", + "paste", + "rand", + "rustix", "thiserror", - "wasmer-types", - "winapi 0.3.9", + "wasmtime-asm-macros", + "wasmtime-environ", + "wasmtime-fiber", + "wasmtime-jit-debug", + "windows-sys", ] [[package]] -name = "wasmer-wasi" -version = "2.1.1" +name = "wasmtime-types" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2b1d981ad312dac6e74a41a35b9bca41a6d1157c3e6a575fb1041e4b516610" +checksum = "d23d61cb4c46e837b431196dd06abb11731541021916d03476a178b54dc07aeb" dependencies = [ - "cfg-if 1.0.0", - "generational-arena", - "getrandom", - "libc", + "cranelift-entity", + "serde", "thiserror", - "tracing", - "wasm-bindgen", - "wasmer", - "wasmer-vfs", - "wasmer-wasi-types", - "winapi 0.3.9", + "wasmparser", ] [[package]] -name = "wasmer-wasi-types" -version = "2.1.1" +name = "wasmtime-wasi" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7731240c0ae536623414beb73091dddf68d1a080f49086fc31ec916536b1af98" +checksum = "e69271e6b52d59a9e1a5309fefb4c38969baff8eebc03c76293e7c7dc44e0ba1" dependencies = [ - "byteorder", - "time 0.2.27", - "wasmer-types", + "anyhow", + "wasi-cap-std-sync", + "wasi-common", + "wasmtime", + "wiggle", ] [[package]] -name = "wasmparser" -version = "0.78.2" +name = "wast" +version = "35.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52144d4c78e5cf8b055ceab8e5fa22814ce4315d6002ad32cfd914f37c12fd65" +checksum = "2ef140f1b49946586078353a453a1d28ba90adfc54dde75710bc1931de204d68" +dependencies = [ + "leb128", +] [[package]] name = "wast" -version = "38.0.1" +version = "47.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae0d7b256bef26c898fa7344a2d627e8499f5a749432ce0a05eae1a64ff0c271" +checksum = "117ccfc4262e62a28a13f0548a147f19ffe71e8a08be802af23ae4ea0bedad73" dependencies = [ "leb128", + "memchr", + "unicode-width", + "wasm-encoder", ] [[package]] name = "wat" -version = "1.0.40" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcfaeb27e2578d2c6271a45609f4a055e6d7ba3a12eff35b1fd5ba147bdf046" +checksum = "7aab4e20c60429fbba9670a6cae0fff9520046ba0aa3e6d0b1cd2653bea14898" dependencies = [ - "wast", + "wast 47.0.0", ] [[package]] name = "web-sys" -version = "0.3.53" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224b2f6b67919060055ef1a67807367c2066ed520c3862cc013d26cf893a783c" +checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" dependencies = [ "js-sys", "wasm-bindgen", @@ -5470,19 +6112,61 @@ dependencies = [ [[package]] name = "weezl" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c97e489d8f836838d497091de568cf16b117486d529ec5579233521065bd5e4" +checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" [[package]] name = "which" -version = "4.2.5" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" +checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" dependencies = [ "either", - "lazy_static", "libc", + "once_cell", +] + +[[package]] +name = "wiggle" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3cd76a4d5e4052fb377eb7629a8971ce3e4668ba397e8e4c03d86ada0c7f4f1" +dependencies = [ + "anyhow", + "async-trait", + "bitflags", + "thiserror", + "tracing", + "wasmtime", + "wiggle-macro", +] + +[[package]] +name = "wiggle-generate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec1cc12e9d5af2d9488588be80b98f045a8872500bbb78c93b85a205e557f91" +dependencies = [ + "anyhow", + "heck 0.4.0", + "proc-macro2", + "quote", + "shellexpand", + "syn", + "witx", +] + +[[package]] +name = "wiggle-macro" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7d2f18f246c48657537c507de7c1941970b09ef2d4c6351debc739a1827ebd3" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wiggle-generate", ] [[package]] @@ -5528,17 +6212,30 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57b543186b344cc61c85b5aab0d2e3adf4e0f99bc076eff9aa5927bcc0b8a647" +dependencies = [ + "windows_aarch64_msvc 0.37.0", + "windows_i686_gnu 0.37.0", + "windows_i686_msvc 0.37.0", + "windows_x86_64_gnu 0.37.0", + "windows_x86_64_msvc 0.37.0", +] + [[package]] name = "windows-sys" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", ] [[package]] @@ -5547,30 +6244,60 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +[[package]] +name = "windows_aarch64_msvc" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2623277cb2d1c216ba3b578c0f3cf9cdebeddb6e66b1b218bb33596ea7769c3a" + [[package]] name = "windows_i686_gnu" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +[[package]] +name = "windows_i686_gnu" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3925fd0b0b804730d44d4b6278c50f9699703ec49bcd628020f46f4ba07d9e1" + [[package]] name = "windows_i686_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +[[package]] +name = "windows_i686_msvc" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce907ac74fe331b524c1298683efbf598bb031bc84d5e274db2083696d07c57c" + [[package]] name = "windows_x86_64_gnu" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2babfba0828f2e6b32457d5341427dcbb577ceef556273229959ac23a10af33d" + [[package]] name = "windows_x86_64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +[[package]] +name = "windows_x86_64_msvc" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4dd6dc7df2d84cf7b33822ed5b86318fb1781948e9663bacd047fc9dd52259d" + [[package]] name = "winreg" version = "0.10.1" @@ -5589,6 +6316,17 @@ dependencies = [ "toml", ] +[[package]] +name = "winx" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7b01e010390eb263a4518c8cebf86cb67469d1511c00b749a47b64c39e8054d" +dependencies = [ + "bitflags", + "io-lifetimes", + "windows-sys", +] + [[package]] name = "wio" version = "0.2.2" @@ -5598,6 +6336,18 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "witx" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e366f27a5cabcddb2706a78296a40b8fcc451e1a6aba2fc1d94b4a01bdaaef4b" +dependencies = [ + "anyhow", + "log 0.4.17", + "thiserror", + "wast 35.0.2", +] + [[package]] name = "ws2_32-sys" version = "0.2.1" @@ -5609,15 +6359,12 @@ dependencies = [ ] [[package]] -name = "xi-rope" -version = "0.3.0" -source = "git+https://github.com/lapce/xi-editor#5578c7253ff8f644638bebace1261b6a412ce03c" +name = "xattr" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" dependencies = [ - "bytecount", - "memchr", - "regex", - "serde 1.0.130", - "unicode-segmentation", + "libc", ] [[package]] @@ -5626,6 +6373,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a67300977d3dc3f8034dae89778f502b6ba20b269527b3223ba59c0cf393bb8a" +[[package]] +name = "xml-rs" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2" +dependencies = [ + "bitflags", +] + [[package]] name = "xml-rs" version = "0.8.4" @@ -5661,9 +6417,9 @@ checksum = "c03b3e19c937b5b9bd8e52b1c88f30cce5c0d33d676cf174866175bb794ff658" [[package]] name = "yeslogic-fontconfig-sys" -version = "3.0.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3f5a91c31bef6650d3a1b69192b4217fd88e4cfedc8101813e4dc3394ecbb8" +checksum = "f2bbd69036d397ebbff671b1b8e4d918610c181c5a16073b96f984a38d08c386" dependencies = [ "const-cstr", "dlib", @@ -5676,3 +6432,44 @@ name = "zeno" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c110ba09c9b3a43edd4803d570df0da2414fed6e822e22b976a4e3ef50860701" + +[[package]] +name = "zip" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537ce7411d25e54e8ae21a7ce0b15840e7bfcff15b51d697ec3266cc76bdf080" +dependencies = [ + "byteorder", + "crc32fast", + "crossbeam-utils", + "flate2", +] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.1+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fd07cbbc53846d9145dbffdf6dd09a7a0aa52be46741825f5c97bdd4f73f12b" +dependencies = [ + "cc", + "libc", +] diff --git a/Cargo.toml b/Cargo.toml index 41206af432..66aae91ac1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "lapce" -version = "0.1.2" +version = "0.2.6" authors = ["Dongdong Zhou "] edition = "2021" -rust-version = "1.60" -resolver = "2" +rust-version = "1.65" +default-run = "lapce" [dependencies] lapce-ui = { path = "./lapce-ui" } @@ -21,6 +21,61 @@ path = "lapce-proxy/src/bin/lapce-proxy.rs" [workspace] members = ["lapce-ui", "lapce-proxy", "lapce-rpc", "lapce-data", "lapce-core"] +[workspace.package] +version = "0.2.6" +edition = "2021" +rust-version = "1.64" +homepage = "https://lapce.dev" +authors = ["Dongdong Zhou "] + +[workspace.dependencies] +alacritty_terminal = "0.17.0" +anyhow = "1.0" +chrono = "0.4" +clap = { version = "3.2.17", features = ["derive"] } +crossbeam-channel = "0.5.0" +directories = "4.0.1" +flate2 = "1.0" +hashbrown = { version = "0.12.3", features = ["serde"] } +im = { version = "15.0.0", features = ["serde"] } +include_dir = "0.6.2" +indexmap = { version = "1.9", features = ["serde"] } +interprocess = "1.1.1" +itertools = "0.10.1" +log = "0.4" +notify = { version = "5.0.0", features = ["serde"] } +once_cell = "1.17" +parking_lot = { version = "0.11.0", features = ["deadlock_detection"] } +rayon = "1.5.1" +regex = "1.7.0" +reqwest = { version = "0.11", features = ["blocking", "json", "socks"] } +serde = "1.0" +serde_json = "1.0" +smallvec = "1.10.0" +strum = "0.21.0" # follow same version as system-deps in lockfile +strum_macros = "0.21.1" # ditto +tar = "0.4" +thiserror = "1.0" +toml_edit = { version = "0.14.4", features = ["easy"] } + +lsp-types = { version = "0.93", features = ["proposed"] } +psp-types = { git = "https://github.com/lapce/psp-types" } + + +lapce-xi-rope = { version = "0.3.1", features = ["serde"] } + +lapce-core = { path = "./lapce-core" } +lapce-rpc = { path = "./lapce-rpc" } +lapce-data = { path = "./lapce-data" } +lapce-proxy = { path = "./lapce-proxy" } + +[workspace.dependencies.druid] +git = "https://github.com/lapce/druid" +branch = "shell_opengl" +# path = "../../druid/druid" +features = ["svg", "im", "serde"] + + [profile.release-lto] inherits = "release" lto = true diff --git a/Makefile b/Makefile index c470a454e7..d852cd8195 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,7 @@ TARGET = lapce +CODESIGN_IDENTITY = FAC8FBEA99169DC1980731029648F110628D6A32 + ASSETS_DIR = extra RELEASE_DIR = target/release-lto @@ -31,7 +33,7 @@ $(TARGET)-universal: MACOSX_DEPLOYMENT_TARGET="10.11" cargo build --profile release-lto --target=x86_64-apple-darwin MACOSX_DEPLOYMENT_TARGET="10.11" cargo build --profile release-lto --target=aarch64-apple-darwin @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 FAC8FBEA99169DC1980731029648F110628D6A32 $(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 @@ -44,7 +46,7 @@ $(APP_NAME)-%: $(TARGET)-% @echo "Created '$(APP_NAME)' in '$(APP_DIR)'" xattr -c $(APP_DIR)/$(APP_NAME)/Contents/Info.plist 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 FAC8FBEA99169DC1980731029648F110628D6A32 $(APP_DIR)/$(APP_NAME) + /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 @@ -57,7 +59,7 @@ $(DMG_NAME)-%: $(APP_NAME)-% -srcfolder $(APP_DIR) \ -ov -format UDZO @echo "Packed '$(APP_NAME)' in '$(APP_DIR)'" - /usr/bin/codesign -vvv --deep --entitlements $(ASSETS_DIR)/entitlements.plist --strict --options=runtime --force -s FAC8FBEA99169DC1980731029648F110628D6A32 $(DMG_DIR)/$(DMG_NAME) + /usr/bin/codesign -vvv --deep --entitlements $(ASSETS_DIR)/entitlements.plist --strict --options=runtime --force -s $(CODESIGN_IDENTITY) $(DMG_DIR)/$(DMG_NAME) install: $(INSTALL)-native ## Mount disk image install-universal: $(INSTALL)-native ## Mount universal disk image diff --git a/README.md b/README.md index e14f926589..50158ad606 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,11 @@
+<<<<<<< HEAD Lapceは純粋なRustで書かれており、UIは [Druid](https://github.com/linebender/druid) (これもRustで作成されています) のUIを使用して純粋なRustで記述されています。 [Rope Science](https://xi-editor.io/docs/rope_science_00.html) の [Xi-Editor](https://github.com/xi-editor/xi-editor) を使って設計されているので、計算が非常に速いです。レンダリングには [OpenGL](https://www.opengl.org/) を利用しています。Lapce の機能についての詳細は [Lapceのウェブサイト](https://lapce.dev) から、ユーザードキュメントは [GitBook](https://docs.lapce.dev/) から閲覧が可能です。 +======= +Lapce (IPA: /læps/) is written in pure Rust with a UI in [Druid](https://github.com/linebender/druid) (which is also written in Rust). It is designed with [Rope Science](https://xi-editor.io/docs/rope_science_00.html) from the [Xi-Editor](https://github.com/xi-editor/xi-editor) which makes for lightning-fast computation, and leverages [OpenGL](https://www.opengl.org/) for rendering. More information about the features of Lapce can be found on the [main website](https://lapce.dev) and user documentation can be found on [GitBook](https://docs.lapce.dev/). +>>>>>>> 9845c1a0b3fbfd6afdc0fb1504d3be78764e0c7b ![](https://github.com/lapce/lapce/blob/master/extra/images/screenshot.png?raw=true) @@ -36,44 +40,14 @@ Lapceは純粋なRustで書かれており、UIは [Druid](https://github.com/li * Plugins can be written in programming languages that can compile to the [WASI](https://wasi.dev/) format (C, Rust, [AssemblyScript](https://www.assemblyscript.org/)) * Built-in terminal, so you can execute commands in your workspace, without leaving Lapce. -## Contributing - -Guidelines for contributing to Lapce can be found in [`CONTRIBUTING.md`](CONTRIBUTING.md). - -## 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. - -1. Install the Rust compiler and Cargo using [`rustup.rs`](https://rustup.rs/). If you already have the toolchain, ensure you are using version 1.60 or higher. +## Installation -2. Install dependencies for your operating system: +You can find pre-built releases for Windows, Linux and macOS [here](https://github.com/lapce/lapce/releases), or [installing with a package manager](docs/installing-with-package-manager.md). +If you'd like to compile from source, you can find the [guide](docs/building-from-source.md). -#### Ubuntu -```sh -sudo apt install cmake pkg-config libfontconfig-dev libgtk-3-dev -``` -#### Fedora -```sh -sudo dnf install gcc-c++ perl-FindBin perl-File-Compare gtk3-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 -``` - -```sh -cargo build --release -``` - -> If you use a different distribution, and are having trouble finding appropriate dependencies, let us know in an issue! +## Contributing -Once Lapce is compiled, the executable will be available in `target/release/lapce`. +Guidelines for contributing to Lapce can be found in [`CONTRIBUTING.md`](CONTRIBUTING.md). ## Feedback & Contact @@ -85,4 +59,4 @@ There is also a [Matrix Space](https://matrix.to/#/#lapce-editor:matrix.org), wh ## License -Lapce is released under the Apache License Version 2, which is an open source license. You may contribute to this project, or use the code as you please as long as you adhere to its conditions. You can find a copy of the license text within `LICENSE`. +Lapce is released under the Apache License Version 2, which is an open source license. You may contribute to this project, or use the code as you please as long as you adhere to its conditions. You can find a copy of the license text here: [`LICENSE`](LICENSE). diff --git a/defaults/dark-theme.toml b/defaults/dark-theme.toml index 11ab1b0df0..111ec8c266 100644 --- a/defaults/dark-theme.toml +++ b/defaults/dark-theme.toml @@ -1,4 +1,6 @@ -[theme] +#:schema ../extra/schemas/color-theme.json + +[color-theme] name = "Lapce Dark" [ui] @@ -11,20 +13,20 @@ activity-width = 50 scroll-width = 10 drop-shadow-width = 0 -[theme.base] -white = "#ABB2BF" +[color-theme.base] black = "#282C34" -grey = "#3E4451" blue = "#61AFEF" -red = "#E06C75" -yellow = "#E5C07B" -orange = "#D19A66" -green = "#98C379" -purple = "#C678DD" cyan = "#56B6C2" +green = "#98C379" +grey = "#3E4451" magenta = "#C678DD" +orange = "#D19A66" +purple = "#C678DD" +red = "#E06C75" +white = "#ABB2BF" +yellow = "#E5C07B" -[theme.syntax] +[color-theme.syntax] "comment" = "#5C6370" "constant" = "$yellow" "type" = "$yellow" @@ -45,22 +47,53 @@ magenta = "#C678DD" "property" = "$red" "enumMember" = "$red" "enum-member" = "$red" -"variable.other.member" = "$red" "string" = "$green" "type.builtin" = "$cyan" "builtinType" = "$cyan" "escape" = "$cyan" +"string.escape" = "$cyan" "embedded" = "$cyan" +"punctuation.delimiter" = "$yellow" +"text.title" = "$orange" +"text.uri" = "$cyan" +"text.reference" = "$yellow" +"variable" = "$red" +"variable.other.member" = "$green" +"tag" = "$blue" -[theme.ui] -"lapce.active_tab" = "$black" -"lapce.inactive_tab" = "$grey" +[color-theme.ui] "lapce.error" = "$red" "lapce.warn" = "$yellow" "lapce.dropdown_shadow" = "#000000" "lapce.border" = "#000000" "lapce.scroll_bar" = "$grey" +"lapce.button.primary.background" = "#50a14f" +"lapce.button.primary.foreground" = "$black" + +# tab +"lapce.tab.active.background" = "$black" +"lapce.tab.active.foreground" = "$white" +"lapce.tab.active.underline" = "#528BFF" + +"lapce.tab.inactive.background" = "#21252b" +"lapce.tab.inactive.foreground" = "$white" +"lapce.tab.inactive.underline" = "#528BFF77" + +"lapce.tab.separator" = "" + +"lapce.icon.active" = "$white" +"lapce.icon.inactive" = "#5C6370" + +"lapce.remote.icon" = "$black" +"lapce.remote.local" = "#4078F2" +"lapce.remote.connected" = "#50A14F" +"lapce.remote.connecting" = "#C18401" +"lapce.remote.disconnected" = "#E45649" + +"lapce.plugin.name" = "#DDDDDD" +"lapce.plugin.description" = "$white" +"lapce.plugin.author" = "#B0B0B0" "editor.background" = "$black" "editor.foreground" = "$white" @@ -69,14 +102,31 @@ magenta = "#C678DD" "editor.caret" = "#528BFF" "editor.selection" = "$grey" "editor.current_line" = "#2C313C" -"editor.link" = "$cyan" +"editor.link" = "$blue" +"editor.visible_whitespace" = "$grey" +"editor.indent_guide" = "$grey" +"editor.drag_drop_background" = "#79c1fc55" +"editor.drag_drop_tab_background" = "#0b0e1455" +"editor.sticky_header_background" = "$black" + +"inlay_hint.foreground" = "$white" +"inlay_hint.background" = "#528abF37" + +"error_lens.error.foreground" = "$red" +"error_lens.error.background" = "#E06C7520" +"error_lens.warning.foreground" = "$yellow" +"error_lens.warning.background" = "#E5C07B20" +"error_lens.other.foreground" = "#5C6370" +"error_lens.other.background" = "#5C637020" "source_control.added" = "#50A14F32" "source_control.removed" = "#FF526632" "source_control.modified" = "#0184BC32" "palette.background" = "#21252B" -"palette.current" = "#2C313A" +"palette.foreground" = "$white" +"palette.current.background" = "#2C313A" +"palette.current.foreground" = "$white" "completion.background" = "#21252B" "completion.current" = "#2C313A" @@ -87,14 +137,25 @@ magenta = "#C678DD" "activity.current" = "$black" "panel.background" = "#21252B" -"panel.current" = "#2C313A" -"panel.hovered" = "#343A45" +"panel.foreground" = "$white" +"panel.foreground.dim" = "#5C6370" +"panel.current.background" = "#2C313A" +"panel.current.foreground" = "$white" +"panel.current.foreground.dim" = "#5C6370" +"panel.hovered.background" = "#343A45" +"panel.hovered.foreground" = "$white" +"panel.hovered.foreground.dim" = "#5C6370" "status.background" = "#21252B" -"status.modal.normal" = "$blue" -"status.modal.insert" = "$red" -"status.modal.visual" = "$yellow" -"status.modal.terminal" = "$purple" +"status.foreground" = "$white" +"status.modal.normal.background" = "$blue" +"status.modal.normal.foreground" = "$black" +"status.modal.insert.background" = "$red" +"status.modal.insert.foreground" = "$black" +"status.modal.visual.background" = "$yellow" +"status.modal.visual.foreground" = "$black" +"status.modal.terminal.background" = "$purple" +"status.modal.terminal.foreground" = "$black" "markdown.blockquote" = "#898989" diff --git a/defaults/icon-theme.toml b/defaults/icon-theme.toml new file mode 100644 index 0000000000..a9a246377b --- /dev/null +++ b/defaults/icon-theme.toml @@ -0,0 +1,12 @@ +#:schema ../extra/schemas/icon-theme.json + +[icon-theme] +name = "Lapce Codicons" + +[icon-theme.ui] + +[icon-theme.foldername] + +[icon-theme.filename] + +[icon-theme.extension] diff --git a/defaults/keymaps-common.toml b/defaults/keymaps-common.toml index af917082a3..f480b787c0 100644 --- a/defaults/keymaps-common.toml +++ b/defaults/keymaps-common.toml @@ -4,6 +4,10 @@ key = "F1" command = "palette.command" +# [[keymaps]] +# key = "ctrl+q" +# command = "quit" + # --------------------------------- Basic editing --------------------------------------- [[keymaps]] @@ -26,6 +30,11 @@ key = "backspace" command = "delete_backward" mode = "i" +[[keymaps]] +key = "shift+backspace" +command = "delete_backward" +mode = "i" + [[keymaps]] key = "Home" command = "line_start_non_blank" @@ -55,16 +64,35 @@ command = "scroll_down" # ------------------------------------ Multi cursor ------------------------------------- [[keymaps]] -key = "alt+I" +key = "alt+shift+i" command = "insert_cursor_end_of_line" mode = "i" +# ----------------------------------- Editor Management ------------------------------- + +[[keymaps]] +key = "ctrl+tab" +command = "next_editor_tab" + +[[keymaps]] +key = "ctrl+shift+tab" +command = "previous_editor_tab" + # --------------------------------- Rich Language Editing ---------------------------- +[[keymaps]] +key = "F2" +command = "rename_symbol" + [[keymaps]] key = "F12" command = "goto_definition" +[[keymaps]] +key = "g f" +command = "show_code_actions" +mode = "n" + # ------------------------------------ Navigation ------------------------------------- [[keymaps]] @@ -108,7 +136,15 @@ mode = "i" [[keymaps]] key = "esc" command = "clear_search" -when = "search_focus" +when = "search_active || search_focus" + +[[keymaps]] +key = "ctrl+shift+up" +command = "select_next_syntax_item" + +[[keymaps]] +key = "ctrl+shift+down" +command = "select_previous_syntax_item" [[keymaps]] key = "ctrl+m" @@ -135,6 +171,11 @@ key = "up" command = "list.previous" when = "list_focus" +[[keymaps]] +key = "PageUp" +command = "list.previous_page" +when = "list_focus" + [[keymaps]] key = "ctrl+n" command = "list.next" @@ -145,6 +186,11 @@ key = "down" command = "list.next" when = "list_focus" +[[keymaps]] +key = "PageDown" +command = "list.next_page" +when = "list_focus" + [[keymaps]] key = "o" command = "list.expand" @@ -222,6 +268,12 @@ command = "global_search_refresh" when = "global_search_focus" mode = "i" +[[keymaps]] +key = "enter" +command = "confirm_rename" +when = "rename_focus" +mode = "i" + [[keymaps]] key = "tab" command = "insert_tab" @@ -234,19 +286,35 @@ command = "insert_new_line" when = "!list_focus" mode = "i" +[[keymaps]] +key = "alt+shift+up" +command = "duplicate_line_up" +mode = "i" + +[[keymaps]] +key = "alt+shift+down" +command = "duplicate_line_down" +mode = "i" + # ------------------------------------ Modal ----------------------------------------- [[keymaps]] key = "esc" command = "normal_mode" mode = "niv" -when = "!search_focus && !modal_focus" +when = "!search_focus && !modal_focus && !search_active" + +[[keymaps]] +key = "ctrl+c" +command = "normal_mode" +mode = "niv" +when = "!search_focus && !modal_focus && !search_active" [[keymaps]] key = "ctrl+[" command = "normal_mode" mode = "niv" -when = "!search_focus" +when = "!search_focus && !search_active" [[keymaps]] key = ":" @@ -254,7 +322,7 @@ command = "palette.command" mode = "n" [[keymaps]] -key = "G" +key = "shift+g" command = "go_to_line_default_last" mode = "nv" @@ -289,7 +357,7 @@ command = "append" mode = "n" [[keymaps]] -key = "A" +key = "shift+a" command = "append_end_of_line" mode = "n" @@ -328,13 +396,23 @@ key = "g d" command = "goto_definition" mode = "n" +[[keymaps]] +key = "g h" +command = "show_hover" +mode = "n" + [[keymaps]] key = "p" command = "paste" mode = "nv" [[keymaps]] -key = "J" +key = "shift+p" +command = "paste_before" +mode = "nv" + +[[keymaps]] +key = "shift+j" command = "join_lines" mode = "n" @@ -359,7 +437,32 @@ command = "delete_forward_and_insert" mode = "nv" [[keymaps]] -key = "I" +key = "c" +command = "delete_forward_and_insert" +mode = "v" + +[[keymaps]] +key = "shift+s" +command = "delete_line_and_insert" +mode = "n" + +[[keymaps]] +key = "c c" +command = "delete_line_and_insert" +mode = "n" + +[[keymaps]] +key = "c w" +command = "delete_word_and_insert" +mode = "n" + +[[keymaps]] +key = "c e" +command = "delete_word_and_insert" +mode = "n" + +[[keymaps]] +key = "shift+i" command = "insert_first_non_blank" mode = "nv" @@ -399,7 +502,7 @@ command = "word_backward" mode = "nv" [[keymaps]] -key = "O" +key = "shift+o" command = "new_line_above" mode = "nv" @@ -449,7 +552,7 @@ command = "inline_find_right" mode = "nv" [[keymaps]] -key = "F" +key = "shift+f" command = "inline_find_left" mode = "nv" @@ -489,7 +592,7 @@ command = "search_forward" mode = "nv" [[keymaps]] -key = "N" +key = "shift+n" command = "search_backward" mode = "nv" @@ -524,7 +627,7 @@ command = "toggle_visual_mode" mode = "nv" [[keymaps]] -key = "V" +key = "shift+v" command = "toggle_linewise_visual_mode" mode = "nv" @@ -587,3 +690,8 @@ mode = "v" key = "<" command = "outdent_line" mode = "v" + +[[keymaps]] +key = "shift+c" +command = "delete_to_end_and_insert" +mode = "n" diff --git a/defaults/keymaps-macos.toml b/defaults/keymaps-macos.toml index 1e3a59cfbe..7b562557b3 100644 --- a/defaults/keymaps-macos.toml +++ b/defaults/keymaps-macos.toml @@ -1,3 +1,9 @@ +# --------------------------------- Window --------------------------------------------- + +[[keymaps]] +command = "window_close" +key = "Meta+Shift+W" + # --------------------------------- General -------------------------------------------- [[keymaps]] @@ -5,7 +11,7 @@ key = "meta+p" command = "palette" [[keymaps]] -key = "meta+P" +key = "meta+shift+p" command = "palette.command" [[keymaps]] @@ -21,6 +27,10 @@ command = "open_settings" key = "meta+k meta+s" command = "open_keyboard_shortcuts" +# [[keymaps]] +# key = "meta+q" +# command = "quit" + # --------------------------------- Basic editing --------------------------------------- [[keymaps]] @@ -28,7 +38,11 @@ key = "meta+z" command = "undo" [[keymaps]] -key = "meta+Z" +key = "meta+shift+z" +command = "redo" + +[[keymaps]] +key = "meta+y" command = "redo" [[keymaps]] @@ -67,51 +81,71 @@ key = "meta+right" command = "line_end" mode = "i" -[[keymaps]] -key = "alt+backspace" -command = "delete_word_backward" +[[keymaps]] +key = "ctrl+a" +command = "line_start_non_blank" +mode = "i" + +[[keymaps]] +key = "ctrl+e" +command = "line_end" +mode = "i" + +[[keymaps]] +key = "meta+shift+k" +command = "delete_line" +mode = "i" + +[[keymaps]] +key = "alt+backspace" +command = "delete_word_backward" +mode = "i" + +[[keymaps]] +key = "meta+backspace" +command = "delete_to_beginning_of_line" mode = "i" -[[keymaps]] -key = "meta+backspace" -command = "delete_to_beginning_of_line" +[[keymaps]] +key = "ctrl+k" +command = "delete_to_end_of_line" mode = "i" -[[keymaps]] -key = "alt+delete" -command = "delete_word_forward" +[[keymaps]] +key = "alt+delete" +command = "delete_word_forward" mode = "i" -[[keymaps]] -key = "meta+|" -command = "match_pairs" +[[keymaps]] +key = "meta+|" +command = "match_pairs" mode = "i" -[[keymaps]] -key = "meta+/" -command = "toggle_line_comment" +[[keymaps]] +key = "meta+/" +command = "toggle_line_comment" -[[keymaps]] -key = "meta+]" -command = "indent_line" +[[keymaps]] +key = "meta+]" +command = "indent_line" -[[keymaps]] -key = "meta+[" -command = "outdent_line" +[[keymaps]] +key = "meta+[" +command = "outdent_line" -[[keymaps]] -key = "meta+a" -command = "select_all" +[[keymaps]] +key = "meta+a" +command = "select_all" -[[keymaps]] +[[keymaps]] key = "meta+enter" command = "new_line_below" -mode = "i" +mode = "i" -[[keymaps]] +[[keymaps]] key = "meta+shift+enter" command = "new_line_above" -mode = "i" +mode = "i" # ------------------------------------ Multi cursor ------------------------------------- @@ -131,7 +165,7 @@ command = "select_current_line" mode = "i" [[keymaps]] -key = "meta+L" +key = "meta+shift+l" command = "select_all_current" mode = "i" @@ -190,6 +224,11 @@ key = "meta+i" command = "get_completion" mode = "i" +[[keymaps]] +key = "ctrl+shift+space" +command = "get_signature" +mode = "i" + [[keymaps]] key = "meta+." command = "show_code_actions" @@ -197,19 +236,19 @@ command = "show_code_actions" # --------------------------------- Display ------------------------------------------- [[keymaps]] -key = "meta+E" +key = "meta+shift+e" command = "toggle_file_explorer_focus" [[keymaps]] -key = "meta+F" +key = "meta+shift+f" command = "toggle_search_focus" [[keymaps]] -key = "meta+X" +key = "meta+shift+x" command = "toggle_plugin_focus" [[keymaps]] -key = "meta+M" +key = "meta+shift+m" command = "toggle_problem_focus" # ------------------------------------ Navigation ------------------------------------- @@ -223,9 +262,13 @@ key = "meta+down" command = "document_end" [[keymaps]] -key = "meta+O" +key = "meta+shift+o" command = "palette.symbol" +[[keymaps]] +key = "meta+t" +command = "palette.workspace_symbol" + [[keymaps]] key = "ctrl+g" command = "palette.line" diff --git a/defaults/keymaps-nonmacos.toml b/defaults/keymaps-nonmacos.toml index a291b90ffd..b89b3389e1 100644 --- a/defaults/keymaps-nonmacos.toml +++ b/defaults/keymaps-nonmacos.toml @@ -1,3 +1,9 @@ +# --------------------------------- Window --------------------------------------------- + +[[keymaps]] +command = "close_window" +key = "Alt+F4" + # --------------------------------- General -------------------------------------------- [[keymaps]] @@ -5,7 +11,7 @@ key = "ctrl+p" command = "palette" [[keymaps]] -key = "Ctrl+P" +key = "ctrl+shift+p" command = "palette.command" [[keymaps]] @@ -21,6 +27,18 @@ command = "open_settings" key = "ctrl+k ctrl+s" command = "open_keyboard_shortcuts" +# --------------------------------- Terminal copy/paste --------------------------------- + +[[keymaps]] +key = "ctrl+shift+c" +command = "clipboard_copy" +mode = "t" + +[[keymaps]] +key = "ctrl+shift+v" +command = "clipboard_paste" +mode = "t" + # --------------------------------- Basic editing --------------------------------------- [[keymaps]] @@ -29,7 +47,13 @@ command = "undo" mode = "i" [[keymaps]] -key = "ctrl+Z" +key = "ctrl+shift+z" +command = "redo" +mode = "i" + + +[[keymaps]] +key = "ctrl+y" command = "redo" mode = "i" @@ -38,16 +62,31 @@ key = "ctrl+x" command = "clipboard_cut" mode = "i" +[[keymaps]] +key = "shift+Delete" +command = "clipboard_cut" +mode = "i" + [[keymaps]] key = "ctrl+c" command = "clipboard_copy" mode = "i" +[[keymaps]] +key = "ctrl+insert" +command = "clipboard_copy" +mode = "i" + [[keymaps]] key = "ctrl+v" command = "clipboard_paste" mode = "i" +[[keymaps]] +key = "shift+insert" +command = "clipboard_paste" +mode = "i" + [[keymaps]] key = "ctrl+f" command = "search" @@ -62,46 +101,51 @@ key = "ctrl+left" command = "word_backward" mode = "i" -[[keymaps]] -key = "ctrl+backspace" -command = "delete_word_backward" +[[keymaps]] +key = "ctrl+backspace" +command = "delete_word_backward" mode = "i" -[[keymaps]] -key = "ctrl+delete" -command = "delete_word_forward" +[[keymaps]] +key = "ctrl+delete" +command = "delete_word_forward" mode = "i" -[[keymaps]] -key = "ctrl+|" -command = "match_pairs" +[[keymaps]] +key = "shift+delete" +command = "delete_line" mode = "i" -[[keymaps]] -key = "ctrl+/" -command = "toggle_line_comment" +[[keymaps]] +key = "ctrl+|" +command = "match_pairs" +mode = "i" -[[keymaps]] -key = "ctrl+]" -command = "indent_line" +[[keymaps]] +key = "ctrl+/" +command = "toggle_line_comment" -[[keymaps]] -key = "ctrl+[" -command = "outdent_line" +[[keymaps]] +key = "ctrl+]" +command = "indent_line" -[[keymaps]] -key = "ctrl+a" -command = "select_all" +[[keymaps]] +key = "ctrl+[" +command = "outdent_line" -[[keymaps]] +[[keymaps]] +key = "ctrl+a" +command = "select_all" + +[[keymaps]] key = "ctrl+enter" command = "new_line_below" -mode = "i" +mode = "i" -[[keymaps]] +[[keymaps]] key = "ctrl+shift+enter" command = "new_line_above" -mode = "i" +mode = "i" # ------------------------------------ Multi cursor ------------------------------------- @@ -121,7 +165,7 @@ command = "select_current_line" mode = "i" [[keymaps]] -key = "ctrl+L" +key = "ctrl+shift+l" command = "select_all_current" mode = "i" @@ -185,6 +229,11 @@ key = "ctrl+i" command = "get_completion" mode = "i" +[[keymaps]] +key = "ctrl+shift+space" +command = "get_signature" +mode = "i" + [[keymaps]] key = "ctrl+." command = "show_code_actions" @@ -192,19 +241,19 @@ command = "show_code_actions" # --------------------------------- Display ------------------------------------------- [[keymaps]] -key = "ctrl+E" +key = "ctrl+shift+e" command = "toggle_file_explorer_focus" [[keymaps]] -key = "ctrl+F" +key = "ctrl+shift+f" command = "toggle_search_focus" [[keymaps]] -key = "ctrl+X" +key = "ctrl+shift+x" command = "toggle_plugin_focus" [[keymaps]] -key = "ctrl+M" +key = "ctrl+shift+m" command = "toggle_problem_focus" # ------------------------------------ Navigation ------------------------------------- @@ -218,9 +267,13 @@ key = "Ctrl+End" command = "document_end" [[keymaps]] -key = "ctrl+O" +key = "ctrl+shift+o" command = "palette.symbol" +[[keymaps]] +key = "ctrl+t" +command = "palette.workspace_symbol" + [[keymaps]] key = "ctrl+g" command = "palette.line" diff --git a/defaults/light-theme.toml b/defaults/light-theme.toml index 3d5520f71a..c5196e2acf 100644 --- a/defaults/light-theme.toml +++ b/defaults/light-theme.toml @@ -1,4 +1,6 @@ -[theme] +#:schema ../extra/schemas/color-theme.json + +[color-theme] name = "Lapce Light" [ui] @@ -11,22 +13,21 @@ activity-width = 50 scroll-width = 10 drop-shadow-width = 0 -[theme.base] -white = "#FAFAFA" +[color-theme.base] black = "#383A42" -grey = "#E5E5E6" -light_grey = "#F2F2F2" blue = "#4078F2" -red = "#E45649" -yellow = "#C18401" -green = "#50A14F" -purple = "#A626A4" cyan = "#0184BC" +green = "#50A14F" +grey = "#E5E5E6" magenta = "#A626A4" +orange = "#D19A66" +purple = "#A626A4" +red = "#E45649" +white = "#FAFAFA" +yellow = "#C18401" -[theme.syntax] +[color-theme.syntax] "comment" = "#A0A1A7" - "constant" = "$yellow" "type" = "$yellow" "typeAlias" = "$yellow" @@ -49,24 +50,57 @@ magenta = "#A626A4" "property" = "$red" "enumMember" = "$red" "enum-member" = "$red" -"variable.other.member" = "$red" "string" = "$green" +"string.escape" = "$cyan" "type.builtin" = "$cyan" "builtinType" = "$cyan" "escape" = "$cyan" "embedded" = "$cyan" -[theme.ui] -"lapce.active_tab" = "$white" -"lapce.inactive_tab" = "$grey" +"punctuation.delimiter" = "$yellow" +"text.title" = "$orange" +"text.uri" = "$cyan" +"text.reference" = "$yellow" +"variable" = "$red" +"variable.other.member" = "$green" +"tag" = "$blue" + +[color-theme.ui] "lapce.error" = "#E51400" "lapce.warn" = "#E9A700" "lapce.dropdown_shadow" = "#B4B4B4" "lapce.border" = "#B4B4B4" "lapce.scroll_bar" = "#B4B4B4" +"lapce.button.primary.background" = "#50a14f" +"lapce.button.primary.foreground" = "$white" + +# tab +"lapce.tab.active.background" = "$white" +"lapce.tab.active.foreground" = "$black" +"lapce.tab.active.underline" = "#528BFF" + +"lapce.tab.inactive.background" = "#EAEAEB" +"lapce.tab.inactive.foreground" = "$black" +"lapce.tab.inactive.underline" = "#528BFF77" + +"lapce.tab.separator" = "#B4B4B4" + +"lapce.icon.active" = "$black" +"lapce.icon.inactive" = "#A0A1A7" + +"lapce.remote.icon" = "$white" +"lapce.remote.local" = "#4078F2" +"lapce.remote.connected" = "#50A14F" +"lapce.remote.connecting" = "#C18401" +"lapce.remote.disconnected" = "#E45649" + +"lapce.plugin.name" = "#444444" +"lapce.plugin.description" = "$black" +"lapce.plugin.author" = "#707070" + "terminal.cursor" = "$black" "terminal.foreground" = "$black" "terminal.background" = "$white" @@ -94,14 +128,31 @@ magenta = "#A626A4" "editor.caret" = "#526FFF" "editor.selection" = "$grey" "editor.current_line" = "#F2F2F2" -"editor.link" = "$cyan" +"editor.link" = "$blue" +"editor.visible_whitespace" = "$grey" +"editor.indent_guide" = "$grey" +"editor.drag_drop_background" = "#79c1fc33" +"editor.drag_drop_tab_background" = "#0b0e1433" +"editor.sticky_header_background" = "$white" + +"inlay_hint.foreground" = "$black" +"inlay_hint.background" = "#528bFF55" + +"error_lens.error.foreground" = "$red" +"error_lens.error.background" = "#E4564920" +"error_lens.warning.foreground" = "$yellow" +"error_lens.warning.background" = "#C1840120" +"error_lens.other.foreground" = "#A0A1A7" +"error_lens.other.background" = "#A0A1A720" "source_control.added" = "#50A14F32" "source_control.removed" = "#FF526632" "source_control.modified" = "#0184BC32" "palette.background" = "#EAEAEB" -"palette.current" = "#DBDBDC" +"palette.foreground" = "$black" +"palette.current.background" = "#DBDBDC" +"palette.current.foreground" = "$black" "completion.background" = "#EAEAEB" "completion.current" = "#DBDBDC" @@ -112,13 +163,24 @@ magenta = "#A626A4" "activity.current" = "$white" "panel.background" = "#EAEAEB" -"panel.current" = "#DBDBDC" -"panel.hovered" = "#E4E4E6" +"panel.foreground" = "$black" +"panel.foreground.dim" = "#A0A1A7" +"panel.current.background" = "#DBDBDC" +"panel.current.foreground" = "$black" +"panel.current.foreground.dim" = "#A0A1A7" +"panel.hovered.background" = "#E4E4E6" +"panel.hovered.foreground" = "$black" +"panel.hovered.foreground.dim" = "#A0A1A7" "status.background" = "#EAEAEB" -"status.modal.normal" = "$blue" -"status.modal.insert" = "$red" -"status.modal.visual" = "$yellow" -"status.modal.terminal" = "$purple" +"status.foreground" = "$black" +"status.modal.normal.background" = "$blue" +"status.modal.normal.foreground" = "$white" +"status.modal.insert.background" = "$red" +"status.modal.insert.foreground" = "$white" +"status.modal.visual.background" = "$yellow" +"status.modal.visual.foreground" = "$white" +"status.modal.terminal.background" = "$purple" +"status.modal.terminal.foreground" = "$white" "markdown.blockquote" = "#686868" diff --git a/defaults/settings.toml b/defaults/settings.toml index cd1e772f63..611335419d 100644 --- a/defaults/settings.toml +++ b/defaults/settings.toml @@ -1,19 +1,53 @@ -[lapce] +#:schema ../extra/schemas/settings.json + +[core] modal = false color-theme = "Lapce Dark" -icon-theme = "" +icon-theme = "Lapce Codicons" +custom-titlebar = true [editor] font-family = "Cascadia Code" font-size = 13 code-lens-font-size = 2 -line-height = 25 +line-height = 1.5 tab-width = 4 show-tab = true +show-bread-crumbs = true scroll-beyond-last-line = true -hover-delay = 300 # ms +cursor-surrounding-lines = 1 +sticky-header = true +completion-show-documentation = true +show-signature = true +signature-label-code-block = true +auto-closing-matching-pairs = true +hover-delay = 300 # ms modal-mode-relative-line-numbers = true -format-on-save = true +format-on-save = false +highlight-matching-brackets = true +highlight-scope-lines = false +autosave-interval = 0 +format-on-autosave = true +enable-inlay-hints = true +inlay-hint-font-family = "" +inlay-hint-font-size = 0 +enable-error-lens = true +error-lens-end-of-line = true +error-lens-font-family = "" +error-lens-font-size = 0 +enable-completion-lens = false +completion-lens-font-family = "" +completion-lens-font-size = 0 +blink-interval = 500 # ms +multicursor-case-sensitive = true +multicursor-whole-words = true +render-whitespace = "none" +show-indent-guide = true +atomic-soft-tabs = false +double-click = "single" +move-focus-while-search = true +diff-context-lines=3 +scroll-speed-modifier=1 [terminal] font-family = "" @@ -24,17 +58,22 @@ shell = "" [ui] font-family = "" font-size = 13 +icon-size = 0 header-height = 35 status-height = 25 tab-min-width = 100 -activity-width = 50 scroll-width = 10 drop-shadow-width = 0 +preview-editor-width = 0 +hover-font-family = "" +hover-font-size = 0 +trim-search-results-whitespace = true +list-line-height = 25 -[theme] +[color-theme] name = "" -[theme.base] +[color-theme.base] white = "#ABB2BF" black = "#282C34" grey = "#3E4451" @@ -47,7 +86,7 @@ purple = "#C678DD" cyan = "#56B6C2" magenta = "#C678DD" -[theme.syntax] +[color-theme.syntax] "comment" = "#5C6370" "constant" = "$yellow" "type" = "$yellow" @@ -63,6 +102,7 @@ magenta = "#C678DD" "method" = "$blue" "function.method" = "$blue" "keyword" = "$purple" +"keyword.control" = "$purple" "selfKeyword" = "$purple" "field" = "$red" "property" = "$red" @@ -74,16 +114,42 @@ magenta = "#C678DD" "builtinType" = "$cyan" "escape" = "$cyan" "embedded" = "$cyan" +"symbol" = "$yellow" -[theme.ui] -"lapce.active_tab" = "$black" -"lapce.inactive_tab" = "$grey" +[color-theme.ui] "lapce.error" = "$red" "lapce.warn" = "$yellow" "lapce.dropdown_shadow" = "#000000" "lapce.border" = "#000000" "lapce.scroll_bar" = "$grey" +"lapce.button.primary.background" = "#50a14f" +"lapce.button.primary.foreground" = "$black" + +# tab +"lapce.tab.active.background" = "$black" +"lapce.tab.active.foreground" = "$white" +"lapce.tab.active.underline" = "#528BFF" + +"lapce.tab.inactive.background" = "#21252b" +"lapce.tab.inactive.foreground" = "$white" +"lapce.tab.inactive.underline" = "#528BFF77" + +"lapce.tab.separator" = "#000000" + +"lapce.icon.active" = "$white" +"lapce.icon.inactive" = "#5C6370" + +"lapce.remote.icon" = "$black" +"lapce.remote.local" = "#4078F2" +"lapce.remote.connected" = "#50A14F" +"lapce.remote.connecting" = "#C18401" +"lapce.remote.disconnected" = "#E45649" + +"lapce.plugin.name" = "#DDDDDD" +"lapce.plugin.description" = "$white" +"lapce.plugin.author" = "#B0B0B0" + "editor.background" = "$black" "editor.foreground" = "$white" "editor.dim" = "#5C6370" @@ -91,14 +157,33 @@ magenta = "#C678DD" "editor.caret" = "#528bFF" "editor.selection" = "$grey" "editor.current_line" = "#2C313C" -"editor.link" = "$cyan" +"editor.link" = "$blue" +"editor.visible_whitespace" = "#5C6370" +"editor.indent_guide" = "$grey" +"editor.drag_drop_background" = "#79c1fc55" +"editor.drag_drop_tab_background" = "#0b0e1455" +"editor.sticky_header_background" = "$black" + +"inlay_hint.foreground" = "$white" +"inlay_hint.background" = "#528bFF88" + +"error_lens.error.foreground" = "$red" +"error_lens.error.background" = "#E06C7520" +"error_lens.warning.foreground" = "$yellow" +"error_lens.warning.background" = "#E5C07B20" +"error_lens.other.foreground" = "#5C6370" +"error_lens.other.background" = "#5C637020" + +"completion_lens.foreground" = "#5C6370" "source_control.added" = "#50A14F32" "source_control.removed" = "#FF526632" "source_control.modified" = "#0184BC32" "palette.background" = "#21252B" -"palette.current" = "#2C313A" +"palette.foreground" = "$white" +"palette.current.background" = "#2C313A" +"palette.current.foreground" = "$white" "completion.background" = "#21252B" "completion.current" = "#2C313A" @@ -109,14 +194,25 @@ magenta = "#C678DD" "activity.current" = "$black" "panel.background" = "#21252B" -"panel.current" = "#2C313A" -"panel.hovered" = "#343A45" +"panel.foreground" = "$white" +"panel.foreground.dim" = "#5C6370" +"panel.current.background" = "#2C313A" +"panel.current.foreground" = "$white" +"panel.current.foreground.dim" = "#5C6370" +"panel.hovered.background" = "#343A45" +"panel.hovered.foreground" = "$white" +"panel.hovered.foreground.dim" = "#5C6370" "status.background" = "#21252B" -"status.modal.normal" = "$blue" -"status.modal.insert" = "$red" -"status.modal.visual" = "$yellow" -"status.modal.terminal" = "$purple" +"status.foreground" = "$white" +"status.modal.normal.background" = "$blue" +"status.modal.normal.foreground" = "$black" +"status.modal.insert.background" = "$red" +"status.modal.insert.foreground" = "$black" +"status.modal.visual.background" = "$yellow" +"status.modal.visual.foreground" = "$black" +"status.modal.terminal.background" = "$purple" +"status.modal.terminal.foreground" = "$black" "markdown.blockquote" = "#898989" @@ -139,3 +235,122 @@ magenta = "#C678DD" "terminal.bright_cyan" = "$cyan" "terminal.bright_magenta" = "$magenta" "terminal.bright_black" = "#545862" + +[icon-theme] +name = "" + +[icon-theme.ui] +"logo" = "lapce_logo.svg" +"link" = "link.svg" +"error" = "error.svg" +"add" = "add.svg" +"close" = "close.svg" +"remote" = "lapce_remote.svg" +"unsaved" = "circle-filled.svg" +"warning" = "warning.svg" +"problem" = "problem.svg" +"settings" = "settings-gear.svg" +"terminal" = "terminal.svg" +"lightbulb" = "lightbulb.svg" +"extensions" = "extensions.svg" +"breadcrumb_separator" = "chevron-right.svg" + +"window.close" = "chrome-close.svg" +"window.restore" = "chrome-restore.svg" +"window.maximize" = "chrome-maximize.svg" +"window.minimize" = "chrome-minimize.svg" + +"file" = "file.svg" +"file_explorer" = "files.svg" +"file_picker_up" = "arrow-up.svg" + +"image_loading" = "refresh.svg" +"image_error" = "error.svg" + +"scm.icon" = "source-control.svg" +"scm.diff.modified" = "diff-modified.svg" +"scm.diff.added" = "diff-added.svg" +"scm.diff.removed" = "diff-removed.svg" +"scm.diff.renamed" = "diff-renamed.svg" +"scm.change.add" = "add.svg" +"scm.change.remove" = "remove.svg" + +"palette.menu" = "chevron-down.svg" + +"dropdown.arrow" = "chevron-down.svg" + +"location.forward" = "arrow-right.svg" +"location.backward" = "arrow-left.svg" + +"item.opened" = "chevron-down.svg" +"item.closed" = "chevron-right.svg" + +"directory.closed" = "folder.svg" +"directory.opened" = "folder-opened.svg" + +"panel.restore" = "chevron-down.svg" +"panel.maximise" = "chevron-right.svg" + +"split.horizontal" = "split-horizontal.svg" + +"tab.previous" = "chevron-left.svg" +"tab.next" = "chevron-right.svg" + +"sidebar.left.on" = "layout-sidebar-left.svg" +"sidebar.left.off" = "layout-sidebar-left-off.svg" +"sidebar.right.on" = "layout-sidebar-right.svg" +"sidebar.right.off" = "layout-sidebar-right-off.svg" + +"layout.panel.on" = "layout-panel.svg" +"layout.panel.off" = "layout-panel-off.svg" + +"search.icon" = "search.svg" +"search.clear" = "close.svg" +"search.forward" = "arrow-down.svg" +"search.backward" = "arrow-up.svg" +"search.case_sensitive" = "case-sensitive.svg" + +"symbol_kind.array" = "symbol-array.svg" +"symbol_kind.boolean" = "symbol-boolean.svg" +"symbol_kind.class" = "symbol-class.svg" +"symbol_kind.constant" = "symbol-constant.svg" +"symbol_kind.enum_member" = "symbol-enum-member.svg" +"symbol_kind.enum" = "symbol-enum.svg" +"symbol_kind.event" = "symbol-event.svg" +"symbol_kind.field" = "symbol-field.svg" +"symbol_kind.file" = "symbol-file.svg" +"symbol_kind.function" = "symbol-method.svg" +"symbol_kind.interface" = "symbol-interface.svg" +"symbol_kind.key" = "symbol-key.svg" +"symbol_kind.method" = "symbol-method.svg" +"symbol_kind.namespace" = "symbol-namespace.svg" +"symbol_kind.number" = "symbol-numeric.svg" +"symbol_kind.object" = "symbol-namespace.svg" +"symbol_kind.operator" = "symbol-operator.svg" +"symbol_kind.property" = "symbol-property.svg" +"symbol_kind.string" = "symbol-string.svg" +"symbol_kind.struct" = "symbol-structure.svg" +"symbol_kind.type_parameter" = "symbol-parameter.svg" +"symbol_kind.variable" = "symbol-variable.svg" + +"completion_item_kind.class" = "symbol-class.svg" +"completion_item_kind.constant" = "symbol-constant.svg" +"completion_item_kind.enum_member" = "symbol-enum-member.svg" +"completion_item_kind.enum" = "symbol-enum.svg" +"completion_item_kind.field" = "symbol-field.svg" +"completion_item_kind.function" = "symbol-method.svg" +"completion_item_kind.interface" = "symbol-interface.svg" +"completion_item_kind.keyword" = "symbol-keyword.svg" +"completion_item_kind.method" = "symbol-method.svg" +"completion_item_kind.module" = "symbol-namespace.svg" +"completion_item_kind.property" = "symbol-property.svg" +"completion_item_kind.snippet" = "symbol-snippet.svg" +"completion_item_kind.string" = "symbol-string.svg" +"completion_item_kind.struct" = "symbol-structure.svg" +"completion_item_kind.variable" = "symbol-variable.svg" + +[icon-theme.foldername] + +[icon-theme.filename] + +[icon-theme.extension] diff --git a/docs/building-from-source.md b/docs/building-from-source.md new file mode 100644 index 0000000000..72e5aa7ce0 --- /dev/null +++ b/docs/building-from-source.md @@ -0,0 +1,34 @@ +## 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. + +1. Install the Rust compiler and Cargo using [`rustup.rs`](https://rustup.rs/). If you already have the toolchain, ensure you are using version 1.64 or higher. + +2. Install dependencies for your operating system: + +#### Ubuntu +```sh +sudo apt install cmake pkg-config libfontconfig-dev libgtk-3-dev g++ +``` +#### Fedora +```sh +sudo dnf install gcc-c++ perl-FindBin perl-File-Compare gtk3-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 +``` + +```sh +cargo build --release +``` + +> 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 `target/release/lapce`. diff --git a/docs/installing-with-package-manager.md b/docs/installing-with-package-manager.md new file mode 100644 index 0000000000..1f82b3afb5 --- /dev/null +++ b/docs/installing-with-package-manager.md @@ -0,0 +1,43 @@ +## Installation With Package Manager + +### Arch Linux + +There is an community package that can be installed with `pacman`: + +```bash +sudo pacman -Syu lapce +``` + +### Fedora +```bash +sudo dnf copr enable titaniumtown/lapce +sudo dnf install lapce +``` + +### Flatpak + +Lapce is available as a flatpak [here](https://flathub.org/apps/details/dev.lapce.lapce) + +```bash +flatpak install flathub dev.lapce.lapce +``` + +### Homebrew + +```bash +brew install lapce +``` + +### Scoop + +```bash +scoop install lapce +``` + +### winget + +You can find the packages [here](https://github.com/microsoft/winget-pkgs/tree/master/manifests/l/Lapce/Lapce): + +```bash +winget install lapce +``` diff --git a/docs/new-contributor-guide-developer.md b/docs/new-contributor-guide-developer.md index 46d536e499..59c3d9a34b 100644 --- a/docs/new-contributor-guide-developer.md +++ b/docs/new-contributor-guide-developer.md @@ -4,7 +4,7 @@ This document contains some useful resources for anyone wishing to contribute to ## Quick Start -1. Get an overview of the architecture from [`docs/why-lapce.md`](why-lapce.md). +1. Get an overview of the architecture from [`docs/why-lapce.md`](why-lapce.md) and [Architecture](https://docs.lapce.dev/development/architecture). 2. Explore the rope data structure, a key part of Lapce's architecture. The crate used is [xi_rope](https://crates.io/crates/xi-rope). @@ -16,8 +16,8 @@ This document contains some useful resources for anyone wishing to contribute to ## Resources -The [Wikipedia article on ropes](https://citeseer.ist.psu.edu/viewdoc/download?doi=10.1.1.14.9450&rep=rep1&type=pdf) provides an overview of the data structure. +The [Wikipedia article on ropes](https://en.wikipedia.org/wiki/Rope_(data_structure)) provides an overview of the data structure. -For some context, also see [Ropes: an Alternative to Strings](https://citeseer.ist.psu.edu/viewdoc/download?doi=10.1.1.14.9450&rep=rep1&type=pdf) by Boehm, Atkinson, and Plass. +For some context, also see [Ropes: an Alternative to Strings](https://www.cs.tufts.edu/comp/150FP/archive/hans-boehm/ropes.pdf) by Boehm, Atkinson, and Plass. diff --git a/docs/why-lapce.md b/docs/why-lapce.md index 17a4dd345b..8ecfa5c6b6 100644 --- a/docs/why-lapce.md +++ b/docs/why-lapce.md @@ -1,23 +1,23 @@ -I'm a Vim fan. After years of using it, I started to customize it like everybody else. I thought I had something that worked quite well until I hit one problem. My linter sometimes took seconds to check the code, and it would freeze Vim because Vim didn't have asynchronous support. I looked around; I found NeoVim and problem solved. Happy days. - -But there was always this one thing I couldn't solve. I want to make Vim pretty. I tried all kinds of themes. Tried all kinds of status bar plugins with icons in it. File explorers with file icons in them. But no, I also wanted a 1px vertical split bar, not the thick colored one or the dashed line drawn with pipe characters. After hours and hours of search, it occurred to me that it's impossible to do. Again NeoVim was the savior. It introduced external UI. The idea was that NeoVim splits the UI and the backend. The backend emits events to the UI, and the UI draws them. I couldn't wait to try it out with writing a UI in Electron, with the hope that I could solve my vertical split bar dream. But I didn't because it emits the drawing events treating it as a whole canvas, and I don't get the boundary of each splits. I started to hack NeoVim code. I made it to emit split sizes and positions, and I finally can draw the bars in the UI. With joy, I also looked at emits the command modes to the UI, so I could put the command in the middle of the window. And then echo messages, status line, etc. I pushed a PR for the hacky solution(https://github.com/neovim/neovim/pull/5686). Then I hit performance issues in Electron because Javascript was not fast enough to deserialize the drawing events from NeoVim. So I wrote another UI in Go with Qt binding(https://github.com/dzhou121/gonvim). - -I wanted to external more and more components in NeoVim, but I found it harder and harder, and I spotted Xi-Editor. I started to write a UI for it straightaway. Creating a code editor with Vim editing experience was the plan. There were things missing that I had to add in Xi. And working on it was so much easier because Xi was built to be the UI/backend architecture without the heritage(burden) of (Neo)Vim. - -Then one day, I experienced VSCode's remote development feature, and it felt so "local". I wanted to add the feature to my code editor. Then I realized that it can't be done with NeoVim or Xi's UI/backend architecture. The reason was that (Neo)Vim/Xi backends are the editing engine, so when you put the backend to a remote machine, every keyboard input needs to be sent to it, and the backend emits the drawing events to you, which will include the network latency in everything you type. That wouldn't work. The editing logic must be tightly bound with the UI to give the best editing experience. - -So the new architecture I came up with was like this: - - UI -Reads file from Proxy
-Handle keyboard/mouse events and do the edits on the file buffer
-Send the file editing delta to the proxy to keep the file in sync
- - Proxy -Receive save event from UI and flush the file buffer to disk
-proxy the events between UI and the plugins
- - Plugin -Communicate with UI through proxy
- -UI sits locally. Proxy and Plugin will be in the remote box when doing remote development. With this architecture, I can make sure the editing experience is always the best, with other considerations like syntax highlighting being done in a different thread, so nothing blocks the main thread at any time. I finally had a lightning-fast and powerful code editor. (which can be beautiful as well) +I'm a Vim fan. After years of using it, I started to customize it like everybody else. I thought I had something that worked quite well until I hit one problem. My linter sometimes took seconds to check the code, and it would freeze Vim because Vim didn't have asynchronous support. I looked around; I found NeoVim and problem solved. Happy days. + +But there was always this one thing I couldn't solve. I want to make Vim pretty. I tried all kinds of themes. Tried all kinds of status bar plugins with icons in it. File explorers with file icons in them. But no, I also wanted a 1px vertical split bar, not the thick colored one or the dashed line drawn with pipe characters. After hours and hours of search, it occurred to me that it's impossible to do. Again NeoVim was the savior. It introduced external UI. The idea was that NeoVim splits the UI and the backend. The backend emits events to the UI, and the UI draws them. I couldn't wait to try it out with writing a UI in Electron, with the hope that I could solve my vertical split bar dream. But I didn't because it emits the drawing events treating it as a whole canvas, and I don't get the boundary of each splits. I started to hack NeoVim code. I made it to emit split sizes and positions, and I finally can draw the bars in the UI. With joy, I also looked at emits the command modes to the UI, so I could put the command in the middle of the window. And then echo messages, status line, etc. I pushed a PR for the hacky solution(https://github.com/neovim/neovim/pull/5686). Then I hit performance issues in Electron because Javascript was not fast enough to deserialize the drawing events from NeoVim. So I wrote another UI in Go with Qt binding(https://github.com/dzhou121/gonvim). + +I wanted to external more and more components in NeoVim, but I found it harder and harder, and I spotted Xi-Editor. I started to write a UI for it straightaway. Creating a code editor with Vim editing experience was the plan. There were things missing that I had to add in Xi. And working on it was so much easier because Xi was built to be the UI/backend architecture without the heritage(burden) of (Neo)Vim. + +Then one day, I experienced VSCode's remote development feature, and it felt so "local". I wanted to add the feature to my code editor. Then I realized that it can't be done with NeoVim or Xi's UI/backend architecture. The reason was that (Neo)Vim/Xi backends are the editing engine, so when you put the backend to a remote machine, every keyboard input needs to be sent to it, and the backend emits the drawing events to you, which will include the network latency in everything you type. That wouldn't work. The editing logic must be tightly bound with the UI to give the best editing experience. + +So the new architecture I came up with was like this: + + UI +Reads file from Proxy
+Handle keyboard/mouse events and do the edits on the file buffer
+Send the file editing delta to the proxy to keep the file in sync
+ + Proxy +Receive save event from UI and flush the file buffer to disk
+proxy the events between UI and the plugins
+ + Plugin +Communicate with UI through proxy
+ +UI sits locally. Proxy and Plugin will be in the remote box when doing remote development. With this architecture, I can make sure the editing experience is always the best, with other considerations like syntax highlighting being done in a different thread, so nothing blocks the main thread at any time. I finally had a lightning-fast and powerful code editor. (which can be beautiful as well) diff --git a/extra/images/logo.png b/extra/images/logo.png index d52ace007c..73c0b50e33 100644 Binary files a/extra/images/logo.png and b/extra/images/logo.png differ diff --git a/extra/images/logo_app.svg b/extra/images/logo_app.svg new file mode 100644 index 0000000000..4865afe4ff --- /dev/null +++ b/extra/images/logo_app.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/extra/images/logo_app_light.svg b/extra/images/logo_app_light.svg new file mode 100644 index 0000000000..d5106d0778 --- /dev/null +++ b/extra/images/logo_app_light.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/extra/images/logo_color.svg b/extra/images/logo_color.svg new file mode 100644 index 0000000000..3a781785b1 --- /dev/null +++ b/extra/images/logo_color.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/extra/images/screenshot.png b/extra/images/screenshot.png index 1ccce3d5e6..9d44b90f71 100644 Binary files a/extra/images/screenshot.png and b/extra/images/screenshot.png differ diff --git a/extra/images/volt.png b/extra/images/volt.png new file mode 100644 index 0000000000..4bcfe9b294 Binary files /dev/null and b/extra/images/volt.png differ diff --git a/extra/linux/dev.lapce.lapce.desktop b/extra/linux/dev.lapce.lapce.desktop index 83f9c5cc1f..f4aee65474 100644 --- a/extra/linux/dev.lapce.lapce.desktop +++ b/extra/linux/dev.lapce.lapce.desktop @@ -5,7 +5,15 @@ Type=Application Name=Lapce Comment=Lightning-fast and powerful code editor written in Rust Categories=Development;IDE; +GenericName=Code Editor Icon=dev.lapce.lapce Exec=lapce Terminal=false +MimeType=text/plain;inode/directory; +Actions=new-window; + +[Desktop Action new-window] +Name=New Window +Exec=lapce --new %F +Icon=dev.lapce.lapce diff --git a/extra/linux/dev.lapce.lapce.metainfo.xml b/extra/linux/dev.lapce.lapce.metainfo.xml index 429c2ae698..791c4a23d9 100644 --- a/extra/linux/dev.lapce.lapce.metainfo.xml +++ b/extra/linux/dev.lapce.lapce.metainfo.xml @@ -30,6 +30,6 @@ - + diff --git a/extra/macos/Lapce.app/Contents/Info.plist b/extra/macos/Lapce.app/Contents/Info.plist index 86f6dd6695..6fa8fa641b 100644 --- a/extra/macos/Lapce.app/Contents/Info.plist +++ b/extra/macos/Lapce.app/Contents/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.10.0-dev + 0.2.6 CFBundleSupportedPlatforms MacOSX diff --git a/extra/macos/Lapce.app/Contents/Resources/lapce.icns b/extra/macos/Lapce.app/Contents/Resources/lapce.icns index d6a237c844..691e4b1eee 100644 Binary files a/extra/macos/Lapce.app/Contents/Resources/lapce.icns and b/extra/macos/Lapce.app/Contents/Resources/lapce.icns differ diff --git a/extra/proxy.ps1 b/extra/proxy.ps1 new file mode 100644 index 0000000000..42bc12ef05 --- /dev/null +++ b/extra/proxy.ps1 @@ -0,0 +1,47 @@ +[CmdletBinding()] +param( + [string]$version, + [string]$directory +) + +$proxy = (Join-Path $directory 'lapce.exe') + +$LapceProcesses = (Get-Process -Name 'lapce' -EA SilentlyContinue).Count +if ($LapceProcesses -ne 0) { + Write-Host 'Proxy currently in use. Aborting installation' + exit +} + +if (Test-Path $proxy) { + Write-Host 'Proxy already installed' + exit +} + +switch ($env:PROCESSOR_ARCHITECTURE) { + # Only x86_64 is supported currently + 'AMD64' { + $arch = 'x86_64' + } +} + +$url = "https://github.com/lapce/lapce/releases/download/${version}/lapce-proxy-windows-${arch}.gz" +$gzip = Join-Path "${env:TMP}" "lapce-proxy-windows-${arch}.gz" + +$webclient = [System.Net.WebClient]::new() +$webclient.DownloadFile($url, $gzip) +$webclient.Dispose() + +[System.IO.Directory]::CreateDirectory($directory) + +$archive = [System.IO.File]::Open($gzip, [System.IO.FileMode]::Open) +$proxy_file = [System.IO.File]::Create($proxy) +$compressor = [System.IO.Compression.GZipStream]::new($archive, [System.IO.Compression.CompressionMode]::Decompress) +$compressor.CopyTo($proxy_file) +Start-Sleep -Seconds 3 +$compressor.close() +$proxy_file.close() +$archive.close() + +[System.IO.File]::Delete($gzip) + +Write-Host 'lapce-proxy installed' \ No newline at end of file diff --git a/extra/proxy.sh b/extra/proxy.sh new file mode 100644 index 0000000000..87e727e62d --- /dev/null +++ b/extra/proxy.sh @@ -0,0 +1,92 @@ +#!/bin/sh +set -eux + +# This script is written to be as POSIX as possible +# so it works fine for all Unix-like operating systems + +test_cmd() { + command -v "$1" >/dev/null +} + +tmp_dir='/tmp' +# proxy version +lapce_new_ver="${1}" +# proxy directory +# eval to resolve '~' into proper user dir +eval lapce_dir="'${2}'" + +if [ -e "${lapce_dir}/lapce" ]; then + chmod +x "${lapce_dir}/lapce" + + lapce_installed_ver=$("${lapce_dir}/lapce" --version | cut -d'v' -f2) + + printf '[DEBUG]: Current proxy version: %s\n' "${lapce_installed_ver}" + printf '[DEBUG]: New proxy version: %s\n' "${lapce_new_ver}" + if [ "${lapce_installed_ver}" = "${lapce_new_ver}" ]; then + printf 'Proxy already exists\n' + exit 0 + else + printf 'Proxy outdated. Replacing proxy\n' + rm "${lapce_dir}/lapce" + fi +fi + +for _cmd in tar gzip uname; do + if ! test_cmd "${_cmd}"; then + printf 'Missing required command: %s\n' "${_cmd}" + exit 1 + fi +done + +# Currently only linux/darwin are supported +case $(uname -s) in + Linux) os_name=linux ;; + Darwin) os_name=darwin ;; + *) + printf '[ERROR] unsupported os' + ;; +esac + +# Currently only amd64/arm64 are supported +case $(uname -m) in + x86_64|amd64|x64) arch_name=x86_64 ;; + arm64|aarch64) arch_name=aarch64 ;; + # riscv64) arch_name=riscv64 ;; + *) + printf '[ERROR] unsupported arch' + ;; +esac + +printf 'Switching to "%s"\n' "${tmp_dir}" +cd "${tmp_dir}" + +lapce_download_url="https://github.com/lapce/lapce/releases/download/${lapce_new_ver}/lapce-proxy-${os_name}-${arch_name}.gz" + +if test_cmd 'curl'; then + # How old curl has these options? we'll find out + printf 'Downloading using curl\n' + curl --proto '=https' --tlsv1.2 -LfS -O "${lapce_download_url}" + # curl --proto '=https' --tlsv1.2 -LZfS -o "${tmp_dir}/lapce-proxy-${os_name}-${arch_name}.gz" "${lapce_download_url}" +elif test_cmd 'wget'; then + printf 'Downloading using wget\n' + wget "${lapce_download_url}" +else + printf 'curl/wget not found, failed to download proxy\n' + exit 1 +fi + +printf 'Creating "%s"\n' "${lapce_dir}" +mkdir -p "${lapce_dir}" + +printf 'Decompressing gzip\n' +gzip -d "${tmp_dir}/lapce-proxy-${os_name}-${arch_name}.gz" + +printf 'Moving proxy to our dir\n' +mv -v "${tmp_dir}/lapce-proxy-${os_name}-${arch_name}" "${lapce_dir}/lapce" + +printf 'Making it executable\n' +chmod +x "${lapce_dir}/lapce" + +printf 'lapce-proxy installed\n' + +exit 0 diff --git a/extra/schemas/color-theme.json b/extra/schemas/color-theme.json new file mode 100644 index 0000000000..55ca4caed0 --- /dev/null +++ b/extra/schemas/color-theme.json @@ -0,0 +1,223 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$ref": "#/definitions/ColorTheme", + "definitions": { + "ColorTheme": { + "type": "object", + "additionalProperties": false, + "properties": { + "color-theme": { + "$ref": "#/definitions/ColorThemeClass" + }, + "ui": { + "$ref": "#/definitions/UI" + } + }, + "required": [], + "title": "ColorTheme" + }, + "ColorThemeClass": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "base": { + "$ref": "#/definitions/Base" + }, + "syntax": { + "$ref": "#/definitions/Syntax" + }, + "ui": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "required": [], + "title": "ColorThemeClass" + }, + "Base": { + "type": "object", + "additionalProperties": false, + "properties": { + "white": { + "type": "string" + }, + "black": { + "type": "string" + }, + "grey": { + "type": "string" + }, + "blue": { + "type": "string" + }, + "red": { + "type": "string" + }, + "yellow": { + "type": "string" + }, + "orange": { + "type": "string" + }, + "green": { + "type": "string" + }, + "purple": { + "type": "string" + }, + "cyan": { + "type": "string" + }, + "magenta": { + "type": "string" + } + }, + "required": [], + "title": "Base" + }, + "Syntax": { + "type": "object", + "additionalProperties": false, + "properties": { + "comment": { + "type": "string" + }, + "constant": { + "type": "string" + }, + "type": { + "type": "string" + }, + "typeAlias": { + "type": "string" + }, + "number": { + "type": "string" + }, + "enum": { + "type": "string" + }, + "struct": { + "type": "string" + }, + "structure": { + "type": "string" + }, + "interface": { + "type": "string" + }, + "attribute": { + "type": "string" + }, + "constructor": { + "type": "string" + }, + "function": { + "type": "string" + }, + "method": { + "type": "string" + }, + "function.method": { + "type": "string" + }, + "keyword": { + "type": "string" + }, + "selfKeyword": { + "type": "string" + }, + "field": { + "type": "string" + }, + "property": { + "type": "string" + }, + "enumMember": { + "type": "string" + }, + "enum-member": { + "type": "string" + }, + "string": { + "type": "string" + }, + "type.builtin": { + "type": "string" + }, + "builtinType": { + "type": "string" + }, + "escape": { + "type": "string" + }, + "string.escape": { + "type": "string" + }, + "embedded": { + "type": "string" + }, + "punctuation.delimiter": { + "type": "string" + }, + "text.title": { + "type": "string" + }, + "text.uri": { + "type": "string" + }, + "text.reference": { + "type": "string" + }, + "variable": { + "type": "string" + }, + "variable.other.member": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "required": [], + "title": "Syntax" + }, + "UI": { + "type": "object", + "additionalProperties": false, + "properties": { + "font-family": { + "type": "string" + }, + "font-size": { + "type": "integer" + }, + "header-height": { + "type": "integer" + }, + "status-height": { + "type": "integer" + }, + "tab-min-width": { + "type": "integer" + }, + "activity-width": { + "type": "integer" + }, + "scroll-width": { + "type": "integer" + }, + "drop-shadow-width": { + "type": "integer" + } + }, + "required": [], + "title": "UI" + } + } +} diff --git a/extra/schemas/icon-theme.json b/extra/schemas/icon-theme.json new file mode 100644 index 0000000000..9bcc116dfd --- /dev/null +++ b/extra/schemas/icon-theme.json @@ -0,0 +1,60 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$ref": "#/definitions/IconTheme", + "definitions": { + "IconTheme": { + "type": "object", + "additionalProperties": false, + "properties": { + "icon-theme": { + "$ref": "#/definitions/IconThemeClass" + } + }, + "required": [], + "title": "IconTheme" + }, + "IconThemeClass": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "ui": { + "$ref": "#/definitions/IconMapping" + }, + "foldername": { + "$ref": "#/definitions/IconMapping" + }, + "filename": { + "$ref": "#/definitions/IconMapping" + }, + "extension": { + "$ref": "#/definitions/IconMapping" + } + }, + "required": [], + "title": "IconThemeClass" + }, + "IconMapping": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "*" : { + "type": "string" + } + }, + "title": "IconMapping" + }, + "Extension": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "[a-zA-Z0-9]" : { + "type": "string" + } + }, + "title": "IconMapping" + } + } +} diff --git a/extra/schemas/settings.json b/extra/schemas/settings.json new file mode 100644 index 0000000000..184b756817 --- /dev/null +++ b/extra/schemas/settings.json @@ -0,0 +1,347 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$ref": "#/definitions/Settings", + "definitions": { + "Settings": { + "type": "object", + "additionalProperties": false, + "properties": { + "core": { + "$ref": "#/definitions/Core" + }, + "editor": { + "$ref": "#/definitions/Editor" + }, + "terminal": { + "$ref": "#/definitions/Terminal" + }, + "ui": { + "$ref": "#/definitions/UI" + }, + "color-theme": { + "$ref": "file://./color-theme.json" + }, + "icon-theme": { + "$schema": "file://./icon-theme.json" + } + }, + "required": [], + "title": "Settings" + }, + "Base": { + "type": "object", + "additionalProperties": false, + "properties": { + "white": { + "type": "string" + }, + "black": { + "type": "string" + }, + "grey": { + "type": "string" + }, + "blue": { + "type": "string" + }, + "red": { + "type": "string" + }, + "yellow": { + "type": "string" + }, + "orange": { + "type": "string" + }, + "green": { + "type": "string" + }, + "purple": { + "type": "string" + }, + "cyan": { + "type": "string" + }, + "magenta": { + "type": "string" + } + }, + "required": [], + "title": "Base" + }, + "Syntax": { + "type": "object", + "additionalProperties": false, + "properties": { + "comment": { + "type": "string" + }, + "constant": { + "type": "string" + }, + "type": { + "type": "string" + }, + "typeAlias": { + "type": "string" + }, + "number": { + "type": "string" + }, + "enum": { + "type": "string" + }, + "struct": { + "type": "string" + }, + "structure": { + "type": "string" + }, + "interface": { + "type": "string" + }, + "attribute": { + "type": "string" + }, + "constructor": { + "type": "string" + }, + "function": { + "type": "string" + }, + "method": { + "type": "string" + }, + "function.method": { + "type": "string" + }, + "keyword": { + "type": "string" + }, + "keyword.control": { + "type": "string" + }, + "selfKeyword": { + "type": "string" + }, + "field": { + "type": "string" + }, + "property": { + "type": "string" + }, + "enumMember": { + "type": "string" + }, + "enum-member": { + "type": "string" + }, + "variable.other.member": { + "type": "string" + }, + "string": { + "type": "string" + }, + "type.builtin": { + "type": "string" + }, + "builtinType": { + "type": "string" + }, + "escape": { + "type": "string" + }, + "embedded": { + "type": "string" + }, + "symbol": { + "type": "string" + } + }, + "required": [], + "title": "Syntax" + }, + "Core": { + "type": "object", + "additionalProperties": false, + "properties": { + "modal": { + "type": "boolean" + }, + "color-theme": { + "type": "string" + }, + "icon-theme": { + "type": "string" + }, + "custom-titlebar": { + "type": "boolean" + } + }, + "required": [], + "title": "Core" + }, + "Editor": { + "type": "object", + "additionalProperties": false, + "properties": { + "font-family": { + "type": "string" + }, + "font-size": { + "type": "integer" + }, + "code-lens-font-size": { + "type": "integer" + }, + "line-height": { + "type": "number" + }, + "tab-width": { + "type": "integer" + }, + "show-tab": { + "type": "boolean" + }, + "show-bread-crumbs": { + "type": "boolean" + }, + "scroll-beyond-last-line": { + "type": "boolean" + }, + "cursor-surrounding-lines": { + "type": "integer" + }, + "sticky-header": { + "type": "boolean" + }, + "completion-show-documentation": { + "type": "boolean" + }, + "auto-closing-matching-pairs": { + "type": "boolean" + }, + "hover-delay": { + "type": "integer" + }, + "modal-mode-relative-line-numbers": { + "type": "boolean" + }, + "format-on-save": { + "type": "boolean" + }, + "highlight-matching-brackets": { + "type": "boolean" + }, + "autosave-interval": { + "type": "integer" + }, + "enable-inlay-hints": { + "type": "boolean" + }, + "inlay-hint-font-family": { + "type": "string" + }, + "inlay-hint-font-size": { + "type": "integer" + }, + "enable-error-lens": { + "type": "boolean" + }, + "error-lens-end-of-line": { + "type": "boolean" + }, + "error-lens-font-family": { + "type": "string" + }, + "error-lens-font-size": { + "type": "integer" + }, + "blink-interval": { + "type": "integer" + }, + "multicursor-case-sensitive": { + "type": "boolean" + }, + "multicursor-whole-words": { + "type": "boolean" + }, + "render-whitespace": { + "type": "string" + }, + "show-indent-guide": { + "type": "boolean" + }, + "atomic-soft-tabs": { + "type": "boolean" + } + }, + "required": [], + "title": "Editor" + }, + "Terminal": { + "type": "object", + "additionalProperties": false, + "properties": { + "font-family": { + "type": "string" + }, + "font-size": { + "type": "integer" + }, + "line-height": { + "type": "integer" + }, + "shell": { + "type": "string" + } + }, + "required": [], + "title": "Terminal" + }, + "UI": { + "type": "object", + "additionalProperties": false, + "properties": { + "font-family": { + "type": "string" + }, + "font-size": { + "type": "integer" + }, + "icon-size": { + "type": "integer" + }, + "header-height": { + "type": "integer" + }, + "status-height": { + "type": "integer" + }, + "tab-min-width": { + "type": "integer" + }, + "scroll-width": { + "type": "integer" + }, + "drop-shadow-width": { + "type": "integer" + }, + "preview-editor-width": { + "type": "integer" + }, + "hover-font-family": { + "type": "string" + }, + "hover-font-size": { + "type": "integer" + }, + "trim-search-results-whitespace": { + "type": "boolean" + } + }, + "required": [], + "title": "UI" + } + } +} diff --git a/extra/windows/lapce.ico b/extra/windows/lapce.ico index 6c4bb0b21d..c78b16b406 100644 Binary files a/extra/windows/lapce.ico and b/extra/windows/lapce.ico differ diff --git a/extra/windows/wix/lapce.wxs b/extra/windows/wix/lapce.wxs index 0f83e41a47..1ca22ba4ff 100644 --- a/extra/windows/wix/lapce.wxs +++ b/extra/windows/wix/lapce.wxs @@ -1,6 +1,6 @@ - + @@ -53,7 +53,7 @@ - + diff --git a/icons/arrow-down.svg b/icons/arrow-down.svg deleted file mode 100644 index 3b9527c06b..0000000000 --- a/icons/arrow-down.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/icons/arrow-up.svg b/icons/arrow-up.svg deleted file mode 100644 index 4ed3c5166b..0000000000 --- a/icons/arrow-up.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/icons/chevron-down.svg b/icons/chevron-down.svg deleted file mode 100644 index 252d40eb81..0000000000 --- a/icons/chevron-down.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/icons/chevron-up.svg b/icons/chevron-up.svg deleted file mode 100644 index 19a7f69813..0000000000 --- a/icons/chevron-up.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/icons/close.svg b/icons/close.svg deleted file mode 100644 index 5a087a380b..0000000000 --- a/icons/close.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/icons/codicons/LICENSE b/icons/codicons/LICENSE new file mode 100644 index 0000000000..a2c95fc155 --- /dev/null +++ b/icons/codicons/LICENSE @@ -0,0 +1,395 @@ +Attribution 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution 4.0 International Public License ("Public License"). To the +extent this Public License may be interpreted as a contract, You are +granted the Licensed Rights in consideration of Your acceptance of +these terms and conditions, and the Licensor grants You such rights in +consideration of benefits the Licensor receives from making the +Licensed Material available under these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + d. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + e. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + f. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + g. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + h. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + i. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + j. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + k. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material; and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. \ No newline at end of file diff --git a/icons/codicons/README.md b/icons/codicons/README.md new file mode 100644 index 0000000000..0b0eca8053 --- /dev/null +++ b/icons/codicons/README.md @@ -0,0 +1,3 @@ +# vscode-codicons + +Source: [https://github.com/microsoft/vscode-codicons](https://github.com/microsoft/vscode-codicons) diff --git a/icons/codicons/add.svg b/icons/codicons/add.svg new file mode 100644 index 0000000000..aed9bc6919 --- /dev/null +++ b/icons/codicons/add.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/arrow-both.svg b/icons/codicons/arrow-both.svg new file mode 100644 index 0000000000..c0fa479da4 --- /dev/null +++ b/icons/codicons/arrow-both.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/arrow-down.svg b/icons/codicons/arrow-down.svg new file mode 100644 index 0000000000..1c9268b3f3 --- /dev/null +++ b/icons/codicons/arrow-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/arrow-left.svg b/icons/codicons/arrow-left.svg new file mode 100644 index 0000000000..6e658755aa --- /dev/null +++ b/icons/codicons/arrow-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/arrow-right.svg b/icons/codicons/arrow-right.svg new file mode 100644 index 0000000000..f61ddd1754 --- /dev/null +++ b/icons/codicons/arrow-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/arrow-swap.svg b/icons/codicons/arrow-swap.svg new file mode 100644 index 0000000000..6496412119 --- /dev/null +++ b/icons/codicons/arrow-swap.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/arrow-up.svg b/icons/codicons/arrow-up.svg new file mode 100644 index 0000000000..81a022073e --- /dev/null +++ b/icons/codicons/arrow-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/blank.svg b/icons/codicons/blank.svg new file mode 100644 index 0000000000..7aacd329fc --- /dev/null +++ b/icons/codicons/blank.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/case-sensitive.svg b/icons/codicons/case-sensitive.svg new file mode 100644 index 0000000000..9faa9b7c41 --- /dev/null +++ b/icons/codicons/case-sensitive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/chevron-down.svg b/icons/codicons/chevron-down.svg new file mode 100644 index 0000000000..59a4873495 --- /dev/null +++ b/icons/codicons/chevron-down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/chevron-left.svg b/icons/codicons/chevron-left.svg similarity index 100% rename from icons/chevron-left.svg rename to icons/codicons/chevron-left.svg diff --git a/icons/chevron-right.svg b/icons/codicons/chevron-right.svg similarity index 100% rename from icons/chevron-right.svg rename to icons/codicons/chevron-right.svg diff --git a/icons/codicons/chevron-up.svg b/icons/codicons/chevron-up.svg new file mode 100644 index 0000000000..f103cfdd1f --- /dev/null +++ b/icons/codicons/chevron-up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/chrome-close.svg b/icons/codicons/chrome-close.svg new file mode 100644 index 0000000000..6b9a55a41e --- /dev/null +++ b/icons/codicons/chrome-close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/chrome-maximize.svg b/icons/codicons/chrome-maximize.svg new file mode 100644 index 0000000000..7627e7fab4 --- /dev/null +++ b/icons/codicons/chrome-maximize.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/chrome-minimize.svg b/icons/codicons/chrome-minimize.svg new file mode 100644 index 0000000000..abcc15bf99 --- /dev/null +++ b/icons/codicons/chrome-minimize.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/chrome-restore.svg b/icons/codicons/chrome-restore.svg new file mode 100644 index 0000000000..1537b4a808 --- /dev/null +++ b/icons/codicons/chrome-restore.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/circle-filled.svg b/icons/codicons/circle-filled.svg new file mode 100644 index 0000000000..955f153996 --- /dev/null +++ b/icons/codicons/circle-filled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/close.svg b/icons/codicons/close.svg new file mode 100644 index 0000000000..a63b1e0fbc --- /dev/null +++ b/icons/codicons/close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/diff-added.svg b/icons/codicons/diff-added.svg new file mode 100644 index 0000000000..9eca31e537 --- /dev/null +++ b/icons/codicons/diff-added.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/diff-ignored.svg b/icons/codicons/diff-ignored.svg new file mode 100644 index 0000000000..bbbedece23 --- /dev/null +++ b/icons/codicons/diff-ignored.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/diff-modified.svg b/icons/codicons/diff-modified.svg new file mode 100644 index 0000000000..cae06cbf75 --- /dev/null +++ b/icons/codicons/diff-modified.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/diff-removed.svg b/icons/codicons/diff-removed.svg new file mode 100644 index 0000000000..2da06cd8b6 --- /dev/null +++ b/icons/codicons/diff-removed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/diff-renamed.svg b/icons/codicons/diff-renamed.svg new file mode 100644 index 0000000000..f86550664e --- /dev/null +++ b/icons/codicons/diff-renamed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/diff.svg b/icons/codicons/diff.svg new file mode 100644 index 0000000000..4af4ba742d --- /dev/null +++ b/icons/codicons/diff.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/discard.svg b/icons/codicons/discard.svg new file mode 100644 index 0000000000..a22942fe6c --- /dev/null +++ b/icons/codicons/discard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/edit.svg b/icons/codicons/edit.svg new file mode 100644 index 0000000000..552fbf976b --- /dev/null +++ b/icons/codicons/edit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/error.svg b/icons/codicons/error.svg new file mode 100644 index 0000000000..4cfb5bbfab --- /dev/null +++ b/icons/codicons/error.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/extensions.svg b/icons/codicons/extensions.svg new file mode 100644 index 0000000000..bbdf50fa9d --- /dev/null +++ b/icons/codicons/extensions.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/file-binary.svg b/icons/codicons/file-binary.svg new file mode 100644 index 0000000000..18bafdacec --- /dev/null +++ b/icons/codicons/file-binary.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/file-code.svg b/icons/codicons/file-code.svg new file mode 100644 index 0000000000..f6d50e43d4 --- /dev/null +++ b/icons/codicons/file-code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/file-media.svg b/icons/codicons/file-media.svg new file mode 100644 index 0000000000..0667efb05e --- /dev/null +++ b/icons/codicons/file-media.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/file-pdf.svg b/icons/codicons/file-pdf.svg new file mode 100644 index 0000000000..b1dc9d50a9 --- /dev/null +++ b/icons/codicons/file-pdf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/file-submodule.svg b/icons/codicons/file-submodule.svg new file mode 100644 index 0000000000..08261dfbdc --- /dev/null +++ b/icons/codicons/file-submodule.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/file-symlink-directory.svg b/icons/codicons/file-symlink-directory.svg new file mode 100644 index 0000000000..77aac76da7 --- /dev/null +++ b/icons/codicons/file-symlink-directory.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/file-symlink-file.svg b/icons/codicons/file-symlink-file.svg new file mode 100644 index 0000000000..5cb31f51da --- /dev/null +++ b/icons/codicons/file-symlink-file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/file-zip.svg b/icons/codicons/file-zip.svg new file mode 100644 index 0000000000..95da24528c --- /dev/null +++ b/icons/codicons/file-zip.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/file.svg b/icons/codicons/file.svg new file mode 100644 index 0000000000..18ce72c80d --- /dev/null +++ b/icons/codicons/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/files.svg b/icons/codicons/files.svg new file mode 100644 index 0000000000..8671a7b93f --- /dev/null +++ b/icons/codicons/files.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/folder-active.svg b/icons/codicons/folder-active.svg new file mode 100644 index 0000000000..d50cabfe08 --- /dev/null +++ b/icons/codicons/folder-active.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/folder-library.svg b/icons/codicons/folder-library.svg new file mode 100644 index 0000000000..b5a25acaea --- /dev/null +++ b/icons/codicons/folder-library.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/folder-opened.svg b/icons/codicons/folder-opened.svg new file mode 100644 index 0000000000..52eb52c934 --- /dev/null +++ b/icons/codicons/folder-opened.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/folder.svg b/icons/codicons/folder.svg new file mode 100644 index 0000000000..2940f745a0 --- /dev/null +++ b/icons/codicons/folder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/gear.svg b/icons/codicons/gear.svg new file mode 100644 index 0000000000..8ee3ec48ab --- /dev/null +++ b/icons/codicons/gear.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/git-commit.svg b/icons/codicons/git-commit.svg new file mode 100644 index 0000000000..9c11c79b37 --- /dev/null +++ b/icons/codicons/git-commit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/git-compare.svg b/icons/codicons/git-compare.svg new file mode 100644 index 0000000000..e08789ce45 --- /dev/null +++ b/icons/codicons/git-compare.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/git-merge.svg b/icons/codicons/git-merge.svg new file mode 100644 index 0000000000..92ea23132c --- /dev/null +++ b/icons/codicons/git-merge.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/go-to-file.svg b/icons/codicons/go-to-file.svg new file mode 100644 index 0000000000..4c688f2fce --- /dev/null +++ b/icons/codicons/go-to-file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/group-by-ref-type.svg b/icons/codicons/group-by-ref-type.svg new file mode 100644 index 0000000000..4c688a0b02 --- /dev/null +++ b/icons/codicons/group-by-ref-type.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/history.svg b/icons/codicons/history.svg new file mode 100644 index 0000000000..53d41f7c7b --- /dev/null +++ b/icons/codicons/history.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/info.svg b/icons/codicons/info.svg new file mode 100644 index 0000000000..fff5a9fbcf --- /dev/null +++ b/icons/codicons/info.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/inspect.svg b/icons/codicons/inspect.svg new file mode 100644 index 0000000000..2de8bfb0c3 --- /dev/null +++ b/icons/codicons/inspect.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/issues.svg b/icons/codicons/issues.svg new file mode 100644 index 0000000000..666a3baac7 --- /dev/null +++ b/icons/codicons/issues.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/json.svg b/icons/codicons/json.svg new file mode 100644 index 0000000000..ff10d4b248 --- /dev/null +++ b/icons/codicons/json.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/key.svg b/icons/codicons/key.svg new file mode 100644 index 0000000000..a8de84794a --- /dev/null +++ b/icons/codicons/key.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-activitybar-left.svg b/icons/codicons/layout-activitybar-left.svg new file mode 100644 index 0000000000..87378a21e9 --- /dev/null +++ b/icons/codicons/layout-activitybar-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-activitybar-right.svg b/icons/codicons/layout-activitybar-right.svg new file mode 100644 index 0000000000..43a89406a0 --- /dev/null +++ b/icons/codicons/layout-activitybar-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-centered.svg b/icons/codicons/layout-centered.svg new file mode 100644 index 0000000000..9865f136bd --- /dev/null +++ b/icons/codicons/layout-centered.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-menubar.svg b/icons/codicons/layout-menubar.svg new file mode 100644 index 0000000000..98666ab70a --- /dev/null +++ b/icons/codicons/layout-menubar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-panel-center.svg b/icons/codicons/layout-panel-center.svg new file mode 100644 index 0000000000..d720c12053 --- /dev/null +++ b/icons/codicons/layout-panel-center.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-panel-justify.svg b/icons/codicons/layout-panel-justify.svg new file mode 100644 index 0000000000..67a749c395 --- /dev/null +++ b/icons/codicons/layout-panel-justify.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-panel-left.svg b/icons/codicons/layout-panel-left.svg new file mode 100644 index 0000000000..181dd75876 --- /dev/null +++ b/icons/codicons/layout-panel-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-panel-off.svg b/icons/codicons/layout-panel-off.svg new file mode 100644 index 0000000000..fc8464f43a --- /dev/null +++ b/icons/codicons/layout-panel-off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-panel-right.svg b/icons/codicons/layout-panel-right.svg new file mode 100644 index 0000000000..7cf4177249 --- /dev/null +++ b/icons/codicons/layout-panel-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-panel.svg b/icons/codicons/layout-panel.svg new file mode 100644 index 0000000000..7ac17fb7d5 --- /dev/null +++ b/icons/codicons/layout-panel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-sidebar-left-off.svg b/icons/codicons/layout-sidebar-left-off.svg new file mode 100644 index 0000000000..50019bfe5f --- /dev/null +++ b/icons/codicons/layout-sidebar-left-off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-sidebar-left.svg b/icons/codicons/layout-sidebar-left.svg new file mode 100644 index 0000000000..b513bdac67 --- /dev/null +++ b/icons/codicons/layout-sidebar-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-sidebar-right-off.svg b/icons/codicons/layout-sidebar-right-off.svg new file mode 100644 index 0000000000..951b957155 --- /dev/null +++ b/icons/codicons/layout-sidebar-right-off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-sidebar-right.svg b/icons/codicons/layout-sidebar-right.svg new file mode 100644 index 0000000000..1017debe0e --- /dev/null +++ b/icons/codicons/layout-sidebar-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout-statusbar.svg b/icons/codicons/layout-statusbar.svg new file mode 100644 index 0000000000..7f60e5b123 --- /dev/null +++ b/icons/codicons/layout-statusbar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/layout.svg b/icons/codicons/layout.svg new file mode 100644 index 0000000000..655d365c8c --- /dev/null +++ b/icons/codicons/layout.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/lightbulb-autofix.svg b/icons/codicons/lightbulb-autofix.svg similarity index 100% rename from icons/lightbulb-autofix.svg rename to icons/codicons/lightbulb-autofix.svg diff --git a/icons/lightbulb.svg b/icons/codicons/lightbulb.svg similarity index 100% rename from icons/lightbulb.svg rename to icons/codicons/lightbulb.svg diff --git a/icons/codicons/link-external.svg b/icons/codicons/link-external.svg new file mode 100644 index 0000000000..9a594b72b6 --- /dev/null +++ b/icons/codicons/link-external.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/link.svg b/icons/codicons/link.svg new file mode 100644 index 0000000000..46bf4d5340 --- /dev/null +++ b/icons/codicons/link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/merge.svg b/icons/codicons/merge.svg new file mode 100644 index 0000000000..0e3049f315 --- /dev/null +++ b/icons/codicons/merge.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/multiple-windows.svg b/icons/codicons/multiple-windows.svg new file mode 100644 index 0000000000..7ee7455754 --- /dev/null +++ b/icons/codicons/multiple-windows.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/new-file.svg b/icons/codicons/new-file.svg new file mode 100644 index 0000000000..caac07c667 --- /dev/null +++ b/icons/codicons/new-file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/new-folder.svg b/icons/codicons/new-folder.svg new file mode 100644 index 0000000000..3ada63a64a --- /dev/null +++ b/icons/codicons/new-folder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/open-preview.svg b/icons/codicons/open-preview.svg new file mode 100644 index 0000000000..765c739044 --- /dev/null +++ b/icons/codicons/open-preview.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/plugin-icon.svg b/icons/codicons/plugin-icon.svg similarity index 100% rename from icons/plugin-icon.svg rename to icons/codicons/plugin-icon.svg diff --git a/icons/codicons/references.svg b/icons/codicons/references.svg new file mode 100644 index 0000000000..280b3d8375 --- /dev/null +++ b/icons/codicons/references.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/refresh.svg b/icons/codicons/refresh.svg new file mode 100644 index 0000000000..9196015694 --- /dev/null +++ b/icons/codicons/refresh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/remote-explorer.svg b/icons/codicons/remote-explorer.svg new file mode 100644 index 0000000000..0152f47296 --- /dev/null +++ b/icons/codicons/remote-explorer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/remove.svg b/icons/codicons/remove.svg new file mode 100644 index 0000000000..cf31dfe1d4 --- /dev/null +++ b/icons/codicons/remove.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/repo-clone.svg b/icons/codicons/repo-clone.svg new file mode 100644 index 0000000000..ab8f19a75b --- /dev/null +++ b/icons/codicons/repo-clone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/repo-force-push.svg b/icons/codicons/repo-force-push.svg new file mode 100644 index 0000000000..37c9a3dcf5 --- /dev/null +++ b/icons/codicons/repo-force-push.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/repo-forked.svg b/icons/codicons/repo-forked.svg new file mode 100644 index 0000000000..0cc80938ea --- /dev/null +++ b/icons/codicons/repo-forked.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/repo-pull.svg b/icons/codicons/repo-pull.svg new file mode 100644 index 0000000000..821095901d --- /dev/null +++ b/icons/codicons/repo-pull.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/repo-push.svg b/icons/codicons/repo-push.svg new file mode 100644 index 0000000000..8faf45146f --- /dev/null +++ b/icons/codicons/repo-push.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/repo.svg b/icons/codicons/repo.svg new file mode 100644 index 0000000000..72fd4acd23 --- /dev/null +++ b/icons/codicons/repo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/root-folder-opened.svg b/icons/codicons/root-folder-opened.svg new file mode 100644 index 0000000000..b31bb8f9cf --- /dev/null +++ b/icons/codicons/root-folder-opened.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/root-folder.svg b/icons/codicons/root-folder.svg new file mode 100644 index 0000000000..93839d04ca --- /dev/null +++ b/icons/codicons/root-folder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/screen-full.svg b/icons/codicons/screen-full.svg new file mode 100644 index 0000000000..59d640356b --- /dev/null +++ b/icons/codicons/screen-full.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/screen-normal.svg b/icons/codicons/screen-normal.svg new file mode 100644 index 0000000000..e64985e69e --- /dev/null +++ b/icons/codicons/screen-normal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/search-stop.svg b/icons/codicons/search-stop.svg new file mode 100644 index 0000000000..7a80b70de5 --- /dev/null +++ b/icons/codicons/search-stop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/search.svg b/icons/codicons/search.svg new file mode 100644 index 0000000000..13c4df07b7 --- /dev/null +++ b/icons/codicons/search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/settings-gear.svg b/icons/codicons/settings-gear.svg new file mode 100644 index 0000000000..0abb193364 --- /dev/null +++ b/icons/codicons/settings-gear.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/settings.svg b/icons/codicons/settings.svg new file mode 100644 index 0000000000..67127eaa5c --- /dev/null +++ b/icons/codicons/settings.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/source-control.svg b/icons/codicons/source-control.svg new file mode 100644 index 0000000000..edb96f80a2 --- /dev/null +++ b/icons/codicons/source-control.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/split-horizontal.svg b/icons/codicons/split-horizontal.svg new file mode 100644 index 0000000000..d744a79841 --- /dev/null +++ b/icons/codicons/split-horizontal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/codicons/split-vertical.svg b/icons/codicons/split-vertical.svg new file mode 100644 index 0000000000..3a18ab9f06 --- /dev/null +++ b/icons/codicons/split-vertical.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/symbol-array.svg b/icons/codicons/symbol-array.svg similarity index 100% rename from icons/symbol-array.svg rename to icons/codicons/symbol-array.svg diff --git a/icons/symbol-boolean.svg b/icons/codicons/symbol-boolean.svg similarity index 100% rename from icons/symbol-boolean.svg rename to icons/codicons/symbol-boolean.svg diff --git a/icons/symbol-class.svg b/icons/codicons/symbol-class.svg similarity index 100% rename from icons/symbol-class.svg rename to icons/codicons/symbol-class.svg diff --git a/icons/symbol-color.svg b/icons/codicons/symbol-color.svg similarity index 100% rename from icons/symbol-color.svg rename to icons/codicons/symbol-color.svg diff --git a/icons/symbol-constant.svg b/icons/codicons/symbol-constant.svg similarity index 100% rename from icons/symbol-constant.svg rename to icons/codicons/symbol-constant.svg diff --git a/icons/symbol-enum-member.svg b/icons/codicons/symbol-enum-member.svg similarity index 100% rename from icons/symbol-enum-member.svg rename to icons/codicons/symbol-enum-member.svg diff --git a/icons/symbol-enum.svg b/icons/codicons/symbol-enum.svg similarity index 100% rename from icons/symbol-enum.svg rename to icons/codicons/symbol-enum.svg diff --git a/icons/symbol-event.svg b/icons/codicons/symbol-event.svg similarity index 100% rename from icons/symbol-event.svg rename to icons/codicons/symbol-event.svg diff --git a/icons/symbol-field.svg b/icons/codicons/symbol-field.svg similarity index 100% rename from icons/symbol-field.svg rename to icons/codicons/symbol-field.svg diff --git a/icons/symbol-file.svg b/icons/codicons/symbol-file.svg similarity index 100% rename from icons/symbol-file.svg rename to icons/codicons/symbol-file.svg diff --git a/icons/symbol-interface.svg b/icons/codicons/symbol-interface.svg similarity index 100% rename from icons/symbol-interface.svg rename to icons/codicons/symbol-interface.svg diff --git a/icons/symbol-key.svg b/icons/codicons/symbol-key.svg similarity index 100% rename from icons/symbol-key.svg rename to icons/codicons/symbol-key.svg diff --git a/icons/symbol-keyword.svg b/icons/codicons/symbol-keyword.svg similarity index 100% rename from icons/symbol-keyword.svg rename to icons/codicons/symbol-keyword.svg diff --git a/icons/symbol-method.svg b/icons/codicons/symbol-method.svg similarity index 100% rename from icons/symbol-method.svg rename to icons/codicons/symbol-method.svg diff --git a/icons/symbol-misc.svg b/icons/codicons/symbol-misc.svg similarity index 100% rename from icons/symbol-misc.svg rename to icons/codicons/symbol-misc.svg diff --git a/icons/symbol-namespace.svg b/icons/codicons/symbol-namespace.svg similarity index 100% rename from icons/symbol-namespace.svg rename to icons/codicons/symbol-namespace.svg diff --git a/icons/symbol-numeric.svg b/icons/codicons/symbol-numeric.svg similarity index 100% rename from icons/symbol-numeric.svg rename to icons/codicons/symbol-numeric.svg diff --git a/icons/symbol-operator.svg b/icons/codicons/symbol-operator.svg similarity index 100% rename from icons/symbol-operator.svg rename to icons/codicons/symbol-operator.svg diff --git a/icons/symbol-parameter.svg b/icons/codicons/symbol-parameter.svg similarity index 100% rename from icons/symbol-parameter.svg rename to icons/codicons/symbol-parameter.svg diff --git a/icons/symbol-property.svg b/icons/codicons/symbol-property.svg similarity index 100% rename from icons/symbol-property.svg rename to icons/codicons/symbol-property.svg diff --git a/icons/symbol-ruler.svg b/icons/codicons/symbol-ruler.svg similarity index 100% rename from icons/symbol-ruler.svg rename to icons/codicons/symbol-ruler.svg diff --git a/icons/symbol-snippet.svg b/icons/codicons/symbol-snippet.svg similarity index 100% rename from icons/symbol-snippet.svg rename to icons/codicons/symbol-snippet.svg diff --git a/icons/symbol-string.svg b/icons/codicons/symbol-string.svg similarity index 100% rename from icons/symbol-string.svg rename to icons/codicons/symbol-string.svg diff --git a/icons/symbol-structure.svg b/icons/codicons/symbol-structure.svg similarity index 100% rename from icons/symbol-structure.svg rename to icons/codicons/symbol-structure.svg diff --git a/icons/symbol-variable.svg b/icons/codicons/symbol-variable.svg similarity index 100% rename from icons/symbol-variable.svg rename to icons/codicons/symbol-variable.svg diff --git a/icons/codicons/terminal.svg b/icons/codicons/terminal.svg new file mode 100644 index 0000000000..2ffc08e285 --- /dev/null +++ b/icons/codicons/terminal.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/unsaved.svg b/icons/codicons/unsaved.svg similarity index 100% rename from icons/unsaved.svg rename to icons/codicons/unsaved.svg diff --git a/icons/codicons/warning.svg b/icons/codicons/warning.svg new file mode 100644 index 0000000000..9a33f87391 --- /dev/null +++ b/icons/codicons/warning.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/default_file.svg b/icons/default_file.svg deleted file mode 100644 index 9ee39aa091..0000000000 --- a/icons/default_file.svg +++ /dev/null @@ -1 +0,0 @@ -default_file \ No newline at end of file diff --git a/icons/default_folder.svg b/icons/default_folder.svg deleted file mode 100644 index c6f9b035e9..0000000000 --- a/icons/default_folder.svg +++ /dev/null @@ -1 +0,0 @@ -default_folder \ No newline at end of file diff --git a/icons/default_folder_opened.svg b/icons/default_folder_opened.svg deleted file mode 100644 index 8aab2ff5c3..0000000000 --- a/icons/default_folder_opened.svg +++ /dev/null @@ -1 +0,0 @@ -default_folder_opened \ No newline at end of file diff --git a/icons/diff-added.svg b/icons/diff-added.svg deleted file mode 100644 index 0f9cd120e9..0000000000 --- a/icons/diff-added.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/icons/diff-modified.svg b/icons/diff-modified.svg deleted file mode 100644 index e7a3694998..0000000000 --- a/icons/diff-modified.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/icons/diff-removed.svg b/icons/diff-removed.svg deleted file mode 100644 index 8a9891b2a7..0000000000 --- a/icons/diff-removed.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/icons/diff-renamed.svg b/icons/diff-renamed.svg deleted file mode 100644 index 1b1624c376..0000000000 --- a/icons/diff-renamed.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/icons/error.svg b/icons/error.svg deleted file mode 100644 index 3c35622732..0000000000 --- a/icons/error.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/icons/file-explorer.svg b/icons/file-explorer.svg deleted file mode 100644 index 2c8a9611c4..0000000000 --- a/icons/file-explorer.svg +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/icons/file_type_c.svg b/icons/file_type_c.svg deleted file mode 100644 index 5a6001d67f..0000000000 --- a/icons/file_type_c.svg +++ /dev/null @@ -1 +0,0 @@ -file_type_c \ No newline at end of file diff --git a/icons/file_type_cpp.svg b/icons/file_type_cpp.svg deleted file mode 100644 index 9563371f7f..0000000000 --- a/icons/file_type_cpp.svg +++ /dev/null @@ -1 +0,0 @@ -file_type_cpp \ No newline at end of file diff --git a/icons/file_type_go.svg b/icons/file_type_go.svg deleted file mode 100644 index 05a1baa1bb..0000000000 --- a/icons/file_type_go.svg +++ /dev/null @@ -1 +0,0 @@ -file_type_go \ No newline at end of file diff --git a/icons/file_type_json.svg b/icons/file_type_json.svg deleted file mode 100644 index 26c39ba7c4..0000000000 --- a/icons/file_type_json.svg +++ /dev/null @@ -1 +0,0 @@ -file_type_json \ No newline at end of file diff --git a/icons/file_type_license.svg b/icons/file_type_license.svg deleted file mode 100644 index 6859deae8d..0000000000 --- a/icons/file_type_license.svg +++ /dev/null @@ -1 +0,0 @@ -file_type_license \ No newline at end of file diff --git a/icons/file_type_markdown.svg b/icons/file_type_markdown.svg deleted file mode 100644 index c5b32a6f7b..0000000000 --- a/icons/file_type_markdown.svg +++ /dev/null @@ -1 +0,0 @@ -file_type_markdown \ No newline at end of file diff --git a/icons/file_type_rust.svg b/icons/file_type_rust.svg deleted file mode 100644 index f62525ee8c..0000000000 --- a/icons/file_type_rust.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/icons/file_type_toml.svg b/icons/file_type_toml.svg deleted file mode 100644 index a0a5890783..0000000000 --- a/icons/file_type_toml.svg +++ /dev/null @@ -1 +0,0 @@ -file_type_toml \ No newline at end of file diff --git a/icons/file_type_yaml.svg b/icons/file_type_yaml.svg deleted file mode 100644 index 601979d57d..0000000000 --- a/icons/file_type_yaml.svg +++ /dev/null @@ -1 +0,0 @@ -file_type_yaml \ No newline at end of file diff --git a/icons/git-icon.svg b/icons/git-icon.svg deleted file mode 100644 index 74a9c0ab76..0000000000 --- a/icons/git-icon.svg +++ /dev/null @@ -1,52 +0,0 @@ - - - -image/svg+xml \ No newline at end of file diff --git a/icons/remote.svg b/icons/lapce/lapce_remote.svg similarity index 100% rename from icons/remote.svg rename to icons/lapce/lapce_remote.svg diff --git a/icons/link.svg b/icons/link.svg deleted file mode 100644 index 1f9933c9bd..0000000000 --- a/icons/link.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/icons/search.svg b/icons/search.svg deleted file mode 100644 index 9a39565868..0000000000 --- a/icons/search.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/icons/settings.svg b/icons/settings.svg deleted file mode 100644 index 9a64fbdf88..0000000000 --- a/icons/settings.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/icons/split-horizontal.svg b/icons/split-horizontal.svg deleted file mode 100644 index f025e26ba0..0000000000 --- a/icons/split-horizontal.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/icons/terminal.svg b/icons/terminal.svg deleted file mode 100644 index d279a90653..0000000000 --- a/icons/terminal.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/icons/triangle-right.svg b/icons/triangle-right.svg deleted file mode 100644 index 689b27c299..0000000000 --- a/icons/triangle-right.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/icons/warning.svg b/icons/warning.svg deleted file mode 100644 index 32695e1117..0000000000 --- a/icons/warning.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/lapce-core/Cargo.toml b/lapce-core/Cargo.toml index ca415493fa..5ff71ea2c4 100644 --- a/lapce-core/Cargo.toml +++ b/lapce-core/Cargo.toml @@ -1,76 +1,142 @@ [package] name = "lapce-core" -version = "0.1.2" -authors = ["Dongdong Zhou "] -edition = "2021" +version.workspace = true +authors.workspace = true +edition.workspace = true [dependencies] -thiserror = "1.0" -itertools = "0.10.3" -log = "0.4.14" +anyhow.workspace = true +directories.workspace = true +itertools.workspace = true +log.workspace = true +once_cell.workspace = true +serde.workspace = true +strum.workspace = true +strum_macros.workspace = true +thiserror.workspace = true + +lsp-types.workspace = true + +lapce-xi-rope.workspace = true + +lapce-rpc.workspace = true + bitflags = "1.3.2" -strum = "0.24.0" -strum_macros = "0.24" -serde = "1.0" -serde_json = "1.0" -tree-sitter = "0.20.6" -tree-sitter-highlight = "0.20.1" -tree-sitter-rust = { version = "0.20.0", optional = true } -tree-sitter-go = { version = "0.19.1", optional = true } -tree-sitter-javascript = { version = "0.20.0", optional = true } -tree-sitter-typescript = { version = "0.20.0", optional = true } -tree-sitter-python = { version = "0.19.1", optional = true } -tree-sitter-toml = { version = "0.20.0", optional = true } -tree-sitter-elixir = { git = "https://github.com/elixir-lang/tree-sitter-elixir.git", version = "0.19.0", optional = true } -tree-sitter-php = { git = "https://github.com/tree-sitter/tree-sitter-php.git", version = "0.19.1", optional = true } -tree-sitter-ruby = { git = "https://github.com/Liberatys/tree-sitter-ruby.git", branch = "chore/allow-range-of-tree-sitter", optional = true } -tree-sitter-c = { version = "0.20.1", optional = true } +slotmap = "1.0" +arc-swap = "1.5.1" +tree-sitter = "0.20.7" + +# please keep below dependencies and features sorted just like LANGUAGES in language.rs + +tree-sitter-bash = { git = "https://github.com/tree-sitter/tree-sitter-bash", rev = "4488aa41406547e478636a4fcfd24f5bbc3f2f74", optional = true } +tree-sitter-c = { version = "0.20.2", optional = true } +tree-sitter-c-sharp = { git = "https://github.com/tree-sitter/tree-sitter-c-sharp", rev = "5b60f99545fea00a33bbfae5be956f684c4c69e2", optional = true } tree-sitter-cpp = { version = "0.20.0", optional = true } -tree-sitter-json = { version = "0.19.0", optional = true } -tree-sitter-md = { git = "https://github.com/MDeiml/tree-sitter-markdown.git", version = "0.0.1", optional = true } -tree-sitter-html = { version = "0.19.0", optional = true } -tree-sitter-java = { git = "https://github.com/tree-sitter/tree-sitter-java.git", version = "0.20.0", optional = true } +tree-sitter-clojure = { git = "https://github.com/abreumatheus/tree-sitter-clojure", rev = "fdc969eb04fc711e38ad74afe441d74b3b5d3091", optional = true } +tree-sitter-cmake = { version = "0.1.0", optional = true } +# switch to upstream version after this is merged https://github.com/tree-sitter/tree-sitter-css/pull/22 +tree-sitter-css = { git = "https://github.com/syntacti/tree-sitter-css", rev = "397aa132b9982fcdd2d473ed69343762a557f10a", optional = true } +tree-sitter-d = { git = "https://github.com/ghishadow/tree-sitter-d", rev = "36603135ecb37ac6494c520efff91b875815d6f7", optional = true } +tree-sitter-dart = { git = "https://github.com/syntacti/tree-sitter-dart", rev = "78cad4503571d72666f78d5ba8ed6c1417653063", optional = true } +tree-sitter-dockerfile = { git = "https://github.com/panekj/tree-sitter-dockerfile", rev = "c49d819e07685c90456270f1cc654d9cba640f53", optional = true } +tree-sitter-elixir = { git = "https://github.com/elixir-lang/tree-sitter-elixir.git", rev = "05e3631c6a0701c1fa518b0fee7be95a2ceef5e2", optional = true } tree-sitter-elm = { version = "5.6.0", optional = true } -tree-sitter-swift = { version = "0.3.0", optional = true } -tree-sitter-ql = { git = "https://github.com/tree-sitter/tree-sitter-ql", version = "0.19.0", optional = true } -tree-sitter-haskell = { git = "https://github.com/tree-sitter/tree-sitter-haskell", version = "0.14.0", optional = true } -tree-sitter-ocaml = { git = "https://github.com/tree-sitter/tree-sitter-ocaml", version = "0.20.0", optional = true } -tree-sitter-glimmer = { git = "https://github.com/VixieTSQ/tree-sitter-glimmer", version = "0.0.1", optional = true } -tree-sitter-haxe = { git = "https://github.com/VixieTSQ/tree-sitter-haxe", version = "0.0.1", optional = true } -tree-sitter-hcl = { git = "https://github.com/VixieTSQ/tree-sitter-hcl", version = "0.0.1", optional = true } -tree-sitter-scss = { git = "https://github.com/VixieTSQ/tree-sitter-scss", version = "0.0.1", branch = "patch-1", optional = true } +tree-sitter-erlang = { git = "https://github.com/WhatsApp/tree-sitter-erlang", rev = "a8b8b0e16c4f5552f5e85af3dec976a5d16af8b9", optional = true } +tree-sitter-glimmer = { git = "https://github.com/VixieTSQ/tree-sitter-glimmer", rev = "7281caca2ba114e1960c5d944a37860ef0841426", optional = true } +tree-sitter-glsl = { git = "https://github.com/theHamsta/tree-sitter-glsl", rev = "74329feb2605deccd32b1c644af507daa6fb82f1", optional = true } +tree-sitter-go = { version = "0.19.1", optional = true } tree-sitter-hare = { version = "0.20.7", optional = true } -lsp-types = { version = "0.89.2", features = ["proposed"] } -xi-rope = { git = "https://github.com/lapce/xi-editor", features = ["serde"] } -lapce-rpc = { path = "../lapce-rpc" } +tree-sitter-haskell = { git = "https://github.com/tree-sitter/tree-sitter-haskell", rev = "e30bdfd53eb28c73f26a68b77d436fd2140af167", optional = true } +tree-sitter-haxe = { git = "https://github.com/vantreeseba/tree-sitter-haxe", rev = "52e3d2b9c3955aca886bccc38b496ef99b603a09", optional = true } +tree-sitter-hcl = { git = "https://github.com/VixieTSQ/tree-sitter-hcl", rev = "f4aa4553344e03e149ec459549a7f686d6846626", optional = true } +tree-sitter-html = { version = "0.19.0", optional = true } +tree-sitter-java = { git = "https://github.com/tree-sitter/tree-sitter-java.git", rev = "09d650def6cdf7f479f4b78f595e9ef5b58ce31e", optional = true } +tree-sitter-javascript = { version = "0.20.0", optional = true } +# new version cannot be published on crates.io - https://github.com/tree-sitter/tree-sitter-json/issues/21 +# tree-sitter-json = { version = "0.19.0", optional = true } +tree-sitter-json = { git = "https://github.com/tree-sitter/tree-sitter-json.git", rev = "11e2cc12d9b267766fb11a06e52952792fd8e3f0", optional = true } +tree-sitter-julia = { git = "https://github.com/varlad/tree-sitter-julia.git", rev = "2ad4c9b79e0f213b61dbb3820754bfc6306e595a", optional = true } +tree-sitter-kotlin = { git = "https://github.com/fwcd/tree-sitter-kotlin", rev = "a4f71eb9b8c9b19ded3e0e9470be4b1b77c2b569", optional = true } +tree-sitter-latex = { git = "https://github.com/latex-lsp/tree-sitter-latex", rev = "b3b2cf27f33e71438ebe46934900b1153901c6f2", optional = true } +tree-sitter-lua = { git = "https://github.com/syntacti/tree-sitter-lua", rev = "a29f646c14ed800aaeef1ca58a9bacc6d92922e8", optional = true } +tree-sitter-md = { git = "https://github.com/MDeiml/tree-sitter-markdown.git", rev = "272e080bca0efd19a06a7f4252d746417224959e", optional = true } +tree-sitter-nix = { git = "https://github.com/panekj/tree-sitter-nix", rev = "59fc47150ab437e8bb356c7ab21e9531e87f7cc8", optional = true } +tree-sitter-ocaml = { git = "https://github.com/tree-sitter/tree-sitter-ocaml", rev = "cc26b1ef111100f26a137bcbcd39fd4e35be9a59", optional = true } +tree-sitter-php = { git = "https://github.com/tree-sitter/tree-sitter-php.git", rev = "ab2e72179ceb8bb0b249c8ac9162a148e911b3dc", optional = true } +tree-sitter-prisma-io = { version = "1.3.0", optional = true } +tree-sitter-protobuf = { git = "https://github.com/yusdacra/tree-sitter-protobuf", rev = "5aef38d655f76a6b0d172340eed3766c93b3124c", optional = true } +tree-sitter-python = { version = "0.20.1", optional = true } +tree-sitter-ql = { git = "https://github.com/tree-sitter/tree-sitter-ql", rev = "bd087020f0d8c183080ca615d38de0ec827aeeaf", optional = true } +tree-sitter-r = { version = "0.19.5", optional = true } +tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "656abef0645caea793e33c1c773570722463e1d8", optional = true } +tree-sitter-rust = { version = "0.20.0", optional = true } +tree-sitter-scheme = { git = "https://github.com/6cdh/tree-sitter-scheme.git", rev = "af0fd1fa452cb2562dc7b5c8a8c55551c39273b9", optional = true } +tree-sitter-scss = { git = "https://github.com/VixieTSQ/tree-sitter-scss", rev = "3aac3391ede5098edbf4cc8a9f6d0cfdfe28e5dc", optional = true } +# switch to upstream version after this is merged https://github.com/m-novikov/tree-sitter-sql/pull/68 +tree-sitter-sql = { git = "https://github.com/oknozor/tree-sitter-sql", rev = "15dad0f3cae8a094a7dac17d712ea8fb25228011", optional = true } +tree-sitter-svelte = { git = "https://github.com/Himujjal/tree-sitter-svelte", rev = "52e122ae68b316d3aa960a0a422d3645ba717f42", optional = true } +tree-sitter-swift = { version = "0.3.4", optional = true } +tree-sitter-toml = { version = "0.20.0", optional = true } +tree-sitter-typescript = { version = "0.20.0", optional = true } +tree-sitter-vue = { version = "0.0.3", optional = true } +tree-sitter-wgsl = { git = "https://github.com/szebniok/tree-sitter-wgsl", rev = "272e89ef2aeac74178edb9db4a83c1ffef80a463", optional = true } +tree-sitter-xml = { git = "https://github.com/RenjiSann/tree-sitter-xml", rev = "422528a43630db6dcc1e222d1c5ee3babd559473", optional = true } +tree-sitter-yaml = { git = "https://github.com/panekj/tree-sitter-yaml", rev = "80c8d76847f03e772c5c524cf29bafb56858a8d1", optional = true } +tree-sitter-zig = { git = "https://github.com/maxxnino/tree-sitter-zig", rev = "8d3224c3bd0890fe08358886ebf54fca2ed448a6", optional = true } [features] default = [] # See lapce-ui/Cargo.toml for how to choose the languages. See also # src/language.rs for how to add new languages. The feature names should follow # the tree-sitter crate names. -lang-rust = ["dep:tree-sitter-rust"] -lang-go = ["dep:tree-sitter-go"] -lang-javascript = ["dep:tree-sitter-javascript"] -lang-typescript = ["dep:tree-sitter-typescript"] -lang-python = ["dep:tree-sitter-python"] -lang-toml = ["dep:tree-sitter-toml"] -lang-elixir = ["dep:tree-sitter-elixir"] -lang-php = ["dep:tree-sitter-php"] -lang-ruby = ["dep:tree-sitter-ruby"] +lang-bash = ["dep:tree-sitter-bash"] lang-c = ["dep:tree-sitter-c"] +lang-clojure = ["dep:tree-sitter-clojure"] +lang-cmake = ["dep:tree-sitter-cmake"] lang-cpp = ["dep:tree-sitter-cpp"] -lang-json = ["dep:tree-sitter-json"] -lang-md = ["dep:tree-sitter-md"] -lang-html = ["dep:tree-sitter-html"] -lang-java = ["dep:tree-sitter-java"] +lang-csharp = ["dep:tree-sitter-c-sharp"] +lang-css = ["dep:tree-sitter-css"] +lang-d = ["dep:tree-sitter-d"] +lang-dart = ["dep:tree-sitter-dart"] +lang-dockerfile = ["dep:tree-sitter-dockerfile"] +lang-elixir = ["dep:tree-sitter-elixir"] lang-elm = ["dep:tree-sitter-elm"] -lang-swift = ["dep:tree-sitter-swift"] -lang-ql = ["dep:tree-sitter-ql"] -lang-haskell = ["dep:tree-sitter-haskell"] -lang-ocaml = ["dep:tree-sitter-ocaml"] +lang-erlang = ["dep:tree-sitter-erlang"] lang-glimmer = ["dep:tree-sitter-glimmer"] +lang-glsl = ["dep:tree-sitter-glsl"] +lang-go = ["dep:tree-sitter-go"] +lang-hare = ["dep:tree-sitter-hare"] +lang-haskell = ["dep:tree-sitter-haskell"] lang-haxe = ["dep:tree-sitter-haxe"] lang-hcl = ["dep:tree-sitter-hcl"] +lang-html = ["dep:tree-sitter-html"] +lang-java = ["dep:tree-sitter-java"] +lang-javascript = ["dep:tree-sitter-javascript"] +lang-json = ["dep:tree-sitter-json"] +lang-julia = ["dep:tree-sitter-julia"] +lang-kotlin = ["dep:tree-sitter-kotlin"] +lang-latex = ["dep:tree-sitter-latex"] +lang-lua = ["dep:tree-sitter-lua"] +lang-markdown = ["dep:tree-sitter-md"] +lang-nix = ["dep:tree-sitter-nix"] +lang-ocaml = ["dep:tree-sitter-ocaml"] +lang-php = ["dep:tree-sitter-php"] +lang-prisma = ["dep:tree-sitter-prisma-io"] +lang-protobuf = ["dep:tree-sitter-protobuf"] +lang-python = ["dep:tree-sitter-python"] +lang-ql = ["dep:tree-sitter-ql"] +lang-r = ["dep:tree-sitter-r"] +lang-ruby = ["dep:tree-sitter-ruby"] +lang-rust = ["dep:tree-sitter-rust"] +lang-scheme = ["dep:tree-sitter-scheme"] lang-scss = ["dep:tree-sitter-scss"] -lang-hare = ["dep:tree-sitter-hare"] \ No newline at end of file +lang-sql = ["dep:tree-sitter-sql"] +lang-svelte = ["dep:tree-sitter-svelte"] +lang-swift = ["dep:tree-sitter-swift"] +lang-toml = ["dep:tree-sitter-toml"] +lang-typescript = ["dep:tree-sitter-typescript"] +lang-vue = ["dep:tree-sitter-vue"] +lang-wgsl = ["dep:tree-sitter-wgsl"] +lang-yaml = ["dep:tree-sitter-yaml"] +lang-xml = ["dep:tree-sitter-xml"] +lang-zig = ["dep:tree-sitter-zig"] diff --git a/lapce-core/queries/c/highlights.scm b/lapce-core/queries/c/highlights.scm new file mode 100644 index 0000000000..d01f6ed2f7 --- /dev/null +++ b/lapce-core/queries/c/highlights.scm @@ -0,0 +1,145 @@ +; source: https://github.com/helix-editor/helix/blob/master/runtime/queries/c/highlights.scm +; licence: https://github.com/helix-editor/helix/blob/master/LICENSE +; spdx: MPL-2.0 + +"sizeof" @keyword + +[ + "enum" + "struct" + "typedef" + "union" +] @keyword.storage.type + +[ + "extern" + "register" + (type_qualifier) + (storage_class_specifier) +] @keyword.storage.modifier + +[ + "goto" + "break" + "continue" +] @keyword.control + +[ + "do" + "for" + "while" +] @keyword.control.repeat + +[ + "if" + "else" + "switch" + "case" + "default" +] @keyword.control.conditional + +"return" @keyword.control.return + +[ + "defined" + "#define" + "#elif" + "#else" + "#endif" + "#if" + "#ifdef" + "#ifndef" + "#include" + (preproc_directive) +] @keyword.directive + +(pointer_declarator "*" @type.builtin) +(abstract_pointer_declarator "*" @type.builtin) + +[ + "+" + "-" + "*" + "/" + "++" + "--" + "%" + "==" + "!=" + ">" + "<" + ">=" + "<=" + "&&" + "||" + "!" + "&" + "|" + "^" + "~" + "<<" + ">>" + "=" + "+=" + "-=" + "*=" + "/=" + "%=" + "<<=" + ">>=" + "&=" + "^=" + "|=" + "?" +] @operator + +(conditional_expression ":" @operator) + +"..." @punctuation + +["," "." ":" ";" "->" "::"] @punctuation.delimiter + +["(" ")" "[" "]" "{" "}"] @punctuation.bracket + +[(true) (false)] @constant.builtin.boolean + +(enumerator name: (identifier) @type.enum.variant) + +(string_literal) @string +(system_lib_string) @string + +(null) @constant +(number_literal) @constant.numeric +(char_literal) @constant.character + +(call_expression + function: (identifier) @function) +(call_expression + function: (field_expression + field: (field_identifier) @function)) +(call_expression (argument_list (identifier) @variable)) +(function_declarator + declarator: [(identifier) (field_identifier)] @function) +(parameter_declaration + declarator: (identifier) @variable.parameter) +(parameter_declaration + (pointer_declarator + declarator: (identifier) @variable.parameter)) +(preproc_function_def + name: (identifier) @function.special) + +(attribute + name: (identifier) @attribute) + +(field_identifier) @variable.other.member +(statement_identifier) @label +(type_identifier) @type +(primitive_type) @type.builtin +(sized_type_specifier) @type.builtin + +((identifier) @constant + (#match? @constant "^[A-Z][A-Z\\d_]*$")) + +(identifier) @variable + +(comment) @comment \ No newline at end of file diff --git a/lapce-core/queries/clojure/highlights.scm b/lapce-core/queries/clojure/highlights.scm new file mode 100644 index 0000000000..daac017277 --- /dev/null +++ b/lapce-core/queries/clojure/highlights.scm @@ -0,0 +1,88 @@ +; src: https://github.com/helix-editor/helix/blob/master/runtime/queries/clojure/highlights.scm +; license: https://github.com/helix-editor/helix/blob/master/LICENSE +; spdx: MPL-2.0 + +(dis_expr) @comment + +(kwd_lit) @string.special.symbol + +(str_lit) @string + +(num_lit) @constant.numeric + +[(bool_lit) (nil_lit)] @constant.builtin + +(comment) @comment + +;; metadata experiment +(meta_lit + marker: "^" @punctuation) + +;; dynamic variables +((sym_lit) @variable + (#match? @variable "^\\*.+\\*$")) + +;; parameter-related +((sym_lit) @variable.parameter + (#match? @variable.parameter "^&.*$")) + +;; gensym +((sym_lit) @variable + (#match? @variable "^.*#$")) + +;; def-like things +(list_lit + . + (sym_lit) @function.macro + . + (sym_lit) @function + (#match? @function.macro "^(declare|def|definline|definterface|defmacro|defmethod|defmulti|defn|defn-|defonce|defprotocol|defstruct|deftype|ns)$")) + +;; other macros +(list_lit + . + (sym_lit) @function.macro + (#match? @function.macro "^(\\.|\\.\\.|\\->|\\->>|amap|and|areduce|as\\->|assert|binding|bound\\-fn|case|catch|comment|cond|cond\\->|cond\\->>|condp|delay|do|doseq|dosync|dotimes|doto|extend-protocol|extend-type|finally|fn|fn\\*|for|future|gen-class|gen-interface|if|if\\-let|if\\-not|if\\-some|import|io!|lazy\\-cat|lazy\\-seq|let|letfn|locking|loop|memfn|monitor\\-enter|monitor\\-exit|or|proxy|proxy-super|pvalues|quote|recur|refer\\-clojure|reify|set!|some\\->|some\\->>|sync|throw|time|try|unquote|unquote\\-splicing|var|vswap!|when|when\\-first|when\\-let|when\\-not|when\\-some|while|with\\-bindings|with\\-in\\-str|with\\-loading\\-context|with\\-local\\-vars|with\\-open|with\\-out\\-str|with\\-precision|with\\-redefs)$")) + +(anon_fn_lit + . + (sym_lit) @function.macro + (#match? @function.macro "^(\\.|\\.\\.|\\->|\\->>|amap|and|areduce|as\\->|assert|binding|bound\\-fn|case|catch|comment|cond|cond\\->|cond\\->>|condp|delay|do|doseq|dosync|dotimes|doto|extend-protocol|extend-type|finally|fn|fn\\*|for|future|gen-class|gen-interface|if|if\\-let|if\\-not|if\\-some|import|io!|lazy\\-cat|lazy\\-seq|let|letfn|locking|loop|memfn|monitor\\-enter|monitor\\-exit|or|proxy|proxy-super|pvalues|quote|recur|refer\\-clojure|reify|set!|some\\->|some\\->>|sync|throw|time|try|unquote|unquote\\-splicing|var|vswap!|when|when\\-first|when\\-let|when\\-not|when\\-some|while|with\\-bindings|with\\-in\\-str|with\\-loading\\-context|with\\-local\\-vars|with\\-open|with\\-out\\-str|with\\-precision|with\\-redefs)$")) + +;; clojure.core=> (cp/pprint (sort (keep (fn [[s v]] (when-not (:macro (meta v)) s)) (ns-publics *ns*)))) +;; ...and then some manual filtering... +(list_lit + . + (sym_lit) @function.builtin + (#match? @function.builtin "^(\\*|\\*'|\\+|\\+'|\\-|\\-'|\\->ArrayChunk|\\->Eduction|\\->Vec|\\->VecNode|\\->VecSeq|\\-cache\\-protocol\\-fn|\\-reset\\-methods|/|<|<=|=|==|>|>=|PrintWriter\\-on|StackTraceElement\\->vec|Throwable\\->map|accessor|aclone|add\\-classpath|add\\-tap|add\\-watch|agent|agent\\-error|agent\\-errors|aget|alength|alias|all\\-ns|alter|alter\\-meta!|alter\\-var\\-root|ancestors|any\\?|apply|array\\-map|aset|aset\\-boolean|aset\\-byte|aset\\-char|aset\\-double|aset\\-float|aset\\-int|aset\\-long|aset\\-short|assoc|assoc!|assoc\\-in|associative\\?|atom|await|await\\-for|await1|bases|bean|bigdec|bigint|biginteger|bit\\-and|bit\\-and\\-not|bit\\-clear|bit\\-flip|bit\\-not|bit\\-or|bit\\-set|bit\\-shift\\-left|bit\\-shift\\-right|bit\\-test|bit\\-xor|boolean|boolean\\-array|boolean\\?|booleans|bound\\-fn\\*|bound\\?|bounded\\-count|butlast|byte|byte\\-array|bytes|bytes\\?|cast|cat|char|char\\-array|char\\-escape\\-string|char\\-name\\-string|char\\?|chars|chunk|chunk\\-append|chunk\\-buffer|chunk\\-cons|chunk\\-first|chunk\\-next|chunk\\-rest|chunked\\-seq\\?|class|class\\?|clear\\-agent\\-errors|clojure\\-version|coll\\?|commute|comp|comparator|compare|compare\\-and\\-set!|compile|complement|completing|concat|conj|conj!|cons|constantly|construct\\-proxy|contains\\?|count|counted\\?|create\\-ns|create\\-struct|cycle|dec|dec'|decimal\\?|dedupe|default\\-data\\-readers|delay\\?|deliver|denominator|deref|derive|descendants|destructure|disj|disj!|dissoc|dissoc!|distinct|distinct\\?|doall|dorun|double|double\\-array|double\\?|doubles|drop|drop\\-last|drop\\-while|eduction|empty|empty\\?|ensure|ensure\\-reduced|enumeration\\-seq|error\\-handler|error\\-mode|eval|even\\?|every\\-pred|every\\?|ex\\-cause|ex\\-data|ex\\-info|ex\\-message|extend|extenders|extends\\?|false\\?|ffirst|file\\-seq|filter|filterv|find|find\\-keyword|find\\-ns|find\\-protocol\\-impl|find\\-protocol\\-method|find\\-var|first|flatten|float|float\\-array|float\\?|floats|flush|fn\\?|fnext|fnil|force|format|frequencies|future\\-call|future\\-cancel|future\\-cancelled\\?|future\\-done\\?|future\\?|gensym|get|get\\-in|get\\-method|get\\-proxy\\-class|get\\-thread\\-bindings|get\\-validator|group\\-by|halt\\-when|hash|hash\\-combine|hash\\-map|hash\\-ordered\\-coll|hash\\-set|hash\\-unordered\\-coll|ident\\?|identical\\?|identity|ifn\\?|in\\-ns|inc|inc'|indexed\\?|init\\-proxy|inst\\-ms|inst\\-ms\\*|inst\\?|instance\\?|int|int\\-array|int\\?|integer\\?|interleave|intern|interpose|into|into\\-array|ints|isa\\?|iterate|iterator\\-seq|juxt|keep|keep\\-indexed|key|keys|keyword|keyword\\?|last|line\\-seq|list|list\\*|list\\?|load|load\\-file|load\\-reader|load\\-string|loaded\\-libs|long|long\\-array|longs|macroexpand|macroexpand\\-1|make\\-array|make\\-hierarchy|map|map\\-entry\\?|map\\-indexed|map\\?|mapcat|mapv|max|max\\-key|memoize|merge|merge\\-with|meta|method\\-sig|methods|min|min\\-key|mix\\-collection\\-hash|mod|munge|name|namespace|namespace\\-munge|nat\\-int\\?|neg\\-int\\?|neg\\?|newline|next|nfirst|nil\\?|nnext|not|not\\-any\\?|not\\-empty|not\\-every\\?|not=|ns\\-aliases|ns\\-imports|ns\\-interns|ns\\-map|ns\\-name|ns\\-publics|ns\\-refers|ns\\-resolve|ns\\-unalias|ns\\-unmap|nth|nthnext|nthrest|num|number\\?|numerator|object\\-array|odd\\?|parents|partial|partition|partition\\-all|partition\\-by|pcalls|peek|persistent!|pmap|pop|pop!|pop\\-thread\\-bindings|pos\\-int\\?|pos\\?|pr|pr\\-str|prefer\\-method|prefers|primitives\\-classnames|print|print\\-ctor|print\\-dup|print\\-method|print\\-simple|print\\-str|printf|println|println\\-str|prn|prn\\-str|promise|proxy\\-call\\-with\\-super|proxy\\-mappings|proxy\\-name|push\\-thread\\-bindings|qualified\\-ident\\?|qualified\\-keyword\\?|qualified\\-symbol\\?|quot|rand|rand\\-int|rand\\-nth|random\\-sample|range|ratio\\?|rational\\?|rationalize|re\\-find|re\\-groups|re\\-matcher|re\\-matches|re\\-pattern|re\\-seq|read|read+string|read\\-line|read\\-string|reader\\-conditional|reader\\-conditional\\?|realized\\?|record\\?|reduce|reduce\\-kv|reduced|reduced\\?|reductions|ref|ref\\-history\\-count|ref\\-max\\-history|ref\\-min\\-history|ref\\-set|refer|release\\-pending\\-sends|rem|remove|remove\\-all\\-methods|remove\\-method|remove\\-ns|remove\\-tap|remove\\-watch|repeat|repeatedly|replace|replicate|require|requiring\\-resolve|reset!|reset\\-meta!|reset\\-vals!|resolve|rest|restart\\-agent|resultset\\-seq|reverse|reversible\\?|rseq|rsubseq|run!|satisfies\\?|second|select\\-keys|send|send\\-off|send\\-via|seq|seq\\?|seqable\\?|seque|sequence|sequential\\?|set|set\\-agent\\-send\\-executor!|set\\-agent\\-send\\-off\\-executor!|set\\-error\\-handler!|set\\-error\\-mode!|set\\-validator!|set\\?|short|short\\-array|shorts|shuffle|shutdown\\-agents|simple\\-ident\\?|simple\\-keyword\\?|simple\\-symbol\\?|slurp|some|some\\-fn|some\\?|sort|sort\\-by|sorted\\-map|sorted\\-map\\-by|sorted\\-set|sorted\\-set\\-by|sorted\\?|special\\-symbol\\?|spit|split\\-at|split\\-with|str|string\\?|struct|struct\\-map|subs|subseq|subvec|supers|swap!|swap\\-vals!|symbol|symbol\\?|tagged\\-literal|tagged\\-literal\\?|take|take\\-last|take\\-nth|take\\-while|tap>|test|the\\-ns|thread\\-bound\\?|to\\-array|to\\-array\\-2d|trampoline|transduce|transient|tree\\-seq|true\\?|type|unchecked\\-add|unchecked\\-add\\-int|unchecked\\-byte|unchecked\\-char|unchecked\\-dec|unchecked\\-dec\\-int|unchecked\\-divide\\-int|unchecked\\-double|unchecked\\-float|unchecked\\-inc|unchecked\\-inc\\-int|unchecked\\-int|unchecked\\-long|unchecked\\-multiply|unchecked\\-multiply\\-int|unchecked\\-negate|unchecked\\-negate\\-int|unchecked\\-remainder\\-int|unchecked\\-short|unchecked\\-subtract|unchecked\\-subtract\\-int|underive|unquote|unquote\\-splicing|unreduced|unsigned\\-bit\\-shift\\-right|update|update\\-in|update\\-proxy|uri\\?|use|uuid\\?|val|vals|var\\-get|var\\-set|var\\?|vary\\-meta|vec|vector|vector\\-of|vector\\?|volatile!|volatile\\?|vreset!|with\\-bindings\\*|with\\-meta|with\\-redefs\\-fn|xml\\-seq|zero\\?|zipmap)$")) + +(anon_fn_lit + . + (sym_lit) @function.builtin + (#match? @function.builtin "^(\\*|\\*'|\\+|\\+'|\\-|\\-'|\\->ArrayChunk|\\->Eduction|\\->Vec|\\->VecNode|\\->VecSeq|\\-cache\\-protocol\\-fn|\\-reset\\-methods|/|<|<=|=|==|>|>=|PrintWriter\\-on|StackTraceElement\\->vec|Throwable\\->map|accessor|aclone|add\\-classpath|add\\-tap|add\\-watch|agent|agent\\-error|agent\\-errors|aget|alength|alias|all\\-ns|alter|alter\\-meta!|alter\\-var\\-root|ancestors|any\\?|apply|array\\-map|aset|aset\\-boolean|aset\\-byte|aset\\-char|aset\\-double|aset\\-float|aset\\-int|aset\\-long|aset\\-short|assoc|assoc!|assoc\\-in|associative\\?|atom|await|await\\-for|await1|bases|bean|bigdec|bigint|biginteger|bit\\-and|bit\\-and\\-not|bit\\-clear|bit\\-flip|bit\\-not|bit\\-or|bit\\-set|bit\\-shift\\-left|bit\\-shift\\-right|bit\\-test|bit\\-xor|boolean|boolean\\-array|boolean\\?|booleans|bound\\-fn\\*|bound\\?|bounded\\-count|butlast|byte|byte\\-array|bytes|bytes\\?|cast|cat|char|char\\-array|char\\-escape\\-string|char\\-name\\-string|char\\?|chars|chunk|chunk\\-append|chunk\\-buffer|chunk\\-cons|chunk\\-first|chunk\\-next|chunk\\-rest|chunked\\-seq\\?|class|class\\?|clear\\-agent\\-errors|clojure\\-version|coll\\?|commute|comp|comparator|compare|compare\\-and\\-set!|compile|complement|completing|concat|conj|conj!|cons|constantly|construct\\-proxy|contains\\?|count|counted\\?|create\\-ns|create\\-struct|cycle|dec|dec'|decimal\\?|dedupe|default\\-data\\-readers|delay\\?|deliver|denominator|deref|derive|descendants|destructure|disj|disj!|dissoc|dissoc!|distinct|distinct\\?|doall|dorun|double|double\\-array|double\\?|doubles|drop|drop\\-last|drop\\-while|eduction|empty|empty\\?|ensure|ensure\\-reduced|enumeration\\-seq|error\\-handler|error\\-mode|eval|even\\?|every\\-pred|every\\?|ex\\-cause|ex\\-data|ex\\-info|ex\\-message|extend|extenders|extends\\?|false\\?|ffirst|file\\-seq|filter|filterv|find|find\\-keyword|find\\-ns|find\\-protocol\\-impl|find\\-protocol\\-method|find\\-var|first|flatten|float|float\\-array|float\\?|floats|flush|fn\\?|fnext|fnil|force|format|frequencies|future\\-call|future\\-cancel|future\\-cancelled\\?|future\\-done\\?|future\\?|gensym|get|get\\-in|get\\-method|get\\-proxy\\-class|get\\-thread\\-bindings|get\\-validator|group\\-by|halt\\-when|hash|hash\\-combine|hash\\-map|hash\\-ordered\\-coll|hash\\-set|hash\\-unordered\\-coll|ident\\?|identical\\?|identity|ifn\\?|in\\-ns|inc|inc'|indexed\\?|init\\-proxy|inst\\-ms|inst\\-ms\\*|inst\\?|instance\\?|int|int\\-array|int\\?|integer\\?|interleave|intern|interpose|into|into\\-array|ints|isa\\?|iterate|iterator\\-seq|juxt|keep|keep\\-indexed|key|keys|keyword|keyword\\?|last|line\\-seq|list|list\\*|list\\?|load|load\\-file|load\\-reader|load\\-string|loaded\\-libs|long|long\\-array|longs|macroexpand|macroexpand\\-1|make\\-array|make\\-hierarchy|map|map\\-entry\\?|map\\-indexed|map\\?|mapcat|mapv|max|max\\-key|memoize|merge|merge\\-with|meta|method\\-sig|methods|min|min\\-key|mix\\-collection\\-hash|mod|munge|name|namespace|namespace\\-munge|nat\\-int\\?|neg\\-int\\?|neg\\?|newline|next|nfirst|nil\\?|nnext|not|not\\-any\\?|not\\-empty|not\\-every\\?|not=|ns\\-aliases|ns\\-imports|ns\\-interns|ns\\-map|ns\\-name|ns\\-publics|ns\\-refers|ns\\-resolve|ns\\-unalias|ns\\-unmap|nth|nthnext|nthrest|num|number\\?|numerator|object\\-array|odd\\?|parents|partial|partition|partition\\-all|partition\\-by|pcalls|peek|persistent!|pmap|pop|pop!|pop\\-thread\\-bindings|pos\\-int\\?|pos\\?|pr|pr\\-str|prefer\\-method|prefers|primitives\\-classnames|print|print\\-ctor|print\\-dup|print\\-method|print\\-simple|print\\-str|printf|println|println\\-str|prn|prn\\-str|promise|proxy\\-call\\-with\\-super|proxy\\-mappings|proxy\\-name|push\\-thread\\-bindings|qualified\\-ident\\?|qualified\\-keyword\\?|qualified\\-symbol\\?|quot|rand|rand\\-int|rand\\-nth|random\\-sample|range|ratio\\?|rational\\?|rationalize|re\\-find|re\\-groups|re\\-matcher|re\\-matches|re\\-pattern|re\\-seq|read|read+string|read\\-line|read\\-string|reader\\-conditional|reader\\-conditional\\?|realized\\?|record\\?|reduce|reduce\\-kv|reduced|reduced\\?|reductions|ref|ref\\-history\\-count|ref\\-max\\-history|ref\\-min\\-history|ref\\-set|refer|release\\-pending\\-sends|rem|remove|remove\\-all\\-methods|remove\\-method|remove\\-ns|remove\\-tap|remove\\-watch|repeat|repeatedly|replace|replicate|require|requiring\\-resolve|reset!|reset\\-meta!|reset\\-vals!|resolve|rest|restart\\-agent|resultset\\-seq|reverse|reversible\\?|rseq|rsubseq|run!|satisfies\\?|second|select\\-keys|send|send\\-off|send\\-via|seq|seq\\?|seqable\\?|seque|sequence|sequential\\?|set|set\\-agent\\-send\\-executor!|set\\-agent\\-send\\-off\\-executor!|set\\-error\\-handler!|set\\-error\\-mode!|set\\-validator!|set\\?|short|short\\-array|shorts|shuffle|shutdown\\-agents|simple\\-ident\\?|simple\\-keyword\\?|simple\\-symbol\\?|slurp|some|some\\-fn|some\\?|sort|sort\\-by|sorted\\-map|sorted\\-map\\-by|sorted\\-set|sorted\\-set\\-by|sorted\\?|special\\-symbol\\?|spit|split\\-at|split\\-with|str|string\\?|struct|struct\\-map|subs|subseq|subvec|supers|swap!|swap\\-vals!|symbol|symbol\\?|tagged\\-literal|tagged\\-literal\\?|take|take\\-last|take\\-nth|take\\-while|tap>|test|the\\-ns|thread\\-bound\\?|to\\-array|to\\-array\\-2d|trampoline|transduce|transient|tree\\-seq|true\\?|type|unchecked\\-add|unchecked\\-add\\-int|unchecked\\-byte|unchecked\\-char|unchecked\\-dec|unchecked\\-dec\\-int|unchecked\\-divide\\-int|unchecked\\-double|unchecked\\-float|unchecked\\-inc|unchecked\\-inc\\-int|unchecked\\-int|unchecked\\-long|unchecked\\-multiply|unchecked\\-multiply\\-int|unchecked\\-negate|unchecked\\-negate\\-int|unchecked\\-remainder\\-int|unchecked\\-short|unchecked\\-subtract|unchecked\\-subtract\\-int|underive|unquote|unquote\\-splicing|unreduced|unsigned\\-bit\\-shift\\-right|update|update\\-in|update\\-proxy|uri\\?|use|uuid\\?|val|vals|var\\-get|var\\-set|var\\?|vary\\-meta|vec|vector|vector\\-of|vector\\?|volatile!|volatile\\?|vreset!|with\\-bindings\\*|with\\-meta|with\\-redefs\\-fn|xml\\-seq|zero\\?|zipmap)$")) + +;; anonymous function positional arguments +((sym_lit) @operator + (#match? @operator "^%")) + +;; other calls +(list_lit + . + (sym_lit) @function) + +;; interop-ish +(list_lit + . + (sym_lit) @function.method + (#match? @function.method "^\\.")) + +;; other symbols +(sym_lit) @variable + +;; quote +(quoting_lit) @constant.character.escape + +;; syntax quote +["{" "}" "(" ")" "[" "]"] @punctuation.bracket +["~" "~@" "#'" "@"] @operator +(syn_quoting_lit) @constant.character.escape diff --git a/lapce-core/queries/clojure/injections.scm b/lapce-core/queries/clojure/injections.scm new file mode 100644 index 0000000000..df707522e1 --- /dev/null +++ b/lapce-core/queries/clojure/injections.scm @@ -0,0 +1,7 @@ +; src: https://github.com/helix-editor/helix/blob/master/runtime/queries/clojure/injections.scm +; license: https://github.com/helix-editor/helix/blob/master/LICENSE +; spdx: MPL-2.0 + +((regex_lit) @injection.content + (#set! injection.language "regex")) + \ No newline at end of file diff --git a/lapce-core/queries/cmake/highlights.scm b/lapce-core/queries/cmake/highlights.scm new file mode 100644 index 0000000000..f03dfd1324 --- /dev/null +++ b/lapce-core/queries/cmake/highlights.scm @@ -0,0 +1,100 @@ +; src: https://github.com/helix-editor/helix/blob/master/runtime/queries/cmake/highlights.scm +; license: https://github.com/helix-editor/helix/blob/master/LICENSE +; spdx: MPL-2.0 + +[ + (quoted_argument) + (bracket_argument) + ] @string + +(variable) @variable + +[ + (bracket_comment) + (line_comment) + ] @comment + +(normal_command (identifier) @function) + +["ENV" "CACHE"] @string.special.symbol +["$" "{" "}" "<" ">"] @punctuation +["(" ")"] @punctuation.bracket + +[ + (function) + (endfunction) + (macro) + (endmacro) + ] @keyword.function + +[ + (if) + (elseif) + (else) + (endif) + ] @keyword.control.conditional + +[ + (foreach) + (endforeach) + (while) + (endwhile) + ] @keyword.control.repeat + +(function_command + (function) + . (argument) @function + (argument)* @variable.parameter + ) + +(macro_command + (macro) + . (argument) @function.macro + (argument)* @variable.parameter + ) + +(normal_command + (identifier) @function.builtin + . (argument) @variable + (#match? @function.builtin "^(?i)(set)$")) + +(normal_command + (identifier) @function.builtin + . (argument) + (argument) @constant + (#match? @constant "^(?:PARENT_SCOPE|CACHE)$") + (#match? @function.builtin "^(?i)(unset)$")) + +(normal_command + (identifier) @function.builtin + . (argument) + . (argument) + (argument) @constant + (#match? @constant "^(?:PARENT_SCOPE|CACHE|FORCE)$") + (#match? @function.builtin "^(?i)(set)$") + ) + +((argument) @constant.builtin.boolean + (#match? @constant.builtin.boolean "^(?i)(?:1|on|yes|true|y|0|off|no|false|n|ignore|notfound|.*-notfound)$") + ) + +(if_command + (if) + (argument) @operator + (#match? @operator "^(?:NOT|AND|OR|COMMAND|POLICY|TARGET|TEST|DEFINED|IN_LIST|EXISTS|IS_NEWER_THAN|IS_DIRECTORY|IS_SYMLINK|IS_ABSOLUTE|MATCHES|LESS|GREATER|EQUAL|LESS_EQUAL|GREATER_EQUAL|STRLESS|STRGREATER|STREQUAL|STRLESS_EQUAL|STRGREATER_EQUAL|VERSION_LESS|VERSION_GREATER|VERSION_EQUAL|VERSION_LESS_EQUAL|VERSION_GREATER_EQUAL)$") +) + +(normal_command + (identifier) @function.builtin + . (argument) + (argument) @constant + (#match? @constant "^(?:ALL|COMMAND|DEPENDS|BYPRODUCTS|WORKING_DIRECTORY|COMMENT|JOB_POOL|VERBATIM|USES_TERMINAL|COMMAND_EXPAND_LISTS|SOURCES)$") + (#match? @function.builtin "^(?i)(add_custom_target)$") + ) + +(normal_command + (identifier) @function.builtin + (argument) @constant + (#match? @constant "^(?:OUTPUT|COMMAND|MAIN_DEPENDENCY|DEPENDS|BYPRODUCTS|IMPLICIT_DEPENDS|WORKING_DIRECTORY|COMMENT|DEPFILE|JOB_POOL|VERBATIM|APPEND|USES_TERMINAL|COMMAND_EXPAND_LISTS)$") + (#match? @function.builtin "^(?i)(add_custom_command)$") + ) diff --git a/lapce-core/queries/cmake/injections.scm b/lapce-core/queries/cmake/injections.scm new file mode 100644 index 0000000000..b4a9b39574 --- /dev/null +++ b/lapce-core/queries/cmake/injections.scm @@ -0,0 +1,8 @@ +; src: https://github.com/helix-editor/helix/blob/master/runtime/queries/cmake/injections.scm +; license: https://github.com/helix-editor/helix/blob/master/LICENSE +; spdx: MPL-2.0 + +((line_comment) @injection.content + (#set! injection.language "comment")) +((bracket_comment) @injection.content + (#set! injection.language "comment")) \ No newline at end of file diff --git a/lapce-core/queries/cpp/highlights.scm b/lapce-core/queries/cpp/highlights.scm new file mode 100644 index 0000000000..48e97b3d58 --- /dev/null +++ b/lapce-core/queries/cpp/highlights.scm @@ -0,0 +1,161 @@ +; source: https://github.com/helix-editor/helix/blob/master/runtime/queries/cpp/highlights.scm +; licence: https://github.com/helix-editor/helix/blob/master/LICENSE +; spdx: MPL-2.0 + +(storage_class_specifier) @keyword.storage + +"goto" @keyword +"register" @keyword +"break" @keyword +"case" @keyword +"continue" @keyword +"default" @keyword +"do" @keyword +"else" @keyword +"enum" @keyword +"extern" @keyword +"for" @keyword +"if" @keyword +"inline" @keyword +"return" @keyword +"sizeof" @keyword +"struct" @keyword +"switch" @keyword +"typedef" @keyword +"union" @keyword +"volatile" @keyword +"while" @keyword +"const" @keyword + +[ + "#define" + "#elif" + "#else" + "#endif" + "#if" + "#ifdef" + "#ifndef" + "#include" + (preproc_directive) +] @keyword.directive + +"--" @operator +"-" @operator +"-=" @operator +"->" @operator +"=" @operator +"!=" @operator +"*" @operator +"&" @operator +"&&" @operator +"+" @operator +"++" @operator +"+=" @operator +"<" @operator +"==" @operator +">" @operator +"||" @operator +">=" @operator +"<=" @operator + +"." @punctuation.delimiter +";" @punctuation.delimiter + +[(true) (false)] @constant.builtin.boolean + +(enumerator) @type.enum.variant + +(string_literal) @string +(system_lib_string) @string + +(null) @constant +(number_literal) @constant.numeric.integer +(char_literal) @constant.character + +(call_expression + function: (identifier) @function) +(call_expression + function: (field_expression + field: (field_identifier) @function)) +(function_declarator + declarator: (identifier) @function) +(preproc_function_def + name: (identifier) @function.special) + +(field_identifier) @variable.other.member +(statement_identifier) @label +(type_identifier) @type +(primitive_type) @type +(sized_type_specifier) @type + +((identifier) @constant + (#match? @constant "^[A-Z][A-Z\\d_]*$")) + +(identifier) @variable + +(comment) @comment + + +; Functions + +(call_expression + function: (qualified_identifier + name: (identifier) @function)) + +(template_function + name: (identifier) @function) + +(template_method + name: (field_identifier) @function) + +(template_function + name: (identifier) @function) + +(function_declarator + declarator: (qualified_identifier + name: (identifier) @function)) + +(function_declarator + declarator: (qualified_identifier + name: (identifier) @function)) + +(function_declarator + declarator: (field_identifier) @function) + +; Types + +((namespace_identifier) @type + (#match? @type "^[A-Z]")) + +(auto) @type + +; Constants + +(this) @variable.builtin +(nullptr) @constant + +; Keywords + +"catch" @keyword +"class" @keyword +"constexpr" @keyword +"delete" @keyword +"explicit" @keyword +"final" @keyword +"friend" @keyword +"mutable" @keyword +"namespace" @keyword +"noexcept" @keyword +"new" @keyword +"override" @keyword +"private" @keyword +"protected" @keyword +"public" @keyword +"template" @keyword +"throw" @keyword +"try" @keyword +"typename" @keyword +"using" @keyword +"virtual" @keyword + +; Strings diff --git a/lapce-core/queries/css/highlights.scm b/lapce-core/queries/css/highlights.scm new file mode 100644 index 0000000000..5a2b68c922 --- /dev/null +++ b/lapce-core/queries/css/highlights.scm @@ -0,0 +1,68 @@ +; source: https://github.com/helix-editor/helix/blob/master/runtime/queries/css/highlights.scm +; licence: https://github.com/helix-editor/helix/blob/master/LICENSE +; spdx: MPL-2.0 + +(comment) @comment + +(tag_name) @tag +(nesting_selector) @tag +(universal_selector) @tag + +"~" @operator +">" @operator +"+" @operator +"-" @operator +"*" @operator +"/" @operator +"=" @operator +"^=" @operator +"|=" @operator +"~=" @operator +"$=" @operator +"*=" @operator + +"and" @operator +"or" @operator +"not" @operator +"only" @operator + +(attribute_selector (plain_value) @string) +(pseudo_element_selector (tag_name) @attribute) +(pseudo_class_selector (class_name) @attribute) + +(class_name) @variable.other.member +(id_name) @variable.other.member +(namespace_name) @variable.other.member +(property_name) @variable.other.member +(feature_name) @variable.other.member + +(attribute_name) @attribute + +(function_name) @function + +((property_name) @variable + (#match? @variable "^--")) +((plain_value) @variable + (#match? @variable "^--")) + +"@media" @keyword +"@import" @keyword +"@charset" @keyword +"@namespace" @keyword +"@supports" @keyword +"@keyframes" @keyword +(at_keyword) @keyword +(to) @keyword +(from) @keyword +(important) @keyword + +(string_value) @string +(color_value) @string.special + +(integer_value) @constant.numeric.integer +(float_value) @constant.numeric.float +(unit) @type + +"#" @punctuation.delimiter +"," @punctuation.delimiter +":" @punctuation.delimiter \ No newline at end of file diff --git a/lapce-core/queries/elm/highlights.scm b/lapce-core/queries/elm/highlights.scm new file mode 100644 index 0000000000..bdc94c7523 --- /dev/null +++ b/lapce-core/queries/elm/highlights.scm @@ -0,0 +1,88 @@ +; source: https://github.com/helix-editor/helix/blob/master/runtime/queries/elm/highlights.scm +; licence: https://github.com/helix-editor/helix/blob/master/LICENSE +; spdx: MPL-2.0 + +; Keywords +[ + "if" + "then" + "else" + "let" + "in" + ] @keyword.control +(case) @keyword.control +(of) @keyword.control + +(colon) @keyword.operator +(backslash) @keyword +(as) @keyword +(port) @keyword +(exposing) @keyword +(alias) @keyword +(infix) @keyword + +(arrow) @keyword.operator +(dot) @keyword.operator + +(port) @keyword + +(type_annotation(lower_case_identifier) @function) +(port_annotation(lower_case_identifier) @function) +(file (value_declaration (function_declaration_left(lower_case_identifier) @function))) + +(field name: (lower_case_identifier) @attribute) +(field_access_expr(lower_case_identifier) @attribute) + +(operator_identifier) @keyword.operator +(eq) @keyword.operator.assignment + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +"|" @keyword +"," @punctuation.delimiter + +[ + "|>" +] @keyword + + +(import) @keyword.control.import +(module) @keyword.other + +(number_constant_expr) @constant.numeric + +(type) @type + +(type_declaration(upper_case_identifier) @type) +(type_ref) @type +(type_alias_declaration name: (upper_case_identifier) @type) + +(union_pattern constructor: (upper_case_qid (upper_case_identifier) @label (dot) (upper_case_identifier) @variable.other.member)) +(union_pattern constructor: (upper_case_qid (upper_case_identifier) @variable.other.member)) + +(union_variant(upper_case_identifier) @variable.other.member) +(value_expr name: (value_qid (upper_case_identifier) @label)) +(value_expr (upper_case_qid (upper_case_identifier) @label (dot) (upper_case_identifier) @variable.other.member)) +(value_expr(upper_case_qid(upper_case_identifier)) @variable.other.member) + +; comments +(line_comment) @comment +(block_comment) @comment + +; strings +(string_escape) @constant.character.escape + +(open_quote) @string +(close_quote) @string +(regular_string_part) @string + +(open_char) @constant.character +(close_char) @constant.character + diff --git a/lapce-core/queries/erlang/highlights.scm b/lapce-core/queries/erlang/highlights.scm new file mode 100644 index 0000000000..a2fa5884f8 --- /dev/null +++ b/lapce-core/queries/erlang/highlights.scm @@ -0,0 +1,108 @@ +; source: https://github.com/nvim-treesitter/nvim-treesitter/blob/master/queries/erlang/highlights.scm +; licence: https://github.com/nvim-treesitter/nvim-treesitter/blob/master/LICENSE +; spdx: Apache-2.0 + +;; keywoord +[ + "fun" + "div" +] @keyword +;; bracket +[ + "(" + ")" + "{" + "}" + "[" + "]" + "#" +] @punctuation.bracket +;; conditional +[ + "receive" + "if" + "case" + "of" + "when" + "after" + "end" +] @conditional + +[ + "catch" + "try" + "throw" +] @exception +;;; module define +[ + "module" + "export" +] @include +;;; operator +[ + ":" + ":=" + "?" + "!" + "-" + "+" + "=" + "->" + "=>" + "|" + ;;;TODO + "$" + ] @operator + +(comment) @comment +(string) @string +(variable) @variable + +(module_name + (atom) @namespace +) +;;; expr_function_call +(expr_function_call + name: (computed_function_name) @function.call +) + +(expr_function_call + arguments: (atom) @variable +) + +;;; map +(map + (map_entry [ + (atom) + (variable) + ] @variable) +) + + +(tuple (atom) @variable) +(pat_tuple ( pattern (atom) @variable)) + +(computed_function_name) @function +;;; case +(case_clause + pattern: (pattern + (atom) @variable + ) +) +(case_clause + body: (atom) @variable +) + +;;; function +(qualified_function_name + module_name: (atom) @attribute + function_name: (atom) @function +) +;; function +(function_clause + name: (atom) @function) +;;;lambda +(lambda_clause + arguments: + (pattern) @variable +) diff --git a/lapce-core/queries/javascript/highlights.scm b/lapce-core/queries/javascript/highlights.scm new file mode 100644 index 0000000000..02bbcb56ba --- /dev/null +++ b/lapce-core/queries/javascript/highlights.scm @@ -0,0 +1,261 @@ +; source: https://github.com/helix-editor/helix/blob/master/runtime/queries/javascript/highlights.scm +; licence: https://github.com/helix-editor/helix/blob/master/LICENSE +; spdx: MPL-2.0 + +; Function and method parameters +;------------------------------- + +; (p) => ... +(formal_parameters + (identifier) @variable.parameter) + +; (...p) => ... +(formal_parameters + (rest_pattern + (identifier) @variable.parameter)) + +; ({ p }) => ... +(formal_parameters + (object_pattern + (shorthand_property_identifier_pattern) @variable.parameter)) + +; ({ a: p }) => ... +(formal_parameters + (object_pattern + (pair_pattern + value: (identifier) @variable.parameter))) + +; ([ p ]) => ... +(formal_parameters + (array_pattern + (identifier) @variable.parameter)) + +; (p = 1) => ... +(formal_parameters + (assignment_pattern + left: (identifier) @variable.parameter)) + +; p => ... +(arrow_function + parameter: (identifier) @variable.parameter) + +; Special identifiers +;-------------------- + +([ + (identifier) + (shorthand_property_identifier) + (shorthand_property_identifier_pattern) + ] @constant + (#match? @constant "^[A-Z_][A-Z\\d_]+$")) + + +((identifier) @constructor + (#match? @constructor "^[A-Z]")) + +((identifier) @variable.builtin + (#match? @variable.builtin "^(arguments|module|console|window|document)$") + (#is-not? local)) + +((identifier) @function.builtin + (#eq? @function.builtin "require") + (#is-not? local)) + +; Function and method definitions +;-------------------------------- + +(function + name: (identifier) @function) +(function_declaration + name: (identifier) @function) +(method_definition + name: (property_identifier) @function.method) + +(pair + key: (property_identifier) @function.method + value: [(function) (arrow_function)]) + +(assignment_expression + left: (member_expression + property: (property_identifier) @function.method) + right: [(function) (arrow_function)]) + +(variable_declarator + name: (identifier) @function + value: [(function) (arrow_function)]) + +(assignment_expression + left: (identifier) @function + right: [(function) (arrow_function)]) + + +; Function and method calls +;-------------------------- + +(call_expression + function: (identifier) @function) + +(call_expression + function: (member_expression + property: (property_identifier) @function.method)) + +; Variables +;---------- + +(identifier) @variable + +; Properties +;----------- + +(property_identifier) @variable.other.member +(shorthand_property_identifier) @variable.other.member +(shorthand_property_identifier_pattern) @variable.other.member + +; Literals +;--------- + +(this) @variable.builtin +(super) @variable.builtin + +[ + (true) + (false) + (null) + (undefined) +] @constant.builtin + +(comment) @comment + +[ + (string) + (template_string) +] @string + +(regex) @string.regexp +(number) @constant.numeric.integer + +; Tokens +;------- + +(template_substitution + "${" @punctuation.special + "}" @punctuation.special) @embedded + +[ + ";" + "?." + "." + "," +] @punctuation.delimiter + +[ + "-" + "--" + "-=" + "+" + "++" + "+=" + "*" + "*=" + "**" + "**=" + "/" + "/=" + "%" + "%=" + "<" + "<=" + "<<" + "<<=" + "=" + "==" + "===" + "!" + "!=" + "!==" + "=>" + ">" + ">=" + ">>" + ">>=" + ">>>" + ">>>=" + "~" + "^" + "&" + "|" + "^=" + "&=" + "|=" + "&&" + "||" + "??" + "&&=" + "||=" + "??=" + "..." +] @operator + +(ternary_expression ["?" ":"] @operator) + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +[ + "as" + "async" + "debugger" + "delete" + "extends" + "function" + "get" + "in" + "instanceof" + "new" + "of" + "set" + "static" + "target" + "try" + "typeof" + "void" + "with" +] @keyword + +[ + "class" + "let" + "const" + "var" +] @keyword.storage.type + +[ + "switch" + "case" + "if" + "else" + "yield" + "throw" + "finally" + "return" + "catch" + "continue" + "while" + "break" + "for" + "do" + "await" +] @keyword.control + +[ + "import" + "default" + "from" + "export" +] @keyword.control.import \ No newline at end of file diff --git a/lapce-core/queries/jsx/highlights.scm b/lapce-core/queries/jsx/highlights.scm new file mode 100644 index 0000000000..96e0da0b74 --- /dev/null +++ b/lapce-core/queries/jsx/highlights.scm @@ -0,0 +1,250 @@ +; source: https://github.com/helix-editor/helix/blob/master/runtime/queries/jsx/highlights.scm +; licence: https://github.com/helix-editor/helix/blob/master/LICENSE +; spdx: MPL-2.0 + +; Special identifiers +;-------------------- + +([ + (identifier) + (shorthand_property_identifier) + (shorthand_property_identifier_pattern) + ] @constant + (#match? @constant "^[A-Z_][A-Z\\d_]+$")) + + +((identifier) @constructor + (#match? @constructor "^[A-Z]")) + +((identifier) @variable.builtin + (#match? @variable.builtin "^(arguments|module|console|window|document)$") + (#is-not? local)) + +((identifier) @function.builtin + (#eq? @function.builtin "require") + (#is-not? local)) + +; Function and method definitions +;-------------------------------- + +(function + name: (identifier) @function) +(function_declaration + name: (identifier) @function) +(method_definition + name: (property_identifier) @function.method) + +(pair + key: (property_identifier) @function.method + value: [(function) (arrow_function)]) + +(assignment_expression + left: (member_expression + property: (property_identifier) @function.method) + right: [(function) (arrow_function)]) + +(variable_declarator + name: (identifier) @function + value: [(function) (arrow_function)]) + +(assignment_expression + left: (identifier) @function + right: [(function) (arrow_function)]) + + +; Function and method calls +;-------------------------- + +(call_expression + function: (identifier) @function) + +(call_expression + function: (member_expression + property: (property_identifier) @function.method)) + +; Variables +;---------- + +(identifier) @variable + +; Properties +;----------- + +(property_identifier) @variable.other.member +(shorthand_property_identifier) @variable.other.member +(shorthand_property_identifier_pattern) @variable.other.member + +; Literals +;--------- + +(this) @variable.builtin +(super) @variable.builtin + +[ + (true) + (false) + (null) + (undefined) +] @constant.builtin + +(comment) @comment + +[ + (string) + (template_string) +] @string + +(regex) @string.regexp +(number) @constant.numeric.integer + +; Tokens +;------- + +(template_substitution + "${" @punctuation.special + "}" @punctuation.special) @embedded + +[ + ";" + "?." + "." + "," +] @punctuation.delimiter + +[ + "-" + "--" + "-=" + "+" + "++" + "+=" + "*" + "*=" + "**" + "**=" + "/" + "/=" + "%" + "%=" + "<" + "<=" + "<<" + "<<=" + "=" + "==" + "===" + "!" + "!=" + "!==" + "=>" + ">" + ">=" + ">>" + ">>=" + ">>>" + ">>>=" + "~" + "^" + "&" + "|" + "^=" + "&=" + "|=" + "&&" + "||" + "??" + "&&=" + "||=" + "??=" + "..." +] @operator + +(ternary_expression ["?" ":"] @operator) + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +[ + "as" + "async" + "debugger" + "delete" + "extends" + "function" + "get" + "in" + "instanceof" + "new" + "of" + "set" + "static" + "target" + "try" + "typeof" + "void" + "with" +] @keyword + +[ + "class" + "let" + "const" + "var" +] @keyword.storage.type + +[ + "switch" + "case" + "if" + "else" + "yield" + "throw" + "finally" + "return" + "catch" + "continue" + "while" + "break" + "for" + "do" + "await" +] @keyword.control + +[ + "import" + "default" + "from" + "export" +] @keyword.control.import + +; Highlight component names differently +(jsx_opening_element ((identifier) @constructor + (#match? @constructor "^[A-Z]"))) + +; Handle the dot operator effectively - +(jsx_opening_element ((nested_identifier (identifier) @tag (identifier) @constructor))) + +(jsx_closing_element ((identifier) @constructor + (#match? @constructor "^[A-Z]"))) + +; Handle the dot operator effectively - +(jsx_closing_element ((nested_identifier (identifier) @tag (identifier) @constructor))) + +(jsx_self_closing_element ((identifier) @constructor + (#match? @constructor "^[A-Z]"))) + +; Handle the dot operator effectively - +(jsx_self_closing_element ((nested_identifier (identifier) @tag (identifier) @constructor))) + +; TODO: also tag @punctuation.delimiter? + +(jsx_opening_element (identifier) @tag) +(jsx_closing_element (identifier) @tag) +(jsx_self_closing_element (identifier) @tag) +(jsx_attribute (property_identifier) @variable.other.member) \ No newline at end of file diff --git a/lapce-core/queries/julia/highlights.scm b/lapce-core/queries/julia/highlights.scm new file mode 100644 index 0000000000..5c059126cf --- /dev/null +++ b/lapce-core/queries/julia/highlights.scm @@ -0,0 +1,296 @@ +; ---------- +; Primitives +; ---------- + +[ + (line_comment) + (block_comment) +] @comment + +( + ((identifier) @constant.builtin) + (#match? @constant.builtin "^(nothing|missing|undef)$")) + +[ + (true) + (false) +] @constant.builtin.boolean + +(integer_literal) @constant.numeric.integer +(float_literal) @constant.numeric.float + +( + ((identifier) @constant.numeric.float) + (#match? @constant.numeric.float "^((Inf|NaN)(16|32|64)?)$")) + +(character_literal) @constant.character +(escape_sequence) @constant.character.escape + +(string_literal) @string + +(prefixed_string_literal + prefix: (identifier) @function.macro) @string + +(quote_expression + (identifier) @string.special.symbol) + +; ------------------- +; Modules and Imports +; ------------------- + +(module_definition + name: (identifier) @namespace) + +(import_statement + (identifier) @namespace) + +(selected_import + . (identifier) @namespace) + +(scoped_identifier + (identifier) @namespace) + +; ----- +; Types +; ----- + +(abstract_definition + name: (identifier) @type) + +(primitive_definition + name: (identifier) @type) + +(struct_definition + name: (identifier) @type) + +(struct_definition + . (_) + (identifier) @variable.other.member) + +(struct_definition + . (_) + (typed_expression + . (identifier) @variable.other.member)) + +(type_parameter_list + (identifier) @type) + +(constrained_type_parameter + (identifier) @type) + +(subtype_clause + (identifier) @type) + +(typed_expression + (identifier) @type . ) + +(parameterized_identifier + (identifier) @type) + +(type_argument_list + (identifier) @type) + +(where_clause + (identifier) @type) + +; ------------------- +; Function definition +; ------------------- + +( + (function_definition + name: [ + (identifier) @function + (scoped_identifier + (identifier) @namespace + (identifier) @function) + ]) + ; prevent constructors (PascalCase) to be highlighted as functions + (#match? @function "^[^A-Z]")) + +( + (short_function_definition + name: [ + (identifier) @function + (scoped_identifier + (identifier) @namespace + (identifier) @function) + ]) + ; prevent constructors (PascalCase) to be highlighted as functions + (#match? @function "^[^A-Z]")) + +(parameter_list + (identifier) @variable.parameter) + +(typed_parameter + (identifier) @variable.parameter + (identifier)? @type) + +(optional_parameter + . (identifier) @variable.parameter) + +(slurp_parameter + (identifier) @variable.parameter) + +(function_expression + . (identifier) @variable.parameter) + +; --------------- +; Functions calls +; --------------- + +( + (call_expression + (identifier) @function) + ; prevent constructors (PascalCase) to be highlighted as functions + (#match? @function "^[^A-Z]")) + +( + (broadcast_call_expression + (identifier) @function) + (#match? @function "^[^A-Z]")) + +( + (call_expression + (field_expression (identifier) @function .)) + (#match? @function "^[^A-Z]")) + +( + (broadcast_call_expression + (field_expression (identifier) @function .)) + (#match? @function "^[^A-Z]")) + +; ------ +; Macros +; ------ + +(macro_definition + name: (identifier) @function.macro) + +(macro_identifier + "@" @function.macro + (identifier) @function.macro) + +; -------- +; Keywords +; -------- + +(function_definition + ["function" "end"] @keyword.function) + +(if_statement + ["if" "end"] @keyword.control.conditional) +(elseif_clause + ["elseif"] @keyword.control.conditional) +(else_clause + ["else"] @keyword.control.conditional) +(ternary_expression + ["?" ":"] @keyword.control.conditional) + +(for_statement + ["for" "end"] @keyword.control.repeat) +(while_statement + ["while" "end"] @keyword.control.repeat) +(break_statement) @keyword.control.repeat +(continue_statement) @keyword.control.repeat +(for_binding + "in" @keyword.control.repeat) +(for_clause + "for" @keyword.control.repeat) + +(try_statement + ["try" "end" ] @keyword.control.exception) +(finally_clause + "finally" @keyword.control.exception) +(catch_clause + "catch" @keyword.control.exception) + +[ + "export" + "import" + "using" +] @keyword.control.import + +[ + "abstract" + "baremodule" + "begin" + "const" + "do" + "end" + "let" + "macro" + "module" + "mutable" + "primitive" + "quote" + "return" + "struct" + "type" + "where" +] @keyword + +; TODO: fix this +((identifier) @keyword (match? @keyword "global|local")) + +; --------- +; Operators +; --------- + +[ + (operator) + "::" + "<:" + ":" + "=>" + "..." + "$" +] @operator + +; ------------ +; Punctuations +; ------------ + +[ + "." + "," + ";" +] @punctuation.delimiter + +[ + "[" + "]" + "(" + ")" + "{" + "}" +] @punctuation.bracket + +; --------------------- +; Remaining identifiers +; --------------------- + +(const_statement + (variable_declaration + . (identifier) @constant)) + +; SCREAMING_SNAKE_CASE +( + (identifier) @constant + (match? @constant "^[A-Z][A-Z0-9_]*$")) + +; remaining identifiers that start with capital letters should be types (PascalCase) +( + (identifier) @type + (match? @type "^[A-Z]")) + +; Field expressions are either module content or struct fields. +; Module types and constants should already be captured, so this +; assumes the remaining identifiers to be struct fields. +(field_expression + (_) + (identifier) @variable.other.member) + +(identifier) @variable + +; Taken from https://github.com/helix-editor/helix/blob/master/runtime/queries/julia/highlights.scm \ No newline at end of file diff --git a/lapce-core/queries/julia/injections.scm b/lapce-core/queries/julia/injections.scm new file mode 100644 index 0000000000..c671e7f427 --- /dev/null +++ b/lapce-core/queries/julia/injections.scm @@ -0,0 +1,30 @@ +( + (source_file + (string_literal) @injection.content + . + [ + (module_definition) + (function_definition) + (macro_definition) + (primitive_definition) + (abstract_definition) + (struct_definition) + (assignment_expression) + (const_statement) + ]) + (#set! injection.language "markdown")) + +( + [ + (line_comment) + (block_comment) + ] @injection.content + (#set! injection.language "comment")) + +( + (prefixed_string_literal + prefix: (identifier) @function.macro) @injection.content + (#eq? @function.macro "re") + (#set! injection.language "regex")) + +;; taken from https://github.com/helix-editor/helix/blob/master/runtime/queries/julia/injections.scm \ No newline at end of file diff --git a/lapce-core/queries/kotlin/highlights.scm b/lapce-core/queries/kotlin/highlights.scm new file mode 100644 index 0000000000..31da4bcc4b --- /dev/null +++ b/lapce-core/queries/kotlin/highlights.scm @@ -0,0 +1,298 @@ +; source: https://github.com/helix-editor/helix/blob/master/runtime/queries/kotlin/highlights.scm +; licence: https://github.com/helix-editor/helix/blob/master/LICENSE +; spdx: MPL-2.0 + + +(multi_line_string_literal + "$" @punctuation + (interpolated_identifier) @none) +(multi_line_string_literal + "${" @punctuation + (interpolated_expression) @none + "}" @punctuation.) + +; NOTE: `interpolated_identifier`s can be highlighted in any way +(line_string_literal + "$" @punctuation + (interpolated_identifier) @none) +(line_string_literal + "${" @punctuation + (interpolated_expression) @none + "}" @punctuation) + +[ + "." + "," + ";" + ":" + "::" +] @punctuation.delimiter + +[ + "(" ")" + "[" "]" + "{" "}" +] @punctuation.bracket + +[ + "!" + "!=" + "!==" + "=" + "==" + "===" + ">" + ">=" + "<" + "<=" + "||" + "&&" + "+" + "++" + "+=" + "-" + "--" + "-=" + "*" + "*=" + "/" + "/=" + "%" + "%=" + "?." + "?:" + "!!" + "is" + "!is" + "in" + "!in" + "as" + "as?" + ".." + "->" +] @operator + +;;; Keywords + +(type_alias "typealias" @keyword) +[ + (class_modifier) + (member_modifier) + (function_modifier) + (property_modifier) + (platform_modifier) + (variance_modifier) + (parameter_modifier) + (visibility_modifier) + (reification_modifier) + (inheritance_modifier) +]@keyword + +[ + "val" + "var" + "enum" + "class" + "object" + "interface" +; "typeof" ; NOTE: It is reserved for future use +] @keyword + +("fun") @keyword.function + +(jump_expression) @keyword.control.return + +[ + "if" + "else" + "when" +] @keyword.control.conditional + +[ + "for" + "do" + "while" +] @keyword.control.repeat + +[ + "try" + "catch" + "throw" + "finally" +] @keyword.control.exception + +(annotation + "@" @attribute (use_site_target)? @attribute) +(annotation + (user_type + (type_identifier) @attribute)) +(annotation + (constructor_invocation + (user_type + (type_identifier) @attribute))) + +(file_annotation + "@" @attribute "file" @attribute ":" @attribute) +(file_annotation + (user_type + (type_identifier) @attribute)) +(file_annotation + (constructor_invocation + (user_type + (type_identifier) @attribute))) + +;;; Literals +; NOTE: Escapes not allowed in multi-line strings +(line_string_literal (character_escape_seq) @constant.character.escape) + +[ + (line_string_literal) + (multi_line_string_literal) +] @string + +(character_literal) @constant.character + +[ + "null" ; should be highlighted the same as booleans + (boolean_literal) +] @constant.builtin.boolean + +(real_literal) @constant.numeric.float +[ + (integer_literal) + (long_literal) + (hex_literal) + (bin_literal) + (unsigned_literal) +] @constant.numeric.integer + +[ + (comment) + (shebang_line) +] @comment + +;;; Function calls + +(call_expression + . (simple_identifier) @function.builtin + (#match? @function.builtin "^(arrayOf|arrayOfNulls|byteArrayOf|shortArrayOf|intArrayOf|longArrayOf|ubyteArrayOf|ushortArrayOf|uintArrayOf|ulongArrayOf|floatArrayOf|doubleArrayOf|booleanArrayOf|charArrayOf|emptyArray|mapOf|setOf|listOf|emptyMap|emptySet|emptyList|mutableMapOf|mutableSetOf|mutableListOf|print|println|error|TODO|run|runCatching|repeat|lazy|lazyOf|enumValues|enumValueOf|assert|check|checkNotNull|require|requireNotNull|with|suspend|synchronized)$")) + +; object.function() or object.property.function() +(call_expression + (navigation_expression + (navigation_suffix + (simple_identifier) @function) . )) + +; function() +(call_expression + . (simple_identifier) @function) + +;;; Function definitions + +; lambda parameters +(lambda_literal + (lambda_parameters + (variable_declaration + (simple_identifier) @variable.parameter))) + +(parameter_with_optional_type + (simple_identifier) @variable.parameter) + +(parameter + (simple_identifier) @variable.parameter) + +(anonymous_initializer + ("init") @constructor) + +(constructor_invocation + (user_type + (type_identifier) @constructor)) + +(secondary_constructor + ("constructor") @constructor) +(primary_constructor) @constructor + +(getter + ("get") @function.builtin) +(setter + ("set") @function.builtin) + +(function_declaration + . (simple_identifier) @function) + +; TODO: Separate labeled returns/breaks/continue/super/this +; Must be implemented in the parser first +(label) @label + +(import_header + (identifier + (simple_identifier) @function @_import .) + (import_alias + (type_identifier) @function)? + (#match? @_import "^[a-z]")) + +; The last `simple_identifier` in a `import_header` will always either be a function +; or a type. Classes can appear anywhere in the import path, unlike functions +(import_header + (identifier + (simple_identifier) @type @_import) + (import_alias + (type_identifier) @type)? + (#match? @_import "^[A-Z]")) + +(import_header + "import" @keyword.control.import) + +(package_header + . (identifier)) @namespace + +((type_identifier) @type.builtin + (#match? @function.builtin "^(Byte|Short|Int|Long|UByte|UShort|UInt|ULong|Float|Double|Boolean|Char|String|Array|ByteArray|ShortArray|IntArray|LongArray|UByteArray|UShortArray|UIntArray|ULongArray|FloatArray|DoubleArray|BooleanArray|CharArray|Map|Set|List|EmptyMap|EmptySet|EmptyList|MutableMap|MutableSet|MutableList)$")) + +(type_identifier) @type + +(enum_entry + (simple_identifier) @constant) + +(_ + (navigation_suffix + (simple_identifier) @constant + (#match? @constant "^[A-Z][A-Z0-9_]*$"))) + +; SCREAMING CASE identifiers are assumed to be constants +((simple_identifier) @constant +(#match? @constant "^[A-Z][A-Z0-9_]*$")) + +; id_1.id_2.id_3: `id_2` and `id_3` are assumed as object properties +(_ + (navigation_suffix + (simple_identifier) @variable.other.member)) + +(class_body + (property_declaration + (variable_declaration + (simple_identifier) @variable.other.member))) + +(class_parameter + (simple_identifier) @variable.other.member) + +; `super` keyword inside classes +(super_expression) @variable.builtin + +; `this` this keyword inside classes +(this_expression) @variable.builtin + +;;; Identifiers +; `field` keyword inside property getter/setter +; FIXME: This will highlight the keyword outside of getters and setters +; since tree-sitter does not allow us to check for arbitrary nestation +((simple_identifier) @variable.builtin +(#eq? @variable.builtin "field")) + +; `it` keyword inside lambdas +; FIXME: This will highlight the keyword outside of lambdas since tree-sitter +; does not allow us to check for arbitrary nestation +((simple_identifier) @variable.builtin +(#eq? @variable.builtin "it")) + +(simple_identifier) @variable diff --git a/lapce-core/queries/kotlin/injections.scm b/lapce-core/queries/kotlin/injections.scm new file mode 100644 index 0000000000..06d39e1dfb --- /dev/null +++ b/lapce-core/queries/kotlin/injections.scm @@ -0,0 +1,40 @@ +; source: https://github.com/helix-editor/helix/blob/master/runtime/queries/kotlin/injections.scm +; licence: https://github.com/helix-editor/helix/blob/master/LICENSE +; spdx: MPL-2.0 + +((comment) @injection.content + (#set! injection.language "comment")) + +; There are 3 ways to define a regex +; - "[abc]?".toRegex() +((call_expression + (navigation_expression + ([(line_string_literal) (multi_line_string_literal)] @injection.content) + (navigation_suffix + ((simple_identifier) @_function + (#eq? @_function "toRegex"))))) + (#set! injection.language "regex")) + +; - Regex("[abc]?") +((call_expression + ((simple_identifier) @_function + (#eq? @_function "Regex")) + (call_suffix + (value_arguments + (value_argument + [ (line_string_literal) (multi_line_string_literal) ] @injection.content)))) + (#set! injection.language "regex")) + +; - Regex.fromLiteral("[abc]?") +((call_expression + (navigation_expression + ((simple_identifier) @_class + (#eq? @_class "Regex")) + (navigation_suffix + ((simple_identifier) @_function + (#eq? @_function "fromLiteral")))) + (call_suffix + (value_arguments + (value_argument + [ (line_string_literal) (multi_line_string_literal) ] @injection.content)))) + (#set! injection.language "regex")) diff --git a/lapce-core/queries/latex/highlights.scm b/lapce-core/queries/latex/highlights.scm new file mode 100644 index 0000000000..1ad0d86184 --- /dev/null +++ b/lapce-core/queries/latex/highlights.scm @@ -0,0 +1,247 @@ +; source: https://github.com/nvim-treesitter/nvim-treesitter/blob/965a74f76a2999b81fe3a543fb5e53bf6c84b8b7/queries/latex/highlights.scm +; licence: https://github.com/nvim-treesitter/nvim-treesitter/blob/965a74f76a2999b81fe3a543fb5e53bf6c84b8b7/LICENSE +; spdx: Apache-2.0 + +;; General syntax +(ERROR) @error + +(command_name) @function +(caption + command: _ @function) + +(key_value_pair + key: (_) @parameter + value: (_)) + +[ + (line_comment) + (block_comment) + (comment_environment) +] @comment + +[ + (brack_group) + (brack_group_argc) +] @parameter + +[(operator) "="] @operator + +"\\item" @punctuation.special + +((word) @punctuation.delimiter +(#eq? @punctuation.delimiter "&")) + +["[" "]" "{" "}"] @punctuation.bracket ; "(" ")" has no syntactical meaning in LaTeX + +;; General environments +(begin + command: _ @text.environment + name: (curly_group_text (text) @text.environment.name)) + +(end + command: _ @text.environment + name: (curly_group_text (text) @text.environment.name)) + +;; Definitions and references +(new_command_definition + command: _ @function.macro + declaration: (curly_group_command_name (_) @function)) +(old_command_definition + command: _ @function.macro + declaration: (_) @function) +(let_command_definition + command: _ @function.macro + declaration: (_) @function) + +(environment_definition + command: _ @function.macro + name: (curly_group_text (_) @text.reference)) + +(theorem_definition + command: _ @function.macro + name: (curly_group_text (_) @text.environment.name)) + +(paired_delimiter_definition + command: _ @function.macro + declaration: (curly_group_command_name (_) @function)) + +(label_definition + command: _ @function.macro + name: (curly_group_text (_) @text.reference)) +(label_reference_range + command: _ @function.macro + from: (curly_group_text (_) @text.reference) + to: (curly_group_text (_) @text.reference)) +(label_reference + command: _ @function.macro + names: (curly_group_text_list (_) @text.reference)) +(label_number + command: _ @function.macro + name: (curly_group_text (_) @text.reference) + number: (_) @text.reference) + +(citation + command: _ @function.macro + keys: (curly_group_text_list) @text.reference) + +(glossary_entry_definition + command: _ @function.macro + name: (curly_group_text (_) @text.reference)) +(glossary_entry_reference + command: _ @function.macro + name: (curly_group_text (_) @text.reference)) + +(acronym_definition + command: _ @function.macro + name: (curly_group_text (_) @text.reference)) +(acronym_reference + command: _ @function.macro + name: (curly_group_text (_) @text.reference)) + +(color_definition + command: _ @function.macro + name: (curly_group_text (_) @text.reference)) +(color_reference + command: _ @function.macro + name: (curly_group_text (_) @text.reference)) + +;; Math +[ + (displayed_equation) + (inline_formula) +] @text.math + +(math_environment + (begin + command: _ @text.math + name: (curly_group_text (text) @text.math))) + +(math_environment + (text) @text.math) + +(math_environment + (end + command: _ @text.math + name: (curly_group_text (text) @text.math))) + +;; Sectioning +(title_declaration + command: _ @namespace + options: (brack_group (_) @text.title)? + text: (curly_group (_) @text.title)) + +(author_declaration + command: _ @namespace + authors: (curly_group_author_list + ((author)+ @text.title))) + +(chapter + command: _ @namespace + toc: (brack_group (_) @text.title)? + text: (curly_group (_) @text.title)) + +(part + command: _ @namespace + toc: (brack_group (_) @text.title)? + text: (curly_group (_) @text.title)) + +(section + command: _ @namespace + toc: (brack_group (_) @text.title)? + text: (curly_group (_) @text.title)) + +(subsection + command: _ @namespace + toc: (brack_group (_) @text.title)? + text: (curly_group (_) @text.title)) + +(subsubsection + command: _ @namespace + toc: (brack_group (_) @text.title)? + text: (curly_group (_) @text.title)) + +(paragraph + command: _ @namespace + toc: (brack_group (_) @text.title)? + text: (curly_group (_) @text.title)) + +(subparagraph + command: _ @namespace + toc: (brack_group (_) @text.title)? + text: (curly_group (_) @text.title)) + +;; Beamer frames +(generic_environment + (begin + name: (curly_group_text + (text) @text.environment.name) + (#any-of? @text.environment.name "frame")) + . + (curly_group (_) @text.title)) + +((generic_command + command: (command_name) @_name + arg: (curly_group + (text) @text.title)) + (#eq? @_name "\\frametitle")) + +;; Formatting +((generic_command + command: (command_name) @_name + arg: (curly_group (_) @text.emphasis)) + (#eq? @_name "\\emph")) + +((generic_command + command: (command_name) @_name + arg: (curly_group (_) @text.emphasis)) + (#match? @_name "^(\\\\textit|\\\\mathit)$")) + +((generic_command + command: (command_name) @_name + arg: (curly_group (_) @text.strong)) + (#match? @_name "^(\\\\textbf|\\\\mathbf)$")) + +((generic_command + command: (command_name) @_name + . + arg: (curly_group (_) @text.uri)) + (#match? @_name "^(\\\\url|\\\\href)$")) + +;; File inclusion commands +(class_include + command: _ @include + path: (curly_group_path) @string) + +(package_include + command: _ @include + paths: (curly_group_path_list) @string) + +(latex_include + command: _ @include + path: (curly_group_path) @string) +(import_include + command: _ @include + directory: (curly_group_path) @string + file: (curly_group_path) @string) + +(bibtex_include + command: _ @include + path: (curly_group_path) @string) +(biblatex_include + "\\addbibresource" @include + glob: (curly_group_glob_pattern) @string.regex) + +(graphics_include + command: _ @include + path: (curly_group_path) @string) +(tikz_library_import + command: _ @include + paths: (curly_group_path_list) @string) + +( + (text) @spell + (#not-has-parent? @spell + inline_formula + displayed_equation + ) +) \ No newline at end of file diff --git a/lapce-core/queries/latex/injections.scm b/lapce-core/queries/latex/injections.scm new file mode 100644 index 0000000000..d2b924b5ed --- /dev/null +++ b/lapce-core/queries/latex/injections.scm @@ -0,0 +1,25 @@ +; source: https://github.com/nvim-treesitter/nvim-treesitter/blob/965a74f76a2999b81fe3a543fb5e53bf6c84b8b7/queries/latex/injections.scm +; licence: https://github.com/nvim-treesitter/nvim-treesitter/blob/965a74f76a2999b81fe3a543fb5e53bf6c84b8b7/LICENSE +; spdx: Apache-2.0 + +[ + (line_comment) + (block_comment) + (comment_environment) +] @comment + +(pycode_environment + code: (source_code) @python +) + +(minted_environment + (begin + language: (curly_group_text + (text) @language)) + (source_code) @content) + +((generic_environment + (begin + name: (curly_group_text + (text) @_env))) @c + (#any-of? @_env "asy" "asydef")) diff --git a/lapce-core/queries/lua/highlights.scm b/lapce-core/queries/lua/highlights.scm new file mode 100644 index 0000000000..0f7fd62167 --- /dev/null +++ b/lapce-core/queries/lua/highlights.scm @@ -0,0 +1,196 @@ +;; source: https://github.com/nvim-treesitter/nvim-treesitter/blob/master/queries/lua +;; license: https://github.com/nvim-treesitter/nvim-treesitter/blob/master/LICENSE +;; spdx: Apache-2.0 + +;; Keywords + +"return" @keyword.return + +[ + "goto" + "in" + "local" +] @keyword + +(label_statement) @label + +(break_statement) @keyword + +(do_statement +[ + "do" + "end" +] @keyword) + +(while_statement +[ + "while" + "do" + "end" +] @repeat) + +(repeat_statement +[ + "repeat" + "until" +] @repeat) + +(if_statement +[ + "if" + "elseif" + "else" + "then" + "end" +] @conditional) + +(elseif_statement +[ + "elseif" + "then" + "end" +] @conditional) + +(else_statement +[ + "else" + "end" +] @conditional) + +(for_statement +[ + "for" + "do" + "end" +] @repeat) + +(function_declaration +[ + "function" + "end" +] @keyword.function) + +(function_definition +[ + "function" + "end" +] @keyword.function) + +;; Operators + +[ + "and" + "not" + "or" +] @keyword.operator + +[ + "+" + "-" + "*" + "/" + "%" + "^" + "#" + "==" + "~=" + "<=" + ">=" + "<" + ">" + "=" + "&" + "~" + "|" + "<<" + ">>" + "//" + ".." +] @operator + +;; Punctuations + +[ + ";" + ":" + "," + "." +] @punctuation.delimiter + +;; Brackets + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +;; Variables + +(identifier) @variable + +((identifier) @variable.builtin + (#eq? @variable.builtin "self")) + +;; Constants + +((identifier) @constant + (#lua-match? @constant "^[A-Z][A-Z_0-9]*$")) + +(vararg_expression) @constant + +(nil) @constant.builtin + +[ + (false) + (true) +] @boolean + +;; Tables + +(field name: (identifier) @field) + +(dot_index_expression field: (identifier) @field) + +(table_constructor +[ + "{" + "}" +] @constructor) + +;; Functions + +(parameters (identifier) @parameter) + +(function_call name: (identifier) @function) +(function_declaration name: (identifier) @function) + +(function_call name: (dot_index_expression field: (identifier) @function)) +(function_declaration name: (dot_index_expression field: (identifier) @function)) + +(method_index_expression method: (identifier) @method) + +(function_call + (identifier) @function.builtin + (#any-of? @function.builtin + ;; built-in functions in Lua 5.1 + "assert" "collectgarbage" "dofile" "error" "getfenv" "getmetatable" "ipairs" + "load" "loadfile" "loadstring" "module" "next" "pairs" "pcall" "print" + "rawequal" "rawget" "rawset" "require" "select" "setfenv" "setmetatable" + "tonumber" "tostring" "type" "unpack" "xpcall")) + +;; Others + +(comment) @comment + +(hash_bang_line) @comment + +(number) @number + +(string) @string + +;; Error +(ERROR) @error \ No newline at end of file diff --git a/lapce-core/queries/markdown.inline/highlights.scm b/lapce-core/queries/markdown.inline/highlights.scm new file mode 100644 index 0000000000..df8fb3d0c6 --- /dev/null +++ b/lapce-core/queries/markdown.inline/highlights.scm @@ -0,0 +1,91 @@ +;; From MDeiml/tree-sitter-markdown +[ + (code_span) + (link_title) +] @text.literal + +[ + (emphasis_delimiter) + (code_span_delimiter) +] @punctuation.delimiter + +(emphasis) @text.emphasis + +(strong_emphasis) @text.strong + +[ + (link_destination) + (uri_autolink) +] @text.uri + +[ + (link_label) + (link_text) + (image_description) +] @text.reference + +[ + (backslash_escape) + (hard_line_break) +] @string.escape + +; "(" not part of query because of +; https://github.com/nvim-treesitter/nvim-treesitter/issues/2206 +; TODO: Find better fix for this +(image ["!" "[" "]" "("] @punctuation.delimiter) +(inline_link ["[" "]" "("] @punctuation.delimiter) +(shortcut_link ["[" "]"] @punctuation.delimiter) + +([ + (code_span_delimiter) + (emphasis_delimiter) +] @conceal +(#set! conceal "")) + +; Conceal inline links +(inline_link + [ + "[" + "]" + "(" + (link_destination) + ")" + ] @conceal + (#set! conceal "")) + +; Conceal image links +(image + [ + "!" + "[" + "]" + "(" + (link_destination) + ")" + ] @conceal + (#set! conceal "")) + +; Conceal full reference links +(full_reference_link + [ + "[" + "]" + (link_label) + ] @conceal + (#set! conceal "")) + +; Conceal collapsed reference links +(collapsed_reference_link + [ + "[" + "]" + ] @conceal + (#set! conceal "")) + +; Conceal shortcut links +(shortcut_link + [ + "[" + "]" + ] @conceal + (#set! conceal "")) \ No newline at end of file diff --git a/lapce-core/queries/markdown.inline/injections.scm b/lapce-core/queries/markdown.inline/injections.scm new file mode 100644 index 0000000000..c137a8222a --- /dev/null +++ b/lapce-core/queries/markdown.inline/injections.scm @@ -0,0 +1,2 @@ + +((html_tag) @injection.content (#set! injection.language "html")) diff --git a/lapce-core/queries/markdown/highlights.scm b/lapce-core/queries/markdown/highlights.scm new file mode 100644 index 0000000000..ecd0596a82 --- /dev/null +++ b/lapce-core/queries/markdown/highlights.scm @@ -0,0 +1,58 @@ +;From MDeiml/tree-sitter-markdown +(atx_heading (inline) @text.title) +(setext_heading (paragraph) @text.title) + +[ + (atx_h1_marker) + (atx_h2_marker) + (atx_h3_marker) + (atx_h4_marker) + (atx_h5_marker) + (atx_h6_marker) + (setext_h1_underline) + (setext_h2_underline) +] @punctuation.special + +[ + (link_title) + (indented_code_block) + (fenced_code_block) +] @text.literal + +[ + (fenced_code_block_delimiter) +] @punctuation.delimiter + +(code_fence_content) @none + +[ + (link_destination) +] @text.uri + +[ + (link_label) +] @text.reference + +[ + (list_marker_plus) + (list_marker_minus) + (list_marker_star) + (list_marker_dot) + (list_marker_parenthesis) + (thematic_break) +] @punctuation.special + +[ + (block_continuation) + (block_quote_marker) +] @punctuation.special + +[ + (backslash_escape) +] @string.escape + +([ + (info_string) + (fenced_code_block_delimiter) +] @conceal +(#set! conceal "")) \ No newline at end of file diff --git a/lapce-core/queries/markdown/injections.scm b/lapce-core/queries/markdown/injections.scm new file mode 100644 index 0000000000..16f7936bf9 --- /dev/null +++ b/lapce-core/queries/markdown/injections.scm @@ -0,0 +1,15 @@ +; From nvim-treesitter/nvim-treesitter + +(fenced_code_block + (info_string + (language) @injection.language) + (code_fence_content) @injection.content (#set! injection.include-unnamed-children)) + +((html_block) @injection.content (#set! injection.language "html") (#set! injection.include-unnamed-children)) + +([ + (minus_metadata) + (plus_metadata) +] @injection.content (#set! injection.language "yaml") (#set! injection.include-unnamed-children)) + +((inline) @injection.content (#set! injection.language "markdown.inline") (#set! injection.include-unnamed-children)) \ No newline at end of file diff --git a/lapce-core/queries/prisma/highlights.scm b/lapce-core/queries/prisma/highlights.scm new file mode 100644 index 0000000000..946865c163 --- /dev/null +++ b/lapce-core/queries/prisma/highlights.scm @@ -0,0 +1,60 @@ +; source: https://github.com/victorhqc/tree-sitter-prisma/blob/master/queries/highlights.scm +; https://github.com/victorhqc/tree-sitter-prisma/blob/master/LICENSE +; spdx: MIT + +(string) @string + +(enumeral) @constant +(number) @constant.numeric + +(variable) @variable +(column_type) @type + +(arguments) @variable.other.member +(model_declaration (identifier) @type) + +[ + "datasource" + "enum" + "generator" + "model" + "type" +] @keyword + +[ + (comment) + (developer_comment) +] @comment + +[ + (attribute) + (block_attribute_declaration) + (call_expression) +] @function.builtin + +[ + (true) + (false) + (null) +] @constant.builtin.boolean + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +[ + ":" + "," +] @punctuation.delimiter + +[ + "=" + "@" + "@@" + (binary_expression) +] @operator diff --git a/lapce-core/queries/protobuf/highlights.scm b/lapce-core/queries/protobuf/highlights.scm new file mode 100644 index 0000000000..bd15e60d4c --- /dev/null +++ b/lapce-core/queries/protobuf/highlights.scm @@ -0,0 +1,62 @@ +; source: https://github.com/helix-editor/helix/blob/master/runtime/queries/protobuf/highlights.scm +; licence: https://github.com/helix-editor/helix/blob/master/LICENSE +; spdx: MPL-2.0 + +[ + "syntax" + "package" + "option" + "import" + "service" + "rpc" + "returns" + "message" + "enum" + "oneof" + "repeated" + "reserved" + "to" + "stream" + "extend" + "optional" +] @keyword + +[ + (keyType) + (type) +] @type.builtin + +[ + (mapName) + (enumName) + (messageName) + (extendName) + (serviceName) + (rpcName) +] @type + +[ + (fieldName) + (optionName) +] @variable.other.member +(enumVariantName) @type.enum.variant + +(fullIdent) @namespace + +(intLit) @constant.numeric.integer +(floatLit) @constant.numeric.float +(boolLit) @constant.builtin.boolean +(strLit) @string + +(constant) @constant + +(comment) @comment + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket \ No newline at end of file diff --git a/lapce-core/queries/protobuf/injections.scm b/lapce-core/queries/protobuf/injections.scm new file mode 100644 index 0000000000..8454f9fe19 --- /dev/null +++ b/lapce-core/queries/protobuf/injections.scm @@ -0,0 +1,6 @@ +; source: https://github.com/helix-editor/helix/blob/master/runtime/queries/protobuf/injections.scm +; licence: https://github.com/helix-editor/helix/blob/master/LICENSE +; spdx: MPL-2.0 + +((comment) @injection.content + (#set! injection.language "comment")) \ No newline at end of file diff --git a/lapce-core/queries/r/highlights.scm b/lapce-core/queries/r/highlights.scm new file mode 100644 index 0000000000..6bb904386b --- /dev/null +++ b/lapce-core/queries/r/highlights.scm @@ -0,0 +1,128 @@ +; source: https://raw.githubusercontent.com/r-lib/tree-sitter-r/1589b7d83441c57cd77c5188e44f2af40d45ff49/queries/highlights.scm +; license: https://github.com/r-lib/tree-sitter-r/blob/1589b7d83441c57cd77c5188e44f2af40d45ff49/LICENSE +; spdx: mit +; highlights.scm + + +; Literals + +(integer) @number + +(float) @float + +(complex) @number + +(string) @string +(string (escape_sequence) @string.escape) + +(comment) @comment + +(identifier) @variable + +(formal_parameters (identifier) @parameter) + +; Operators +[ + "=" + "<-" + "<<-" + "->>" + "->" +] @operator + +(unary operator: [ + "-" + "+" + "!" + "~" +] @operator) + +(binary operator: [ + "-" + "+" + "*" + "/" + "^" + "<" + ">" + "<=" + ">=" + "==" + "!=" + "||" + "|" + "&&" + "&" + ":" + "~" +] @operator) + +[ + "|>" + (special) +] @operator + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +(dollar "$" @operator) + +(subset2 + "[[" @punctuation.bracket + "]]" @punctuation.bracket) + +[ + "in" + (dots) + (break) + (next) + (inf) +] @keyword + +[ + (nan) + (na) + (null) +] @type.builtin + +[ + "if" + "else" +] @conditional + +[ + "while" + "repeat" + "for" +] @repeat + +[ + (true) + (false) +] @boolean + +"function" @keyword.function + +(call function: (identifier) @function) +(call arguments: + (arguments + name: (identifier) @parameter )) + +(lambda_function "\\" @operator) + +(namespace_get function: (identifier) @method) +(namespace_get_internal function: (identifier) @method) + +(namespace_get namespace: (identifier) @namespace + "::" @operator) +(namespace_get_internal namespace: (identifier) @namespace + ":::" @operator) + +; Error +(ERROR) @error diff --git a/lapce-core/queries/svelte/highlights.scm b/lapce-core/queries/svelte/highlights.scm new file mode 100644 index 0000000000..2e30815f45 --- /dev/null +++ b/lapce-core/queries/svelte/highlights.scm @@ -0,0 +1,110 @@ +; src: https://github.com/helix-editor/helix/blob/master/runtime/queries/svelte/highlights.scm +; licence: https://github.com/helix-editor/helix/blob/master/LICENSE +; spdx: MPL-2.0 + +(tag_name) @tag +(erroneous_end_tag_name) @error +(comment) @comment +(attribute_name) @tag.attribute +(attribute + (quoted_attribute_value) @string) +(text) @text @spell + +((element (start_tag (tag_name) @_tag) (text) @text.title) + (#match? @_tag "^(h[0-9]|title)$")) + +((element (start_tag (tag_name) @_tag) (text) @text.strong) + (#match? @_tag "^(strong|b)$")) + +((element (start_tag (tag_name) @_tag) (text) @text.emphasis) + (#match? @_tag "^(em|i)$")) + +((element (start_tag (tag_name) @_tag) (text) @text.strike) + (#match? @_tag "^(s|del)$")) + +((element (start_tag (tag_name) @_tag) (text) @text.underline) + (#eq? @_tag "u")) + +((element (start_tag (tag_name) @_tag) (text) @text.literal) + (#match? @_tag "^(code|kbd)$")) + +((element (start_tag (tag_name) @_tag) (text) @text.uri) + (#eq? @_tag "a")) + +((attribute + (attribute_name) @_attr + (quoted_attribute_value (attribute_value) @text.uri)) + (#match? @_attr "^(href|src)$")) + +[ + "<" + ">" + "" +] @tag.delimiter + +"=" @operator +((element (start_tag (tag_name) @_tag) (text) @text.title) + (#match? @_tag "^(h[0-9]|title)$")) + +((element (start_tag (tag_name) @_tag) (text) @text.strong) + (#match? @_tag "^(strong|b)$")) + +((element (start_tag (tag_name) @_tag) (text) @text.emphasis) + (#match? @_tag "^(em|i)$")) + +((element (start_tag (tag_name) @_tag) (text) @text.strike) + (#match? @_tag "^(s|del)$")) + +((element (start_tag (tag_name) @_tag) (text) @text.underline) + (#eq? @_tag "u")) + +((element (start_tag (tag_name) @_tag) (text) @text.literal) + (#match? @_tag "^(code|kbd)$")) + +((element (start_tag (tag_name) @_tag) (text) @text.uri) + (#eq? @_tag "a")) + +((attribute + (attribute_name) @_attr + (quoted_attribute_value (attribute_value) @text.uri)) + (#match? @_attr "^(href|src)$")) + +(tag_name) @tag +(attribute_name) @property +(erroneous_end_tag_name) @error +(comment) @comment + +[ + (attribute_value) + (quoted_attribute_value) +] @string + +[ + (text) + (raw_text_expr) +] @none + +[ + (special_block_keyword) + (then) + (as) +] @keyword + +[ + "{" + "}" +] @punctuation.bracket + +"=" @operator + +[ + "<" + ">" + "" + "#" + ":" + "/" + "@" +] @tag.delimiter diff --git a/lapce-core/queries/svelte/indents.scm b/lapce-core/queries/svelte/indents.scm new file mode 100644 index 0000000000..716a3f2321 --- /dev/null +++ b/lapce-core/queries/svelte/indents.scm @@ -0,0 +1,24 @@ +;src: https://github.com/nvim-treesitter/nvim-treesitter/blob/master/queries/svelte/indents.scm +;licence https://github.com/nvim-treesitter/nvim-treesitter/blob/master/LICENSE +; spdx: Apache-2.0 + +[ + (element) + (if_statement) + (each_statement) + (await_statement) + (script_element) + (style_element) +] @indent + +[ + (end_tag) + (else_statement) + (if_end_expr) + (each_end_expr) + (await_end_expr) + ">" + "/>" +] @branch + +(comment) @ignore diff --git a/lapce-core/queries/svelte/injections.scm b/lapce-core/queries/svelte/injections.scm new file mode 100644 index 0000000000..f24f89bcf8 --- /dev/null +++ b/lapce-core/queries/svelte/injections.scm @@ -0,0 +1,32 @@ +; src: https://github.com/helix-editor/helix/blob/master/runtime/queries/svelte/injections.scm +; licence: https://github.com/helix-editor/helix/blob/master/LICENSE +; spdx: MPL-2.0 + +((style_element + (raw_text) @injection.content) + (#set! injection.language "css")) + +((attribute + (attribute_name) @_attr + (quoted_attribute_value (attribute_value) @css)) + (#eq? @_attr "style")) + +((script_element + (raw_text) @injection.content) + (#set! injection.language "javascript")) + +((raw_text_expr) @injection.content + (#set! injection.language "javascript")) + +( + (script_element + (start_tag + (attribute + (quoted_attribute_value (attribute_value) @_lang))) + (raw_text) @injection.content) + (#match? @_lang "(ts|typescript)") + (#set! injection.language "typescript") +) + +((comment) @injection.content + (#set! injection.language "comment")) diff --git a/lapce-core/queries/typescript/highlights.scm b/lapce-core/queries/typescript/highlights.scm new file mode 100644 index 0000000000..e98606165e --- /dev/null +++ b/lapce-core/queries/typescript/highlights.scm @@ -0,0 +1,287 @@ +; source: https://github.com/helix-editor/helix/blob/master/runtime/queries/typescript/highlights.scm +; licence: https://github.com/helix-editor/helix/blob/master/LICENSE +; spdx: MPL-2.0 + +; Namespaces + +(internal_module + [((identifier) @namespace) ((nested_identifier (identifier) @namespace))]) + +(ambient_declaration "global" @namespace) + + +; Variables + +(required_parameter (identifier) @variable.parameter) +(optional_parameter (identifier) @variable.parameter) + +; Punctuation + +[ + ":" +] @punctuation.delimiter + +(optional_parameter "?" @punctuation.special) +(property_signature "?" @punctuation.special) + +(conditional_type ["?" ":"] @operator) + + + +; Keywords + +[ + "abstract" + "declare" + "export" + "infer" + "implements" + "keyof" + "namespace" +] @keyword + +[ + "type" + "interface" + "enum" +] @keyword.storage.type + +[ + "public" + "private" + "protected" + "readonly" +] @keyword.storage.modifier + +; Special identifiers +;-------------------- + +([ + (identifier) + (shorthand_property_identifier) + (shorthand_property_identifier_pattern) + ] @constant + (#match? @constant "^[A-Z_][A-Z\\d_]+$")) + + +((identifier) @constructor + (#match? @constructor "^[A-Z]")) + +((identifier) @variable.builtin + (#match? @variable.builtin "^(arguments|module|console|window|document)$") + (#is-not? local)) + +((identifier) @function.builtin + (#eq? @function.builtin "require") + (#is-not? local)) + +; Function and method definitions +;-------------------------------- + +(function + name: (identifier) @function) +(function_declaration + name: (identifier) @function) +(method_definition + name: (property_identifier) @function.method) + +(pair + key: (property_identifier) @function.method + value: [(function) (arrow_function)]) + +(assignment_expression + left: (member_expression + property: (property_identifier) @function.method) + right: [(function) (arrow_function)]) + +(variable_declarator + name: (identifier) @function + value: [(function) (arrow_function)]) + +(assignment_expression + left: (identifier) @function + right: [(function) (arrow_function)]) + + +; Function and method calls +;-------------------------- + +(call_expression + function: (identifier) @function) + +(call_expression + function: (member_expression + property: (property_identifier) @function.method)) + +; Variables +;---------- + +(identifier) @variable + +; Properties +;----------- + +(property_identifier) @variable.other.member +(shorthand_property_identifier) @variable.other.member +(shorthand_property_identifier_pattern) @variable.other.member + +; Literals +;--------- + +(this) @variable.builtin +(super) @variable.builtin + +[ + (true) + (false) + (null) + (undefined) +] @constant.builtin + +(comment) @comment + +[ + (string) + (template_string) +] @string + +(regex) @string.regexp +(number) @constant.numeric.integer + +; Tokens +;------- + +(template_substitution + "${" @punctuation.special + "}" @punctuation.special) @embedded + +[ + ";" + "?." + "." + "," +] @punctuation.delimiter + +[ + "-" + "--" + "-=" + "+" + "++" + "+=" + "*" + "*=" + "**" + "**=" + "/" + "/=" + "%" + "%=" + "<" + "<=" + "<<" + "<<=" + "=" + "==" + "===" + "!" + "!=" + "!==" + "=>" + ">" + ">=" + ">>" + ">>=" + ">>>" + ">>>=" + "~" + "^" + "&" + "|" + "^=" + "&=" + "|=" + "&&" + "||" + "??" + "&&=" + "||=" + "??=" + "..." +] @operator + +(ternary_expression ["?" ":"] @operator) + +[ + "(" + ")" + "[" + "]" + "{" + "}" +] @punctuation.bracket + +[ + "as" + "async" + "debugger" + "delete" + "extends" + "function" + "get" + "in" + "instanceof" + "new" + "of" + "set" + "static" + "target" + "try" + "typeof" + "void" + "with" +] @keyword + +[ + "class" + "let" + "const" + "var" +] @keyword.storage.type + +[ + "switch" + "case" + "if" + "else" + "yield" + "throw" + "finally" + "return" + "catch" + "continue" + "while" + "break" + "for" + "do" + "await" +] @keyword.control + +[ + "import" + "default" + "from" + "export" +] @keyword.control.import + +; Types + +(type_identifier) @type +(predefined_type) @type.builtin + +(type_arguments + "<" @punctuation.bracket + ">" @punctuation.bracket) + +((identifier) @type + (#match? @type "^[A-Z]")) \ No newline at end of file diff --git a/lapce-core/queries/zig/highlights.scm b/lapce-core/queries/zig/highlights.scm new file mode 100644 index 0000000000..3bb5f685cd --- /dev/null +++ b/lapce-core/queries/zig/highlights.scm @@ -0,0 +1,232 @@ +; source: https://github.com/helix-editor/helix/blob/master/runtime/queries/zig/highlights.scm +; licence: https://github.com/helix-editor/helix/blob/master/LICENSE +; spdx: MPL-2.0 + +[ + (container_doc_comment) + (doc_comment) +] @comment.documentation + +[ + (line_comment) +] @comment.line + +;; assume TitleCase is a type +( + [ + variable_type_function: (IDENTIFIER) + field_access: (IDENTIFIER) + parameter: (IDENTIFIER) + ] @type + (#match? @type "^[A-Z]([a-z]+[A-Za-z0-9]*)*$") +) + +;; assume camelCase is a function +( + [ + variable_type_function: (IDENTIFIER) + field_access: (IDENTIFIER) + parameter: (IDENTIFIER) + ] @function + (#match? @function "^[a-z]+([A-Z][a-z0-9]*)+$") +) + +;; assume all CAPS_1 is a constant +( + [ + variable_type_function: (IDENTIFIER) + field_access: (IDENTIFIER) + ] @constant + (#match? @constant "^[A-Z][A-Z_0-9]+$") +) + +;; _ +( + (IDENTIFIER) @variable.builtin + (#eq? @variable.builtin "_") +) + +;; C Pointers [*c]T +(PtrTypeStart "c" @variable.builtin) + +[ + variable: (IDENTIFIER) + variable_type_function: (IDENTIFIER) +] @variable + +parameter: (IDENTIFIER) @variable.parameter + +[ + field_member: (IDENTIFIER) + field_access: (IDENTIFIER) +] @variable.other.member + +[ + function_call: (IDENTIFIER) + function: (IDENTIFIER) +] @function + +exception: "!" @keyword.control.exception + +field_constant: (IDENTIFIER) @constant + +(BUILTINIDENTIFIER) @function.builtin + +((BUILTINIDENTIFIER) @keyword.control.import + (#any-of? @keyword.control.import "@import" "@cImport")) + +(INTEGER) @constant.numeric.integer + +(FLOAT) @constant.numeric.float + +[ + (LINESTRING) + (STRINGLITERALSINGLE) +] @string + +(CHAR_LITERAL) @constant.character +(EscapeSequence) @constant.character.escape +(FormatSequence) @string.special + +[ + "anytype" + "anyframe" + (BuildinTypeExpr) +] @type.builtin + +(BreakLabel (IDENTIFIER) @label) +(BlockLabel (IDENTIFIER) @label) + +[ + "true" + "false" +] @constant.builtin.boolean + +[ + "undefined" + "unreachable" + "null" +] @constant.builtin + +[ + "else" + "if" + "switch" +] @keyword.control.conditional + +[ + "for" + "while" +] @keyword.control.repeat + +[ + "or" + "and" + "orelse" +] @keyword.operator + +[ + "struct" + "enum" + "union" + "packed" + "opaque" + "export" + "extern" + "linksection" +] @keyword.storage.type + +[ + "const" + "var" + "threadlocal" + "allowzero" + "volatile" + "align" +] @keyword.storage.modifier + +[ + "try" + "error" + "catch" +] @keyword.control.exception + +[ + "fn" +] @keyword.function + +[ + "test" +] @keyword + +[ + "pub" + "usingnamespace" +] @keyword.control.import + +[ + "return" + "break" + "continue" +] @keyword.control.return + +[ + "defer" + "errdefer" + "async" + "nosuspend" + "await" + "suspend" + "resume" +] @function.macro + +[ + "comptime" + "inline" + "noinline" + "asm" + "callconv" + "noalias" +] @keyword.directive + +[ + (CompareOp) + (BitwiseOp) + (BitShiftOp) + (AdditionOp) + (AssignOp) + (MultiplyOp) + (PrefixOp) + "*" + "**" + "->" + ".?" + ".*" + "?" +] @operator + +[ + ";" + "." + "," + ":" +] @punctuation.delimiter + +[ + ".." + "..." +] @punctuation.special + +[ + "[" + "]" + "(" + ")" + "{" + "}" + (Payload "|") + (PtrPayload "|") + (PtrIndexPayload "|") +] @punctuation.bracket + +(ERROR) @keyword.control.exception \ No newline at end of file diff --git a/lapce-core/src/buffer.rs b/lapce-core/src/buffer/mod.rs similarity index 73% rename from lapce-core/src/buffer.rs rename to lapce-core/src/buffer/mod.rs index f8cecba6f2..6b6f23ea2a 100644 --- a/lapce-core/src/buffer.rs +++ b/lapce-core/src/buffer/mod.rs @@ -9,23 +9,32 @@ use std::{ }, }; -use lsp_types::Position; -use xi_rope::{ +use lapce_xi_rope::{ + delta::InsertDelta, diff::{Diff, LineHashDiff}, - multiset::Subset, - Cursor, Delta, DeltaBuilder, Interval, Rope, RopeDelta, + interval::IntervalBounds, + multiset::{CountMatcher, Subset}, + tree::{Node, NodeInfo}, + Cursor, Delta, DeltaBuilder, DeltaElement, Interval, Rope, RopeDelta, RopeInfo, }; +use lsp_types::Position; use crate::{ + char_buffer::CharBuffer, cursor::CursorMode, editor::EditType, indent::{auto_detect_indent_style, IndentStyle}, mode::Mode, + paragraph::ParagraphCursor, selection::Selection, - syntax::Syntax, + syntax::{self, edit::SyntaxEdit, Syntax}, word::WordCursor, }; +pub mod rope_text; + +use rope_text::*; + #[derive(Clone)] enum Contents { Edit { @@ -90,6 +99,12 @@ pub struct Buffer { max_len_line: usize, } +impl ToString for Buffer { + fn to_string(&self) -> String { + self.text().to_string() + } +} + impl Buffer { pub fn new(text: &str) -> Self { Self { @@ -126,12 +141,14 @@ impl Buffer { } } + /// The current buffer revision pub fn rev(&self) -> u64 { self.revs.last().unwrap().num } + /// Mark the buffer as pristine (aka 'saved') pub fn set_pristine(&mut self) { - self.pristine_rev_id = self.rev() + self.pristine_rev_id = self.rev(); } pub fn is_pristine(&self) -> bool { @@ -179,14 +196,14 @@ impl Buffer { } pub fn num_lines(&self) -> usize { - self.line_of_offset(self.text.len()) + 1 + RopeText::new(&self.text).num_lines() } fn get_max_line_len(&self) -> (usize, usize) { let mut pre_offset = 0; let mut max_len = 0; let mut max_len_line = 0; - for line in 0..self.num_lines() + 1 { + for line in 0..=self.num_lines() { let offset = self.offset_of_line(line); let line_len = offset - pre_offset; pre_offset = offset; @@ -231,14 +248,14 @@ impl Buffer { self.max_len } - fn line_len(&self, line: usize) -> usize { - self.offset_of_line(line + 1) - self.offset_of_line(line) + pub fn line_len(&self, line: usize) -> usize { + RopeText::new(&self.text).line_len(line) } pub fn init_content(&mut self, content: Rope) { if !content.is_empty() { let delta = Delta::simple_edit(Interval::new(0, 0), content, 0); - let (new_rev, new_text, new_tombstones, new_deletes_from_union) = + let (new_rev, new_text, new_tombstones, new_deletes_from_union, _) = self.mk_new_rev(0, delta.clone()); self.apply_edit( &delta, @@ -255,14 +272,14 @@ impl Buffer { &mut self, content: Rope, set_pristine: bool, - ) -> (RopeDelta, InvalLines) { + ) -> (RopeDelta, InvalLines, SyntaxEdit) { let delta = LineHashDiff::compute_delta(&self.text, &content); self.this_edit_type = EditType::Other; - let (delta, inval_lines) = self.add_delta(delta); + let (delta, inval_lines, edits) = self.add_delta(delta); if set_pristine { self.set_pristine(); } - (delta, inval_lines) + (delta, inval_lines, edits) } pub fn detect_indent(&mut self, syntax: Option<&Syntax>) { @@ -279,14 +296,14 @@ impl Buffer { } pub fn reset_edit_type(&mut self) { - self.last_edit_type = EditType::Other + self.last_edit_type = EditType::Other; } pub fn edit( &mut self, edits: &[(impl AsRef, &str)], edit_type: EditType, - ) -> (RopeDelta, InvalLines) { + ) -> (RopeDelta, InvalLines, SyntaxEdit) { let mut builder = DeltaBuilder::new(self.len()); let mut interval_rope = Vec::new(); for (selection, content) in edits { @@ -312,11 +329,14 @@ impl Buffer { self.add_delta(delta) } - fn add_delta(&mut self, delta: RopeDelta) -> (RopeDelta, InvalLines) { + fn add_delta( + &mut self, + delta: RopeDelta, + ) -> (RopeDelta, InvalLines, SyntaxEdit) { let undo_group = self.calculate_undo_group(); self.last_edit_type = self.this_edit_type; - let (new_rev, new_text, new_tombstones, new_deletes_from_union) = + let (new_rev, new_text, new_tombstones, new_deletes_from_union, edits) = self.mk_new_rev(undo_group, delta.clone()); let inval_lines = self.apply_edit( @@ -327,7 +347,7 @@ impl Buffer { new_deletes_from_union, ); - (delta, inval_lines) + (delta, inval_lines, edits) } fn apply_edit( @@ -380,13 +400,46 @@ impl Buffer { } } + fn generate_edits( + &self, + ins_delta: &InsertDelta, + deletes: &Subset, + ) -> SyntaxEdit { + let deletes = deletes.transform_expand(&ins_delta.inserted_subset()); + + let mut edits = Vec::new(); + + let mut insert_edits: Vec = + InsertsValueIter::new(ins_delta) + .map(|insert| { + let start = insert.old_offset; + let inserted = insert.node; + syntax::edit::create_insert_edit(&self.text, start, inserted) + }) + .collect(); + insert_edits.reverse(); + edits.append(&mut insert_edits); + + let text = ins_delta.apply(&self.text); + let mut delete_edits: Vec = deletes + .range_iter(CountMatcher::NonZero) + .map(|(start, end)| syntax::edit::create_delete_edit(&text, start, end)) + .collect(); + delete_edits.reverse(); + edits.append(&mut delete_edits); + + SyntaxEdit::new(edits) + } + fn mk_new_rev( &self, undo_group: usize, delta: RopeDelta, - ) -> (Revision, Rope, Rope, Subset) { + ) -> (Revision, Rope, Rope, Subset, SyntaxEdit) { let (ins_delta, deletes) = delta.factor(); + let edits = self.generate_edits(&ins_delta, &deletes); + let deletes_at_rev = &self.deletes_from_union; let union_ins_delta = ins_delta.transform_expand(deletes_at_rev, true); @@ -416,7 +469,7 @@ impl Buffer { &new_deletes_from_union, ); - let head_rev = &self.revs.last().unwrap(); + let head_rev = self.revs.last().unwrap(); self.atomic_rev .store(self.rev_counter, atomic::Ordering::Release); ( @@ -434,6 +487,7 @@ impl Buffer { new_text, new_tombstones, new_deletes_from_union, + edits, ) } @@ -567,7 +621,7 @@ impl Buffer { Contents::Undo { .. } => None, }) .and_then(|group| { - let mut cursor: Option<&CursorMode> = None; + let mut cursor = None; for rev in &self.revs[first_candidate..] { if let Contents::Edit { ref undo_group, .. } = rev.edit { if group == undo_group { @@ -605,6 +659,7 @@ impl Buffer { ) -> ( RopeDelta, InvalLines, + SyntaxEdit, Option, Option, ) { @@ -614,6 +669,10 @@ impl Buffer { &self.deletes_from_union, &new_deletes_from_union, ); + let edits = { + let (ins_delta, deletes) = delta.clone().factor(); + self.generate_edits(&ins_delta, &deletes) + }; let new_text = delta.apply(&self.text); let new_tombstones = shuffle_tombstones( &self.text, @@ -634,154 +693,100 @@ impl Buffer { new_deletes_from_union, ); - (delta, inval_lines, cursor_before, cursor_after) + (delta, inval_lines, edits, cursor_before, cursor_after) } pub fn do_undo( &mut self, - ) -> Option<(RopeDelta, InvalLines, Option)> { - if self.cur_undo > 1 { - self.cur_undo -= 1; - self.undos.insert(self.live_undos[self.cur_undo]); - self.last_edit_type = EditType::Undo; - let (delta, inval_lines, cursor_before, _cursor_after) = - self.undo(self.undos.clone()); - Some((delta, inval_lines, cursor_before)) - } else { - None + ) -> Option<(RopeDelta, InvalLines, SyntaxEdit, Option)> { + if self.cur_undo <= 1 { + return None; } + + self.cur_undo -= 1; + self.undos.insert(self.live_undos[self.cur_undo]); + self.last_edit_type = EditType::Undo; + let (delta, inval_lines, edits, cursor_before, _cursor_after) = + self.undo(self.undos.clone()); + + Some((delta, inval_lines, edits, cursor_before)) } pub fn do_redo( &mut self, - ) -> Option<(RopeDelta, InvalLines, Option)> { - if self.cur_undo < self.live_undos.len() { - self.undos.remove(&self.live_undos[self.cur_undo]); - self.cur_undo += 1; - self.last_edit_type = EditType::Redo; - let (delta, inval_lines, _cursor_before, cursor_after) = - self.undo(self.undos.clone()); - Some((delta, inval_lines, cursor_after)) - } else { - None + ) -> Option<(RopeDelta, InvalLines, SyntaxEdit, Option)> { + if self.cur_undo >= self.live_undos.len() { + return None; } + + self.undos.remove(&self.live_undos[self.cur_undo]); + self.cur_undo += 1; + self.last_edit_type = EditType::Redo; + let (delta, inval_lines, edits, _cursor_before, cursor_after) = + self.undo(self.undos.clone()); + + Some((delta, inval_lines, edits, cursor_after)) + } + + pub fn rope_text(&self) -> RopeText { + RopeText::new(&self.text) } pub fn last_line(&self) -> usize { - self.line_of_offset(self.text.len()) + RopeText::new(&self.text).last_line() } pub fn offset_of_line(&self, line: usize) -> usize { - let last_line = self.last_line(); - let line = if line > last_line + 1 { - last_line + 1 - } else { - line - }; - self.text.offset_of_line(line) + RopeText::new(&self.text).offset_of_line(line) } pub fn offset_line_end(&self, offset: usize, caret: bool) -> usize { - let line = self.line_of_offset(offset); - self.line_end_offset(line, caret) + RopeText::new(&self.text).offset_line_end(offset, caret) } pub fn line_of_offset(&self, offset: usize) -> usize { - let max = self.len(); - let offset = if offset > max { max } else { offset }; - self.text.line_of_offset(offset) + RopeText::new(&self.text).line_of_offset(offset) } + /// Converts a UTF8 offset to a UTF16 LSP position pub fn offset_to_position(&self, offset: usize) -> Position { - let (line, col) = self.offset_to_line_col(offset); - Position { - line: line as u32, - character: col as u32, - } + RopeText::new(&self.text).offset_to_position(offset) } pub fn offset_of_position(&self, pos: &Position) -> usize { - self.offset_of_line_col(pos.line as usize, pos.character as usize) + RopeText::new(&self.text).offset_of_position(pos) } - pub fn offset_to_line_col(&self, offset: usize) -> (usize, usize) { - let max = self.len(); - let offset = if offset > max { max } else { offset }; - let line = self.line_of_offset(offset); - let line_start = self.offset_of_line(line); - if offset == line_start { - return (line, 0); - } + pub fn position_to_line_col(&self, pos: &Position) -> (usize, usize) { + RopeText::new(&self.text).position_to_line_col(pos) + } - let col = offset - line_start; - (line, col) + pub fn offset_to_line_col(&self, offset: usize) -> (usize, usize) { + RopeText::new(&self.text).offset_to_line_col(offset) } pub fn offset_of_line_col(&self, line: usize, col: usize) -> usize { - let mut pos = 0; - let mut offset = self.offset_of_line(line); - for c in self - .slice_to_cow(offset..self.offset_of_line(line + 1)) - .chars() - { - if c == '\n' { - return offset; - } - - let char_len = c.len_utf8(); - if pos + char_len > col { - return offset; - } - pos += char_len; - offset += char_len; - } - offset + RopeText::new(&self.text).offset_of_line_col(line, col) } pub fn line_end_col(&self, line: usize, caret: bool) -> usize { - let line_start = self.offset_of_line(line); - let offset = self.line_end_offset(line, caret); - offset - line_start + RopeText::new(&self.text).line_end_col(line, caret) } pub fn first_non_blank_character_on_line(&self, line: usize) -> usize { - let last_line = self.last_line(); - let line = if line > last_line + 1 { - last_line - } else { - line - }; - let line_start_offset = self.text.offset_of_line(line); - WordCursor::new(&self.text, line_start_offset).next_non_blank_char() + RopeText::new(&self.text).first_non_blank_character_on_line(line) } pub fn indent_on_line(&self, line: usize) -> String { - let line_start_offset = self.text.offset_of_line(line); - let word_boundary = - WordCursor::new(&self.text, line_start_offset).next_non_blank_char(); - let indent = self.text.slice_to_cow(line_start_offset..word_boundary); - indent.to_string() + RopeText::new(&self.text).indent_on_line(line) } pub fn line_end_offset(&self, line: usize, caret: bool) -> usize { - let mut offset = self.offset_of_line(line + 1); - let mut line_content: &str = &self.line_content(line); - if line_content.ends_with("\r\n") { - offset -= 2; - line_content = &line_content[..line_content.len() - 2]; - } else if line_content.ends_with('\n') { - offset -= 1; - line_content = &line_content[..line_content.len() - 1]; - } - if !caret && !line_content.is_empty() { - offset = self.prev_grapheme_offset(offset, 1, 0); - } - offset + RopeText::new(&self.text).line_end_offset(line, caret) } pub fn line_content(&self, line: usize) -> Cow { - self.text - .slice_to_cow(self.offset_of_line(line)..self.offset_of_line(line + 1)) + RopeText::new(&self.text).line_content(line) } pub fn prev_grapheme_offset( @@ -790,20 +795,7 @@ impl Buffer { count: usize, limit: usize, ) -> usize { - let mut cursor = Cursor::new(&self.text, offset); - let mut new_offset = offset; - for _i in 0..count { - if let Some(prev_offset) = cursor.prev_grapheme() { - if prev_offset < limit { - return new_offset; - } - new_offset = prev_offset; - cursor.set(prev_offset); - } else { - return new_offset; - } - } - new_offset + RopeText::new(&self.text).prev_grapheme_offset(offset, count, limit) } pub fn prev_code_boundary(&self, offset: usize) -> usize { @@ -815,24 +807,20 @@ impl Buffer { } pub fn move_left(&self, offset: usize, mode: Mode, count: usize) -> usize { - let line = self.line_of_offset(offset); - let line_start_offset = self.offset_of_line(line); let min_offset = if mode == Mode::Insert { 0 } else { - line_start_offset + let line = self.line_of_offset(offset); + self.offset_of_line(line) }; - self.prev_grapheme_offset(offset, count, min_offset) } pub fn move_right(&self, offset: usize, mode: Mode, count: usize) -> usize { - let line_end = self.offset_line_end(offset, mode != Mode::Normal); - let max_offset = if mode == Mode::Insert { self.len() } else { - line_end + self.offset_line_end(offset, mode != Mode::Normal) }; self.next_grapheme_offset(offset, count, max_offset) @@ -842,8 +830,8 @@ impl Buffer { self.move_n_words_forward(offset, 1) } - pub fn move_word_backward(&self, offset: usize) -> usize { - self.move_n_words_backward(offset, 1) + pub fn move_word_backward(&self, offset: usize, mode: Mode) -> usize { + self.move_n_words_backward(offset, 1, mode) } pub fn next_grapheme_offset( @@ -885,6 +873,7 @@ impl Buffer { if self.is_empty() { return None; } + let offset = offset.min(self.len()); WordCursor::new(&self.text, offset) .inner .peek_next_codepoint() @@ -897,21 +886,65 @@ impl Buffer { offset: usize, ) -> Option { if let Some(syntax) = syntax { - syntax.find_tag(offset, true, &c.to_string()) + syntax.find_tag(offset, true, &CharBuffer::new(c)) } else { WordCursor::new(&self.text, offset).previous_unmatched(c) } } + /// Get the content of the rope as a Cow string, for 'nice' ranges (small, and at the right + /// offsets) this will be a reference to the rope's data. Otherwise, it allocates a new string. + /// You should be somewhat wary of requesting large parts of the rope, as it will allocate + /// a new string since it isn't contiguous in memory for large chunks. pub fn slice_to_cow(&self, range: Range) -> Cow { self.text .slice_to_cow(range.start.min(self.len())..range.end.min(self.len())) } + /// Iterate over (utf8_offset, char) values in the given range + /// This uses `iter_chunks` and so does not allocate, compared to `slice_to_cow` which can + pub fn char_indices_iter( + &self, + range: T, + ) -> impl Iterator + '_ { + CharIndicesJoin::new(self.text.iter_chunks(range).map(str::char_indices)) + } + pub fn len(&self) -> usize { self.text.len() } + fn find_nth_paragraph( + &self, + offset: usize, + mut count: usize, + mut find_next: F, + ) -> usize + where + F: FnMut(&mut ParagraphCursor) -> Option, + { + let mut cursor = ParagraphCursor::new(self.text(), offset); + let mut new_offset = offset; + while count != 0 { + // FIXME: wait for if-let-chain + if let Some(offset) = find_next(&mut cursor) { + new_offset = offset; + } else { + break; + } + count -= 1; + } + new_offset + } + + pub fn move_n_paragraphs_forward(&self, offset: usize, count: usize) -> usize { + self.find_nth_paragraph(offset, count, |cursor| cursor.next_boundary()) + } + + pub fn move_n_paragraphs_backward(&self, offset: usize, count: usize) -> usize { + self.find_nth_paragraph(offset, count, |cursor| cursor.prev_boundary()) + } + /// Find the nth (`count`) word starting at `offset` in either direction /// depending on `find_next`. /// @@ -960,8 +993,17 @@ impl Buffer { new_offset } - pub fn move_n_words_backward(&self, offset: usize, count: usize) -> usize { - self.find_nth_word(offset, count, |cursor| cursor.prev_boundary()) + pub fn move_n_words_backward( + &self, + offset: usize, + count: usize, + mode: Mode, + ) -> usize { + self.find_nth_word(offset, count, |cursor| cursor.prev_boundary(mode)) + } + + pub fn move_word_backward_deletion(&self, offset: usize) -> usize { + self.find_nth_word(offset, 1, |cursor| cursor.prev_deletion_boundary()) } } @@ -1006,14 +1048,14 @@ fn shuffle( ) } -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum DiffResult { Left(T), Both(T, T), Right(T), } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum DiffLines { Left(Range), Both(Range, Range), @@ -1026,6 +1068,7 @@ pub fn rope_diff( right_rope: Rope, rev: u64, atomic_rev: Arc, + context_lines: Option, ) -> Option> { let left_lines = left_rope.lines(..).collect::>>(); let right_lines = right_rope.lines(..).collect::>>(); @@ -1154,58 +1197,118 @@ pub fn rope_diff( right_count - trailing_equals..right_count, )); } - if !changes.is_empty() { - let changes_last = changes.len() - 1; - for (i, change) in changes.clone().iter().enumerate().rev() { - if atomic_rev.load(atomic::Ordering::Acquire) != rev { - return None; - } - if let DiffLines::Both(l, r) = change { - if i == 0 || i == changes_last { - if r.len() > 3 { - if i == 0 { - changes[i] = - DiffLines::Both(l.end - 3..l.end, r.end - 3..r.end); - changes.insert( - i, - DiffLines::Skip( - l.start..l.end - 3, - r.start..r.end - 3, - ), - ); - } else { - changes[i] = DiffLines::Skip( - l.start + 3..l.end, - r.start + 3..r.end, - ); - changes.insert( - i, - DiffLines::Both( - l.start..l.start + 3, - r.start..r.start + 3, - ), - ); + if let Some(context_lines) = context_lines { + if !changes.is_empty() { + let changes_last = changes.len() - 1; + for (i, change) in changes.clone().iter().enumerate().rev() { + if atomic_rev.load(atomic::Ordering::Acquire) != rev { + return None; + } + if let DiffLines::Both(l, r) = change { + if i == 0 || i == changes_last { + if r.len() > context_lines { + if i == 0 { + changes[i] = DiffLines::Both( + l.end - context_lines..l.end, + r.end - context_lines..r.end, + ); + changes.insert( + i, + DiffLines::Skip( + l.start..l.end - context_lines, + r.start..r.end - context_lines, + ), + ); + } else { + changes[i] = DiffLines::Skip( + l.start + context_lines..l.end, + r.start + context_lines..r.end, + ); + changes.insert( + i, + DiffLines::Both( + l.start..l.start + context_lines, + r.start..r.start + context_lines, + ), + ); + } } + } else if r.len() > context_lines * 2 { + changes[i] = DiffLines::Both( + l.end - context_lines..l.end, + r.end - context_lines..r.end, + ); + changes.insert( + i, + DiffLines::Skip( + l.start + context_lines..l.end - context_lines, + r.start + context_lines..r.end - context_lines, + ), + ); + changes.insert( + i, + DiffLines::Both( + l.start..l.start + context_lines, + r.start..r.start + context_lines, + ), + ); } - } else if r.len() > 6 { - changes[i] = DiffLines::Both(l.end - 3..l.end, r.end - 3..r.end); - changes.insert( - i, - DiffLines::Skip( - l.start + 3..l.end - 3, - r.start + 3..r.end - 3, - ), - ); - changes.insert( - i, - DiffLines::Both(l.start..l.start + 3, r.start..r.start + 3), - ); } } } } + Some(changes) } +pub struct DeltaValueRegion<'a, N: NodeInfo + 'a> { + pub old_offset: usize, + pub new_offset: usize, + pub len: usize, + pub node: &'a Node, +} + +/// Modified version of `xi_rope::delta::InsertsIter` which includes the node +pub struct InsertsValueIter<'a, N: NodeInfo + 'a> { + pos: usize, + last_end: usize, + els_iter: std::slice::Iter<'a, DeltaElement>, +} +impl<'a, N: NodeInfo + 'a> InsertsValueIter<'a, N> { + pub fn new(delta: &'a Delta) -> InsertsValueIter<'a, N> { + InsertsValueIter { + pos: 0, + last_end: 0, + els_iter: delta.els.iter(), + } + } +} +impl<'a, N: NodeInfo> Iterator for InsertsValueIter<'a, N> { + type Item = DeltaValueRegion<'a, N>; + + fn next(&mut self) -> Option { + for elem in &mut self.els_iter { + match *elem { + DeltaElement::Copy(b, e) => { + self.pos += e - b; + self.last_end = e; + } + DeltaElement::Insert(ref n) => { + let result = Some(DeltaValueRegion { + old_offset: self.last_end, + new_offset: self.pos, + len: n.len(), + node: n, + }); + self.pos += n.len(); + self.last_end += n.len(); + return result; + } + } + } + None + } +} + #[cfg(test)] mod test; diff --git a/lapce-core/src/buffer/rope_text.rs b/lapce-core/src/buffer/rope_text.rs new file mode 100644 index 0000000000..0a67c32285 --- /dev/null +++ b/lapce-core/src/buffer/rope_text.rs @@ -0,0 +1,461 @@ +use std::{borrow::Cow, ops::Range}; + +use lapce_xi_rope::{interval::IntervalBounds, Cursor, Rope}; +use lsp_types::Position; + +use crate::{ + encoding::{offset_utf16_to_utf8, offset_utf8_to_utf16}, + word::WordCursor, +}; + +/// A wrapper around a rope that provides utility functions atop it. +pub struct RopeText<'a> { + text: &'a Rope, +} + +impl<'a> RopeText<'a> { + pub fn new(text: &'a Rope) -> Self { + Self { text } + } + + pub fn len(&self) -> usize { + self.text.len() + } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// The last line of the held rope + pub fn last_line(&self) -> usize { + self.line_of_offset(self.len()) + } + + /// Get the offset into the rope of the start of the given line. + /// If the line it out of bounds, then the last offset (the len) is returned. + pub fn offset_of_line(&self, line: usize) -> usize { + let last_line = self.last_line(); + let line = line.min(last_line + 1); + self.text.offset_of_line(line) + } + + pub fn offset_line_end(&self, offset: usize, caret: bool) -> usize { + let line = self.line_of_offset(offset); + self.line_end_offset(line, caret) + } + + pub fn line_of_offset(&self, offset: usize) -> usize { + let offset = offset.min(self.len()); + let offset = self + .text + .at_or_prev_codepoint_boundary(offset) + .unwrap_or(offset); + + self.text.line_of_offset(offset) + } + + /// Converts a UTF8 offset to a UTF16 LSP position + /// Returns None if it is not a valid UTF16 offset + pub fn offset_to_position(&self, offset: usize) -> Position { + let (line, col) = self.offset_to_line_col(offset); + let line_offset = self.offset_of_line(line); + + let utf16_col = + offset_utf8_to_utf16(self.char_indices_iter(line_offset..), col); + + Position { + line: line as u32, + character: utf16_col as u32, + } + } + + pub fn offset_of_position(&self, pos: &Position) -> usize { + let (line, column) = self.position_to_line_col(pos); + + self.offset_of_line_col(line, column) + } + + pub fn position_to_line_col(&self, pos: &Position) -> (usize, usize) { + let line = pos.line as usize; + let line_offset = self.offset_of_line(line); + + let column = offset_utf16_to_utf8( + self.char_indices_iter(line_offset..), + pos.character as usize, + ); + + (line, column) + } + + pub fn offset_to_line_col(&self, offset: usize) -> (usize, usize) { + let offset = offset.min(self.len()); + let line = self.line_of_offset(offset); + let line_start = self.offset_of_line(line); + if offset == line_start { + return (line, 0); + } + + let col = offset - line_start; + (line, col) + } + + pub fn offset_of_line_col(&self, line: usize, col: usize) -> usize { + let mut pos = 0; + let mut offset = self.offset_of_line(line); + for c in self + .slice_to_cow(offset..self.offset_of_line(line + 1)) + .chars() + { + if c == '\n' { + return offset; + } + + let char_len = c.len_utf8(); + if pos + char_len > col { + return offset; + } + pos += char_len; + offset += char_len; + } + offset + } + + pub fn line_end_col(&self, line: usize, caret: bool) -> usize { + let line_start = self.offset_of_line(line); + let offset = self.line_end_offset(line, caret); + offset - line_start + } + + /// Get the offset of the end of the line. The caret decides whether it is after the last + /// character, or before it. + /// If the line is out of bounds, then the last offset (the len) is returned. + /// ```rust,ignore + /// let text = Rope::from("hello\nworld"); + /// let text = RopeText::new(&text); + /// assert_eq!(text.line_end_offset(0, false), 4); // "hell|o" + /// assert_eq!(text.line_end_offset(0, true), 5); // "hello|" + /// assert_eq!(text.line_end_offset(1, false), 10); // "worl|d" + /// assert_eq!(text.line_end_offset(1, true), 11); // "world|" + /// // Out of bounds + /// assert_eq!(text.line_end_offset(2, false), 11); // "world|" + /// ``` + pub fn line_end_offset(&self, line: usize, caret: bool) -> usize { + let mut offset = self.offset_of_line(line + 1); + let mut line_content: &str = &self.line_content(line); + if line_content.ends_with("\r\n") { + offset -= 2; + line_content = &line_content[..line_content.len() - 2]; + } else if line_content.ends_with('\n') { + offset -= 1; + line_content = &line_content[..line_content.len() - 1]; + } + if !caret && !line_content.is_empty() { + offset = self.prev_grapheme_offset(offset, 1, 0); + } + offset + } + + /// Returns the content of the given line. + /// Includes the line ending if it exists. (-> the last line won't have a line ending) + /// Lines past the end of the document will return an empty string. + pub fn line_content(&self, line: usize) -> Cow<'a, str> { + self.text + .slice_to_cow(self.offset_of_line(line)..self.offset_of_line(line + 1)) + } + + /// Get the offset of the previous grapheme cluster. + pub fn prev_grapheme_offset( + &self, + offset: usize, + count: usize, + limit: usize, + ) -> usize { + let offset = offset.min(self.len()); + let mut cursor = Cursor::new(self.text, offset); + let mut new_offset = offset; + for _i in 0..count { + if let Some(prev_offset) = cursor.prev_grapheme() { + if prev_offset < limit { + return new_offset; + } + new_offset = prev_offset; + cursor.set(prev_offset); + } else { + return new_offset; + } + } + new_offset + } + + /// Returns the offset of the first non-blank character on the given line. + /// If the line is one past the last line, then the offset at the end of the rope is returned. + /// If the line is further past that, then it defaults to the last line. + pub fn first_non_blank_character_on_line(&self, line: usize) -> usize { + let last_line = self.last_line(); + let line = if line > last_line + 1 { + last_line + } else { + line + }; + let line_start_offset = self.text.offset_of_line(line); + WordCursor::new(self.text, line_start_offset).next_non_blank_char() + } + + pub fn indent_on_line(&self, line: usize) -> String { + let line_start_offset = self.text.offset_of_line(line); + let word_boundary = + WordCursor::new(self.text, line_start_offset).next_non_blank_char(); + let indent = self.text.slice_to_cow(line_start_offset..word_boundary); + indent.to_string() + } + + /// Get the content of the rope as a Cow string, for 'nice' ranges (small, and at the right + /// offsets) this will be a reference to the rope's data. Otherwise, it allocates a new string. + /// You should be somewhat wary of requesting large parts of the rope, as it will allocate + /// a new string since it isn't contiguous in memory for large chunks. + pub fn slice_to_cow(&self, range: Range) -> Cow<'a, str> { + self.text + .slice_to_cow(range.start.min(self.len())..range.end.min(self.len())) + } + + /// Iterate over (utf8_offset, char) values in the given range + /// This uses `iter_chunks` and so does not allocate, compared to `slice_to_cow` which can + pub fn char_indices_iter( + &self, + range: T, + ) -> impl Iterator + 'a { + CharIndicesJoin::new(self.text.iter_chunks(range).map(str::char_indices)) + } + + /// The number of lines in the file + pub fn num_lines(&self) -> usize { + self.last_line() + 1 + } + + /// The length of the given line + pub fn line_len(&self, line: usize) -> usize { + self.offset_of_line(line + 1) - self.offset_of_line(line) + } +} + +/// Joins an iterator of iterators over char indices `(usize, char)` into one +/// as if they were from a single long string +/// Assumes the iterators end after the first `None` value +#[derive(Clone)] +pub struct CharIndicesJoin, O: Iterator> +{ + /// Our iterator of iterators + main_iter: O, + /// Our current working iterator of indices + current_indices: Option, + /// The amount we should shift future offsets + current_base: usize, + /// The latest base, since we don't know when the `current_indices` iterator will end + latest_base: usize, +} + +impl, O: Iterator> + CharIndicesJoin +{ + pub fn new(main_iter: O) -> CharIndicesJoin { + CharIndicesJoin { + main_iter, + current_indices: None, + current_base: 0, + latest_base: 0, + } + } +} + +impl, O: Iterator> Iterator + for CharIndicesJoin +{ + type Item = (usize, char); + + fn next(&mut self) -> Option { + if let Some(current) = &mut self.current_indices { + if let Some((next_offset, next_ch)) = current.next() { + // Shift by the current base offset, which is the accumulated offset from previous + // iterators, which makes so the offset produced looks like it is from one long str + let next_offset = self.current_base + next_offset; + // Store the latest base offset, because we don't know when the current iterator + // will end (though technically the str iterator impl does) + self.latest_base = next_offset + next_ch.len_utf8(); + return Some((next_offset, next_ch)); + } + } + + // Otherwise, if we didn't return something above, then we get a next iterator + if let Some(next_current) = self.main_iter.next() { + // Update our current working iterator + self.current_indices = Some(next_current); + // Update the current base offset with the previous iterators latest offset base + // This is what we are shifting by + self.current_base = self.latest_base; + + // Get the next item without new current iterator + // As long as main_iter and the iterators it produces aren't infinite then this + // recursion won't be infinite either + // and even the non-recursion version would be infinite if those were infinite + self.next() + } else { + // We didn't get anything from the main iter, so we're completely done. + None + } + } +} + +#[cfg(test)] +mod tests { + use lapce_xi_rope::Rope; + + use super::RopeText; + + #[test] + fn test_line_content() { + let text = Rope::from(""); + let text = RopeText::new(&text); + + assert_eq!(text.line_content(0), ""); + assert_eq!(text.line_content(1), ""); + assert_eq!(text.line_content(2), ""); + + let text = Rope::from("abc\ndef\nghi"); + let text = RopeText::new(&text); + + assert_eq!(text.line_content(0), "abc\n"); + assert_eq!(text.line_content(1), "def\n"); + assert_eq!(text.line_content(2), "ghi"); + assert_eq!(text.line_content(3), ""); + assert_eq!(text.line_content(4), ""); + assert_eq!(text.line_content(5), ""); + + let text = Rope::from("abc\r\ndef\r\nghi"); + let text = RopeText::new(&text); + + assert_eq!(text.line_content(0), "abc\r\n"); + assert_eq!(text.line_content(1), "def\r\n"); + assert_eq!(text.line_content(2), "ghi"); + assert_eq!(text.line_content(3), ""); + assert_eq!(text.line_content(4), ""); + assert_eq!(text.line_content(5), ""); + } + + #[test] + fn test_offset_of_line() { + let text = Rope::from(""); + let text = RopeText::new(&text); + + assert_eq!(text.offset_of_line(0), 0); + assert_eq!(text.offset_of_line(1), 0); + assert_eq!(text.offset_of_line(2), 0); + + let text = Rope::from("abc\ndef\nghi"); + let text = RopeText::new(&text); + + assert_eq!(text.offset_of_line(0), 0); + assert_eq!(text.offset_of_line(1), 4); + assert_eq!(text.offset_of_line(2), 8); + assert_eq!(text.offset_of_line(3), text.len()); // 11 + assert_eq!(text.offset_of_line(4), text.len()); + assert_eq!(text.offset_of_line(5), text.len()); + + let text = Rope::from("abc\r\ndef\r\nghi"); + let text = RopeText::new(&text); + + assert_eq!(text.offset_of_line(0), 0); + assert_eq!(text.offset_of_line(1), 5); + assert_eq!(text.offset_of_line(2), 10); + assert_eq!(text.offset_of_line(3), text.len()); // 13 + assert_eq!(text.offset_of_line(4), text.len()); + assert_eq!(text.offset_of_line(5), text.len()); + } + + #[test] + fn test_line_end_offset() { + let text = Rope::from(""); + let text = RopeText::new(&text); + + assert_eq!(text.line_end_offset(0, false), 0); + assert_eq!(text.line_end_offset(0, true), 0); + assert_eq!(text.line_end_offset(1, false), 0); + assert_eq!(text.line_end_offset(1, true), 0); + assert_eq!(text.line_end_offset(2, false), 0); + assert_eq!(text.line_end_offset(2, true), 0); + + let text = Rope::from("abc\ndef\nghi"); + let text = RopeText::new(&text); + + assert_eq!(text.line_end_offset(0, false), 2); + assert_eq!(text.line_end_offset(0, true), 3); + assert_eq!(text.line_end_offset(1, false), 6); + assert_eq!(text.line_end_offset(1, true), 7); + assert_eq!(text.line_end_offset(2, false), 10); + assert_eq!(text.line_end_offset(2, true), text.len()); + assert_eq!(text.line_end_offset(3, false), text.len()); + assert_eq!(text.line_end_offset(3, true), text.len()); + assert_eq!(text.line_end_offset(4, false), text.len()); + assert_eq!(text.line_end_offset(4, true), text.len()); + + // This is equivalent to the doc test for RopeText::line_end_offset + // because you don't seem to be able to do a `use RopeText` in a doc test since it isn't + // public.. + let text = Rope::from("hello\nworld"); + let text = RopeText::new(&text); + assert_eq!(text.line_end_offset(0, false), 4); // "hell|o" + assert_eq!(text.line_end_offset(0, true), 5); // "hello|" + assert_eq!(text.line_end_offset(1, false), 10); // "worl|d" + assert_eq!(text.line_end_offset(1, true), 11); // "world|" + // Out of bounds + assert_eq!(text.line_end_offset(2, false), 11); // "world|" + } + + #[test] + fn test_prev_grapheme_offset() { + let text = Rope::from(""); + let text = RopeText::new(&text); + + assert_eq!(text.prev_grapheme_offset(0, 0, 0), 0); + assert_eq!(text.prev_grapheme_offset(0, 1, 0), 0); + assert_eq!(text.prev_grapheme_offset(0, 1, 1), 0); + + let text = Rope::from("abc def ghi"); + let text = RopeText::new(&text); + + assert_eq!(text.prev_grapheme_offset(0, 0, 0), 0); + assert_eq!(text.prev_grapheme_offset(0, 1, 0), 0); + assert_eq!(text.prev_grapheme_offset(0, 1, 1), 0); + assert_eq!(text.prev_grapheme_offset(2, 1, 0), 1); + assert_eq!(text.prev_grapheme_offset(2, 1, 1), 1); + } + + #[test] + fn test_first_non_blank_character_on_line() { + let text = Rope::from(""); + let text = RopeText::new(&text); + + assert_eq!(text.first_non_blank_character_on_line(0), 0); + assert_eq!(text.first_non_blank_character_on_line(1), 0); + assert_eq!(text.first_non_blank_character_on_line(2), 0); + + let text = Rope::from("abc\ndef\nghi"); + let text = RopeText::new(&text); + + assert_eq!(text.first_non_blank_character_on_line(0), 0); + assert_eq!(text.first_non_blank_character_on_line(1), 4); + assert_eq!(text.first_non_blank_character_on_line(2), 8); + assert_eq!(text.first_non_blank_character_on_line(3), 11); + assert_eq!(text.first_non_blank_character_on_line(4), 8); + assert_eq!(text.first_non_blank_character_on_line(5), 8); + + let text = Rope::from("abc\r\ndef\r\nghi"); + let text = RopeText::new(&text); + + assert_eq!(text.first_non_blank_character_on_line(0), 0); + assert_eq!(text.first_non_blank_character_on_line(1), 5); + assert_eq!(text.first_non_blank_character_on_line(2), 10); + assert_eq!(text.first_non_blank_character_on_line(3), 13); + assert_eq!(text.first_non_blank_character_on_line(4), 10); + assert_eq!(text.first_non_blank_character_on_line(5), 10); + } +} diff --git a/lapce-core/src/buffer/test.rs b/lapce-core/src/buffer/test.rs index 122d9d1565..a119d59ba1 100644 --- a/lapce-core/src/buffer/test.rs +++ b/lapce-core/src/buffer/test.rs @@ -1,9 +1,10 @@ use super::Buffer; mod editing { + use lapce_xi_rope::Rope; + use super::*; use crate::{editor::EditType, selection::Selection}; - use xi_rope::Rope; #[test] fn is_pristine() { @@ -19,6 +20,7 @@ mod editing { mod motion { use super::*; + use crate::mode::Mode; #[test] fn cannot_move_in_empty_buffer() { @@ -26,8 +28,8 @@ mod motion { assert_eq!(buffer.move_word_forward(0), 0); assert_eq!(buffer.move_n_words_forward(0, 2), 0); - assert_eq!(buffer.move_word_backward(0), 0); - assert_eq!(buffer.move_n_words_backward(0, 2), 0); + assert_eq!(buffer.move_word_backward(0, Mode::Insert), 0); + assert_eq!(buffer.move_n_words_backward(0, 2, Mode::Insert), 0); assert_eq!(buffer.move_n_wordends_forward(0, 2, false), 0); assert_eq!(buffer.move_n_wordends_forward(0, 2, true), 0); @@ -40,15 +42,15 @@ mod motion { // 0 count does not move. assert_eq!(buffer.move_n_words_forward(0, 0), 0); - assert_eq!(buffer.move_n_words_backward(0, 0), 0); + assert_eq!(buffer.move_n_words_backward(0, 0, Mode::Insert), 0); for offset in 0..4 { assert_eq!(buffer.move_word_forward(offset), 4); - assert_eq!(buffer.move_word_backward(offset), 0); + assert_eq!(buffer.move_word_backward(offset, Mode::Insert), 0); } assert_eq!(buffer.move_word_forward(4), 8); - assert_eq!(buffer.move_word_backward(4), 0); + assert_eq!(buffer.move_word_backward(4, Mode::Insert), 0); let end = buffer.len() - 1; for offset in 0..4 { @@ -56,14 +58,17 @@ mod motion { } assert_eq!(buffer.move_n_words_forward(4, 2), 15); for offset in 0..5 { - assert_eq!(buffer.move_n_words_backward(end - offset, 2), 8) + assert_eq!( + buffer.move_n_words_backward(end - offset, 2, Mode::Insert), + 8 + ) } - assert_eq!(buffer.move_n_words_backward(end - 6, 2), 4); + assert_eq!(buffer.move_n_words_backward(end - 6, 2, Mode::Insert), 4); assert_eq!(buffer.move_n_words_forward(0, 2), 8); assert_eq!(buffer.move_n_words_forward(0, 3), 15); - assert_eq!(buffer.move_n_words_backward(end, 2), 8); - assert_eq!(buffer.move_n_words_backward(end, 3), 4); + assert_eq!(buffer.move_n_words_backward(end, 2, Mode::Insert), 8); + assert_eq!(buffer.move_n_words_backward(end, 3, Mode::Insert), 4); // FIXME: see #501 for possible issues in WordCursor::next_boundary() // @@ -74,7 +79,10 @@ mod motion { // In the other direction. for offset in 0..end { - assert_eq!(buffer.move_n_words_backward(end - offset, 100), 0); + assert_eq!( + buffer.move_n_words_backward(end - offset, 100, Mode::Insert), + 0 + ); } } diff --git a/lapce-core/src/char_buffer.rs b/lapce-core/src/char_buffer.rs new file mode 100644 index 0000000000..6ad777ba3e --- /dev/null +++ b/lapce-core/src/char_buffer.rs @@ -0,0 +1,1083 @@ +extern crate alloc; + +use alloc::borrow::Cow; +use alloc::rc::Rc; +use alloc::sync::Arc; +use core::borrow::Borrow; +use core::cmp::Ordering; +use core::convert::AsRef; +use core::fmt; +use core::hash; +use core::ops::Deref; +use core::str; + +/// This is a small memory buffer allocated on the stack to store a +/// ‘string slice’ of exactly one character in length. That is, this +/// structure stores the result of converting [`char`] to [`prim@str`] +/// (which can be accessed as [`&str`]). +/// +/// In other words, this struct is a helper for performing `char -> &str` +/// type conversion without heap allocation. +/// +/// # Note +/// +/// In general, it is not recommended to perform `char -> CharBuffer -> char` +/// type conversions, as this may affect performance. +/// +/// [`&str`]: https://doc.rust-lang.org/core/primitive.str.html +/// +/// # Examples +/// +/// ``` +/// use lapce_core::char_buffer::CharBuffer; +/// +/// let word = "goodbye"; +/// +/// let mut chars_buf = word.chars().map(CharBuffer::new); +/// +/// assert_eq!("g", chars_buf.next().unwrap().as_ref()); +/// assert_eq!("o", chars_buf.next().unwrap().as_ref()); +/// assert_eq!("o", chars_buf.next().unwrap().as_ref()); +/// assert_eq!("d", chars_buf.next().unwrap().as_ref()); +/// assert_eq!("b", chars_buf.next().unwrap().as_ref()); +/// assert_eq!("y", chars_buf.next().unwrap().as_ref()); +/// assert_eq!("e", chars_buf.next().unwrap().as_ref()); +/// +/// assert_eq!(None, chars_buf.next()); +/// +/// for (char, char_buf) in word.chars().zip(word.chars().map(CharBuffer::new)) { +/// assert_eq!(char.to_string(), char_buf); +/// } +/// ``` +#[derive(Clone, Copy, PartialEq, Eq)] +pub struct CharBuffer { + len: usize, + buf: [u8; 4], +} + +/// The type of error returned when the conversion from [`prim@str`], [`String`] or their borrowed +/// or native forms to [`CharBuffer`] fails. +/// +/// This `structure` is created by various `CharBuffer::try_from` methods (for example, +/// by the [`CharBuffer::try_from<&str>`] method). +/// +/// See its documentation for more. +/// +/// [`CharBuffer::try_from<&str>`]: CharBuffer::try_from<&str> +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub struct CharBufferTryFromError(()); + +impl CharBuffer { + /// Creates a new `CharBuffer` from the given [`char`]. + /// + /// # Examples + /// + /// ``` + /// use lapce_core::char_buffer::CharBuffer; + /// + /// let char_buf = CharBuffer::new('a'); + /// assert_eq!("a", &char_buf); + /// + /// let string = "Some string"; + /// let char_vec = string.chars().map(CharBuffer::new).collect::>(); + /// assert_eq!( + /// ["S", "o", "m", "e", " ", "s", "t", "r", "i", "n", "g"].as_ref(), + /// &char_vec + /// ); + /// ``` + #[inline] + pub fn new(char: char) -> Self { + let mut buf = [0; 4]; + let len = char.encode_utf8(&mut buf).as_bytes().len(); + Self { len, buf } + } + + /// Converts a `CharBuffer` into an immutable string slice. + /// + /// # Examples + /// + /// ``` + /// use lapce_core::char_buffer::CharBuffer; + /// + /// let char_buf = CharBuffer::from('r'); + /// assert_eq!("r", char_buf.as_str()); + /// ``` + #[inline] + pub fn as_str(&self) -> &str { + self + } + + /// Returns the length of a `&str` stored inside the `CharBuffer`, in bytes, + /// not [`char`]s or graphemes. In other words, it might not be what a human + /// considers the length of the string. + /// + /// # Examples + /// + /// ``` + /// use lapce_core::char_buffer::CharBuffer; + /// + /// let f = CharBuffer::new('f'); + /// assert_eq!(f.len(), 1); + /// + /// let fancy_f = CharBuffer::new('ƒ'); + /// assert_eq!(fancy_f.len(), 2); + /// ``` + #[inline] + pub fn len(&self) -> usize { + self.len + } + + /// Always returns `false` since this structure can only be created from + /// [`char`], which cannot be empty. + /// + /// # Examples + /// + /// ``` + /// use lapce_core::char_buffer::CharBuffer; + /// + /// let c = CharBuffer::new('\0'); + /// assert!(!c.is_empty()); + /// assert_eq!(c.len(), 1); + /// ``` + #[inline] + pub fn is_empty(&self) -> bool { + false + } +} + +impl From for CharBuffer { + /// Creates a new [`CharBuffer`] from the given [`char`]. + /// + /// Calling this function is the same as calling [`new`](CharBuffer::new) + /// function. + /// + /// # Example + /// + /// ``` + /// use lapce_core::char_buffer::CharBuffer; + /// + /// let char_buf = CharBuffer::from('a'); + /// assert_eq!("a", &char_buf); + /// + /// let string = "Some string"; + /// let char_vec = string.chars().map(CharBuffer::from).collect::>(); + /// assert_eq!( + /// ["S", "o", "m", "e", " ", "s", "t", "r", "i", "n", "g"].as_ref(), + /// &char_vec + /// ); + /// ``` + #[inline] + fn from(char: char) -> Self { + Self::new(char) + } +} + +impl From<&char> for CharBuffer { + /// Converts a `&char` into a [`CharBuffer`]. + /// + /// # Example + /// + /// ``` + /// use lapce_core::char_buffer::CharBuffer; + /// + /// let string = "Some string"; + /// let char_vec = string.chars().collect::>(); + /// assert_eq!( + /// ['S', 'o', 'm', 'e', ' ', 's', 't', 'r', 'i', 'n', 'g'].as_ref(), + /// &char_vec + /// ); + /// + /// let string_vec = char_vec.iter().map(CharBuffer::from).collect::>(); + /// + /// assert_eq!( + /// ["S", "o", "m", "e", " ", "s", "t", "r", "i", "n", "g"].as_ref(), + /// &string_vec + /// ); + /// ```` + #[inline] + fn from(char: &char) -> Self { + Self::new(*char) + } +} + +impl From<&mut char> for CharBuffer { + /// Converts a `&mut char` into a [`CharBuffer`]. + /// + /// # Example + /// + /// ``` + /// use lapce_core::char_buffer::CharBuffer; + /// + /// let string = "Some string"; + /// let mut char_vec = string.chars().collect::>(); + /// assert_eq!( + /// ['S', 'o', 'm', 'e', ' ', 's', 't', 'r', 'i', 'n', 'g'].as_ref(), + /// &char_vec + /// ); + /// + /// let string_vec = char_vec + /// .iter_mut() + /// .map(CharBuffer::from) + /// .collect::>(); + /// + /// assert_eq!( + /// ["S", "o", "m", "e", " ", "s", "t", "r", "i", "n", "g"].as_ref(), + /// &string_vec + /// ); + /// ```` + #[inline] + fn from(char: &mut char) -> Self { + Self::new(*char) + } +} + +impl From for char { + /// Creates a new [`char`] from the given reference to [`CharBuffer`]. + /// + /// # Note + /// + /// In general, it is not recommended to perform `char -> CharBuffer -> char` + /// type conversions, as this may affect performance. + /// + /// # Example + /// + /// ``` + /// use lapce_core::char_buffer::CharBuffer; + /// + /// let char_buf = CharBuffer::from('a'); + /// let char: char = char_buf.into(); + /// assert_eq!('a', char); + /// + /// let string = "Some string"; + /// + /// // Such type conversions are not recommended, use `char` directly + /// let char_vec = string + /// .chars() + /// .map(CharBuffer::from) + /// .map(char::from) + /// .collect::>(); + /// + /// assert_eq!( + /// ['S', 'o', 'm', 'e', ' ', 's', 't', 'r', 'i', 'n', 'g'].as_ref(), + /// &char_vec + /// ); + /// ```` + #[inline] + fn from(char: CharBuffer) -> Self { + // SAFETY: The structure stores a valid utf8 character + unsafe { char.chars().next().unwrap_unchecked() } + } +} + +impl From<&CharBuffer> for char { + /// Converts a `&CharBuffer` into a [`char`]. + /// + /// # Note + /// + /// In general, it is not recommended to perform `char -> CharBuffer -> char` + /// type conversions, as this may affect performance. + /// + /// # Example + /// + /// ``` + /// use lapce_core::char_buffer::CharBuffer; + /// + /// let char_buf = CharBuffer::from('a'); + /// let char: char = char::from(&char_buf); + /// assert_eq!('a', char); + /// + /// let string = "Some string"; + /// + /// // Such type conversions are not recommended, use `char` directly + /// let char_buf_vec = string.chars().map(CharBuffer::from).collect::>(); + /// let char_vec = char_buf_vec.iter().map(char::from).collect::>(); + /// + /// assert_eq!( + /// ['S', 'o', 'm', 'e', ' ', 's', 't', 'r', 'i', 'n', 'g'].as_ref(), + /// &char_vec + /// ); + /// ```` + #[inline] + fn from(char: &CharBuffer) -> Self { + // SAFETY: The structure stores a valid utf8 character + unsafe { char.chars().next().unwrap_unchecked() } + } +} + +impl From<&CharBuffer> for CharBuffer { + /// Converts a `&CharBuffer` into a [`CharBuffer`]. + /// + /// # Example + /// + /// ``` + /// use lapce_core::char_buffer::CharBuffer; + /// + /// let char_buf1 = CharBuffer::from('a'); + /// let char_buf2: CharBuffer = CharBuffer::from(&char_buf1); + /// assert_eq!(char_buf1, char_buf2); + /// + /// let string = "Some string"; + /// let char_vec1 = string.chars().map(CharBuffer::from).collect::>(); + /// let char_vec2 = char_vec1.iter().map(CharBuffer::from).collect::>(); + /// + /// assert_eq!(char_vec1, char_vec2); + /// ```` + #[inline] + fn from(char: &CharBuffer) -> Self { + *char + } +} + +impl From for String { + /// Allocates an owned [`String`] from a single character. + /// + /// # Example + /// + /// ``` + /// use lapce_core::char_buffer::CharBuffer; + /// + /// let c: CharBuffer = CharBuffer::from('a'); + /// let s: String = String::from(c); + /// assert_eq!("a", &s[..]); + /// ``` + #[inline] + fn from(char: CharBuffer) -> Self { + char.as_ref().to_string() + } +} + +impl From<&CharBuffer> for String { + /// Allocates an owned [`String`] from a single character. + /// + /// # Example + /// + /// ``` + /// use lapce_core::char_buffer::CharBuffer; + /// + /// let c: CharBuffer = CharBuffer::from('a'); + /// let s: String = String::from(&c); + /// assert_eq!("a", &s[..]); + /// ``` + #[inline] + fn from(char: &CharBuffer) -> Self { + char.as_ref().to_string() + } +} + +impl<'a> From<&'a CharBuffer> for &'a str { + /// Converts a `&CharBuffer` into a [`prim@str`]. + /// + /// # Example + /// + /// ``` + /// use lapce_core::char_buffer::CharBuffer; + /// + /// let c: CharBuffer = CharBuffer::from('a'); + /// let s: &str = From::from(&c); + /// assert_eq!("a", &s[..]); + /// ``` + #[inline] + fn from(char: &'a CharBuffer) -> Self { + char + } +} + +impl<'a> From<&'a CharBuffer> for Cow<'a, str> { + /// Converts a `&'a CharBuffer` into a [`Cow<'a, str>`]. + /// + /// # Example + /// + /// ``` + /// use lapce_core::char_buffer::CharBuffer; + /// use std::borrow::Cow; + /// + /// let c: CharBuffer = CharBuffer::from('a'); + /// let s: Cow = From::from(&c); + /// assert_eq!("a", &s[..]); + /// ``` + /// [`Cow<'a, str>`]: https://doc.rust-lang.org/std/borrow/enum.Cow.html + #[inline] + fn from(s: &'a CharBuffer) -> Self { + Cow::Borrowed(&**s) + } +} + +impl From for Cow<'_, CharBuffer> { + /// Converts a `CharBuffer` into a [`Cow<'_, CharBuffer>`]. + /// + /// # Example + /// + /// ``` + /// use lapce_core::char_buffer::CharBuffer; + /// use std::borrow::Cow; + /// + /// let c: CharBuffer = CharBuffer::from('a'); + /// let s: Cow = From::from(c); + /// assert_eq!("a", &s[..]); + /// ``` + /// [`Cow<'_, CharBuffer>`]: https://doc.rust-lang.org/std/borrow/enum.Cow.html + #[inline] + fn from(s: CharBuffer) -> Self { + Cow::Owned(s) + } +} + +macro_rules! impl_from_to_ptr { + ( + $(#[$meta:meta])* + $ptr:ident + ) => { + $(#[$meta])* + impl From for $ptr { + #[inline] + fn from(s: CharBuffer) -> Self { + Self::from(&*s) + } + } + + $(#[$meta])* + impl From<&CharBuffer> for $ptr { + #[inline] + fn from(s: &CharBuffer) -> Self { + Self::from(&**s) + } + } + } +} + +impl_from_to_ptr! { + /// Converts a `CharBuffer` into a [`Arc`]. + /// + /// # Example + /// + /// ``` + /// use lapce_core::char_buffer::CharBuffer; + /// use std::sync::Arc; + /// + /// let c: CharBuffer = CharBuffer::from('a'); + /// let s1: Arc = From::from(&c); + /// assert_eq!("a", &s1[..]); + /// + /// let s2: Arc = From::from(c); + /// assert_eq!("a", &s2[..]); + /// ``` + /// [`Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html + Arc +} + +impl_from_to_ptr! { + /// Converts a `CharBuffer` into a [`Box`]. + /// + /// # Example + /// + /// ``` + /// use lapce_core::char_buffer::CharBuffer; + /// + /// let c: CharBuffer = CharBuffer::from('a'); + /// let s1: Box = From::from(&c); + /// assert_eq!("a", &s1[..]); + /// + /// let s2: Box = From::from(c); + /// assert_eq!("a", &s2[..]); + /// ``` + /// [`Box`]: https://doc.rust-lang.org/std/boxed/struct.Box.html + Box +} + +impl_from_to_ptr! { + /// Converts a `CharBuffer` into a [`Rc`]. + /// + /// # Example + /// + /// ``` + /// use lapce_core::char_buffer::CharBuffer; + /// use std::rc::Rc; + /// + /// let c: CharBuffer = CharBuffer::from('a'); + /// let s1: Rc = From::from(&c); + /// assert_eq!("a", &s1[..]); + /// + /// let s2: Rc = From::from(c); + /// assert_eq!("a", &s2[..]); + /// ``` + /// [`Rc`]: https://doc.rust-lang.org/std/rc/struct.Rc.html + Rc +} + +macro_rules! impl_try_from { + ($lhs:ty) => { + impl TryFrom<$lhs> for CharBuffer { + type Error = CharBufferTryFromError; + + fn try_from(str: $lhs) -> Result { + let mut chars = str.chars(); + match (chars.next(), chars.next()) { + (Some(char), None) => Ok(Self::new(char)), + _ => Err(CharBufferTryFromError(())), + } + } + } + }; +} + +impl_try_from!(&str); +impl_try_from!(&mut str); + +impl_try_from!(String); +impl_try_from!(&String); +impl_try_from!(&mut String); + +impl_try_from!(Box); +impl_try_from!(&Box); +impl_try_from!(&mut Box); + +impl_try_from!(Arc); +impl_try_from!(&Arc); +impl_try_from!(&mut Arc); + +impl_try_from!(Rc); +impl_try_from!(&Rc); +impl_try_from!(&mut Rc); + +impl Deref for CharBuffer { + type Target = str; + + #[inline] + fn deref(&self) -> &Self::Target { + // SAFETY: + // - This is the same buffer that we passed to `encode_utf8` during creating this structure, + // so valid utf8 is stored there; + // - The length was directly calculated from the `&str` returned by the `encode_utf8` function + unsafe { str::from_utf8_unchecked(self.buf.get_unchecked(..self.len)) } + } +} + +impl AsRef for CharBuffer { + #[inline] + fn as_ref(&self) -> &str { + self + } +} + +impl Borrow for CharBuffer { + #[inline] + fn borrow(&self) -> &str { + self + } +} + +#[allow(clippy::derive_hash_xor_eq)] +impl hash::Hash for CharBuffer { + #[inline] + fn hash(&self, hasher: &mut H) { + (**self).hash(hasher) + } +} + +impl fmt::Debug for CharBuffer { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&**self, f) + } +} + +impl fmt::Display for CharBuffer { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&**self, f) + } +} + +impl PartialOrd for CharBuffer { + #[inline] + fn partial_cmp(&self, other: &Self) -> Option { + (**self).partial_cmp(&**other) + } +} + +impl Ord for CharBuffer { + #[inline] + fn cmp(&self, other: &Self) -> Ordering { + (**self).cmp(&**other) + } +} + +macro_rules! impl_eq { + ($lhs:ty, $rhs: ty) => { + #[allow(unused_lifetimes)] + impl<'a, 'b> PartialEq<$rhs> for $lhs { + #[inline] + fn eq(&self, other: &$rhs) -> bool { + PartialEq::eq(&self[..], &other[..]) + } + } + + #[allow(unused_lifetimes)] + impl<'a, 'b> PartialEq<$lhs> for $rhs { + #[inline] + fn eq(&self, other: &$lhs) -> bool { + PartialEq::eq(&self[..], &other[..]) + } + } + }; +} + +impl_eq! { CharBuffer, str } +impl_eq! { CharBuffer, &'a str } +impl_eq! { CharBuffer, &'a mut str } + +impl_eq! { CharBuffer, String } +impl_eq! { CharBuffer, &'a String } +impl_eq! { CharBuffer, &'a mut String } + +impl_eq! { Cow<'a, str>, CharBuffer } +impl_eq! { Cow<'_, CharBuffer>, CharBuffer } + +#[allow(clippy::single_match)] +#[test] +fn test_char_buffer() { + #[cfg(miri)] + let mut string = String::from(" + This is some text. Это некоторый текст. Αυτό είναι κάποιο κείμενο. 這是一些文字。" + ); + #[cfg(not(miri))] + let mut string = String::from( + " + https://www.w3.org/2001/06/utf-8-test/UTF-8-demo.html + + Original by Markus Kuhn, adapted for HTML by Martin Dürst. + + UTF-8 encoded sample plain-text file + ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ + + Markus Kuhn [ˈmaʳkʊs kuːn] — 1999-08-20 + + + The ASCII compatible UTF-8 encoding of ISO 10646 and Unicode + plain-text files is defined in RFC 2279 and in ISO 10646-1 Annex R. + + + Using Unicode/UTF-8, you can write in emails and source code things such as + + Mathematics and Sciences: + + ∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i), ∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β), + + ℕ ⊆ ℕ₀ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ, ⊥ < a ≠ b ≡ c ≤ d ≪ ⊤ ⇒ (A ⇔ B), + + 2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm + + Linguistics and dictionaries: + + ði ıntəˈnæʃənəl fəˈnɛtık əsoʊsiˈeıʃn + Y [ˈʏpsilɔn], Yen [jɛn], Yoga [ˈjoːgɑ] + + APL: + + ((V⍳V)=⍳⍴V)/V←,V ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈ + + Nicer typography in plain text files: + + ╔══════════════════════════════════════════╗ + ║ ║ + ║ • ‘single’ and “double” quotes ║ + ║ ║ + ║ • Curly apostrophes: “We’ve been here” ║ + ║ ║ + ║ • Latin-1 apostrophe and accents: '´` ║ + ║ ║ + ║ • ‚deutsche‘ „Anführungszeichen“ ║ + ║ ║ + ║ • †, ‡, ‰, •, 3–4, —, −5/+5, ™, … ║ + ║ ║ + ║ • ASCII safety test: 1lI|, 0OD, 8B ║ + ║ ╭─────────╮ ║ + ║ • the euro symbol: │ 14.95 € │ ║ + ║ ╰─────────╯ ║ + ╚══════════════════════════════════════════╝ + + Greek (in Polytonic): + + The Greek anthem: + + Σὲ γνωρίζω ἀπὸ τὴν κόψη + τοῦ σπαθιοῦ τὴν τρομερή, + σὲ γνωρίζω ἀπὸ τὴν ὄψη + ποὺ μὲ βία μετράει τὴ γῆ. + + ᾿Απ᾿ τὰ κόκκαλα βγαλμένη + τῶν ῾Ελλήνων τὰ ἱερά + καὶ σὰν πρῶτα ἀνδρειωμένη + χαῖρε, ὦ χαῖρε, ᾿Ελευθεριά! + + From a speech of Demosthenes in the 4th century BC: + + Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι, + ὅταν τ᾿ εἰς τὰ πράγματα ἀποβλέψω καὶ ὅταν πρὸς τοὺς + λόγους οὓς ἀκούω· τοὺς μὲν γὰρ λόγους περὶ τοῦ + τιμωρήσασθαι Φίλιππον ὁρῶ γιγνομένους, τὰ δὲ πράγματ᾿ + εἰς τοῦτο προήκοντα, ὥσθ᾿ ὅπως μὴ πεισόμεθ᾿ αὐτοὶ + πρότερον κακῶς σκέψασθαι δέον. οὐδέν οὖν ἄλλο μοι δοκοῦσιν + οἱ τὰ τοιαῦτα λέγοντες ἢ τὴν ὑπόθεσιν, περὶ ἧς βουλεύεσθαι, + οὐχὶ τὴν οὖσαν παριστάντες ὑμῖν ἁμαρτάνειν. ἐγὼ δέ, ὅτι μέν + ποτ᾿ ἐξῆν τῇ πόλει καὶ τὰ αὑτῆς ἔχειν ἀσφαλῶς καὶ Φίλιππον + τιμωρήσασθαι, καὶ μάλ᾿ ἀκριβῶς οἶδα· ἐπ᾿ ἐμοῦ γάρ, οὐ πάλαι + γέγονεν ταῦτ᾿ ἀμφότερα· νῦν μέντοι πέπεισμαι τοῦθ᾿ ἱκανὸν + προλαβεῖν ἡμῖν εἶναι τὴν πρώτην, ὅπως τοὺς συμμάχους + σώσομεν. ἐὰν γὰρ τοῦτο βεβαίως ὑπάρξῃ, τότε καὶ περὶ τοῦ + τίνα τιμωρήσεταί τις καὶ ὃν τρόπον ἐξέσται σκοπεῖν· πρὶν δὲ + τὴν ἀρχὴν ὀρθῶς ὑποθέσθαι, μάταιον ἡγοῦμαι περὶ τῆς + τελευτῆς ὁντινοῦν ποιεῖσθαι λόγον. + + Δημοσθένους, Γ´ ᾿Ολυνθιακὸς + + Georgian: + + From a Unicode conference invitation: + + გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო + კონფერენციაზე დასასწრებად, რომელიც გაიმართება 10-12 მარტს, + ქ. მაინცში, გერმანიაში. კონფერენცია შეჰკრებს ერთად მსოფლიოს + ექსპერტებს ისეთ დარგებში როგორიცაა ინტერნეტი და Unicode-ი, + ინტერნაციონალიზაცია და ლოკალიზაცია, Unicode-ის გამოყენება + ოპერაციულ სისტემებსა, და გამოყენებით პროგრამებში, შრიფტებში, + ტექსტების დამუშავებასა და მრავალენოვან კომპიუტერულ სისტემებში. + + Russian: + + From a Unicode conference invitation: + + Зарегистрируйтесь сейчас на Десятую Международную Конференцию по + Unicode, которая состоится 10-12 марта 1997 года в Майнце в Германии. + Конференция соберет широкий круг экспертов по вопросам глобального + Интернета и Unicode, локализации и интернационализации, воплощению и + применению Unicode в различных операционных системах и программных + приложениях, шрифтах, верстке и многоязычных компьютерных системах. + + Thai (UCS Level 2): + + Excerpt from a poetry on The Romance of The Three Kingdoms (a Chinese + classic 'San Gua'): + + [----------------------------|------------------------] + ๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่ + สิบสองกษัตริย์ก่อนหน้าแลถัดไป สององค์ไซร้โง่เขลาเบาปัญญา + ทรงนับถือขันทีเป็นที่พึ่ง บ้านเมืองจึงวิปริตเป็นนักหนา + โฮจิ๋นเรียกทัพทั่วหัวเมืองมา หมายจะฆ่ามดชั่วตัวสำคัญ + เหมือนขับไสไล่เสือจากเคหา รับหมาป่าเข้ามาเลยอาสัญ + ฝ่ายอ้องอุ้นยุแยกให้แตกกัน ใช้สาวนั้นเป็นชนวนชื่นชวนใจ + พลันลิฉุยกุยกีกลับก่อเหตุ ช่างอาเพศจริงหนาฟ้าร้องไห้ + ต้องรบราฆ่าฟันจนบรรลัย ฤๅหาใครค้ำชูกู้บรรลังก์ ฯ + + (The above is a two-column text. If combining characters are handled + correctly, the lines of the second column should be aligned with the + | character above.) + + Ethiopian: + + Proverbs in the Amharic language: + + ሰማይ አይታረስ ንጉሥ አይከሰስ። + ብላ ካለኝ እንደአባቴ በቆመጠኝ። + ጌጥ ያለቤቱ ቁምጥና ነው። + ደሀ በሕልሙ ቅቤ ባይጠጣ ንጣት በገደለው። + የአፍ ወለምታ በቅቤ አይታሽም። + አይጥ በበላ ዳዋ ተመታ። + ሲተረጉሙ ይደረግሙ። + ቀስ በቀስ፥ ዕንቁላል በእግሩ ይሄዳል። + ድር ቢያብር አንበሳ ያስር። + ሰው እንደቤቱ እንጅ እንደ ጉረቤቱ አይተዳደርም። + እግዜር የከፈተውን ጉሮሮ ሳይዘጋው አይድርም። + የጎረቤት ሌባ፥ ቢያዩት ይስቅ ባያዩት ያጠልቅ። + ሥራ ከመፍታት ልጄን ላፋታት። + ዓባይ ማደሪያ የለው፥ ግንድ ይዞ ይዞራል። + የእስላም አገሩ መካ የአሞራ አገሩ ዋርካ። + ተንጋሎ ቢተፉ ተመልሶ ባፉ። + ወዳጅህ ማር ቢሆን ጨርስህ አትላሰው። + እግርህን በፍራሽህ ልክ ዘርጋ። + + Runes: + + ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ + + (Old English, which transcribed into Latin reads 'He cwaeth that he + bude thaem lande northweardum with tha Westsae.' and means 'He said + that he lived in the northern land near the Western Sea.') + + Braille: + + ⡌⠁⠧⠑ ⠼⠁⠒ ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌ + + ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠙⠑⠁⠙⠒ ⠞⠕ ⠃⠑⠛⠔ ⠺⠊⠹⠲ ⡹⠻⠑ ⠊⠎ ⠝⠕ ⠙⠳⠃⠞ + ⠱⠁⠞⠑⠧⠻ ⠁⠃⠳⠞ ⠹⠁⠞⠲ ⡹⠑ ⠗⠑⠛⠊⠌⠻ ⠕⠋ ⠙⠊⠎ ⠃⠥⠗⠊⠁⠇ ⠺⠁⠎ + ⠎⠊⠛⠝⠫ ⠃⠹ ⠹⠑ ⠊⠇⠻⠛⠹⠍⠁⠝⠂ ⠹⠑ ⠊⠇⠻⠅⠂ ⠹⠑ ⠥⠝⠙⠻⠞⠁⠅⠻⠂ + ⠁⠝⠙ ⠹⠑ ⠡⠊⠑⠋ ⠍⠳⠗⠝⠻⠲ ⡎⠊⠗⠕⠕⠛⠑ ⠎⠊⠛⠝⠫ ⠊⠞⠲ ⡁⠝⠙ + ⡎⠊⠗⠕⠕⠛⠑⠰⠎ ⠝⠁⠍⠑ ⠺⠁⠎ ⠛⠕⠕⠙ ⠥⠏⠕⠝ ⠰⡡⠁⠝⠛⠑⠂ ⠋⠕⠗ ⠁⠝⠹⠹⠔⠛ ⠙⠑ + ⠡⠕⠎⠑ ⠞⠕ ⠏⠥⠞ ⠙⠊⠎ ⠙⠁⠝⠙ ⠞⠕⠲ + + ⡕⠇⠙ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ + + ⡍⠔⠙⠖ ⡊ ⠙⠕⠝⠰⠞ ⠍⠑⠁⠝ ⠞⠕ ⠎⠁⠹ ⠹⠁⠞ ⡊ ⠅⠝⠪⠂ ⠕⠋ ⠍⠹ + ⠪⠝ ⠅⠝⠪⠇⠫⠛⠑⠂ ⠱⠁⠞ ⠹⠻⠑ ⠊⠎ ⠏⠜⠞⠊⠊⠥⠇⠜⠇⠹ ⠙⠑⠁⠙ ⠁⠃⠳⠞ + ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ ⡊ ⠍⠊⠣⠞ ⠙⠁⠧⠑ ⠃⠑⠲ ⠔⠊⠇⠔⠫⠂ ⠍⠹⠎⠑⠇⠋⠂ ⠞⠕ + ⠗⠑⠛⠜⠙ ⠁ ⠊⠕⠋⠋⠔⠤⠝⠁⠊⠇ ⠁⠎ ⠹⠑ ⠙⠑⠁⠙⠑⠌ ⠏⠊⠑⠊⠑ ⠕⠋ ⠊⠗⠕⠝⠍⠕⠝⠛⠻⠹ + ⠔ ⠹⠑ ⠞⠗⠁⠙⠑⠲ ⡃⠥⠞ ⠹⠑ ⠺⠊⠎⠙⠕⠍ ⠕⠋ ⠳⠗ ⠁⠝⠊⠑⠌⠕⠗⠎ + ⠊⠎ ⠔ ⠹⠑ ⠎⠊⠍⠊⠇⠑⠆ ⠁⠝⠙ ⠍⠹ ⠥⠝⠙⠁⠇⠇⠪⠫ ⠙⠁⠝⠙⠎ + ⠩⠁⠇⠇ ⠝⠕⠞ ⠙⠊⠌⠥⠗⠃ ⠊⠞⠂ ⠕⠗ ⠹⠑ ⡊⠳⠝⠞⠗⠹⠰⠎ ⠙⠕⠝⠑ ⠋⠕⠗⠲ ⡹⠳ + ⠺⠊⠇⠇ ⠹⠻⠑⠋⠕⠗⠑ ⠏⠻⠍⠊⠞ ⠍⠑ ⠞⠕ ⠗⠑⠏⠑⠁⠞⠂ ⠑⠍⠏⠙⠁⠞⠊⠊⠁⠇⠇⠹⠂ ⠹⠁⠞ + ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ + + (The first couple of paragraphs of \"A Christmas Carol\" by Dickens) + + Compact font selection example text: + + ABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789 + abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ + –—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвгд + ∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi�⑀₂ἠḂӥẄɐː⍎אԱა + + Greetings in various languages: + + Hello world, Καλημέρα κόσμε, コンニチハ + + Box drawing alignment tests: █ + ▉ + ╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳ + ║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳ + ║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳ + ╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳ + ║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎ + ║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏ + ╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█ + +", + ); + + match CharBuffer::try_from(string.as_str()) { + Ok(_) => panic!("This should fail because of long string"), + Err(_) => {} + } + + match CharBuffer::try_from(string.as_mut_str()) { + Ok(_) => panic!("This should fail because of long string"), + Err(_) => {} + } + + match CharBuffer::try_from(&string) { + Ok(_) => panic!("This should fail because of long string"), + Err(_) => {} + } + + match CharBuffer::try_from(&mut string) { + Ok(_) => panic!("This should fail because of long string"), + Err(_) => {} + } + + match CharBuffer::try_from(string.clone()) { + Ok(_) => panic!("This should fail because of long string"), + Err(_) => {} + } + + let mut some_box: Box = Box::from(string.clone()); + + match CharBuffer::try_from(&some_box) { + Ok(_) => panic!("This should fail because of long string"), + Err(_) => {} + } + + match CharBuffer::try_from(&mut some_box) { + Ok(_) => panic!("This should fail because of long string"), + Err(_) => {} + } + + match CharBuffer::try_from(some_box) { + Ok(_) => panic!("This should fail because of long string"), + Err(_) => {} + } + + let mut some_arc: Arc = Arc::from(string.clone()); + + match CharBuffer::try_from(&some_arc) { + Ok(_) => panic!("This should fail because of long string"), + Err(_) => {} + } + + match CharBuffer::try_from(&mut some_arc) { + Ok(_) => panic!("This should fail because of long string"), + Err(_) => {} + } + + match CharBuffer::try_from(some_arc) { + Ok(_) => panic!("This should fail because of long string"), + Err(_) => {} + } + + let mut some_rc: Rc = Rc::from(string.clone()); + + match CharBuffer::try_from(&some_rc) { + Ok(_) => panic!("This should fail because of long string"), + Err(_) => {} + } + + match CharBuffer::try_from(&mut some_rc) { + Ok(_) => panic!("This should fail because of long string"), + Err(_) => {} + } + + match CharBuffer::try_from(some_rc) { + Ok(_) => panic!("This should fail because of long string"), + Err(_) => {} + } + + let hash_builder = std::collections::hash_map::RandomState::default(); + + fn make_hash(hash_builder: &S, val: &Q) -> u64 + where + Q: std::hash::Hash + ?Sized, + S: core::hash::BuildHasher, + { + use core::hash::Hasher; + let mut state = hash_builder.build_hasher(); + val.hash(&mut state); + state.finish() + } + + for mut char in string.chars() { + let mut char_string = char.to_string(); + + assert_eq!(CharBuffer::new(char), char_string); + assert_eq!(CharBuffer::new(char).as_str(), char_string); + assert_eq!(CharBuffer::new(char).len(), char_string.len()); + assert_eq!(CharBuffer::from(char), char_string); + assert_eq!(CharBuffer::from(&char), char_string); + assert_eq!(CharBuffer::from(&mut char), char_string); + + let char_buf = CharBuffer::new(char); + + assert_eq!( + make_hash(&hash_builder, &char_buf), + make_hash(&hash_builder, &char_string) + ); + + assert_eq!(CharBuffer::new(char), char_buf); + assert_eq!(CharBuffer::new(char), CharBuffer::from(&char_buf)); + assert_eq!(&*char_buf, char_string.as_str()); + assert_eq!(char_buf.as_ref(), char_string.as_str()); + let str: &str = char_buf.borrow(); + assert_eq!(str, char_string.as_str()); + + assert_eq!(char::from(&char_buf), char); + assert_eq!(char::from(char_buf), char); + assert_eq!(String::from(char_buf), char_string); + assert_eq!(String::from(&char_buf), char_string); + + let str: &str = From::from(&char_buf); + assert_eq!(str, char_string); + + let str: Cow = From::from(&char_buf); + assert_eq!(str, char_string); + + let str: Cow = From::from(char_buf); + assert_eq!(str.as_str(), char_string); + + let str: Arc = From::from(char_buf); + assert_eq!(&str[..], char_string); + + let str: Arc = From::from(&char_buf); + assert_eq!(&str[..], char_string); + + let str: Box = From::from(char_buf); + assert_eq!(&str[..], char_string); + + let str: Box = From::from(&char_buf); + assert_eq!(&str[..], char_string); + + let str: Rc = From::from(char_buf); + assert_eq!(&str[..], char_string); + + let str: Rc = From::from(&char_buf); + assert_eq!(&str[..], char_string); + + match CharBuffer::try_from(char_string.as_str()) { + Ok(char_buf) => { + assert_eq!(char_buf, char_string.as_str()); + assert_eq!(char_string.as_str(), char_buf); + } + Err(_) => panic!("This should not fail because of single char"), + } + match CharBuffer::try_from(char_string.as_mut_str()) { + Ok(char_buf) => { + assert_eq!(char_buf, char_string.as_mut_str()); + assert_eq!(char_string.as_mut_str(), char_buf); + } + Err(_) => panic!("This should not fail because of single char"), + } + + match CharBuffer::try_from(&char_string) { + Ok(char_buf) => { + assert_eq!(char_buf, &char_string); + assert_eq!(&char_string, char_buf); + } + Err(_) => panic!("This should not fail because of single char"), + } + match CharBuffer::try_from(&mut char_string) { + Ok(char_buf) => { + assert_eq!(char_buf, &mut char_string); + assert_eq!(&mut char_string, char_buf); + } + Err(_) => panic!("This should not fail because of single char"), + } + match CharBuffer::try_from(char_string.clone()) { + Ok(char_buf) => { + assert_eq!(char_buf, char_string); + assert_eq!(char_string, char_buf); + } + Err(_) => panic!("This should not fail because of single char"), + } + + let mut some_box: Box = Box::from(char_string.clone()); + + match CharBuffer::try_from(&some_box) { + Ok(char_buf) => assert_eq!(char_buf, some_box.as_ref()), + Err(_) => panic!("This should not fail because of single char"), + } + match CharBuffer::try_from(&mut some_box) { + Ok(char_buf) => assert_eq!(char_buf, some_box.as_ref()), + Err(_) => panic!("This should not fail because of single char"), + } + match CharBuffer::try_from(some_box) { + Ok(char_buf) => assert_eq!(char_buf, char_string), + Err(_) => panic!("This should not fail because of single char"), + } + + let mut some_arc: Arc = Arc::from(char_string.clone()); + + match CharBuffer::try_from(&some_arc) { + Ok(char_buf) => assert_eq!(char_buf, some_arc.as_ref()), + Err(_) => panic!("This should not fail because of single char"), + } + match CharBuffer::try_from(&mut some_arc) { + Ok(char_buf) => assert_eq!(char_buf, some_arc.as_ref()), + Err(_) => panic!("This should not fail because of single char"), + } + match CharBuffer::try_from(some_arc) { + Ok(char_buf) => assert_eq!(char_buf, char_string), + Err(_) => panic!("This should not fail because of single char"), + } + + let mut some_rc: Rc = Rc::from(char_string.clone()); + + match CharBuffer::try_from(&some_rc) { + Ok(char_buf) => assert_eq!(char_buf, some_rc.as_ref()), + Err(_) => panic!("This should not fail because of single char"), + } + match CharBuffer::try_from(&mut some_rc) { + Ok(char_buf) => assert_eq!(char_buf, some_rc.as_ref()), + Err(_) => panic!("This should not fail because of single char"), + } + match CharBuffer::try_from(some_rc) { + Ok(char_buf) => assert_eq!(char_buf, char_string), + Err(_) => panic!("This should not fail because of single char"), + } + } +} diff --git a/lapce-core/src/command.rs b/lapce-core/src/command.rs index 43b78390c9..ad04d40fd5 100644 --- a/lapce-core/src/command.rs +++ b/lapce-core/src/command.rs @@ -8,6 +8,7 @@ use crate::movement::{LinePosition, Movement}; EnumIter, Clone, PartialEq, + Eq, Debug, EnumMessage, IntoStaticStr, @@ -29,14 +30,25 @@ pub enum EditCommand { DeleteBackward, #[strum(serialize = "delete_forward")] DeleteForward, + #[strum(serialize = "delete_line")] + DeleteLine, #[strum(serialize = "delete_forward_and_insert")] DeleteForwardAndInsert, + #[strum(serialize = "delete_word_and_insert")] + DeleteWordAndInsert, + #[strum(serialize = "delete_line_and_insert")] + DeleteLineAndInsert, #[strum(serialize = "delete_word_forward")] DeleteWordForward, #[strum(serialize = "delete_word_backward")] DeleteWordBackward, #[strum(serialize = "delete_to_beginning_of_line")] DeleteToBeginningOfLine, + #[strum(serialize = "delete_to_end_of_line")] + DeleteToEndOfLine, + + #[strum(serialize = "delete_to_end_and_insert")] + DeleteToEndOfLineAndInsert, #[strum(message = "Join Lines")] #[strum(serialize = "join_lines")] JoinLines, @@ -66,6 +78,8 @@ pub enum EditCommand { Yank, #[strum(serialize = "paste")] Paste, + #[strum(serialize = "paste_before")] + PasteBefore, #[strum(serialize = "normal_mode")] NormalMode, @@ -83,6 +97,10 @@ pub enum EditCommand { ToggleLinewiseVisualMode, #[strum(serialize = "toggle_blockwise_visual_mode")] ToggleBlockwiseVisualMode, + #[strum(serialize = "duplicate_line_up")] + DuplicateLineUp, + #[strum(serialize = "duplicate_line_down")] + DuplicateLineDown, } #[derive( @@ -91,6 +109,7 @@ pub enum EditCommand { EnumIter, Clone, PartialEq, + Eq, Debug, EnumMessage, IntoStaticStr, @@ -136,6 +155,12 @@ pub enum MoveCommand { NextUnmatchedRightCurlyBracket, #[strum(serialize = "previous_unmatched_left_curly_bracket")] PreviousUnmatchedLeftCurlyBracket, + #[strum(message = "Paragraph forward")] + #[strum(serialize = "paragraph_forward")] + ParagraphForward, + #[strum(message = "Paragraph backward")] + #[strum(serialize = "paragraph_backward")] + ParagraphBackward, } impl MoveCommand { @@ -167,6 +192,8 @@ impl MoveCommand { PreviousUnmatchedLeftBracket => Movement::PreviousUnmatched('('), NextUnmatchedRightCurlyBracket => Movement::NextUnmatched('}'), PreviousUnmatchedLeftCurlyBracket => Movement::PreviousUnmatched('{'), + ParagraphForward => Movement::ParagraphForward, + ParagraphBackward => Movement::ParagraphBackward, } } } @@ -177,6 +204,7 @@ impl MoveCommand { EnumIter, Clone, PartialEq, + Eq, Debug, EnumMessage, IntoStaticStr, @@ -204,6 +232,8 @@ pub enum FocusCommand { SearchForward, #[strum(serialize = "search_backward")] SearchBackward, + #[strum(serialize = "toggle_case_sensitive_search")] + ToggleCaseSensitive, #[strum(serialize = "global_search_refresh")] GlobalSearchRefresh, #[strum(serialize = "clear_search")] @@ -214,8 +244,12 @@ pub enum FocusCommand { ListSelect, #[strum(serialize = "list.next")] ListNext, + #[strum(serialize = "list.next_page")] + ListNextPage, #[strum(serialize = "list.previous")] ListPrevious, + #[strum(serialize = "list.previous_page")] + ListPreviousPage, #[strum(serialize = "list.expand")] ListExpand, #[strum(serialize = "jump_to_next_snippet_placeholder")] @@ -240,6 +274,8 @@ pub enum FocusCommand { ShowCodeActions, #[strum(serialize = "get_completion")] GetCompletion, + #[strum(serialize = "get_signature")] + GetSignature, /// This will close a modal, such as the settings window or completion #[strum(message = "modalを閉じる")] #[strum(serialize = "modal.close")] @@ -247,10 +283,17 @@ pub enum FocusCommand { #[strum(message = "定義へ移動")] #[strum(serialize = "goto_definition")] GotoDefinition, + #[strum(message = "Go to Type Definition")] + #[strum(serialize = "goto_type_definition")] + GotoTypeDefinition, + #[strum(message = "Show Hover")] + #[strum(serialize = "show_hover")] + ShowHover, #[strum(serialize = "jump_location_backward")] JumpLocationBackward, #[strum(serialize = "jump_location_forward")] JumpLocationForward, + #[strum(message = "Next Error in Workspace")] #[strum(serialize = "next_error")] NextError, #[strum(serialize = "previous_error")] @@ -264,6 +307,9 @@ pub enum FocusCommand { #[strum(message = "Code-Lensの切り替え")] #[strum(serialize = "toggle_code_lens")] ToggleCodeLens, + #[strum(message = "Toggle History")] + #[strum(serialize = "toggle_history")] + ToggleHistory, #[strum(serialize = "format_document")] #[strum(message = "文書のformat")] FormatDocument, @@ -278,10 +324,22 @@ pub enum FocusCommand { #[strum(message = "保存")] #[strum(serialize = "save")] Save, + #[strum(message = "Save Without Formatting")] + #[strum(serialize = "save_without_format")] + SaveWithoutFormatting, #[strum(serialize = "save_and_exit")] SaveAndExit, #[strum(serialize = "force_exit")] ForceExit, + #[strum(serialize = "rename_symbol")] + #[strum(message = "Rename Symbol")] + Rename, + #[strum(serialize = "confirm_rename")] + ConfirmRename, + #[strum(serialize = "select_next_syntax_item")] + SelectNextSyntaxItem, + #[strum(serialize = "select_previous_syntax_item")] + SelectPreviousSyntaxItem, } #[derive( @@ -290,6 +348,7 @@ pub enum FocusCommand { EnumIter, Clone, PartialEq, + Eq, Debug, EnumMessage, IntoStaticStr, @@ -311,6 +370,7 @@ pub enum MotionModeCommand { EnumIter, Clone, PartialEq, + Eq, Debug, EnumMessage, IntoStaticStr, diff --git a/lapce-core/src/cursor.rs b/lapce-core/src/cursor.rs index 799d7cdc0a..0a09a31b66 100644 --- a/lapce-core/src/cursor.rs +++ b/lapce-core/src/cursor.rs @@ -1,10 +1,12 @@ +use lapce_xi_rope::{RopeDelta, Transformer}; use serde::{Deserialize, Serialize}; -use xi_rope::{RopeDelta, Transformer}; -use crate::buffer::Buffer; -use crate::mode::{Mode, MotionMode, VisualMode}; -use crate::register::RegisterData; -use crate::selection::{InsertDrift, SelRegion, Selection}; +use crate::{ + buffer::Buffer, + mode::{Mode, MotionMode, VisualMode}, + register::RegisterData, + selection::{InsertDrift, SelRegion, Selection}, +}; #[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)] pub enum ColPosition { @@ -274,6 +276,60 @@ impl Cursor { RegisterData { content, mode } } + /// Return the current selection start and end position for a + /// Single cursor selection + pub fn get_selection(&self) -> Option<(usize, usize)> { + match &self.mode { + CursorMode::Visual { + start, + end, + mode: _, + } => Some((*start, *end)), + CursorMode::Insert(selection) => selection + .regions() + .first() + .map(|region| (region.start, region.end)), + _ => None, + } + } + + pub fn get_line_col_char( + &self, + buffer: &Buffer, + ) -> Option<(usize, usize, usize)> { + match &self.mode { + CursorMode::Normal(offset) => { + let ln_col = buffer.offset_to_line_col(*offset); + Some((ln_col.0, ln_col.1, *offset)) + } + CursorMode::Visual { + start, + end, + mode: _, + } => { + let v = buffer.offset_to_line_col(*start.min(end)); + Some((v.0, v.1, *start)) + } + CursorMode::Insert(selection) => { + if selection.regions().len() > 1 { + return None; + } + + let x = selection.regions().get(0).unwrap(); + let v = buffer.offset_to_line_col(x.start); + + Some((v.0, v.1, x.start)) + } + } + } + + pub fn get_selection_count(&self) -> usize { + match &self.mode { + CursorMode::Insert(selection) => selection.regions().len(), + _ => 0, + } + } + pub fn set_offset(&mut self, offset: usize, modify: bool, new_cursor: bool) { match &self.mode { CursorMode::Normal(old_offset) => { @@ -320,8 +376,7 @@ impl Cursor { } else if modify { let mut new_selection = Selection::new(); if let Some(region) = selection.first() { - let new_region = - SelRegion::new(region.start(), offset, None); + let new_region = SelRegion::new(region.start, offset, None); new_selection.add_region(new_region); } else { new_selection @@ -411,13 +466,13 @@ pub fn get_first_selection_after( let ins = ins.transform_shrink(&del); for el in ins.els.iter() { match el { - xi_rope::DeltaElement::Copy(b, e) => { + lapce_xi_rope::DeltaElement::Copy(b, e) => { // if b == e, ins.inserted_subset() will panic if b == e { return None; } } - xi_rope::DeltaElement::Insert(_) => {} + lapce_xi_rope::DeltaElement::Insert(_) => {} } } @@ -443,7 +498,7 @@ pub fn get_first_selection_after( }); positions - .get(0) + .first() .cloned() .map(Selection::caret) .map(|selection| { diff --git a/lapce-core/src/directory.rs b/lapce-core/src/directory.rs new file mode 100644 index 0000000000..01da03379b --- /dev/null +++ b/lapce-core/src/directory.rs @@ -0,0 +1,128 @@ +use std::path::PathBuf; + +use directories::ProjectDirs; + +use crate::meta::NAME; +pub struct Directory {} + +impl Directory { + fn project_dirs() -> Option { + ProjectDirs::from("dev", "lapce", &NAME) + } + + // Get path of local data directory + // Local data directory differs from data directory + // on some platforms and is not transferred across + // machines + pub fn data_local_directory() -> Option { + match Self::project_dirs() { + Some(dir) => { + let dir = dir.data_local_dir(); + if !dir.exists() { + let _ = std::fs::create_dir_all(dir); + } + Some(dir.to_path_buf()) + } + None => None, + } + } + + /// Get the path to logs directory + /// Each log file is for individual application startup + pub fn logs_directory() -> Option { + if let Some(dir) = Self::data_local_directory() { + let dir = dir.join("logs"); + if !dir.exists() { + let _ = std::fs::create_dir(&dir); + } + Some(dir) + } else { + None + } + } + + /// Get the path to cache directory + pub fn cache_directory() -> Option { + if let Some(dir) = Self::data_local_directory() { + let dir = dir.join("cache"); + if !dir.exists() { + let _ = std::fs::create_dir(&dir); + } + Some(dir) + } else { + None + } + } + + /// Directory to store proxy executables used on local + /// host as well, as ones uploaded to remote host when + /// connecting + pub fn proxy_directory() -> Option { + if let Some(dir) = Self::data_local_directory() { + let dir = dir.join("proxy"); + if !dir.exists() { + let _ = std::fs::create_dir(&dir); + } + Some(dir) + } else { + None + } + } + /// Get the path to the themes folder + /// Themes are stored within as individual toml files + pub fn themes_directory() -> Option { + if let Some(dir) = Self::data_local_directory() { + let dir = dir.join("themes"); + if !dir.exists() { + let _ = std::fs::create_dir(&dir); + } + Some(dir) + } else { + None + } + } + // Get the path to plugins directory + // Each plugin has own directory that contains + // metadata file and plugin wasm + pub fn plugins_directory() -> Option { + if let Some(dir) = Self::data_local_directory() { + let dir = dir.join("plugins"); + if !dir.exists() { + let _ = std::fs::create_dir(&dir); + } + Some(dir) + } else { + None + } + } + + // Config directory contain only configuration files + pub fn config_directory() -> Option { + match Self::project_dirs() { + Some(dir) => { + let dir = dir.config_dir(); + if !dir.exists() { + let _ = std::fs::create_dir_all(dir); + } + Some(dir.to_path_buf()) + } + None => None, + } + } + + pub fn local_socket() -> Option { + Self::data_local_directory().map(|dir| dir.join("local.sock")) + } + + pub fn updates_directory() -> Option { + if let Some(dir) = Self::data_local_directory() { + let dir = dir.join("updates"); + if !dir.exists() { + let _ = std::fs::create_dir(&dir); + } + Some(dir) + } else { + None + } + } +} diff --git a/lapce-core/src/editor.rs b/lapce-core/src/editor.rs index e8ef3dfe89..87275c833e 100644 --- a/lapce-core/src/editor.rs +++ b/lapce-core/src/editor.rs @@ -1,7 +1,7 @@ use std::collections::HashSet; use itertools::Itertools; -use xi_rope::RopeDelta; +use lapce_xi_rope::RopeDelta; use crate::{ buffer::{Buffer, InvalLines}, @@ -11,26 +11,67 @@ use crate::{ register::{Clipboard, Register, RegisterData, RegisterKind}, selection::{InsertDrift, SelRegion, Selection}, syntax::{ - has_unmatched_pair, matching_char, matching_pair_direction, - str_is_pair_left, str_matching_pair, Syntax, + edit::SyntaxEdit, + util::{ + has_unmatched_pair, matching_char, matching_pair_direction, + str_is_pair_left, str_matching_pair, + }, + Syntax, }, - word::{get_word_property, WordProperty}, + word::{get_char_property, CharClassification}, }; +fn format_start_end( + buffer: &Buffer, + start: usize, + end: usize, + is_vertical: bool, + first_non_blank: bool, +) -> (usize, usize) { + if is_vertical { + let start_line = buffer.line_of_offset(start.min(end)); + let end_line = buffer.line_of_offset(end.max(start)); + let start = if first_non_blank { + buffer.first_non_blank_character_on_line(start_line) + } else { + buffer.offset_of_line(start_line) + }; + let end = buffer.offset_of_line(end_line + 1); + (start, end) + } else { + let s = start.min(end); + let e = start.max(end); + (s, e) + } +} -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum EditType { - Other, InsertChars, - InsertNewline, Delete, + DeleteSelection, + InsertNewline, + Cut, + Paste, + Indent, + Outdent, + ToggleComment, + MoveLine, + Completion, + DeleteWord, + DeleteToBeginningOfLine, + DeleteToEndOfLine, + DeleteToEndOfLineAndInsert, + MotionDelete, Undo, Redo, + Other, } impl EditType { /// Checks whether a new undo group should be created between two edits. pub fn breaks_undo_group(self, previous: EditType) -> bool { - self == EditType::Other || self != previous + !((self == EditType::InsertChars || self == EditType::Delete) + && self == previous) } } @@ -42,15 +83,16 @@ impl Editor { buffer: &mut Buffer, s: &str, syntax: Option<&Syntax>, - ) -> Vec<(RopeDelta, InvalLines)> { + auto_closing_matching_pairs: bool, + ) -> Vec<(RopeDelta, InvalLines, SyntaxEdit)> { let mut deltas = Vec::new(); if let CursorMode::Insert(selection) = &cursor.mode { if s.chars().count() != 1 { - let (delta, inval_lines) = + let (delta, inval_lines, edits) = buffer.edit(&[(selection, s)], EditType::InsertChars); let selection = selection.apply_delta(&delta, true, InsertDrift::Default); - deltas.push((delta, inval_lines)); + deltas.push((delta, inval_lines, edits)); cursor.mode = CursorMode::Insert(selection); } else { let c = s.chars().next().unwrap(); @@ -66,9 +108,37 @@ impl Editor { for (idx, region) in selection.regions_mut().iter_mut().enumerate() { let offset = region.end; let cursor_char = buffer.char_at_offset(offset); + let prev_offset = buffer.move_left(offset, Mode::Normal, 1); + let prev_cursor_char = if prev_offset < offset { + buffer.char_at_offset(prev_offset) + } else { + None + }; - if matching_pair_type == Some(false) { - if cursor_char == Some(c) { + // when text is selected, and [,{,(,'," is inserted + // wrap the text with that char and its corresponding closing pair + if region.start != region.end + && (matching_pair_type == Some(true) + || c == '"' + || c == '\'') + { + edits.push(( + Selection::region(region.min(), region.min()), + c.to_string(), + )); + edits_after.push(( + idx, + match c { + '"' => '"', + '\'' => '\'', + _ => matching_char(c).unwrap(), + }, + )); + continue; + } + + if auto_closing_matching_pairs { + if (c == '"' || c == '\'') && cursor_char == Some(c) { // Skip the closing character let new_offset = buffer.next_grapheme_offset(offset, 1, buffer.len()); @@ -77,49 +147,86 @@ impl Editor { continue; } - let line = buffer.line_of_offset(offset); - let line_start = buffer.offset_of_line(line); - if buffer.slice_to_cow(line_start..offset).trim() == "" { - let opening_character = matching_char(c).unwrap(); - if let Some(previous_offset) = buffer.previous_unmatched( - syntax, - opening_character, - offset, - ) { - // Auto-indent closing character to the same level as the opening. - let previous_line = - buffer.line_of_offset(previous_offset); - let line_indent = - buffer.indent_on_line(previous_line); - - let current_selection = - Selection::region(line_start, offset); - - edits.push(( - current_selection, - format!("{line_indent}{c}"), - )); + if matching_pair_type == Some(false) { + if cursor_char == Some(c) { + // Skip the closing character + let new_offset = buffer.next_grapheme_offset( + offset, + 1, + buffer.len(), + ); + + *region = SelRegion::caret(new_offset); continue; } - } - } - if matching_pair_type == Some(true) { - // Create a late edit to insert the closing pair, if allowed. - let is_whitespace_or_punct = cursor_char - .map(|c| { - let prop = get_word_property(c); - prop == WordProperty::Lf - || prop == WordProperty::Space - || prop == WordProperty::Punctuation - }) - .unwrap_or(true); - - if is_whitespace_or_punct { - let insert_after = matching_char(c).unwrap(); - edits_after.push((idx, insert_after)); + let line = buffer.line_of_offset(offset); + let line_start = buffer.offset_of_line(line); + if buffer.slice_to_cow(line_start..offset).trim() == "" { + let opening_character = matching_char(c).unwrap(); + if let Some(previous_offset) = buffer + .previous_unmatched( + syntax, + opening_character, + offset, + ) + { + // Auto-indent closing character to the same level as the opening. + let previous_line = + buffer.line_of_offset(previous_offset); + let line_indent = + buffer.indent_on_line(previous_line); + + let current_selection = + Selection::region(line_start, offset); + + edits.push(( + current_selection, + format!("{line_indent}{c}"), + )); + continue; + } + } } - }; + + if matching_pair_type == Some(true) || c == '"' || c == '\'' + { + // Create a late edit to insert the closing pair, if allowed. + let is_whitespace_or_punct = cursor_char + .map(|c| { + let prop = get_char_property(c); + prop == CharClassification::Lf + || prop == CharClassification::Space + || prop == CharClassification::Punctuation + }) + .unwrap_or(true); + + let should_insert_pair = match c { + '"' | '\'' => { + is_whitespace_or_punct + && prev_cursor_char + .map(|c| { + let prop = get_char_property(c); + prop == CharClassification::Lf + || prop == CharClassification::Space + || prop + == CharClassification::Punctuation + }) + .unwrap_or(true) + } + _ => is_whitespace_or_punct, + }; + + if should_insert_pair { + let insert_after = match c { + '"' => '"', + '\'' => '\'', + _ => matching_char(c).unwrap(), + }; + edits_after.push((idx, insert_after)); + } + }; + } let current_selection = Selection::region(region.start, region.end); @@ -133,7 +240,7 @@ impl Editor { .map(|(selection, content)| (selection, content.as_str())) .collect::>(); - let (delta, inval_lines) = + let (delta, inval_lines, edits) = buffer.edit(&edits, EditType::InsertChars); buffer.set_cursor_before(CursorMode::Insert(selection.clone())); @@ -144,14 +251,14 @@ impl Editor { buffer.set_cursor_after(CursorMode::Insert(selection.clone())); - deltas.push((delta, inval_lines)); + deltas.push((delta, inval_lines, edits)); // Apply late edits let edits_after = edits_after .iter() .map(|(idx, content)| { let region = &selection.regions()[*idx]; ( - Selection::region(region.start, region.end), + Selection::region(region.max(), region.max()), content.to_string(), ) }) @@ -163,17 +270,17 @@ impl Editor { .collect::>(); if !edits_after.is_empty() { - let (delta, inval_lines) = + let (delta, inval_lines, edits) = buffer.edit(&edits_after, EditType::InsertChars); - deltas.push((delta, inval_lines)); + deltas.push((delta, inval_lines, edits)); } // Adjust selection according to previous late edits let mut adjustment = 0; for region in selection.regions_mut().iter_mut().sorted_by( - |region_a, region_b| region_a.start().cmp(®ion_b.start()), + |region_a, region_b| region_a.start.cmp(®ion_b.start), ) { - *region = SelRegion::new( + let new_region = SelRegion::new( region.start + adjustment, region.end + adjustment, None, @@ -181,8 +288,8 @@ impl Editor { if let Some(inserted) = edits_after.iter().find_map(|(selection, str)| { - if selection.last_inserted().map(|r| r.start()) - == Some(region.start()) + if selection.last_inserted().map(|r| r.start) + == Some(region.start) { Some(str) } else { @@ -192,6 +299,8 @@ impl Editor { { adjustment += inserted.len(); } + + *region = new_region; } cursor.mode = CursorMode::Insert(selection); @@ -232,9 +341,8 @@ impl Editor { buffer: &mut Buffer, cursor: &mut Cursor, selection: Selection, - ) -> Vec<(RopeDelta, InvalLines)> { - let mut deltas = Vec::new(); - let mut edits = Vec::new(); + ) -> Vec<(RopeDelta, InvalLines, SyntaxEdit)> { + let mut edits = Vec::with_capacity(selection.regions().len()); let mut extra_edits = Vec::new(); let mut shift = 0i32; for region in selection.regions() { @@ -243,46 +351,47 @@ impl Editor { let line_start = buffer.offset_of_line(line); let line_end = buffer.line_end_offset(line, true); let line_indent = buffer.indent_on_line(line); - let first_half = buffer.slice_to_cow(line_start..offset).to_string(); - let second_half = buffer.slice_to_cow(offset..line_end).to_string(); - - let indent = if has_unmatched_pair(&first_half) { - format!("{}{}", line_indent, buffer.indent_unit()) - } else if second_half.trim().is_empty() { - let next_line_indent = buffer.indent_on_line(line + 1); - if next_line_indent.len() > line_indent.len() { - next_line_indent + let first_half = buffer.slice_to_cow(line_start..offset); + let second_half = buffer.slice_to_cow(offset..line_end); + let second_half = second_half.trim(); + + let new_line_content = { + let indent_storage; + let indent = if has_unmatched_pair(&first_half) { + indent_storage = + format!("{}{}", line_indent, buffer.indent_unit()); + &indent_storage + } else if second_half.is_empty() { + indent_storage = buffer.indent_on_line(line + 1); + if indent_storage.len() > line_indent.len() { + &indent_storage + } else { + &line_indent + } } else { - line_indent.clone() - } - } else { - line_indent.clone() + &line_indent + }; + format!("\n{indent}") }; let selection = Selection::region(region.min(), region.max()); - let content = format!("{}{}", "\n", indent); shift -= (region.max() - region.min()) as i32; - shift += content.len() as i32; - - edits.push((selection, content)); - - for c in first_half.chars().rev() { - if c != ' ' { - if let Some(pair_start) = matching_pair_direction(c) { - if pair_start { - if let Some(c) = matching_char(c) { - if second_half.trim().starts_with(&c.to_string()) { - let selection = Selection::caret( - (region.max() as i32 + shift) as usize, - ); - let content = format!("{}{}", "\n", line_indent); - extra_edits.push((selection.clone(), content)); - } - } + shift += new_line_content.len() as i32; + + edits.push((selection, new_line_content)); + + if let Some(c) = first_half.chars().rev().find(|&c| c != ' ') { + if let Some(true) = matching_pair_direction(c) { + if let Some(c) = matching_char(c) { + if second_half.starts_with(c) { + let selection = Selection::caret( + (region.max() as i32 + shift) as usize, + ); + let content = format!("\n{line_indent}"); + extra_edits.push((selection, content)); } } - break; } } } @@ -290,20 +399,23 @@ impl Editor { let edits = edits .iter() .map(|(selection, s)| (selection, s.as_str())) - .collect::>(); - let (delta, inval_lines) = buffer.edit(&edits, EditType::InsertNewline); + .collect::>(); + let (delta, inval_lines, edits) = + buffer.edit(&edits, EditType::InsertNewline); let mut selection = selection.apply_delta(&delta, true, InsertDrift::Default); - deltas.push((delta, inval_lines)); + + let mut deltas = vec![(delta, inval_lines, edits)]; if !extra_edits.is_empty() { let edits = extra_edits .iter() .map(|(selection, s)| (selection, s.as_str())) - .collect::>(); - let (delta, inval_lines) = buffer.edit(&edits, EditType::InsertNewline); + .collect::>(); + let (delta, inval_lines, edits) = + buffer.edit(&edits, EditType::InsertNewline); selection = selection.apply_delta(&delta, false, InsertDrift::Default); - deltas.push((delta, inval_lines)); + deltas.push((delta, inval_lines, edits)); } cursor.mode = CursorMode::Insert(selection); @@ -319,30 +431,12 @@ impl Editor { end: usize, is_vertical: bool, register: &mut Register, - ) -> Vec<(RopeDelta, InvalLines)> { - fn format_start_end( - buffer: &Buffer, - start: usize, - end: usize, - is_vertical: bool, - ) -> (usize, usize) { - if is_vertical { - let start_line = buffer.line_of_offset(start.min(end)); - let end_line = buffer.line_of_offset(end.max(start)); - let start = buffer.offset_of_line(start_line); - let end = buffer.offset_of_line(end_line + 1); - (start, end) - } else { - let s = start.min(end); - let e = start.max(end); - (s, e) - } - } - + ) -> Vec<(RopeDelta, InvalLines, SyntaxEdit)> { let mut deltas = Vec::new(); match motion_mode { MotionMode::Delete => { - let (start, end) = format_start_end(buffer, start, end, is_vertical); + let (start, end) = + format_start_end(buffer, start, end, is_vertical, false); register.add( RegisterKind::Delete, RegisterData { @@ -355,13 +449,14 @@ impl Editor { }, ); let selection = Selection::region(start, end); - let (delta, inval_lines) = - buffer.edit(&[(&selection, "")], EditType::Delete); + let (delta, inval_lines, edits) = + buffer.edit(&[(&selection, "")], EditType::MotionDelete); cursor.apply_delta(&delta); - deltas.push((delta, inval_lines)); + deltas.push((delta, inval_lines, edits)); } MotionMode::Yank => { - let (start, end) = format_start_end(buffer, start, end, is_vertical); + let (start, end) = + format_start_end(buffer, start, end, is_vertical, false); register.add( RegisterKind::Yank, RegisterData { @@ -376,13 +471,14 @@ impl Editor { } MotionMode::Indent => { let selection = Selection::region(start, end); - let (delta, inval_lines) = Self::do_indent(buffer, selection); - deltas.push((delta, inval_lines)); + let (delta, inval_lines, edits) = Self::do_indent(buffer, selection); + deltas.push((delta, inval_lines, edits)); } MotionMode::Outdent => { let selection = Selection::region(start, end); - let (delta, inval_lines) = Self::do_outdent(buffer, selection); - deltas.push((delta, inval_lines)); + let (delta, inval_lines, edits) = + Self::do_outdent(buffer, selection); + deltas.push((delta, inval_lines, edits)); } } deltas @@ -392,7 +488,7 @@ impl Editor { cursor: &mut Cursor, buffer: &mut Buffer, data: &RegisterData, - ) -> Vec<(RopeDelta, InvalLines)> { + ) -> Vec<(RopeDelta, InvalLines, SyntaxEdit)> { let mut deltas = Vec::new(); match data.mode { VisualMode::Normal => { @@ -407,11 +503,11 @@ impl Editor { } }; let after = cursor.is_insert() || !data.content.contains('\n'); - let (delta, inval_lines) = buffer - .edit(&[(&selection, &data.content)], EditType::InsertChars); + let (delta, inval_lines, edits) = + buffer.edit(&[(&selection, &data.content)], EditType::Paste); let selection = selection.apply_delta(&delta, after, InsertDrift::Default); - deltas.push((delta, inval_lines)); + deltas.push((delta, inval_lines, edits)); if !after { cursor.update_selection(buffer, selection); } else { @@ -458,14 +554,14 @@ impl Editor { (selection, data) } }; - let (delta, inval_lines) = - buffer.edit(&[(&selection, &content)], EditType::InsertChars); + let (delta, inval_lines, edits) = + buffer.edit(&[(&selection, &content)], EditType::Paste); let selection = selection.apply_delta( &delta, cursor.is_insert(), InsertDrift::Default, ); - deltas.push((delta, inval_lines)); + deltas.push((delta, inval_lines, edits)); match cursor.mode { CursorMode::Normal(_) | CursorMode::Visual { .. } => { let offset = selection.min_offset(); @@ -490,7 +586,7 @@ impl Editor { fn do_indent( buffer: &mut Buffer, selection: Selection, - ) -> (RopeDelta, InvalLines) { + ) -> (RopeDelta, InvalLines, SyntaxEdit) { let indent = buffer.indent_unit(); let mut edits = Vec::new(); @@ -505,27 +601,25 @@ impl Editor { } } for line in start_line..=end_line { - if lines.contains(&line) { - continue; - } - lines.insert(line); - let line_content = buffer.line_content(line); - if line_content == "\n" || line_content == "\r\n" { - continue; + if lines.insert(line) { + let line_content = buffer.line_content(line); + if line_content == "\n" || line_content == "\r\n" { + continue; + } + let nonblank = buffer.first_non_blank_character_on_line(line); + let edit = crate::indent::create_edit(buffer, nonblank, indent); + edits.push(edit); } - let nonblank = buffer.first_non_blank_character_on_line(line); - let edit = crate::indent::create_edit(buffer, nonblank, indent); - edits.push(edit); } } - buffer.edit(&edits, EditType::InsertChars) + buffer.edit(&edits, EditType::Indent) } fn do_outdent( buffer: &mut Buffer, selection: Selection, - ) -> (RopeDelta, InvalLines) { + ) -> (RopeDelta, InvalLines, SyntaxEdit) { let indent = buffer.indent_unit(); let mut edits = Vec::new(); @@ -540,24 +634,68 @@ impl Editor { } } for line in start_line..=end_line { - if lines.contains(&line) { - continue; - } - lines.insert(line); - let line_content = buffer.line_content(line); - if line_content == "\n" || line_content == "\r\n" { - continue; - } - let nonblank = buffer.first_non_blank_character_on_line(line); - if let Some(edit) = - crate::indent::create_outdent(buffer, nonblank, indent) - { - edits.push(edit); + if lines.insert(line) { + let line_content = buffer.line_content(line); + if line_content == "\n" || line_content == "\r\n" { + continue; + } + let nonblank = buffer.first_non_blank_character_on_line(line); + if let Some(edit) = + crate::indent::create_outdent(buffer, nonblank, indent) + { + edits.push(edit); + } } } } - buffer.edit(&edits, EditType::Delete) + buffer.edit(&edits, EditType::Outdent) + } + + fn duplicate_line( + cursor: &mut Cursor, + buffer: &mut Buffer, + direction: DuplicateDirection, + ) -> Vec<(RopeDelta, InvalLines, SyntaxEdit)> { + // TODO other modes + let selection = match cursor.mode { + CursorMode::Insert(ref mut sel) => sel, + _ => return vec![], + }; + + let mut line_ranges = HashSet::new(); + for region in selection.regions_mut() { + let start_line = buffer.line_of_offset(region.start); + let end_line = buffer.line_of_offset(region.end) + 1; + + line_ranges.insert(start_line..end_line); + } + + let mut edits = vec![]; + for range in line_ranges { + let start = buffer.offset_of_line(range.start); + let end = buffer.offset_of_line(range.end); + + let content = buffer.slice_to_cow(start..end).into_owned(); + edits.push(( + match direction { + DuplicateDirection::Up => Selection::caret(end), + DuplicateDirection::Down => Selection::caret(start), + }, + content, + )); + } + + let edits = edits + .iter() + .map(|(sel, content)| (sel, content.as_str())) + .collect::>(); + + let (delta, inval_lines, edits) = buffer.edit(&edits, EditType::InsertChars); + + *selection = selection.apply_delta(&delta, true, InsertDrift::Default); + + vec![(delta, inval_lines, edits)] } pub fn do_edit( @@ -568,7 +706,7 @@ impl Editor { clipboard: &mut T, modal: bool, register: &mut Register, - ) -> Vec<(RopeDelta, InvalLines)> { + ) -> Vec<(RopeDelta, InvalLines, SyntaxEdit)> { use crate::command::EditCommand::*; match cmd { MoveLineUp => { @@ -585,7 +723,7 @@ impl Editor { let end = buffer.offset_of_line(end_line + 1); let content = buffer.slice_to_cow(start..end).to_string(); - let (delta, inval_lines) = buffer.edit( + let (delta, inval_lines, edits) = buffer.edit( &[ (&Selection::region(start, end), ""), ( @@ -595,9 +733,9 @@ impl Editor { &content, ), ], - EditType::InsertChars, + EditType::MoveLine, ); - deltas.push((delta, inval_lines)); + deltas.push((delta, inval_lines, edits)); region.start -= previous_line_len; region.end -= previous_line_len; } @@ -621,7 +759,7 @@ impl Editor { let end = buffer.offset_of_line(end_line + 1); let content = buffer.slice_to_cow(start..end).to_string(); - let (delta, inval_lines) = buffer.edit( + let (delta, inval_lines, edits) = buffer.edit( &[ ( &Selection::caret( @@ -631,9 +769,9 @@ impl Editor { ), (&Selection::region(start, end), ""), ], - EditType::InsertChars, + EditType::MoveLine, ); - deltas.push((delta, inval_lines)); + deltas.push((delta, inval_lines, edits)); region.start += next_line_len; region.end += next_line_len; } @@ -683,20 +821,20 @@ impl Editor { } } - let (delta, inval_lines) = + let (delta, inval_lines, edits) = buffer.edit(&edits, EditType::InsertChars); let selection = selection.apply_delta(&delta, true, InsertDrift::Default); - deltas.push((delta, inval_lines)); + deltas.push((delta, inval_lines, edits)); cursor.mode = CursorMode::Insert(selection); } deltas } IndentLine => { let selection = cursor.edit_selection(buffer); - let (delta, inval_lines) = Self::do_indent(buffer, selection); + let (delta, inval_lines, edits) = Self::do_indent(buffer, selection); cursor.apply_delta(&delta); - vec![(delta, inval_lines)] + vec![(delta, inval_lines, edits)] } JoinLines => { let offset = cursor.offset(); @@ -714,9 +852,10 @@ impl Editor { } OutdentLine => { let selection = cursor.edit_selection(buffer); - let (delta, inval_lines) = Self::do_outdent(buffer, selection); + let (delta, inval_lines, edits) = + Self::do_outdent(buffer, selection); cursor.apply_delta(&delta); - vec![(delta, inval_lines)] + vec![(delta, inval_lines, edits)] } ToggleLineComment => { let mut lines = HashSet::new(); @@ -745,7 +884,7 @@ impl Editor { if indent < smallest_indent { smallest_indent = indent; } - if !trimmed_content.starts_with(&comment_token) { + if !trimmed_content.starts_with(comment_token) { had_comment = false; lines.insert((line, indent, 0)); } else { @@ -756,14 +895,14 @@ impl Editor { line, indent, comment_token.len() - + if had_space_after_comment { 1 } else { 0 }, + + usize::from(had_space_after_comment), )); } line += 1; } } - let (delta, inval_lines) = if had_comment { + let (delta, inval_lines, edits) = if had_comment { let mut selection = Selection::new(); for (line, indent, len) in lines.iter() { let start = buffer.offset_of_line(*line) + indent; @@ -773,7 +912,7 @@ impl Editor { None, )) } - buffer.edit(&[(&selection, "")], EditType::Delete) + buffer.edit(&[(&selection, "")], EditType::ToggleComment) } else { let mut selection = Selection::new(); for (line, _, _) in lines.iter() { @@ -782,20 +921,26 @@ impl Editor { } buffer.edit( &[(&selection, &format!("{comment_token} "))], - EditType::InsertChars, + EditType::ToggleComment, ) }; cursor.apply_delta(&delta); - vec![(delta, inval_lines)] + vec![(delta, inval_lines, edits)] } Undo => { - if let Some((delta, inval_lines, cursor_mode)) = buffer.do_undo() { + if let Some((delta, inval_lines, edits, cursor_mode)) = + buffer.do_undo() + { if let Some(cursor_mode) = cursor_mode { - if modal { - cursor.mode = CursorMode::Normal(cursor_mode.offset()); + cursor.mode = if modal { + CursorMode::Normal(cursor_mode.offset()) + } else if cursor.is_insert() { + cursor_mode } else { - cursor.mode = cursor_mode; - } + CursorMode::Insert(Selection::caret( + cursor_mode.offset(), + )) + }; } else if let Some(new_cursor) = get_first_selection_after(cursor, buffer, &delta) { @@ -803,19 +948,25 @@ impl Editor { } else { cursor.apply_delta(&delta); } - vec![(delta, inval_lines)] + vec![(delta, inval_lines, edits)] } else { vec![] } } Redo => { - if let Some((delta, inval_lines, cursor_mode)) = buffer.do_redo() { + if let Some((delta, inval_lines, edits, cursor_mode)) = + buffer.do_redo() + { if let Some(cursor_mode) = cursor_mode { - if modal { - cursor.mode = CursorMode::Normal(cursor_mode.offset()); + cursor.mode = if modal { + CursorMode::Normal(cursor_mode.offset()) + } else if cursor.is_insert() { + cursor_mode } else { - cursor.mode = cursor_mode; - } + CursorMode::Insert(Selection::caret( + cursor_mode.offset(), + )) + }; } else if let Some(new_cursor) = get_first_selection_after(cursor, buffer, &delta) { @@ -823,7 +974,7 @@ impl Editor { } else { cursor.apply_delta(&delta); } - vec![(delta, inval_lines)] + vec![(delta, inval_lines, edits)] } else { vec![] } @@ -867,12 +1018,12 @@ impl Editor { cursor.edit_selection(buffer) }; - let (delta, inval_lines) = - buffer.edit(&[(&selection, "")], EditType::Delete); + let (delta, inval_lines, edits) = + buffer.edit(&[(&selection, "")], EditType::Cut); let selection = selection.apply_delta(&delta, true, InsertDrift::Default); cursor.update_selection(buffer, selection); - vec![(delta, inval_lines)] + vec![(delta, inval_lines, edits)] } ClipboardPaste => { if let Some(s) = clipboard.get_string() { @@ -907,6 +1058,14 @@ impl Editor { let data = register.unnamed.clone(); Self::do_paste(cursor, buffer, &data) } + PasteBefore => { + let offset = cursor.offset(); + let data = register.unnamed.clone(); + let mut local_cursor = + Cursor::new(CursorMode::Insert(Selection::new()), None, None); + local_cursor.set_offset(offset, false, false); + Self::do_paste(&mut local_cursor, buffer, &data) + } NewLineAbove => { let offset = cursor.offset(); let line = buffer.line_of_offset(offset); @@ -928,13 +1087,21 @@ impl Editor { Self::insert_new_line(buffer, cursor, Selection::caret(offset)) } DeleteBackward => { - let selection = match cursor.mode { - CursorMode::Normal(_) | CursorMode::Visual { .. } => { - cursor.edit_selection(buffer) + let (selection, edit_type) = match cursor.mode { + CursorMode::Normal(_) => { + (cursor.edit_selection(buffer), EditType::Delete) + } + CursorMode::Visual { .. } => { + (cursor.edit_selection(buffer), EditType::DeleteSelection) } CursorMode::Insert(_) => { - let indent = buffer.indent_unit(); let selection = cursor.edit_selection(buffer); + let edit_type = if selection.is_caret() { + EditType::Delete + } else { + EditType::DeleteSelection + }; + let indent = buffer.indent_unit(); let mut new_selection = Selection::new(); for region in selection.regions() { let new_region = if region.is_caret() { @@ -982,8 +1149,16 @@ impl Editor { selection.min_offset()..selection.max_offset(), ) .to_string(); - if str_is_pair_left(&delete_str) { - if let Some(c) = str_matching_pair(&delete_str) { + if str_is_pair_left(&delete_str) + || delete_str == "\"" + || delete_str == "'" + { + let matching_char = match delete_str.as_str() { + "\"" => Some('"'), + "'" => Some('\''), + _ => str_matching_pair(&delete_str), + }; + if let Some(c) = matching_char { let offset = selection.max_offset(); let line = buffer.line_of_offset(offset); let line_end = @@ -1005,23 +1180,31 @@ impl Editor { } } } - selection + (selection, edit_type) } }; - let (delta, inval_lines) = - buffer.edit(&[(&selection, "")], EditType::Delete); + let (delta, inval_lines, edits) = + buffer.edit(&[(&selection, "")], edit_type); let selection = selection.apply_delta(&delta, true, InsertDrift::Default); cursor.update_selection(buffer, selection); - vec![(delta, inval_lines)] + vec![(delta, inval_lines, edits)] } DeleteForward => { - let selection = match cursor.mode { - CursorMode::Normal(_) | CursorMode::Visual { .. } => { - cursor.edit_selection(buffer) + let (selection, edit_type) = match cursor.mode { + CursorMode::Normal(_) => { + (cursor.edit_selection(buffer), EditType::Delete) + } + CursorMode::Visual { .. } => { + (cursor.edit_selection(buffer), EditType::DeleteSelection) } CursorMode::Insert(_) => { let selection = cursor.edit_selection(buffer); + let edit_type = if selection.is_caret() { + EditType::Delete + } else { + EditType::DeleteSelection + }; let mut new_selection = Selection::new(); for region in selection.regions() { let new_region = if region.is_caret() { @@ -1033,15 +1216,32 @@ impl Editor { }; new_selection.add_region(new_region); } - new_selection + (new_selection, edit_type) } }; - let (delta, inval_lines) = - buffer.edit(&[(&selection, "")], EditType::Delete); + let (delta, inval_lines, edits) = + buffer.edit(&[(&selection, "")], edit_type); let selection = selection.apply_delta(&delta, true, InsertDrift::Default); cursor.update_selection(buffer, selection); - vec![(delta, inval_lines)] + vec![(delta, inval_lines, edits)] + } + DeleteLine => { + let selection = cursor.edit_selection(buffer); + let (start, end) = format_start_end( + buffer, + selection.min_offset(), + selection.max_offset(), + true, + true, + ); + let selection = Selection::region(start, end); + let (delta, inval_lines, edits) = + buffer.edit(&[(&selection, "")], EditType::Delete); + let selection = + selection.apply_delta(&delta, true, InsertDrift::Default); + cursor.mode = CursorMode::Insert(selection); + vec![(delta, inval_lines, edits)] } DeleteWordForward => { let selection = match cursor.mode { @@ -1061,12 +1261,12 @@ impl Editor { new_selection } }; - let (delta, inval_lines) = - buffer.edit(&[(&selection, "")], EditType::Delete); + let (delta, inval_lines, edits) = + buffer.edit(&[(&selection, "")], EditType::DeleteWord); let selection = selection.apply_delta(&delta, true, InsertDrift::Default); cursor.update_selection(buffer, selection); - vec![(delta, inval_lines)] + vec![(delta, inval_lines, edits)] } DeleteWordBackward => { let selection = match cursor.mode { @@ -1078,7 +1278,7 @@ impl Editor { let selection = cursor.edit_selection(buffer); for region in selection.regions() { - let end = buffer.move_word_backward(region.end); + let end = buffer.move_word_backward_deletion(region.end); let new_region = SelRegion::new(region.start, end, None); new_selection.add_region(new_region); } @@ -1086,12 +1286,12 @@ impl Editor { new_selection } }; - let (delta, inval_lines) = - buffer.edit(&[(&selection, "")], EditType::Delete); + let (delta, inval_lines, edits) = + buffer.edit(&[(&selection, "")], EditType::DeleteWord); let selection = selection.apply_delta(&delta, true, InsertDrift::Default); cursor.update_selection(buffer, selection); - vec![(delta, inval_lines)] + vec![(delta, inval_lines, edits)] } DeleteToBeginningOfLine => { let selection = match cursor.mode { @@ -1112,21 +1312,101 @@ impl Editor { new_selection } }; - let (delta, inval_lines) = - buffer.edit(&[(&selection, "")], EditType::Delete); + let (delta, inval_lines, edits) = buffer + .edit(&[(&selection, "")], EditType::DeleteToBeginningOfLine); let selection = selection.apply_delta(&delta, true, InsertDrift::Default); cursor.update_selection(buffer, selection); - vec![(delta, inval_lines)] + vec![(delta, inval_lines, edits)] + } + DeleteToEndOfLine => { + let selection = match cursor.mode { + CursorMode::Normal(_) | CursorMode::Visual { .. } => { + cursor.edit_selection(buffer) + } + CursorMode::Insert(_) => { + let mut selection = cursor.edit_selection(buffer); + + let cursor_offset = cursor.offset(); + let line = buffer.line_of_offset(cursor_offset); + let end_of_line_offset = buffer.line_end_offset(line, true); + let new_region = + SelRegion::new(cursor_offset, end_of_line_offset, None); + selection.add_region(new_region); + + selection + } + }; + let (delta, inval_lines, edits) = + buffer.edit(&[(&selection, "")], EditType::DeleteToEndOfLine); + let selection = + selection.apply_delta(&delta, true, InsertDrift::Default); + cursor.update_selection(buffer, selection); + vec![(delta, inval_lines, edits)] } DeleteForwardAndInsert => { let selection = cursor.edit_selection(buffer); - let (delta, inval_lines) = + let (delta, inval_lines, edits) = + buffer.edit(&[(&selection, "")], EditType::Delete); + let selection = + selection.apply_delta(&delta, true, InsertDrift::Default); + cursor.mode = CursorMode::Insert(selection); + vec![(delta, inval_lines, edits)] + } + DeleteWordAndInsert => { + let selection = { + let mut new_selection = Selection::new(); + let selection = cursor.edit_selection(buffer); + + for region in selection.regions() { + let end = buffer.move_word_forward(region.end); + let new_region = SelRegion::new(region.start, end, None); + new_selection.add_region(new_region); + } + + new_selection + }; + let (delta, inval_lines, edits) = + buffer.edit(&[(&selection, "")], EditType::DeleteWord); + let selection = + selection.apply_delta(&delta, true, InsertDrift::Default); + cursor.mode = CursorMode::Insert(selection); + vec![(delta, inval_lines, edits)] + } + DeleteLineAndInsert => { + let selection = cursor.edit_selection(buffer); + let (start, end) = format_start_end( + buffer, + selection.min_offset(), + selection.max_offset(), + true, + true, + ); + let selection = Selection::region(start, end - 1); // -1 because we want to keep the line itself + let (delta, inval_lines, edits) = + buffer.edit(&[(&selection, "")], EditType::Delete); + let selection = + selection.apply_delta(&delta, true, InsertDrift::Default); + cursor.mode = CursorMode::Insert(selection); + vec![(delta, inval_lines, edits)] + } + DeleteToEndOfLineAndInsert => { + let mut selection = cursor.edit_selection(buffer); + + let cursor_offset = cursor.offset(); + let line = buffer.line_of_offset(cursor_offset); + let end_of_line_offset = buffer.line_end_offset(line, true); + + let new_region = + SelRegion::new(cursor_offset, end_of_line_offset, None); + selection.add_region(new_region); + + let (delta, inval_lines, edits) = buffer.edit(&[(&selection, "")], EditType::Delete); let selection = selection.apply_delta(&delta, true, InsertDrift::Default); cursor.mode = CursorMode::Insert(selection); - vec![(delta, inval_lines)] + vec![(delta, inval_lines, edits)] } NormalMode => { if !modal { @@ -1198,7 +1478,13 @@ impl Editor { vec![] } Append => { - let offset = buffer.move_right(cursor.offset(), Mode::Insert, 1); + let offset = cursor.offset(); + let line = buffer.line_of_offset(offset); + let line_len = buffer.line_len(line); + let count = (line_len > 1 + || (buffer.last_line() == line && line_len > 0)) + as usize; + let offset = buffer.move_right(cursor.offset(), Mode::Insert, count); cursor.mode = CursorMode::Insert(Selection::caret(offset)); vec![] } @@ -1221,16 +1507,29 @@ impl Editor { Self::toggle_visual(cursor, VisualMode::Blockwise, modal); vec![] } + DuplicateLineUp => { + Self::duplicate_line(cursor, buffer, DuplicateDirection::Up) + } + DuplicateLineDown => { + Self::duplicate_line(cursor, buffer, DuplicateDirection::Down) + } } } } +enum DuplicateDirection { + Up, + Down, +} + #[cfg(test)] mod test { - use crate::buffer::Buffer; - use crate::cursor::{Cursor, CursorMode}; - use crate::editor::Editor; - use crate::selection::{SelRegion, Selection}; + use crate::{ + buffer::Buffer, + cursor::{Cursor, CursorMode}, + editor::{DuplicateDirection, Editor}, + selection::{SelRegion, Selection}, + }; #[test] fn test_insert_simple() { @@ -1238,7 +1537,7 @@ mod test { let mut cursor = Cursor::new(CursorMode::Insert(Selection::caret(1)), None, None); - Editor::insert(&mut cursor, &mut buffer, "e", None); + Editor::insert(&mut cursor, &mut buffer, "e", None, true); assert_eq!("aebc", buffer.slice_to_cow(0..buffer.len())); } @@ -1250,7 +1549,7 @@ mod test { selection.add_region(SelRegion::caret(5)); let mut cursor = Cursor::new(CursorMode::Insert(selection), None, None); - Editor::insert(&mut cursor, &mut buffer, "i", None); + Editor::insert(&mut cursor, &mut buffer, "i", None, true); assert_eq!("aibc\neifg\n", buffer.slice_to_cow(0..buffer.len())); } @@ -1262,13 +1561,13 @@ mod test { selection.add_region(SelRegion::caret(5)); let mut cursor = Cursor::new(CursorMode::Insert(selection), None, None); - Editor::insert(&mut cursor, &mut buffer, "i", None); + Editor::insert(&mut cursor, &mut buffer, "i", None, true); assert_eq!("aibc\neifg\n", buffer.slice_to_cow(0..buffer.len())); - Editor::insert(&mut cursor, &mut buffer, "j", None); + Editor::insert(&mut cursor, &mut buffer, "j", None, true); assert_eq!("aijbc\neijfg\n", buffer.slice_to_cow(0..buffer.len())); - Editor::insert(&mut cursor, &mut buffer, "{", None); + Editor::insert(&mut cursor, &mut buffer, "{", None, true); assert_eq!("aij{bc\neij{fg\n", buffer.slice_to_cow(0..buffer.len())); - Editor::insert(&mut cursor, &mut buffer, " ", None); + Editor::insert(&mut cursor, &mut buffer, " ", None, true); assert_eq!("aij{ bc\neij{ fg\n", buffer.slice_to_cow(0..buffer.len())); } @@ -1280,9 +1579,189 @@ mod test { selection.add_region(SelRegion::caret(6)); let mut cursor = Cursor::new(CursorMode::Insert(selection), None, None); - Editor::insert(&mut cursor, &mut buffer, "{", None); + Editor::insert(&mut cursor, &mut buffer, "{", None, true); assert_eq!("a{} bc\ne{} fg\n", buffer.slice_to_cow(0..buffer.len())); - Editor::insert(&mut cursor, &mut buffer, "}", None); + Editor::insert(&mut cursor, &mut buffer, "}", None, true); + assert_eq!("a{} bc\ne{} fg\n", buffer.slice_to_cow(0..buffer.len())); + } + + #[test] + fn test_insert_pair_with_selection() { + let mut buffer = Buffer::new("a bc\ne fg\n"); + let mut selection = Selection::new(); + selection.add_region(SelRegion::new(0, 4, None)); + selection.add_region(SelRegion::new(5, 9, None)); + let mut cursor = Cursor::new(CursorMode::Insert(selection), None, None); + Editor::insert(&mut cursor, &mut buffer, "{", None, true); + assert_eq!("{a bc}\n{e fg}\n", buffer.slice_to_cow(0..buffer.len())); + } + + #[test] + fn test_insert_pair_without_auto_closing() { + let mut buffer = Buffer::new("a bc\ne fg\n"); + let mut selection = Selection::new(); + selection.add_region(SelRegion::caret(1)); + selection.add_region(SelRegion::caret(6)); + let mut cursor = Cursor::new(CursorMode::Insert(selection), None, None); + + Editor::insert(&mut cursor, &mut buffer, "{", None, false); + assert_eq!("a{ bc\ne{ fg\n", buffer.slice_to_cow(0..buffer.len())); + Editor::insert(&mut cursor, &mut buffer, "}", None, false); assert_eq!("a{} bc\ne{} fg\n", buffer.slice_to_cow(0..buffer.len())); } + + #[test] + fn duplicate_down_simple() { + let mut buffer = Buffer::new("first line\nsecond line\n"); + let mut selection = Selection::new(); + selection.add_region(SelRegion::caret(0)); + let mut cursor = Cursor::new(CursorMode::Insert(selection), None, None); + + Editor::duplicate_line(&mut cursor, &mut buffer, DuplicateDirection::Down); + + assert_ne!(cursor.offset(), 0); + assert_eq!( + "first line\nfirst line\nsecond line\n", + buffer.slice_to_cow(0..buffer.len()) + ); + } + + #[test] + fn duplicate_up_simple() { + let mut buffer = Buffer::new("first line\nsecond line\n"); + let mut selection = Selection::new(); + selection.add_region(SelRegion::caret(0)); + let mut cursor = Cursor::new(CursorMode::Insert(selection), None, None); + + Editor::duplicate_line(&mut cursor, &mut buffer, DuplicateDirection::Up); + + assert_eq!(cursor.offset(), 0); + assert_eq!( + "first line\nfirst line\nsecond line\n", + buffer.slice_to_cow(0..buffer.len()) + ); + } + + #[test] + fn duplicate_down_multiple_cursors_in_same_line() { + let mut buffer = Buffer::new("first line\nsecond line\n"); + let mut selection = Selection::new(); + selection.add_region(SelRegion::caret(0)); + selection.add_region(SelRegion::caret(1)); + let mut cursor = Cursor::new(CursorMode::Insert(selection), None, None); + + Editor::duplicate_line(&mut cursor, &mut buffer, DuplicateDirection::Down); + + assert_eq!( + "first line\nfirst line\nsecond line\n", + buffer.slice_to_cow(0..buffer.len()) + ); + } + + #[test] + fn duplicate_up_multiple_cursors_in_same_line() { + let mut buffer = Buffer::new("first line\nsecond line\n"); + let mut selection = Selection::new(); + selection.add_region(SelRegion::caret(0)); + selection.add_region(SelRegion::caret(1)); + let mut cursor = Cursor::new(CursorMode::Insert(selection), None, None); + + Editor::duplicate_line(&mut cursor, &mut buffer, DuplicateDirection::Up); + + assert_eq!( + "first line\nfirst line\nsecond line\n", + buffer.slice_to_cow(0..buffer.len()) + ); + } + + #[test] + fn duplicate_down_multiple() { + let mut buffer = Buffer::new("first line\nsecond line\n"); + let mut selection = Selection::new(); + selection.add_region(SelRegion::caret(0)); + selection.add_region(SelRegion::caret(15)); + let mut cursor = Cursor::new(CursorMode::Insert(selection), None, None); + + Editor::duplicate_line(&mut cursor, &mut buffer, DuplicateDirection::Down); + + assert_eq!( + "first line\nfirst line\nsecond line\nsecond line\n", + buffer.slice_to_cow(0..buffer.len()) + ); + } + + #[test] + fn duplicate_up_multiple() { + let mut buffer = Buffer::new("first line\nsecond line\n"); + let mut selection = Selection::new(); + selection.add_region(SelRegion::caret(0)); + selection.add_region(SelRegion::caret(15)); + let mut cursor = Cursor::new(CursorMode::Insert(selection), None, None); + + Editor::duplicate_line(&mut cursor, &mut buffer, DuplicateDirection::Up); + + assert_eq!( + "first line\nfirst line\nsecond line\nsecond line\n", + buffer.slice_to_cow(0..buffer.len()) + ); + } + + #[test] + fn duplicate_down_multiple_with_swapped_cursor_order() { + let mut buffer = Buffer::new("first line\nsecond line\n"); + let mut selection = Selection::new(); + selection.add_region(SelRegion::caret(15)); + selection.add_region(SelRegion::caret(0)); + let mut cursor = Cursor::new(CursorMode::Insert(selection), None, None); + + Editor::duplicate_line(&mut cursor, &mut buffer, DuplicateDirection::Down); + + assert_eq!( + "first line\nfirst line\nsecond line\nsecond line\n", + buffer.slice_to_cow(0..buffer.len()) + ); + } + + #[test] + fn duplicate_up_multiple_with_swapped_cursor_order() { + let mut buffer = Buffer::new("first line\nsecond line\n"); + let mut selection = Selection::new(); + selection.add_region(SelRegion::caret(15)); + selection.add_region(SelRegion::caret(0)); + let mut cursor = Cursor::new(CursorMode::Insert(selection), None, None); + + Editor::duplicate_line(&mut cursor, &mut buffer, DuplicateDirection::Up); + + assert_eq!( + "first line\nfirst line\nsecond line\nsecond line\n", + buffer.slice_to_cow(0..buffer.len()) + ); + } + + #[test] + fn check_multiple_cursor_match_insertion() { + let mut buffer = Buffer::new(" 123 567 9ab def"); + let mut selection = Selection::new(); + selection.add_region(SelRegion::caret(0)); + selection.add_region(SelRegion::caret(4)); + selection.add_region(SelRegion::caret(8)); + selection.add_region(SelRegion::caret(12)); + let mut cursor = Cursor::new(CursorMode::Insert(selection), None, None); + + Editor::insert(&mut cursor, &mut buffer, "(", None, true); + + assert_eq!( + "() 123() 567() 9ab() def", + buffer.slice_to_cow(0..buffer.len()) + ); + + let mut end_selection = Selection::new(); + end_selection.add_region(SelRegion::caret(1)); + end_selection.add_region(SelRegion::caret(7)); + end_selection.add_region(SelRegion::caret(13)); + end_selection.add_region(SelRegion::caret(19)); + assert_eq!(cursor.mode, CursorMode::Insert(end_selection)); + } + + // TODO(dbuga): add tests duplicating selections (multiple line blocks) } diff --git a/lapce-core/src/encoding.rs b/lapce-core/src/encoding.rs new file mode 100644 index 0000000000..17975af394 --- /dev/null +++ b/lapce-core/src/encoding.rs @@ -0,0 +1,163 @@ +/// Convert a utf8 offset into a utf16 offset, if possible +/// `text` is what the offsets are into +pub fn offset_utf8_to_utf16( + char_indices: impl Iterator, + offset: usize, +) -> usize { + if offset == 0 { + return 0; + } + + let mut utf16_offset = 0; + let mut last_ich = None; + for (utf8_offset, ch) in char_indices { + last_ich = Some((utf8_offset, ch)); + + match utf8_offset.cmp(&offset) { + std::cmp::Ordering::Less => {} + // We found the right offset + std::cmp::Ordering::Equal => { + return utf16_offset; + } + // Implies that the offset was inside of a character + std::cmp::Ordering::Greater => return utf16_offset, + } + + utf16_offset += ch.len_utf16(); + } + + // TODO: We could use TrustedLen when that is stabilized and it is impl'd on + // the iterators we use + + // We did not find the offset. This means that it is either at the end + // or past the end. + let text_len = last_ich.map(|(i, c)| i + c.len_utf8()); + if text_len == Some(offset) { + // Since the utf16 offset was being incremented each time, by now it is equivalent to the length + // but in utf16 characters + return utf16_offset; + } + + utf16_offset +} + +pub fn offset_utf8_to_utf16_str(text: &str, offset: usize) -> usize { + offset_utf8_to_utf16(text.char_indices(), offset) +} + +/// Convert a utf16 offset into a utf8 offset, if possible +/// `char_indices` is an iterator over utf8 offsets and the characters +/// It is cloneable so that it can be iterated multiple times. Though it should be cheaply cloneable. +pub fn offset_utf16_to_utf8( + char_indices: impl Iterator, + offset: usize, +) -> usize { + if offset == 0 { + return 0; + } + + // We accumulate the utf16 char lens until we find the utf8 offset that matches it + // or, we find out that it went into the middle of sometext + // We also keep track of the last offset and char in order to calculate the length of the text + // if we the index was at the end of the string + let mut utf16_offset = 0; + let mut last_ich = None; + for (utf8_offset, ch) in char_indices { + last_ich = Some((utf8_offset, ch)); + + let ch_utf16_len = ch.len_utf16(); + + match utf16_offset.cmp(&offset) { + std::cmp::Ordering::Less => {} + // We found the right offset + std::cmp::Ordering::Equal => { + return utf8_offset; + } + // This implies that the offset was in the middle of a character as we skipped over it + std::cmp::Ordering::Greater => return utf8_offset, + } + + utf16_offset += ch_utf16_len; + } + + // We did not find the offset, this means that it was either at the end + // or past the end + // Since we've iterated over all the char indices, the utf16_offset is now the + // utf16 length + if let Some((last_utf8_offset, last_ch)) = last_ich { + last_utf8_offset + last_ch.len_utf8() + } else { + 0 + } +} + +pub fn offset_utf16_to_utf8_str(text: &str, offset: usize) -> usize { + offset_utf16_to_utf8(text.char_indices(), offset) +} + +#[cfg(test)] +mod tests { + // TODO: more tests with unicode characters + + use crate::encoding::{offset_utf16_to_utf8_str, offset_utf8_to_utf16_str}; + + #[test] + fn utf8_to_utf16() { + let text = "hello world"; + + assert_eq!(offset_utf8_to_utf16_str(text, 0), 0); + assert_eq!(offset_utf8_to_utf16_str("", 0), 0); + + assert_eq!(offset_utf8_to_utf16_str("", 1), 0); + + assert_eq!(offset_utf8_to_utf16_str("h", 0), 0); + assert_eq!(offset_utf8_to_utf16_str("h", 1), 1); + + assert_eq!(offset_utf8_to_utf16_str(text, text.len()), text.len()); + + assert_eq!( + offset_utf8_to_utf16_str(text, text.len() - 1), + text.len() - 1 + ); + + assert_eq!(offset_utf8_to_utf16_str(text, text.len() + 1), text.len()); + + assert_eq!(offset_utf8_to_utf16_str("×", 0), 0); + assert_eq!(offset_utf8_to_utf16_str("×", 1), 1); + assert_eq!(offset_utf8_to_utf16_str("×", 2), 1); + assert_eq!(offset_utf8_to_utf16_str("a×", 0), 0); + assert_eq!(offset_utf8_to_utf16_str("a×", 1), 1); + assert_eq!(offset_utf8_to_utf16_str("a×", 2), 2); + assert_eq!(offset_utf8_to_utf16_str("a×", 3), 2); + } + + #[test] + fn utf16_to_utf8() { + let text = "hello world"; + + assert_eq!(offset_utf16_to_utf8_str(text, 0), 0); + assert_eq!(offset_utf16_to_utf8_str("", 0), 0); + + assert_eq!(offset_utf16_to_utf8_str("", 1), 0); + + assert_eq!(offset_utf16_to_utf8_str("h", 0), 0); + assert_eq!(offset_utf16_to_utf8_str("h", 1), 1); + + assert_eq!(offset_utf16_to_utf8_str(text, text.len()), text.len()); + + assert_eq!( + offset_utf16_to_utf8_str(text, text.len() - 1), + text.len() - 1 + ); + + assert_eq!(offset_utf16_to_utf8_str(text, text.len() + 1), text.len()); + + assert_eq!(offset_utf16_to_utf8_str("×", 0), 0); + assert_eq!(offset_utf16_to_utf8_str("×", 1), 2); + assert_eq!(offset_utf16_to_utf8_str("a×", 0), 0); + assert_eq!(offset_utf16_to_utf8_str("a×", 1), 1); + assert_eq!(offset_utf16_to_utf8_str("a×", 2), 3); + assert_eq!(offset_utf16_to_utf8_str("×a", 1), 2); + assert_eq!(offset_utf16_to_utf8_str("×a", 2), 3); + } +} diff --git a/lapce-core/src/indent.rs b/lapce-core/src/indent.rs index 169f7be987..1dc53fb872 100644 --- a/lapce-core/src/indent.rs +++ b/lapce-core/src/indent.rs @@ -1,4 +1,4 @@ -use xi_rope::Rope; +use lapce_xi_rope::Rope; use crate::{ buffer::Buffer, diff --git a/lapce-core/src/language.rs b/lapce-core/src/language.rs index f3f8af401e..5b5aa5e7e9 100644 --- a/lapce-core/src/language.rs +++ b/lapce-core/src/language.rs @@ -1,8 +1,9 @@ -use std::{collections::HashSet, path::Path}; +use std::{collections::HashSet, path::Path, str::FromStr}; -use tree_sitter::{Parser, TreeCursor}; +use strum_macros::{Display, EnumString}; +use tree_sitter::TreeCursor; -use crate::style::HighlightConfiguration; +use crate::syntax::highlight::{HighlightConfiguration, HighlightIssue}; // // To add support for an hypothetical language called Foo, for example, using @@ -41,6 +42,7 @@ use crate::style::HighlightConfiguration; // id: LapceLanguage::Foo, // language: tree_sitter_foo::language, // highlight: tree_sitter_foo::HIGHLIGHT_QUERY, +// injection: Some(tree_sitter_foo::INJECTION_QUERY), // or None if there is no injections // comment: "//", // indent: " ", // code_lens: (&[/* ... */], &[/* ... */]), @@ -48,7 +50,10 @@ use crate::style::HighlightConfiguration; // }, // ]; // -// 5. Add a new feature, say "lang-foo", to the lapce-ui crate (see +// 5. In `syntax/highlight.rs`, add `Foo: "lang-foo",` to the list in the +// `declare_language_highlights` macro. +// +// 6. Add a new feature, say "lang-foo", to the lapce-ui crate (see // lapce-ui/Cargo.toml). // // [features] @@ -74,15 +79,27 @@ struct SyntaxProperties { language: fn() -> tree_sitter::Language, /// For most languages, it is `tree_sitter_$crate::HIGHLIGHT_QUERY`. highlight: &'static str, + /// For most languages, it is `tree_sitter_$crate::INJECTION_QUERY`. + /// Though, not all languages have injections. + injection: Option<&'static str>, /// The comment token. "#" for python, "//" for rust for example. comment: &'static str, - /// The indent unit. "\t" for python, " " for rust, for example. + /// The indent unit. " " for javascript, " " for rust, for example. indent: &'static str, - /// TODO: someone more knowledgeable please describe what the two lists are. - /// Anyway, the second element of the tuple is a "ignore list". See - /// `walk_tree`. If unsure, use `DEFAULT_CODE_LENS_LIST` and + /// Lists of tree-sitter node types that control how code lenses are built. + /// The first is a list of nodes that should be traversed and included in + /// the lens, along with thier children. The second is a list of nodes that + /// should be excluded from the lens, though they will still be traversed. + /// See `walk_tree` for more details. + /// + /// The tree-sitter playground may be useful when creating these lists: + /// https://tree-sitter.github.io/tree-sitter/playground + /// + /// If unsure, use `DEFAULT_CODE_LENS_LIST` and /// `DEFAULT_CODE_LENS_IGNORE_LIST`. code_lens: (&'static [&'static str], &'static [&'static str]), + /// the tree sitter tag names that can be put in sticky headers + sticky_headers: &'static [&'static str], /// File name extensions to determine the language. `["py"]` for python, /// `["rs"]` for rust, for example. extensions: &'static [&'static str], @@ -94,87 +111,350 @@ struct SyntaxProperties { // Do not assign values to the variants because the number of variants and // number of elements in the LANGUAGES array change as different features // selected by the cargo build command. -#[derive(Eq, PartialEq, Hash, Clone, Copy, Debug)] +#[derive(Eq, PartialEq, Hash, Clone, Copy, Debug, Display, EnumString)] +#[strum(ascii_case_insensitive)] pub enum LapceLanguage { - #[cfg(feature = "lang-rust")] - Rust, - #[cfg(feature = "lang-go")] - Go, - #[cfg(feature = "lang-javascript")] - Javascript, - #[cfg(feature = "lang-javascript")] - Jsx, - #[cfg(feature = "lang-typescript")] - Typescript, - #[cfg(feature = "lang-typescript")] - Tsx, - #[cfg(feature = "lang-python")] - Python, - #[cfg(feature = "lang-toml")] - Toml, - #[cfg(feature = "lang-php")] - Php, - #[cfg(feature = "lang-elixir")] - Elixir, + #[cfg(feature = "lang-bash")] + #[strum(serialize = "bash", serialize = "sh")] + Bash, #[cfg(feature = "lang-c")] C, + #[cfg(feature = "lang-clojure")] + Clojure, + #[cfg(feature = "lang-cmake")] + Cmake, #[cfg(feature = "lang-cpp")] Cpp, - #[cfg(feature = "lang-json")] - Json, - #[cfg(feature = "lang-md")] - Markdown, - #[cfg(feature = "lang-ruby")] - Ruby, - #[cfg(feature = "lang-html")] - Html, - #[cfg(feature = "lang-java")] - Java, + #[cfg(feature = "lang-csharp")] + Csharp, + #[cfg(feature = "lang-css")] + Css, + #[cfg(feature = "lang-d")] + D, + #[cfg(feature = "lang-dart")] + Dart, + #[cfg(feature = "lang-dockerfile")] + Dockerfile, + #[cfg(feature = "lang-elixir")] + Elixir, #[cfg(feature = "lang-elm")] Elm, - #[cfg(feature = "lang-swift")] - Swift, - #[cfg(feature = "lang-ql")] - QL, - #[cfg(feature = "lang-haskell")] - Haskell, + #[cfg(feature = "lang-erlang")] + Erlang, #[cfg(feature = "lang-glimmer")] Glimmer, + #[cfg(feature = "lang-glsl")] + Glsl, + #[cfg(feature = "lang-go")] + Go, + #[cfg(feature = "lang-hare")] + Hare, + #[cfg(feature = "lang-haskell")] + Haskell, #[cfg(feature = "lang-haxe")] Haxe, #[cfg(feature = "lang-hcl")] - HCL, + Hcl, + #[cfg(feature = "lang-html")] + Html, + #[cfg(feature = "lang-java")] + Java, + #[cfg(feature = "lang-javascript")] + Javascript, + #[cfg(feature = "lang-json")] + Json, + #[cfg(feature = "lang-javascript")] + Jsx, + #[cfg(feature = "lang-julia")] + Julia, + #[cfg(feature = "lang-kotlin")] + Kotlin, + #[cfg(feature = "lang-latex")] + Latex, + #[cfg(feature = "lang-lua")] + Lua, + #[cfg(feature = "lang-markdown")] + Markdown, + // TODO: Hide this when it is shown to the user! + #[cfg(feature = "lang-markdown")] + #[strum(serialize = "markdown.inline")] + MarkdownInline, + #[cfg(feature = "lang-nix")] + Nix, #[cfg(feature = "lang-ocaml")] - OCaml, + Ocaml, #[cfg(feature = "lang-ocaml")] - OCamlInterface, + OcamlInterface, + #[cfg(feature = "lang-php")] + Php, + #[cfg(feature = "lang-prisma")] + Prisma, + #[cfg(feature = "lang-protobuf")] + ProtoBuf, + #[cfg(feature = "lang-python")] + Python, + #[cfg(feature = "lang-ql")] + Ql, + #[cfg(feature = "lang-r")] + R, + #[cfg(feature = "lang-ruby")] + Ruby, + #[cfg(feature = "lang-rust")] + Rust, + #[cfg(feature = "lang-scheme")] + Scheme, #[cfg(feature = "lang-scss")] - SCSS, - #[cfg(feature = "lang-hare")] - Hare, + Scss, + #[cfg(feature = "lang-sql")] + Sql, + #[cfg(feature = "lang-svelte")] + Svelte, + #[cfg(feature = "lang-swift")] + Swift, + #[cfg(feature = "lang-toml")] + Toml, + #[cfg(feature = "lang-typescript")] + Tsx, + #[cfg(feature = "lang-typescript")] + Typescript, + #[cfg(feature = "lang-vue")] + Vue, + #[cfg(feature = "lang-wgsl")] + Wgsl, + #[cfg(feature = "lang-xml")] + Xml, + #[cfg(feature = "lang-yaml")] + Yaml, + #[cfg(feature = "lang-zig")] + Zig, } // 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. const LANGUAGES: &[SyntaxProperties] = &[ - #[cfg(feature = "lang-rust")] + #[cfg(feature = "lang-bash")] SyntaxProperties { - id: LapceLanguage::Rust, - language: tree_sitter_rust::language, - highlight: tree_sitter_rust::HIGHLIGHT_QUERY, + id: LapceLanguage::Bash, + language: tree_sitter_bash::language, + highlight: tree_sitter_bash::HIGHLIGHT_QUERY, + injection: None, + comment: "#", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + extensions: &["sh", "bash"], + }, + #[cfg(feature = "lang-c")] + SyntaxProperties { + id: LapceLanguage::C, + language: tree_sitter_c::language, + highlight: include_str!("../queries/c/highlights.scm"), + injection: None, + comment: "//", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &["function_definition", "struct_specifier"], + extensions: &["c", "h"], + }, + #[cfg(feature = "lang-clojure")] + SyntaxProperties { + id: LapceLanguage::Clojure, + language: tree_sitter_clojure::language, + highlight: include_str!("../queries/clojure/highlights.scm"), + injection: Some(include_str!("../queries/clojure/injections.scm")), + comment: ";", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + extensions: &[ + "clj", + "edn", + "cljs", + "cljc", + "cljd", + "edn", + "bb", + "clj_kondo", + ], + }, + #[cfg(feature = "lang-cmake")] + SyntaxProperties { + id: LapceLanguage::Cmake, + language: tree_sitter_cmake::language, + highlight: include_str!("../queries/cmake/highlights.scm"), + injection: Some(include_str!("../queries/cmake/injections.scm")), + comment: "#", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &["function_definition"], + extensions: &["cmake"], + }, + #[cfg(feature = "lang-cpp")] + SyntaxProperties { + id: LapceLanguage::Cpp, + language: tree_sitter_cpp::language, + highlight: include_str!("../queries/cpp/highlights.scm"), + injection: None, + comment: "//", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[ + "function_definition", + "class_specifier", + "struct_specifier", + ], + extensions: &["cpp", "cxx", "cc", "c++", "hpp", "hxx", "hh", "h++"], + }, + #[cfg(feature = "lang-csharp")] + SyntaxProperties { + id: LapceLanguage::Csharp, + language: tree_sitter_c_sharp::language, + highlight: tree_sitter_c_sharp::HIGHLIGHT_QUERY, + injection: None, comment: "//", indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[ + "interface_declaration", + "class_declaration", + "enum_declaration", + "struct_declaration", + "record_declaration", + "record_struct_declaration", + "namespace_declaration", + "constructor_declaration", + "destructor_declaration", + "method_declaration", + ], + extensions: &["cs", "csx"], + }, + #[cfg(feature = "lang-css")] + SyntaxProperties { + id: LapceLanguage::Css, + language: tree_sitter_css::language, + highlight: include_str!("../queries/css/highlights.scm"), + injection: None, + comment: "/*", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + extensions: &["css"], + }, + #[cfg(feature = "lang-d")] + SyntaxProperties { + id: LapceLanguage::D, + language: tree_sitter_d::language, + highlight: tree_sitter_d::HIGHLIGHTS_QUERY, + injection: None, + comment: "//", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + extensions: &["d", "di", "dlang"], + }, + #[cfg(feature = "lang-dart")] + SyntaxProperties { + id: LapceLanguage::Dart, + language: tree_sitter_dart::language, + highlight: tree_sitter_dart::HIGHLIGHTS_QUERY, + injection: None, + comment: "//", + indent: " ", code_lens: ( - &["source_file", "impl_item", "trait_item", "declaration_list"], - &["source_file", "use_declaration", "line_comment"], + &["program", "class_definition"], + &[ + "program", + "import_or_export", + "comment", + "documentation_comment", + ], ), - extensions: &["rs"], + sticky_headers: &["class_definition"], + extensions: &["dart"], + }, + #[cfg(feature = "lang-dockerfile")] + SyntaxProperties { + id: LapceLanguage::Dockerfile, + language: tree_sitter_dockerfile::language, + highlight: tree_sitter_dockerfile::HIGHLIGHTS_QUERY, + injection: None, + comment: "#", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + extensions: &["containerfile", "dockerfile"], + }, + #[cfg(feature = "lang-elixir")] + SyntaxProperties { + id: LapceLanguage::Elixir, + language: tree_sitter_elixir::language, + highlight: tree_sitter_elixir::HIGHLIGHTS_QUERY, + injection: None, + comment: "#", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &["do_block"], + extensions: &["ex", "exs", "eex", "heex", "sface"], + }, + #[cfg(feature = "lang-elm")] + SyntaxProperties { + id: LapceLanguage::Elm, + language: tree_sitter_elm::language, + highlight: include_str!("../queries/elm/highlights.scm"), + injection: Some(tree_sitter_elm::INJECTIONS_QUERY), + comment: "#", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + extensions: &["elm"], + }, + #[cfg(feature = "lang-erlang")] + SyntaxProperties { + id: LapceLanguage::Erlang, + language: tree_sitter_erlang::language, + highlight: include_str!("../queries/erlang/highlights.scm"), + injection: None, + comment: "%", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + extensions: &["erl", "hrl"], + }, + #[cfg(feature = "lang-glimmer")] + SyntaxProperties { + id: LapceLanguage::Glimmer, + language: tree_sitter_glimmer::language, + highlight: tree_sitter_glimmer::HIGHLIGHTS_QUERY, + injection: None, + comment: "{{!", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + extensions: &["hbs"], + }, + #[cfg(feature = "lang-glsl")] + SyntaxProperties { + id: LapceLanguage::Glsl, + language: tree_sitter_glsl::language, + highlight: tree_sitter_glsl::HIGHLIGHTS_QUERY, + injection: None, + comment: "//", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + extensions: &[ + "glsl", "cs", "vs", "gs", "fs", "csh", "vsh", "gsh", "fsh", "cshader", + "vshader", "gshader", "fshader", "comp", "vert", "geom", "frag", "tesc", + "tese", "mesh", "task", "rgen", "rint", "rahit", "rchit", "rmiss", + "rcall", + ], }, #[cfg(feature = "lang-go")] SyntaxProperties { id: LapceLanguage::Go, language: tree_sitter_go::language, highlight: tree_sitter_go::HIGHLIGHT_QUERY, + injection: None, comment: "//", indent: " ", code_lens: ( @@ -187,278 +467,524 @@ const LANGUAGES: &[SyntaxProperties] = &[ ], &["source_file", "comment", "line_comment"], ), + sticky_headers: &[], extensions: &["go"], }, + #[cfg(feature = "lang-hare")] + SyntaxProperties { + id: LapceLanguage::Hare, + language: tree_sitter_hare::language, + highlight: tree_sitter_hare::HIGHLIGHT_QUERY, + injection: None, + comment: "//", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + extensions: &["ha"], + }, + #[cfg(feature = "lang-haskell")] + SyntaxProperties { + id: LapceLanguage::Haskell, + language: tree_sitter_haskell::language, + highlight: tree_sitter_haskell::HIGHLIGHTS_QUERY, + injection: None, + comment: "--", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + extensions: &["hs"], + }, + #[cfg(feature = "lang-haxe")] + SyntaxProperties { + id: LapceLanguage::Haxe, + language: tree_sitter_haxe::language, + highlight: tree_sitter_haxe::HIGHLIGHTS_QUERY, + injection: Some(tree_sitter_haxe::INJECTIONS_QUERY), + comment: "//", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + extensions: &["hx"], + }, + #[cfg(feature = "lang-hcl")] + SyntaxProperties { + id: LapceLanguage::Hcl, + language: tree_sitter_hcl::language, + highlight: tree_sitter_hcl::HIGHLIGHTS_QUERY, + injection: None, + comment: "//", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + extensions: &["hcl", "tf"], + }, + #[cfg(feature = "lang-html")] + SyntaxProperties { + id: LapceLanguage::Html, + language: tree_sitter_html::language, + highlight: tree_sitter_html::HIGHLIGHT_QUERY, + injection: Some(tree_sitter_html::INJECTION_QUERY), + comment: "", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + extensions: &["html", "htm"], + }, + #[cfg(feature = "lang-java")] + SyntaxProperties { + id: LapceLanguage::Java, + language: tree_sitter_java::language, + highlight: tree_sitter_java::HIGHLIGHT_QUERY, + injection: None, + comment: "//", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + extensions: &["java"], + }, #[cfg(feature = "lang-javascript")] SyntaxProperties { id: LapceLanguage::Javascript, language: tree_sitter_javascript::language, - highlight: tree_sitter_javascript::HIGHLIGHT_QUERY, + highlight: include_str!("../queries/javascript/highlights.scm"), + injection: Some(tree_sitter_javascript::INJECTION_QUERY), comment: "//", indent: " ", code_lens: (&["source_file", "program"], &["source_file"]), - extensions: &["js"], + sticky_headers: &[], + extensions: &["js", "cjs", "mjs"], + }, + #[cfg(feature = "lang-json")] + SyntaxProperties { + id: LapceLanguage::Json, + language: tree_sitter_json::language, + highlight: tree_sitter_json::HIGHLIGHT_QUERY, + injection: None, + comment: "", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &["pair"], + extensions: &["json"], }, #[cfg(feature = "lang-javascript")] SyntaxProperties { id: LapceLanguage::Jsx, language: tree_sitter_javascript::language, - highlight: tree_sitter_javascript::JSX_HIGHLIGHT_QUERY, + highlight: include_str!("../queries/jsx/highlights.scm"), + // TODO: Does jsx use the javascript injection query too? + injection: Some(tree_sitter_javascript::INJECTION_QUERY), comment: "//", indent: " ", code_lens: (&["source_file", "program"], &["source_file"]), + sticky_headers: &[], extensions: &["jsx"], }, - #[cfg(feature = "lang-typescript")] + #[cfg(feature = "lang-julia")] SyntaxProperties { - id: LapceLanguage::Typescript, - language: tree_sitter_typescript::language_typescript, - highlight: tree_sitter_typescript::HIGHLIGHT_QUERY, - comment: "//", + id: LapceLanguage::Julia, + language: tree_sitter_julia::language, + highlight: include_str!("../queries/julia/highlights.scm"), + injection: Some(include_str!("../queries/julia/injections.scm")), + comment: "#", indent: " ", - code_lens: (&["source_file", "program"], &["source_file"]), - extensions: &["ts"], + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[ + "function_definition", + "module_definition", + "macro_definition", + "struct_definition", + ], + extensions: &["julia", "jl"], }, - #[cfg(feature = "lang-typescript")] + #[cfg(feature = "lang-kotlin")] SyntaxProperties { - id: LapceLanguage::Tsx, - language: tree_sitter_typescript::language_tsx, - highlight: tree_sitter_typescript::HIGHLIGHT_QUERY, + id: LapceLanguage::Kotlin, + language: tree_sitter_kotlin::language, + highlight: include_str!("../queries/kotlin/highlights.scm"), + injection: Some(include_str!("../queries/kotlin/injections.scm")), comment: "//", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + extensions: &["kt", "kts"], + }, + #[cfg(feature = "lang-latex")] + SyntaxProperties { + id: LapceLanguage::Latex, + language: tree_sitter_latex::language, + highlight: include_str!("../queries/latex/highlights.scm"), + injection: Some(include_str!("../queries/latex/injections.scm")), + comment: "%", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + extensions: &["tex"], + }, + #[cfg(feature = "lang-lua")] + SyntaxProperties { + id: LapceLanguage::Lua, + language: tree_sitter_lua::language, + highlight: include_str!("../queries/lua/highlights.scm"), + injection: None, + comment: "--", + indent: " ", + sticky_headers: &[], + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + extensions: &["lua"], + }, + #[cfg(feature = "lang-markdown")] + SyntaxProperties { + id: LapceLanguage::Markdown, + language: tree_sitter_md::language, + highlight: include_str!("../queries/markdown/highlights.scm"), + injection: Some(include_str!("../queries/markdown/injections.scm")), + comment: "", indent: " ", - code_lens: (&["source_file", "program"], &["source_file"]), - extensions: &["tsx"], + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + extensions: &["md"], }, - #[cfg(feature = "lang-python")] + #[cfg(feature = "lang-markdown")] SyntaxProperties { - id: LapceLanguage::Python, - language: tree_sitter_python::language, - highlight: tree_sitter_python::HIGHLIGHT_QUERY, - comment: "#", - indent: "\t", - code_lens: ( - &[ - "source_file", - "module", - "class_definition", - "class", - "identifier", - "decorated_definition", - "block", - ], - &["source_file", "import_statement", "import_from_statement"], - ), - extensions: &["py"], + id: LapceLanguage::MarkdownInline, + language: tree_sitter_md::inline_language, + highlight: include_str!("../queries/markdown.inline/highlights.scm"), + injection: Some(include_str!("../queries/markdown.inline/injections.scm")), + comment: "", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + // markdown inline is only used as an injection by the Markdown language + extensions: &[], }, - #[cfg(feature = "lang-toml")] + #[cfg(feature = "lang-nix")] SyntaxProperties { - id: LapceLanguage::Toml, - language: tree_sitter_toml::language, - highlight: tree_sitter_toml::HIGHLIGHT_QUERY, + id: LapceLanguage::Nix, + language: tree_sitter_nix::language, + highlight: tree_sitter_nix::HIGHLIGHTS_QUERY, + injection: None, comment: "#", indent: " ", code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), - extensions: &["toml"], + sticky_headers: &[], + extensions: &["nix"], + }, + #[cfg(feature = "lang-ocaml")] + SyntaxProperties { + id: LapceLanguage::Ocaml, + language: tree_sitter_ocaml::language_ocaml, + highlight: tree_sitter_ocaml::HIGHLIGHTS_QUERY, + injection: None, + comment: "(*", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + extensions: &["ml"], + }, + #[cfg(feature = "lang-ocaml")] + SyntaxProperties { + id: LapceLanguage::Ocaml, + language: tree_sitter_ocaml::language_ocaml_interface, + highlight: tree_sitter_ocaml::HIGHLIGHTS_QUERY, + injection: None, + comment: "(*", + indent: " ", + code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &[], + extensions: &["mli"], }, #[cfg(feature = "lang-php")] SyntaxProperties { id: LapceLanguage::Php, language: tree_sitter_php::language, highlight: tree_sitter_php::HIGHLIGHT_QUERY, + injection: Some(tree_sitter_php::INJECTIONS_QUERY), comment: "//", indent: " ", - code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + code_lens: ( + &[ + "program", + "class_declaration", + "trait_declaration", + "interface_declaration", + "declaration_list", + "method_declaration", + "function_declaration", + ], + &[ + "program", + "php_tag", + "comment", + "namespace_definition", + "namespace_use_declaration", + "use_declaration", + "const_declaration", + "property_declaration", + "expression_statement", + ], + ), + sticky_headers: &[ + "class_declaration", + "trait_declaration", + "interface_declaration", + "method_declaration", + "function_declaration", + ], extensions: &["php"], }, - #[cfg(feature = "lang-elixir")] - SyntaxProperties { - id: LapceLanguage::Elixir, - language: tree_sitter_elixir::language, - highlight: tree_sitter_elixir::HIGHLIGHTS_QUERY, - comment: "#", - indent: " ", - code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), - extensions: &["ex", "exs", "eex", "heex", "sface"], - }, - #[cfg(feature = "lang-c")] + #[cfg(feature = "lang-prisma")] SyntaxProperties { - id: LapceLanguage::C, - language: tree_sitter_c::language, - highlight: tree_sitter_c::HIGHLIGHT_QUERY, + id: LapceLanguage::Prisma, + language: tree_sitter_prisma_io::language, + highlight: include_str!("../queries/prisma/highlights.scm"), + injection: None, comment: "//", indent: " ", code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), - extensions: &["c"], + sticky_headers: &[], + extensions: &["prisma"], }, - #[cfg(feature = "lang-cpp")] + #[cfg(feature = "lang-protobuf")] SyntaxProperties { - id: LapceLanguage::Cpp, - language: tree_sitter_cpp::language, - highlight: tree_sitter_cpp::HIGHLIGHT_QUERY, + id: LapceLanguage::ProtoBuf, + language: tree_sitter_protobuf::language, + highlight: include_str!("../queries/protobuf/highlights.scm"), + injection: Some(include_str!("../queries/protobuf/injections.scm")), comment: "//", - indent: " ", + indent: " ", code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), - extensions: &["cpp", "cxx", "cc", "c++", "hpp", "hxx", "hh", "h++"], + sticky_headers: &[], + extensions: &["proto"], }, - #[cfg(feature = "lang-json")] + #[cfg(feature = "lang-python")] SyntaxProperties { - id: LapceLanguage::Json, - language: tree_sitter_json::language, - highlight: tree_sitter_json::HIGHLIGHT_QUERY, - comment: "", + id: LapceLanguage::Python, + language: tree_sitter_python::language, + highlight: tree_sitter_python::HIGHLIGHT_QUERY, + injection: None, + comment: "#", indent: " ", + code_lens: ( + &[ + "source_file", + "module", + "class_definition", + "class", + "identifier", + "decorated_definition", + "block", + ], + &["source_file", "import_statement", "import_from_statement"], + ), + sticky_headers: &[], + extensions: &["py", "pyi", "pyc", "pyd", "pyw"], + }, + #[cfg(feature = "lang-ql")] + SyntaxProperties { + id: LapceLanguage::Ql, + language: tree_sitter_ql::language, + highlight: tree_sitter_ql::HIGHLIGHTS_QUERY, + injection: None, + comment: "//", + indent: " ", code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), - extensions: &["json"], + sticky_headers: &[], + extensions: &["ql"], }, - #[cfg(feature = "lang-md")] + #[cfg(feature = "lang-r")] SyntaxProperties { - id: LapceLanguage::Markdown, - language: tree_sitter_md::language, - highlight: tree_sitter_md::HIGHLIGHTS_QUERY, - comment: "", - indent: " ", + id: LapceLanguage::R, + language: tree_sitter_r::language, + highlight: include_str!("../queries/r/highlights.scm"), + injection: None, + comment: "#", + indent: " ", code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), - extensions: &["md"], + sticky_headers: &[], + extensions: &["r"], }, #[cfg(feature = "lang-ruby")] SyntaxProperties { id: LapceLanguage::Ruby, language: tree_sitter_ruby::language, highlight: tree_sitter_ruby::HIGHLIGHT_QUERY, + injection: None, comment: "#", indent: " ", code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), + sticky_headers: &["module", "class", "method", "do_block"], extensions: &["rb"], }, - #[cfg(feature = "lang-html")] + #[cfg(feature = "lang-rust")] SyntaxProperties { - id: LapceLanguage::Html, - language: tree_sitter_html::language, - highlight: tree_sitter_html::HIGHLIGHT_QUERY, - comment: "", + id: LapceLanguage::Rust, + language: tree_sitter_rust::language, + highlight: tree_sitter_rust::HIGHLIGHT_QUERY, + injection: None, + comment: "//", indent: " ", + code_lens: ( + &["source_file", "impl_item", "trait_item", "declaration_list"], + &["source_file", "use_declaration", "line_comment"], + ), + sticky_headers: &["struct_item", "enum_item", "function_item", "impl_item"], + extensions: &["rs"], + }, + #[cfg(feature = "lang-scheme")] + SyntaxProperties { + id: LapceLanguage::Scheme, + language: tree_sitter_scheme::language, + highlight: tree_sitter_scheme::HIGHLIGHTS_QUERY, + injection: None, + comment: ";", + indent: " ", code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), - extensions: &["html", "htm"], + sticky_headers: &[], + extensions: &["scm", "ss"], }, - #[cfg(feature = "lang-java")] + #[cfg(feature = "lang-scss")] SyntaxProperties { - id: LapceLanguage::Java, - language: tree_sitter_java::language, - highlight: tree_sitter_java::HIGHLIGHT_QUERY, + id: LapceLanguage::Scss, + language: tree_sitter_scss::language, + highlight: tree_sitter_scss::HIGHLIGHTS_QUERY, + injection: None, comment: "//", indent: " ", code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), - extensions: &["java"], + sticky_headers: &[], + extensions: &["scss"], }, - #[cfg(feature = "lang-elm")] + #[cfg(feature = "lang-sql")] SyntaxProperties { - id: LapceLanguage::Elm, - language: tree_sitter_elm::language, - highlight: tree_sitter_elm::HIGHLIGHTS_QUERY, - comment: "#", - indent: " ", + id: LapceLanguage::Sql, + language: tree_sitter_sql::language, + highlight: tree_sitter_sql::HIGHLIGHTS_QUERY, + injection: None, + comment: "--", + indent: " ", code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), - extensions: &["elm"], + sticky_headers: &[], + extensions: &["sql"], }, - #[cfg(feature = "lang-swift")] + #[cfg(feature = "lang-svelte")] SyntaxProperties { - id: LapceLanguage::Swift, - language: tree_sitter_swift::language, - highlight: tree_sitter_swift::HIGHLIGHTS_QUERY, + id: LapceLanguage::Svelte, + language: tree_sitter_svelte::language, + highlight: include_str!("../queries/svelte/highlights.scm"), + injection: Some(include_str!("../queries/svelte/injections.scm")), comment: "//", indent: " ", code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), - extensions: &["swift"], + sticky_headers: &[], + extensions: &["svelte"], }, - #[cfg(feature = "lang-ql")] + #[cfg(feature = "lang-swift")] SyntaxProperties { - id: LapceLanguage::QL, - language: tree_sitter_ql::language, - highlight: tree_sitter_ql::HIGHLIGHTS_QUERY, + id: LapceLanguage::Swift, + language: tree_sitter_swift::language, + highlight: tree_sitter_swift::HIGHLIGHTS_QUERY, + injection: None, comment: "//", indent: " ", code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), - extensions: &["ql"], + sticky_headers: &[], + extensions: &["swift"], }, - #[cfg(feature = "lang-haskell")] + #[cfg(feature = "lang-toml")] SyntaxProperties { - id: LapceLanguage::Haskell, - language: tree_sitter_haskell::language, - highlight: tree_sitter_haskell::HIGHLIGHTS_QUERY, - comment: "--", + id: LapceLanguage::Toml, + language: tree_sitter_toml::language, + highlight: tree_sitter_toml::HIGHLIGHT_QUERY, + injection: None, + comment: "#", indent: " ", code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), - extensions: &["hs"], + sticky_headers: &[], + extensions: &["toml"], }, - #[cfg(feature = "lang-glimmer")] + #[cfg(feature = "lang-typescript")] SyntaxProperties { - id: LapceLanguage::Glimmer, - language: tree_sitter_glimmer::language, - highlight: tree_sitter_glimmer::HIGHLIGHTS_QUERY, - comment: "{{!", - indent: " ", - code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), - extensions: &["hbs"], + id: LapceLanguage::Tsx, + language: tree_sitter_typescript::language_tsx, + highlight: include_str!("../queries/typescript/highlights.scm"), + injection: None, + comment: "//", + indent: " ", + code_lens: (&["source_file", "program"], &["source_file"]), + sticky_headers: &[], + extensions: &["tsx"], }, - #[cfg(feature = "lang-haxe")] + #[cfg(feature = "lang-typescript")] SyntaxProperties { - id: LapceLanguage::Haxe, - language: tree_sitter_haxe::language, - highlight: tree_sitter_haxe::HIGHLIGHTS_QUERY, + id: LapceLanguage::Typescript, + language: tree_sitter_typescript::language_typescript, + highlight: include_str!("../queries/typescript/highlights.scm"), + injection: None, comment: "//", - indent: " ", - code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), - extensions: &["hx"], + indent: " ", + code_lens: (&["source_file", "program"], &["source_file"]), + sticky_headers: &[], + extensions: &["ts", "cts", "mts"], }, - #[cfg(feature = "lang-hcl")] + #[cfg(feature = "lang-vue")] SyntaxProperties { - id: LapceLanguage::HCL, - language: tree_sitter_hcl::language, - highlight: tree_sitter_hcl::HIGHLIGHTS_QUERY, + id: LapceLanguage::Vue, + language: tree_sitter_vue::language, + highlight: tree_sitter_vue::HIGHLIGHTS_QUERY, + injection: Some(tree_sitter_vue::INJECTIONS_QUERY), comment: "//", indent: " ", code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), - extensions: &["hcl"], + sticky_headers: &[], + extensions: &["vue"], }, - #[cfg(feature = "lang-ocaml")] + #[cfg(feature = "lang-wgsl")] SyntaxProperties { - id: LapceLanguage::OCaml, - language: tree_sitter_ocaml::language_ocaml, - highlight: tree_sitter_ocaml::HIGHLIGHTS_QUERY, - comment: "(*", - indent: " ", + id: LapceLanguage::Wgsl, + language: tree_sitter_wgsl::language, + highlight: tree_sitter_wgsl::HIGHLIGHTS_QUERY, + injection: None, + comment: "//", + indent: " ", code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), - extensions: &["ml"], + sticky_headers: &[], + extensions: &["wgsl"], }, - #[cfg(feature = "lang-ocaml")] + #[cfg(feature = "lang-xml")] SyntaxProperties { - id: LapceLanguage::OCaml, - language: tree_sitter_ocaml::language_ocaml_interface, - highlight: tree_sitter_ocaml::HIGHLIGHTS_QUERY, - comment: "(*", - indent: " ", + id: LapceLanguage::Xml, + language: tree_sitter_xml::language, + highlight: tree_sitter_xml::HIGHLIGHTS_QUERY, + injection: None, + comment: "//", + indent: " ", code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), - extensions: &["mli"], + sticky_headers: &[], + extensions: &["xml"], }, - #[cfg(feature = "lang-scss")] + #[cfg(feature = "lang-yaml")] SyntaxProperties { - id: LapceLanguage::SCSS, - language: tree_sitter_scss::language, - highlight: tree_sitter_scss::HIGHLIGHTS_QUERY, - comment: "//", + id: LapceLanguage::Yaml, + language: tree_sitter_yaml::language, + highlight: tree_sitter_yaml::HIGHLIGHTS_QUERY, + injection: Some(tree_sitter_yaml::INJECTIONS_QUERY), + comment: "#", indent: " ", code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), - extensions: &["scss"], + sticky_headers: &[], + extensions: &["yml", "yaml"], }, - #[cfg(feature = "lang-hare")] + #[cfg(feature = "lang-zig")] SyntaxProperties { - id: LapceLanguage::Hare, - language: tree_sitter_hare::language, - highlight: tree_sitter_hare::HIGHLIGHT_QUERY, + id: LapceLanguage::Zig, + language: tree_sitter_zig::language, + highlight: include_str!("../queries/zig/highlights.scm"), + injection: Some(tree_sitter_zig::INJECTIONS_QUERY), comment: "//", - indent: " ", + indent: " ", code_lens: (DEFAULT_CODE_LENS_LIST, DEFAULT_CODE_LENS_IGNORE_LIST), - extensions: &["ha"], + sticky_headers: &[], + extensions: &["zig"], }, ]; @@ -475,6 +1001,24 @@ impl LapceLanguage { None } + pub fn from_name(name: &str) -> Option { + match LapceLanguage::from_str(name.to_lowercase().as_str()) { + Ok(v) => Some(v), + Err(e) => { + eprintln!("failed parsing {name} LapceLanguage: {e}"); + None + } + } + } + + pub fn languages() -> Vec { + let mut langs = vec![]; + for l in LANGUAGES { + langs.push(format!("{}", l.id)) + } + langs + } + // NOTE: Instead of using `&LANGUAGES[*self as usize]` directly, the // `debug_assertion` gives better feedback should something has gone wrong // badly. @@ -490,6 +1034,10 @@ impl LapceLanguage { l } + pub fn sticky_header_tags(&self) -> &[&'static str] { + self.properties().sticky_headers + } + pub fn comment_token(&self) -> &str { self.properties().comment } @@ -498,18 +1046,26 @@ impl LapceLanguage { self.properties().indent } - pub(crate) fn new_parser(&self) -> Parser { - let language = (self.properties().language)(); - let mut parser = Parser::new(); - parser.set_language(language).unwrap(); - parser - } - - pub(crate) fn new_highlight_config(&self) -> HighlightConfiguration { - let language = (self.properties().language)(); - let query = self.properties().highlight; - - HighlightConfiguration::new(language, query, "", "").unwrap() + pub(crate) fn new_highlight_config( + &self, + ) -> Result { + let props = self.properties(); + let language = (props.language)(); + let query = props.highlight; + let injection = props.injection; + match HighlightConfiguration::new( + language, + query, + injection.unwrap_or(""), + "", + ) { + Ok(x) => Ok(x), + Err(x) => { + let str = format!("Encountered {x:?} while trying to construct HighlightConfiguration for {self}"); + log::error!("{str}"); + Err(HighlightIssue::Error(str)) + } + } } pub(crate) fn walk_tree( @@ -522,6 +1078,10 @@ impl LapceLanguage { } } +/// Walk an AST and determine which lines to include in the code lens. +/// +/// Node types listed in `list` will be walked, along with their children. All +/// nodes encountered will be included, unless they are listed in `ignore_list`. fn walk_tree( cursor: &mut TreeCursor, normal_lines: &mut HashSet, @@ -547,180 +1107,3 @@ fn walk_tree( cursor.goto_parent(); } } - -#[cfg(test)] -mod test { - // If none of the lang features is selected, the imports and the auxiliary - // function(s) in the module become unused. Hence turning off the lints. - #![allow(unused, unreachable_code)] - - use super::LapceLanguage; - use std::path::PathBuf; - - fn assert_language(expected: LapceLanguage, exts: &[&str]) { - for ext in exts { - let path = PathBuf::from(&format!("a.{ext}")); - let lang = LapceLanguage::from_path(&path).unwrap(); - - assert_eq!(lang, expected); - // In debug build, this assertion will never set off. It - // nonetheless exercises the boundary check, and the debug - // assertion, in the `properties()` function. - assert_eq!(lang.properties().id, expected); - } - - // Hopefully there will not be such a file extension to support. - let path = PathBuf::from("a.___"); - assert!(LapceLanguage::from_path(&path).is_none()); - } - - #[test] - #[cfg(feature = "lang-rust")] - fn test_rust_lang() { - assert_language(LapceLanguage::Rust, &["rs"]); - } - - #[test] - #[cfg(feature = "lang-go")] - fn test_go_lang() { - assert_language(LapceLanguage::Go, &["go"]); - } - - #[test] - #[cfg(feature = "lang-javascript")] - fn test_javascript_lang() { - assert_language(LapceLanguage::Javascript, &["js"]); - } - - #[test] - #[cfg(feature = "lang-javascript")] - fn test_jsx_lang() { - assert_language(LapceLanguage::Jsx, &["jsx"]); - } - - #[test] - #[cfg(feature = "lang-typescript")] - fn test_typescript_lang() { - assert_language(LapceLanguage::Typescript, &["ts"]); - } - - #[test] - #[cfg(feature = "lang-typescript")] - fn test_tsx_lang() { - assert_language(LapceLanguage::Tsx, &["tsx"]); - } - - #[test] - #[cfg(feature = "lang-python")] - fn test_python_lang() { - assert_language(LapceLanguage::Python, &["py"]); - } - - #[test] - #[cfg(feature = "lang-toml")] - fn test_toml_lang() { - assert_language(LapceLanguage::Toml, &["toml"]); - } - - #[test] - #[cfg(feature = "lang-elixir")] - fn test_elixir_lang() { - assert_language(LapceLanguage::Elixir, &["ex"]); - } - - #[test] - #[cfg(feature = "lang-php")] - fn test_php_lang() { - assert_language(LapceLanguage::Php, &["php"]); - } - - #[test] - #[cfg(feature = "lang-ruby")] - fn test_ruby_lang() { - assert_language(LapceLanguage::Ruby, &["rb"]); - } - - #[test] - #[cfg(feature = "lang-c")] - fn test_c_lang() { - assert_language(LapceLanguage::C, &["c"]); - } - - #[test] - #[cfg(feature = "lang-cpp")] - fn test_cpp_lang() { - assert_language( - LapceLanguage::Cpp, - &["cpp", "cxx", "cc", "c++", "hpp", "hxx", "hh", "h++"], - ); - } - - #[test] - #[cfg(feature = "lang-json")] - fn test_json_lang() { - assert_language(LapceLanguage::Json, &["json"]); - } - - #[test] - #[cfg(feature = "lang-md")] - fn test_md_lang() { - assert_language(LapceLanguage::Markdown, &["md"]); - } - - #[test] - #[cfg(feature = "lang-html")] - fn test_html_lang() { - assert_language(LapceLanguage::Html, &["html", "htm"]); - } - - #[test] - #[cfg(feature = "lang-java")] - fn test_java_lang() { - assert_language(LapceLanguage::Java, &["java"]); - } - #[test] - #[cfg(feature = "lang-elm")] - fn test_elm_lang() { - assert_language(LapceLanguage::Elm, &["elm"]); - } - #[test] - #[cfg(feature = "lang-swift")] - fn test_swift_lang() { - assert_language(LapceLanguage::Swift, &["swift"]); - } - #[test] - #[cfg(feature = "lang-ql")] - fn test_ql_lang() { - assert_language(LapceLanguage::QL, &["ql"]); - } - #[test] - #[cfg(feature = "lang-haskell")] - fn test_haskell_lang() { - assert_language(LapceLanguage::Haskell, &["hs"]); - } - #[cfg(feature = "lang-glimmer")] - fn test_glimmer_lang() { - assert_language(LapceLanguage::Glimmer, &["hbs"]); - } - #[cfg(feature = "lang-haxe")] - fn test_haxe_lang() { - assert_language(LapceLanguage::Haxe, &["hx"]); - } - #[cfg(feature = "lang-hcl")] - fn test_hcl_lang() { - assert_language(LapceLanguage::HCL, &["hcl"]); - } - #[cfg(feature = "lang-ocaml")] - fn test_ocaml_lang() { - assert_language(LapceLanguage::OCaml, &["ml"]); - assert_language(LapceLanguage::OCamlInterface, &["mli"]); - } - #[cfg(feature = "lang-scss")] - fn test_scss_lang() { - assert_language(LapceLanguage::SCSS, &["scss"]); - } - #[cfg(feature = "lang-hare")] - fn test_hare_lang() { - assert_language(LapceLanguage::Hare, &["ha"]); - } -} diff --git a/lapce-core/src/lens.rs b/lapce-core/src/lens.rs index d25fb70277..713712c194 100644 --- a/lapce-core/src/lens.rs +++ b/lapce-core/src/lens.rs @@ -1,6 +1,6 @@ use std::mem; -use xi_rope::{ +use lapce_xi_rope::{ interval::IntervalBounds, tree::{DefaultMetric, Leaf, Node, NodeInfo, TreeBuilder}, Cursor, Delta, Interval, Metric, @@ -53,10 +53,7 @@ impl Lens { } pub fn height_of_line(&self, line: usize) -> usize { - let max_line = self.0.len(); - if line >= max_line { - return self.0.count::(self.0.len()); - } + let line = self.0.len().min(line); self.0.count::(line) } diff --git a/lapce-core/src/lib.rs b/lapce-core/src/lib.rs index 039c004a80..78b1d38d51 100644 --- a/lapce-core/src/lib.rs +++ b/lapce-core/src/lib.rs @@ -1,13 +1,20 @@ +#![allow(clippy::manual_clamp)] + pub mod buffer; +pub mod char_buffer; pub mod chars; pub mod command; pub mod cursor; +pub mod directory; pub mod editor; +pub mod encoding; pub mod indent; pub mod language; pub mod lens; +pub mod meta; pub mod mode; pub mod movement; +pub mod paragraph; pub mod register; pub mod selection; pub mod style; diff --git a/lapce-core/src/meta.rs b/lapce-core/src/meta.rs new file mode 100644 index 0000000000..37c7cb0f6c --- /dev/null +++ b/lapce-core/src/meta.rs @@ -0,0 +1,46 @@ +use once_cell::sync::Lazy; + +pub static NAME: Lazy<&str> = Lazy::new(application_name); + +fn application_name() -> &'static str { + if cfg!(debug_assertions) { + "Lapce-Debug" + } else if option_env!("RELEASE_TAG_NAME") + .unwrap_or("") + .starts_with("nightly") + { + "Lapce-Nightly" + } else { + "Lapce-Stable" + } +} + +pub static VERSION: Lazy<&str> = Lazy::new(version); + +fn version() -> &'static str { + if cfg!(debug_assertions) { + "debug" + } else if option_env!("RELEASE_TAG_NAME") + .unwrap_or("") + .starts_with("nightly") + { + option_env!("RELEASE_TAG_NAME").unwrap() + } else { + env!("CARGO_PKG_VERSION") + } +} + +pub static RELEASE: Lazy<&str> = Lazy::new(release_type); + +fn release_type() -> &'static str { + if cfg!(debug_assertions) { + "Debug" + } else if option_env!("RELEASE_TAG_NAME") + .unwrap_or("") + .starts_with("nightly") + { + "Nightly" + } else { + "Stable" + } +} diff --git a/lapce-core/src/mode.rs b/lapce-core/src/mode.rs index 2522c3464c..f72b96447c 100644 --- a/lapce-core/src/mode.rs +++ b/lapce-core/src/mode.rs @@ -3,7 +3,7 @@ use std::fmt::Write; use bitflags::bitflags; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum MotionMode { Delete, Yank, @@ -34,7 +34,7 @@ pub enum Mode { bitflags! { pub struct Modes: u32 { - const NORMAL = 0x01; + const NORMAL = 0x1; const INSERT = 0x2; const VISUAL = 0x4; const TERMINAL = 0x8; diff --git a/lapce-core/src/movement.rs b/lapce-core/src/movement.rs index 49ad350c6b..ab9ec842aa 100644 --- a/lapce-core/src/movement.rs +++ b/lapce-core/src/movement.rs @@ -24,6 +24,8 @@ pub enum Movement { NextUnmatched(char), PreviousUnmatched(char), MatchPairs, + ParagraphForward, + ParagraphBackward, } impl PartialEq for Movement { @@ -41,6 +43,8 @@ impl Movement { | Movement::Line(_) | Movement::DocumentStart | Movement::DocumentEnd + | Movement::ParagraphForward + | Movement::ParagraphBackward ) } @@ -55,6 +59,8 @@ impl Movement { | Movement::Offset(_) | Movement::DocumentStart | Movement::DocumentEnd + | Movement::ParagraphForward + | Movement::ParagraphBackward ) } @@ -76,7 +82,7 @@ impl Movement { // Selects the previous entry/line Movement::Up if wrapping => (index + (len.saturating_sub(count))) % len, - Movement::Up => (index.saturating_sub(count)), + Movement::Up => index.saturating_sub(count), Movement::Line(position) => match position { // Selects the nth line @@ -84,6 +90,9 @@ impl Movement { LinePosition::First => 0, LinePosition::Last => last, }, + + Movement::ParagraphForward => 0, + Movement::ParagraphBackward => 0, _ => index, } } diff --git a/lapce-core/src/paragraph.rs b/lapce-core/src/paragraph.rs new file mode 100644 index 0000000000..9b57a1d087 --- /dev/null +++ b/lapce-core/src/paragraph.rs @@ -0,0 +1,135 @@ +use lapce_xi_rope::{Cursor, Rope, RopeInfo}; + +/// Describe char classifications used to compose word boundaries +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum CharClassification { + /// Carriage Return (`r`) + Cr, + /// Line feed (`\n`) + Lf, + /// Includes letters and all of non-ascii unicode + Other, +} + +/// A word boundary can be the start of a word, its end or both for punctuation +#[derive(PartialEq, Eq)] +enum ParagraphBoundary { + /// Denote that this is not a boundary + Interior, + /// A boundary indicating the end of a new-line sequence + Start, + /// A boundary indicating the start of a new-line sequence + End, + /// Both start and end boundaries (when we have only one empty + /// line) + Both, +} + +impl ParagraphBoundary { + fn is_start(&self) -> bool { + *self == ParagraphBoundary::Start || *self == ParagraphBoundary::Both + } + + fn is_end(&self) -> bool { + *self == ParagraphBoundary::End || *self == ParagraphBoundary::Both + } + + #[allow(unused)] + fn is_boundary(&self) -> bool { + *self != ParagraphBoundary::Interior + } +} + +/// A cursor providing utility function to navigate the rope +/// by parahraphs boundaries. +/// Boundaries can be the start of a word, its end, punctuation etc. +pub struct ParagraphCursor<'a> { + pub(crate) inner: Cursor<'a, RopeInfo>, +} + +impl<'a> ParagraphCursor<'a> { + pub fn new(text: &'a Rope, pos: usize) -> ParagraphCursor<'a> { + let inner = Cursor::new(text, pos); + ParagraphCursor { inner } + } + + pub fn prev_boundary(&mut self) -> Option { + if let (Some(ch1), Some(ch2), Some(ch3)) = ( + self.inner.prev_codepoint(), + self.inner.prev_codepoint(), + self.inner.prev_codepoint(), + ) { + let mut prop1 = get_char_property(ch1); + let mut prop2 = get_char_property(ch2); + let mut prop3 = get_char_property(ch3); + let mut candidate = self.inner.pos(); + + while let Some(prev) = self.inner.prev_codepoint() { + let prop_prev = get_char_property(prev); + if classify_boundary(prop_prev, prop3, prop2, prop1).is_start() { + break; + } + (prop3, prop2, prop1) = (prop_prev, prop3, prop2); + candidate = self.inner.pos(); + } + + self.inner.set(candidate + 1); + return Some(candidate + 1); + } + + None + } + + pub fn next_boundary(&mut self) -> Option { + if let (Some(ch1), Some(ch2), Some(ch3)) = ( + self.inner.next_codepoint(), + self.inner.next_codepoint(), + self.inner.next_codepoint(), + ) { + let mut prop1 = get_char_property(ch1); + let mut prop2 = get_char_property(ch2); + let mut prop3 = get_char_property(ch3); + let mut candidate = self.inner.pos(); + + while let Some(next) = self.inner.next_codepoint() { + let prop_next = get_char_property(next); + if classify_boundary(prop1, prop2, prop3, prop_next).is_end() { + break; + } + + (prop1, prop2, prop3) = (prop2, prop3, prop_next); + candidate = self.inner.pos(); + } + self.inner.set(candidate - 1); + return Some(candidate - 1); + } + None + } +} + +/// Return the [`CharClassification`] of the input character +pub fn get_char_property(codepoint: char) -> CharClassification { + match codepoint { + '\r' => CharClassification::Cr, + '\n' => CharClassification::Lf, + _ => CharClassification::Other, + } +} + +fn classify_boundary( + before_prev: CharClassification, + prev: CharClassification, + next: CharClassification, + after_next: CharClassification, +) -> ParagraphBoundary { + use self::{CharClassification::*, ParagraphBoundary::*}; + + match (before_prev, prev, next, after_next) { + (Other, Lf, Lf, Other) => Both, + (_, Lf, Lf, Other) => Start, + (Lf, Cr, Lf, Other) => Start, + (Other, Lf, Lf, _) => End, + (Other, Cr, Lf, Cr) => End, + _ => Interior, + } +} diff --git a/lapce-core/src/selection.rs b/lapce-core/src/selection.rs index 7497a6c57a..fdf4a4cb3d 100644 --- a/lapce-core/src/selection.rs +++ b/lapce-core/src/selection.rs @@ -1,9 +1,12 @@ -use serde::{Deserialize, Serialize}; use std::cmp::{max, min, Ordering}; -use xi_rope::{RopeDelta, Transformer}; + +use lapce_xi_rope::{RopeDelta, Transformer}; +use serde::{Deserialize, Serialize}; use crate::cursor::ColPosition; +/// Indicate whether a delta should be applied inside, outside non-caret selection or +/// after a caret selection (see [`Selection::apply_delta`]. #[derive(Copy, Clone)] pub enum InsertDrift { /// Indicates this edit should happen within any (non-caret) selections if possible. @@ -16,11 +19,16 @@ pub enum InsertDrift { #[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)] pub struct SelRegion { + /// Region start offset pub start: usize, + /// Region end offset pub end: usize, + /// Horizontal rules for multiple selection pub horiz: Option, } +/// A selection holding one or more [`SelRegion`]. +/// Regions are kept in order from the leftmost selection to the rightmost selection. #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub struct Selection { regions: Vec, @@ -34,10 +42,13 @@ impl AsRef for Selection { } impl SelRegion { + /// Creates new [`SelRegion`] from `start` and `end` offset. pub fn new(start: usize, end: usize, horiz: Option) -> SelRegion { SelRegion { start, end, horiz } } + /// Creates a caret [`SelRegion`], + /// i.e. `start` and `end` position are both set to `offset` value. pub fn caret(offset: usize) -> SelRegion { SelRegion { start: offset, @@ -46,35 +57,59 @@ impl SelRegion { } } - fn contains(&self, offset: usize) -> bool { - self.min() <= offset && offset <= self.max() - } - + /// Return the minimum value between region's start and end position + /// + /// **Example:** + /// + /// ```rust + /// # use lapce_core::selection::SelRegion; + /// let region = SelRegion::new(1, 10, None); + /// assert_eq!(region.min(), region.start); + /// let region = SelRegion::new(42, 1, None); + /// assert_eq!(region.min(), region.end); + /// ``` pub fn min(self) -> usize { min(self.start, self.end) } + /// Return the maximum value between region's start and end position. + /// + /// **Example:** + /// + /// ```rust + /// # use lapce_core::selection::SelRegion; + /// let region = SelRegion::new(1, 10, None); + /// assert_eq!(region.max(), region.end); + /// let region = SelRegion::new(42, 1, None); + /// assert_eq!(region.max(), region.start); + /// ``` pub fn max(self) -> usize { max(self.start, self.end) } - pub fn start(self) -> usize { - self.start - } - - pub fn end(self) -> usize { - self.end - } - + /// A [`SelRegion`] is considered to be a caret when its start and end position are equal. + /// + /// **Example:** + /// + /// ```rust + /// # use lapce_core::selection::SelRegion; + /// let region = SelRegion::new(1, 1, None); + /// assert!(region.is_caret()); + /// ``` pub fn is_caret(self) -> bool { self.start == self.end } - fn should_merge(self, other: SelRegion) -> bool { - other.min() < self.max() - || ((self.is_caret() || other.is_caret()) && other.min() == self.max()) - } - + /// Merge two [`SelRegion`] into a single one. + /// + /// **Example:** + /// + /// ```rust + /// # use lapce_core::selection::SelRegion; + /// let region = SelRegion::new(1, 2, None); + /// let other = SelRegion::new(3, 4, None); + /// assert_eq!(region.merge_with(other), SelRegion::new(1, 4, None)); + /// ``` pub fn merge_with(self, other: SelRegion) -> SelRegion { let is_forward = self.end >= self.start; let new_min = min(self.min(), other.min()); @@ -86,9 +121,19 @@ impl SelRegion { }; SelRegion::new(start, end, None) } + + fn should_merge(self, other: SelRegion) -> bool { + other.min() < self.max() + || ((self.is_caret() || other.is_caret()) && other.min() == self.max()) + } + + fn contains(&self, offset: usize) -> bool { + self.min() <= offset && offset <= self.max() + } } impl Selection { + /// Creates a new empty [`Selection`] pub fn new() -> Selection { Selection { regions: Vec::new(), @@ -96,6 +141,7 @@ impl Selection { } } + /// Creates a caret [`Selection`], i.e. a selection with a single caret [`SelRegion`] pub fn caret(offset: usize) -> Selection { Selection { regions: vec![SelRegion::caret(offset)], @@ -103,6 +149,8 @@ impl Selection { } } + /// Creates a region [`Selection`], i.e. a selection with a single [`SelRegion`] + /// from `start` to `end` position pub fn region(start: usize, end: usize) -> Selection { Selection { regions: vec![SelRegion { @@ -114,6 +162,18 @@ impl Selection { } } + /// Returns whether this [`Selection`], contains the given `offset` position or not. + /// + /// **Example:** + /// + /// ```rust + /// # use lapce_core::selection::Selection; + /// let selection = Selection::region(0, 2); + /// assert!(selection.contains(0)); + /// assert!(selection.contains(1)); + /// assert!(selection.contains(2)); + /// assert!(!selection.contains(3)); + /// ``` pub fn contains(&self, offset: usize) -> bool { for region in self.regions.iter() { if region.contains(offset) { @@ -123,14 +183,33 @@ impl Selection { false } + /// Returns this selection regions pub fn regions(&self) -> &[SelRegion] { &self.regions } + /// Returns a mutable reference to this selection regions pub fn regions_mut(&mut self) -> &mut [SelRegion] { &mut self.regions } + /// Returns a copy of [`self`] with all regions converted to caret region at their respective + /// [`SelRegion::min`] offset. + /// + /// **Examples:** + /// + /// ```rust + /// # use lapce_core::selection::{Selection, SelRegion}; + /// let mut selection = Selection::new(); + /// selection.add_region(SelRegion::new(1, 3, None)); + /// selection.add_region(SelRegion::new(6, 12, None)); + /// selection.add_region(SelRegion::new(24, 48, None)); + /// + /// assert_eq!(selection.min().regions(), vec![ + /// SelRegion::caret(1), + /// SelRegion::caret(6), + /// SelRegion::caret(24) + /// ]); pub fn min(&self) -> Selection { let mut selection = Self::new(); for region in &self.regions { @@ -140,42 +219,56 @@ impl Selection { selection } + /// Get the leftmost [`SelRegion`] in this selection if present. pub fn first(&self) -> Option<&SelRegion> { - if self.is_empty() { - return None; - } - Some(&self.regions[0]) + self.regions.get(0) } + /// Get the rightmost [`SelRegion`] in this selection if present. pub fn last(&self) -> Option<&SelRegion> { - if self.is_empty() { - return None; - } - Some(&self.regions[self.len() - 1]) + self.regions.get(self.len() - 1) } + /// Get the last inserted [`SelRegion`] in this selection if present. pub fn last_inserted(&self) -> Option<&SelRegion> { - if self.is_empty() { - return None; - } - Some(&self.regions[self.last_inserted]) + self.regions.get(self.last_inserted) } + /// Get a mutable reference to the last inserted [`SelRegion`] in this selection if present. pub fn last_inserted_mut(&mut self) -> Option<&mut SelRegion> { - if self.is_empty() { - return None; - } - Some(&mut self.regions[self.last_inserted]) + self.regions.get_mut(self.last_inserted) } + /// The number of [`SelRegion`] in this selection. pub fn len(&self) -> usize { self.regions.len() } + /// A [`Selection`] is considered to be a caret if it contains + /// only caret [`SelRegion`] (see [`SelRegion::is_caret`]) + pub fn is_caret(&self) -> bool { + self.regions.iter().all(|region| region.is_caret()) + } + + /// Returns `true` if `self` has zero [`SelRegion`] pub fn is_empty(&self) -> bool { self.len() == 0 } + /// Returns the minimal offset across all region of this selection. + /// + /// This function panics if the selection is empty. + /// + /// **Example:** + /// + /// ```rust + /// # use lapce_core::selection::{Selection, SelRegion}; + /// let mut selection = Selection::new(); + /// selection.add_region(SelRegion::caret(4)); + /// selection.add_region(SelRegion::new(0, 12, None)); + /// selection.add_region(SelRegion::new(24, 48, None)); + /// assert_eq!(selection.min_offset(), 0); + /// ``` pub fn min_offset(&self) -> usize { let mut offset = self.regions()[0].min(); for region in &self.regions { @@ -184,6 +277,20 @@ impl Selection { offset } + /// Returns the maximal offset across all region of this selection. + /// + /// This function panics if the selection is empty. + /// + /// **Example:** + /// + /// ```rust + /// # use lapce_core::selection::{Selection, SelRegion}; + /// let mut selection = Selection::new(); + /// selection.add_region(SelRegion::caret(4)); + /// selection.add_region(SelRegion::new(0, 12, None)); + /// selection.add_region(SelRegion::new(24, 48, None)); + /// assert_eq!(selection.max_offset(), 48); + /// ``` pub fn max_offset(&self) -> usize { let mut offset = self.regions()[0].max(); for region in &self.regions { @@ -192,6 +299,25 @@ impl Selection { offset } + /// Returns regions in [`self`] overlapping or fully enclosed in the provided + /// `start` to `end` range. + /// + /// **Example:** + /// + /// ```rust + /// # use lapce_core::selection::{Selection, SelRegion}; + /// let mut selection = Selection::new(); + /// selection.add_region(SelRegion::new(0, 3, None)); + /// selection.add_region(SelRegion::new(3, 6, None)); + /// selection.add_region(SelRegion::new(7, 8, None)); + /// selection.add_region(SelRegion::new(9, 11, None)); + /// let regions = selection.regions_in_range(5, 10); + /// assert_eq!(regions, vec![ + /// SelRegion::new(3, 6, None), + /// SelRegion::new(7, 8, None), + /// SelRegion::new(9, 11, None) + /// ]); + /// ``` pub fn regions_in_range(&self, start: usize, end: usize) -> &[SelRegion] { let first = self.search(start); let mut last = self.search(end); @@ -201,29 +327,23 @@ impl Selection { &self.regions[first..last] } - pub fn search(&self, offset: usize) -> usize { - if self.regions.is_empty() || offset > self.regions.last().unwrap().max() { - return self.regions.len(); - } - match self.regions.binary_search_by(|r| r.max().cmp(&offset)) { - Ok(ix) => ix, - Err(ix) => ix, - } - } - - pub fn search_min(&self, offset: usize) -> usize { - if self.regions.is_empty() || offset > self.regions.last().unwrap().max() { - return self.regions.len(); - } - match self - .regions - .binary_search_by(|r| r.min().cmp(&(offset + 1))) - { - Ok(ix) => ix, - Err(ix) => ix, - } - } - + /// Returns regions in [`self`] starting between `start` to `end` range. + /// + /// **Example:** + /// + /// ```rust + /// # use lapce_core::selection::{Selection, SelRegion}; + /// let mut selection = Selection::new(); + /// selection.add_region(SelRegion::new(0, 3, None)); + /// selection.add_region(SelRegion::new(3, 6, None)); + /// selection.add_region(SelRegion::new(7, 8, None)); + /// selection.add_region(SelRegion::new(9, 11, None)); + /// let regions = selection.full_regions_in_range(5, 10); + /// assert_eq!(regions, vec![ + /// SelRegion::new(7, 8, None), + /// SelRegion::new(9, 11, None) + /// ]); + /// ``` pub fn full_regions_in_range(&self, start: usize, end: usize) -> &[SelRegion] { let first = self.search_min(start); let mut last = self.search_min(end); @@ -233,24 +353,56 @@ impl Selection { &self.regions[first..last] } - pub fn delete_range(&mut self, start: usize, end: usize, delete_adjacent: bool) { + /// Deletes regions in [`self`] overlapping or enclosing in `start` to `end` range. + /// + /// **Example:** + /// + /// ```rust + /// # use lapce_core::selection::{Selection, SelRegion}; + /// let mut selection = Selection::new(); + /// selection.add_region(SelRegion::new(0, 3, None)); + /// selection.add_region(SelRegion::new(3, 6, None)); + /// selection.add_region(SelRegion::new(7, 8, None)); + /// selection.add_region(SelRegion::new(9, 11, None)); + /// selection.delete_range(5, 10); + /// assert_eq!(selection.regions(), vec![SelRegion::new(0, 3, None)]); + /// ``` + pub fn delete_range(&mut self, start: usize, end: usize) { let mut first = self.search(start); let mut last = self.search(end); if first >= self.regions.len() { return; } - if !delete_adjacent && self.regions[first].max() == start { + if self.regions[first].max() == start { first += 1; } - if last < self.regions.len() - && ((delete_adjacent && self.regions[last].min() <= end) - || (!delete_adjacent && self.regions[last].min() < end)) - { + if last < self.regions.len() && self.regions[last].min() < end { last += 1; } remove_n_at(&mut self.regions, first, last - first); } + /// Add a regions to [`self`]. Note that if provided region overlap + /// on of the selection regions they will be merged in a single region. + /// + /// **Example:** + /// + /// ```rust + /// # use lapce_core::selection::{Selection, SelRegion}; + /// let mut selection = Selection::new(); + /// // Overlapping + /// selection.add_region(SelRegion::new(0, 4, None)); + /// selection.add_region(SelRegion::new(3, 6, None)); + /// assert_eq!(selection.regions(), vec![SelRegion::new(0, 6, None)]); + /// // Non-overlapping + /// let mut selection = Selection::new(); + /// selection.add_region(SelRegion::new(0, 3, None)); + /// selection.add_region(SelRegion::new(3, 6, None)); + /// assert_eq!(selection.regions(), vec![ + /// SelRegion::new(0, 3, None), + /// SelRegion::new(3, 6, None) + /// ]); + /// ``` pub fn add_region(&mut self, region: SelRegion) { let mut ix = self.search(region.min()); if ix == self.regions.len() { @@ -283,6 +435,12 @@ impl Selection { } } + /// Apply [`xi_rope::RopeDelta`] to this selection. + /// Typically used to apply an edit to a buffer and update its selections + /// **Parameters*:* + /// - `delta`[`xi_rope::RopeDelta`] + /// - `after` parameter indicate if the delta should be applied before or after the selection + /// - `drift` see [`InsertDrift`] pub fn apply_delta( &self, delta: &RopeDelta, @@ -292,10 +450,9 @@ impl Selection { let mut result = Selection::new(); let mut transformer = Transformer::new(delta); for region in self.regions() { - let is_caret = region.start == region.end; let is_region_forward = region.start < region.end; - let (start_after, end_after) = match (drift, is_caret) { + let (start_after, end_after) = match (drift, region.is_caret()) { (InsertDrift::Inside, false) => { (!is_region_forward, is_region_forward) } @@ -315,6 +472,7 @@ impl Selection { result } + /// Returns cursor position, which corresponds to last inserted region `end` offset, pub fn get_cursor_offset(&self) -> usize { if self.is_empty() { return 0; @@ -322,6 +480,7 @@ impl Selection { self.regions[self.last_inserted].end } + /// Replaces last inserted [`SelRegion`] of this selection with the provided one. pub fn replace_last_inserted_region(&mut self, region: SelRegion) { if self.is_empty() { self.add_region(region); @@ -331,6 +490,29 @@ impl Selection { self.regions.remove(self.last_inserted); self.add_region(region); } + + fn search(&self, offset: usize) -> usize { + if self.regions.is_empty() || offset > self.regions.last().unwrap().max() { + return self.regions.len(); + } + match self.regions.binary_search_by(|r| r.max().cmp(&offset)) { + Ok(ix) => ix, + Err(ix) => ix, + } + } + + fn search_min(&self, offset: usize) -> usize { + if self.regions.is_empty() || offset > self.regions.last().unwrap().max() { + return self.regions.len(); + } + match self + .regions + .binary_search_by(|r| r.min().cmp(&(offset + 1))) + { + Ok(ix) => ix, + Err(ix) => ix, + } + } } impl Default for Selection { @@ -350,3 +532,196 @@ fn remove_n_at(v: &mut Vec, index: usize, n: usize) { _ => (), }; } + +#[cfg(test)] +mod test { + use crate::{ + buffer::Buffer, + editor::EditType, + selection::{InsertDrift, SelRegion, Selection}, + }; + + #[test] + fn should_return_selection_region_min() { + let region = SelRegion::new(1, 10, None); + assert_eq!(region.min(), region.start); + + let region = SelRegion::new(42, 1, None); + assert_eq!(region.min(), region.end); + } + + #[test] + fn should_return_selection_region_max() { + let region = SelRegion::new(1, 10, None); + assert_eq!(region.max(), region.end); + + let region = SelRegion::new(42, 1, None); + assert_eq!(region.max(), region.start); + } + + #[test] + fn is_caret_should_return_true() { + let region = SelRegion::new(1, 10, None); + assert!(!region.is_caret()); + } + + #[test] + fn is_caret_should_return_false() { + let region = SelRegion::new(1, 1, None); + assert!(region.is_caret()); + } + + #[test] + fn should_merge_regions() { + let region = SelRegion::new(1, 2, None); + let other = SelRegion::new(3, 4, None); + assert_eq!(region.merge_with(other), SelRegion::new(1, 4, None)); + + let region = SelRegion::new(2, 1, None); + let other = SelRegion::new(4, 3, None); + assert_eq!(region.merge_with(other), SelRegion::new(4, 1, None)); + + let region = SelRegion::new(1, 1, None); + let other = SelRegion::new(6, 6, None); + assert_eq!(region.merge_with(other), SelRegion::new(1, 6, None)); + } + + #[test] + fn selection_should_be_caret() { + let mut selection = Selection::new(); + selection.add_region(SelRegion::caret(1)); + selection.add_region(SelRegion::caret(6)); + assert!(selection.is_caret()); + } + + #[test] + fn selection_should_not_be_caret() { + let mut selection = Selection::new(); + selection.add_region(SelRegion::caret(1)); + selection.add_region(SelRegion::new(4, 6, None)); + assert!(!selection.is_caret()); + } + + #[test] + fn should_return_min_selection() { + let mut selection = Selection::new(); + selection.add_region(SelRegion::new(1, 3, None)); + selection.add_region(SelRegion::new(4, 6, None)); + assert_eq!( + selection.min().regions, + vec![SelRegion::caret(1), SelRegion::caret(4)] + ); + } + + #[test] + fn selection_should_contains_region() { + let selection = Selection::region(0, 2); + assert!(selection.contains(0)); + assert!(selection.contains(1)); + assert!(selection.contains(2)); + assert!(!selection.contains(3)); + } + + #[test] + fn should_return_last_inserted_region() { + let mut selection = Selection::region(5, 6); + selection.add_region(SelRegion::caret(1)); + assert_eq!(selection.last_inserted(), Some(&SelRegion::caret(1))); + } + + #[test] + fn should_return_last_region() { + let mut selection = Selection::region(5, 6); + selection.add_region(SelRegion::caret(1)); + assert_eq!(selection.last(), Some(&SelRegion::new(5, 6, None))); + } + + #[test] + fn should_return_first_region() { + let mut selection = Selection::region(5, 6); + selection.add_region(SelRegion::caret(1)); + assert_eq!(selection.first(), Some(&SelRegion::caret(1))); + } + + #[test] + fn should_return_regions_in_range() { + let mut selection = Selection::new(); + selection.add_region(SelRegion::new(0, 3, None)); + selection.add_region(SelRegion::new(3, 6, None)); + selection.add_region(SelRegion::new(7, 8, None)); + selection.add_region(SelRegion::new(9, 11, None)); + + let regions = selection.regions_in_range(5, 10); + + assert_eq!( + regions, + vec![ + SelRegion::new(3, 6, None), + SelRegion::new(7, 8, None), + SelRegion::new(9, 11, None), + ] + ); + } + + #[test] + fn should_return_regions_in_full_range() { + let mut selection = Selection::new(); + selection.add_region(SelRegion::new(0, 3, None)); + selection.add_region(SelRegion::new(3, 6, None)); + selection.add_region(SelRegion::new(7, 8, None)); + selection.add_region(SelRegion::new(9, 11, None)); + + let regions = selection.full_regions_in_range(5, 10); + + assert_eq!( + regions, + vec![SelRegion::new(7, 8, None), SelRegion::new(9, 11, None),] + ); + } + + #[test] + fn should_delete_regions() { + let mut selection = Selection::new(); + selection.add_region(SelRegion::new(0, 3, None)); + selection.add_region(SelRegion::new(3, 6, None)); + selection.add_region(SelRegion::new(7, 8, None)); + selection.add_region(SelRegion::new(9, 11, None)); + selection.delete_range(5, 10); + assert_eq!(selection.regions(), vec![SelRegion::new(0, 3, None)]); + } + + #[test] + fn should_add_regions() { + let mut selection = Selection::new(); + selection.add_region(SelRegion::new(0, 3, None)); + selection.add_region(SelRegion::new(3, 6, None)); + assert_eq!( + selection.regions(), + vec![SelRegion::new(0, 3, None), SelRegion::new(3, 6, None),] + ); + } + + #[test] + fn should_add_and_merge_regions() { + let mut selection = Selection::new(); + + selection.add_region(SelRegion::new(0, 4, None)); + selection.add_region(SelRegion::new(3, 6, None)); + assert_eq!(selection.regions(), vec![SelRegion::new(0, 6, None)]); + } + + #[test] + fn should_apply_delta_after_insertion() { + let selection = Selection::caret(0); + + let (mock_delta, _, _) = { + let mut buffer = Buffer::new(""); + buffer.edit(&[(selection.clone(), "Hello")], EditType::InsertChars) + }; + + assert_eq!( + selection.apply_delta(&mock_delta, true, InsertDrift::Inside), + Selection::caret(5) + ); + } +} diff --git a/lapce-core/src/style.rs b/lapce-core/src/style.rs index 959d1e9548..8a295fa9a8 100644 --- a/lapce-core/src/style.rs +++ b/lapce-core/src/style.rs @@ -1,19 +1,8 @@ -use std::{ - iter, mem, ops, str, - sync::atomic::{AtomicUsize, Ordering}, -}; +use std::str; use lapce_rpc::style::{LineStyle, Style}; -use thiserror::Error; -use tree_sitter::{ - Language, LossyUtf8, Node, Point, Query, QueryCaptures, QueryCursor, QueryError, - QueryMatch, Range, Tree, -}; -use xi_rope::{spans::Spans, Rope}; +use lapce_xi_rope::{spans::Spans, LinesMetric, Rope}; -const CANCELLATION_CHECK_INTERVAL: usize = 100; -const BUFFER_HTML_RESERVE_CAPACITY: usize = 10 * 1024; -const BUFFER_LINES_RESERVE_CAPACITY: usize = 1000; pub const SCOPES: &[&str] = &[ "constant", "type", @@ -24,6 +13,7 @@ pub const SCOPES: &[&str] = &[ "function", "label", "keyword", + "keyword.control", "string", "variable", "variable.other.member", @@ -31,928 +21,32 @@ pub const SCOPES: &[&str] = &[ "attribute", "escape", "embedded", + "symbol", + "punctuation", + "punctuation.special", + "punctuation.delimiter", + "text", + "text.literal", + "text.title", + "text.uri", + "text.reference", + "string.escape", + "conceal", + "none", + "tag", ]; -/// Indicates which highlight should be applied to a region of source code. -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub struct Highlight(pub usize); - -/// Represents the reason why syntax highlighting failed. -#[derive(Debug, Error, PartialEq, Eq)] -pub enum Error { - #[error("Cancelled")] - Cancelled, - #[error("Invalid language")] - InvalidLanguage, - #[error("Unknown error")] - Unknown, -} - -/// Represents a single step in rendering a syntax-highlighted document. -#[derive(Copy, Clone, Debug)] -pub enum HighlightEvent { - Source { start: usize, end: usize }, - HighlightStart(Highlight), - HighlightEnd, -} - -/// Contains the data needed to highlight code written in a particular language. -/// -/// This struct is immutable and can be shared between threads. -pub struct HighlightConfiguration { - pub language: Language, - pub query: Query, - combined_injections_query: Option, - locals_pattern_index: usize, - highlights_pattern_index: usize, - highlight_indices: Vec>, - non_local_variable_patterns: Vec, - injection_content_capture_index: Option, - injection_language_capture_index: Option, - local_scope_capture_index: Option, - local_def_capture_index: Option, - local_def_value_capture_index: Option, - local_ref_capture_index: Option, -} - -/// Performs syntax highlighting, recognizing a given list of highlight names. -/// -/// For the best performance `Highlighter` values should be reused between -/// syntax highlighting calls. A separate highlighter is needed for each thread that -/// is performing highlighting. -pub struct Highlighter { - cursors: Vec, -} - -/// Converts a general-purpose syntax highlighting iterator into a sequence of lines of HTML. -pub struct HtmlRenderer { - pub html: Vec, - pub line_offsets: Vec, - carriage_return_highlight: Option, -} - -#[derive(Debug)] -struct LocalDef<'a> { - name: &'a str, - value_range: ops::Range, - highlight: Option, -} - -#[derive(Debug)] -struct LocalScope<'a> { - inherits: bool, - range: ops::Range, - local_defs: Vec>, -} - -struct HighlightIter<'a, F> -where - F: FnMut(&str) -> Option<&'a HighlightConfiguration> + 'a, -{ - tree: Tree, - source: &'a [u8], - byte_offset: usize, - highlighter: &'a mut Highlighter, - injection_callback: F, - cancellation_flag: Option<&'a AtomicUsize>, - layers: Vec>, - iter_count: usize, - next_event: Option, - last_highlight_range: Option<(usize, usize, usize)>, -} - -struct HighlightIterLayer<'a> { - _tree: Tree, - cursor: QueryCursor, - captures: iter::Peekable>, - config: &'a HighlightConfiguration, - highlight_end_stack: Vec, - scope_stack: Vec>, - ranges: Vec, - depth: usize, -} - -impl Highlight { - pub fn str(&self) -> &str { - SCOPES[self.0] - } -} - -impl Highlighter { - pub fn new() -> Self { - Highlighter { - cursors: Vec::new(), - } - } - - /// Iterate over the highlighted regions for a given slice of source code. - pub fn highlight<'a>( - &'a mut self, - tree: Tree, - config: &'a HighlightConfiguration, - source: &'a [u8], - cancellation_flag: Option<&'a AtomicUsize>, - mut injection_callback: impl FnMut(&str) -> Option<&'a HighlightConfiguration> - + 'a, - ) -> impl Iterator> + 'a { - let layers = HighlightIterLayer::new( - tree.clone(), - source, - self, - &mut injection_callback, - config, - 0, - vec![Range { - start_byte: 0, - end_byte: usize::MAX, - start_point: Point::new(0, 0), - end_point: Point::new(usize::MAX, usize::MAX), - }], - ); - assert_ne!(layers.len(), 0); - let mut result = HighlightIter { - tree, - source, - byte_offset: 0, - injection_callback, - cancellation_flag, - highlighter: self, - iter_count: 0, - layers, - next_event: None, - last_highlight_range: None, - }; - result.sort_layers(); - result - } -} - -impl Default for Highlighter { - fn default() -> Self { - Self::new() - } -} - -impl HighlightConfiguration { - /// Creates a `HighlightConfiguration` for a given `Language` and set of highlighting - /// queries. - /// - /// # Parameters - /// - /// * `language` - The Tree-sitter `Language` that should be used for parsing. - /// * `highlights_query` - A string containing tree patterns for syntax highlighting. This - /// should be non-empty, otherwise no syntax highlights will be added. - /// * `injections_query` - A string containing tree patterns for injecting other languages - /// into the document. This can be empty if no injections are desired. - /// * `locals_query` - A string containing tree patterns for tracking local variable - /// definitions and references. This can be empty if local variable tracking is not needed. - /// - /// Returns a `HighlightConfiguration` that can then be used with the `highlight` method. - pub fn new( - language: Language, - highlights_query: &str, - injection_query: &str, - locals_query: &str, - ) -> Result { - // Concatenate the query strings, keeping track of the start offset of each section. - let mut query_source = String::new(); - query_source.push_str(injection_query); - let locals_query_offset = query_source.len(); - query_source.push_str(locals_query); - let highlights_query_offset = query_source.len(); - query_source.push_str(highlights_query); - - // Construct a single query by concatenating the three query strings, but record the - // range of pattern indices that belong to each individual string. - let mut query = Query::new(language, &query_source)?; - let mut locals_pattern_index = 0; - let mut highlights_pattern_index = 0; - for i in 0..(query.pattern_count()) { - let pattern_offset = query.start_byte_for_pattern(i); - if pattern_offset < highlights_query_offset { - if pattern_offset < highlights_query_offset { - highlights_pattern_index += 1; - } - if pattern_offset < locals_query_offset { - locals_pattern_index += 1; - } - } - } - - // Construct a separate query just for dealing with the 'combined injections'. - // Disable the combined injection patterns in the main query. - let mut combined_injections_query = Query::new(language, injection_query)?; - let mut has_combined_queries = false; - for pattern_index in 0..locals_pattern_index { - let settings = query.property_settings(pattern_index); - if settings.iter().any(|s| &*s.key == "injection.combined") { - has_combined_queries = true; - query.disable_pattern(pattern_index); - } else { - combined_injections_query.disable_pattern(pattern_index); - } - } - let combined_injections_query = if has_combined_queries { - Some(combined_injections_query) - } else { - None - }; - - // Find all of the highlighting patterns that are disabled for nodes that - // have been identified as local variables. - let non_local_variable_patterns = (0..query.pattern_count()) - .map(|i| { - query.property_predicates(i).iter().any(|(prop, positive)| { - !*positive && prop.key.as_ref() == "local" - }) - }) - .collect(); - - // Store the numeric ids for all of the special captures. - let mut injection_content_capture_index = None; - let mut injection_language_capture_index = None; - let mut local_def_capture_index = None; - let mut local_def_value_capture_index = None; - let mut local_ref_capture_index = None; - let mut local_scope_capture_index = None; - for (i, name) in query.capture_names().iter().enumerate() { - let i = Some(i as u32); - match name.as_str() { - "injection.content" => injection_content_capture_index = i, - "injection.language" => injection_language_capture_index = i, - "local.definition" => local_def_capture_index = i, - "local.definition-value" => local_def_value_capture_index = i, - "local.reference" => local_ref_capture_index = i, - "local.scope" => local_scope_capture_index = i, - _ => {} - } - } - - let highlight_indices = vec![None; query.capture_names().len()]; - let mut conf = HighlightConfiguration { - language, - query, - combined_injections_query, - locals_pattern_index, - highlights_pattern_index, - highlight_indices, - non_local_variable_patterns, - injection_content_capture_index, - injection_language_capture_index, - local_def_capture_index, - local_def_value_capture_index, - local_ref_capture_index, - local_scope_capture_index, - }; - conf.configure(SCOPES); - Ok(conf) - } - - /// Get a slice containing all of the highlight names used in the configuration. - pub fn names(&self) -> &[String] { - self.query.capture_names() - } - - /// Set the list of recognized highlight names. - /// - /// Tree-sitter syntax-highlighting queries specify highlights in the form of dot-separated - /// highlight names like `punctuation.bracket` and `function.method.builtin`. Consumers of - /// these queries can choose to recognize highlights with different levels of specificity. - /// For example, the string `function.builtin` will match against `function.method.builtin` - /// and `function.builtin.constructor`, but will not match `function.method`. - /// - /// When highlighting, results are returned as `Highlight` values, which contain the index - /// of the matched highlight this list of highlight names. - fn configure(&mut self, recognized_names: &[impl AsRef]) { - let mut capture_parts = Vec::new(); - self.highlight_indices.clear(); - self.highlight_indices - .extend(self.query.capture_names().iter().map(move |capture_name| { - capture_parts.clear(); - capture_parts.extend(capture_name.split('.')); - - let mut best_index = None; - let mut best_match_len = 0; - for (i, recognized_name) in recognized_names.iter().enumerate() { - let mut len = 0; - let mut matches = true; - for part in recognized_name.as_ref().split('.') { - len += 1; - if !capture_parts.contains(&part) { - matches = false; - break; - } - } - if matches && len > best_match_len { - best_index = Some(i); - best_match_len = len; - } - } - best_index.map(Highlight) - })); - } -} - -impl<'a> HighlightIterLayer<'a> { - /// Create a new 'layer' of highlighting for this document. - /// - /// In the even that the new layer contains "combined injections" (injections where multiple - /// disjoint ranges are parsed as one syntax tree), these will be eagerly processed and - /// added to the returned vector. - fn new Option<&'a HighlightConfiguration> + 'a>( - tree: Tree, - source: &'a [u8], - highlighter: &mut Highlighter, - injection_callback: &mut F, - mut config: &'a HighlightConfiguration, - mut depth: usize, - mut ranges: Vec, - ) -> Vec { - let mut result = Vec::with_capacity(1); - let mut queue = Vec::new(); - loop { - let tree = tree.clone(); - let mut cursor = - highlighter.cursors.pop().unwrap_or_else(QueryCursor::new); - - // Process combined injections. - if let Some(combined_injections_query) = - &config.combined_injections_query - { - let mut injections_by_pattern_index = vec![ - (None, Vec::new(), false); - combined_injections_query - .pattern_count() - ]; - let matches = cursor.matches( - combined_injections_query, - tree.root_node(), - source, - ); - for mat in matches { - let entry = &mut injections_by_pattern_index[mat.pattern_index]; - let (language_name, content_node, include_children) = - injection_for_match( - config, - combined_injections_query, - &mat, - source, - ); - if language_name.is_some() { - entry.0 = language_name; - } - if let Some(content_node) = content_node { - entry.1.push(content_node); - } - entry.2 = include_children; - } - for (lang_name, content_nodes, includes_children) in - injections_by_pattern_index - { - if let (Some(lang_name), false) = - (lang_name, content_nodes.is_empty()) - { - if let Some(next_config) = (injection_callback)(lang_name) { - let ranges = Self::intersect_ranges( - &ranges, - &content_nodes, - includes_children, - ); - if !ranges.is_empty() { - queue.push((next_config, depth + 1, ranges)); - } - } - } - } - } - - // The `captures` iterator borrows the `Tree` and the `QueryCursor`, which - // prevents them from being moved. But both of these values are really just - // pointers, so it's actually ok to move them. - let tree_ref = unsafe { mem::transmute::<_, &'static Tree>(&tree) }; - let cursor_ref = unsafe { - mem::transmute::<_, &'static mut QueryCursor>(&mut cursor) - }; - let captures = cursor_ref - .captures(&config.query, tree_ref.root_node(), source) - .peekable(); - - result.push(HighlightIterLayer { - highlight_end_stack: Vec::new(), - scope_stack: vec![LocalScope { - inherits: false, - range: 0..usize::MAX, - local_defs: Vec::new(), - }], - cursor, - depth, - _tree: tree, - captures, - config, - ranges, - }); - - if queue.is_empty() { - break; - } else { - let (next_config, next_depth, next_ranges) = queue.remove(0); - config = next_config; - depth = next_depth; - ranges = next_ranges; - } - } - - result - } - - // Compute the ranges that should be included when parsing an injection. - // This takes into account three things: - // * `parent_ranges` - The ranges must all fall within the *current* layer's ranges. - // * `nodes` - Every injection takes place within a set of nodes. The injection ranges - // are the ranges of those nodes. - // * `includes_children` - For some injections, the content nodes' children should be - // excluded from the nested document, so that only the content nodes' *own* content - // is reparsed. For other injections, the content nodes' entire ranges should be - // reparsed, including the ranges of their children. - fn intersect_ranges( - parent_ranges: &[Range], - nodes: &[Node], - includes_children: bool, - ) -> Vec { - let mut cursor = nodes[0].walk(); - let mut result = Vec::new(); - let mut parent_range_iter = parent_ranges.iter(); - let mut parent_range = parent_range_iter.next().expect( - "Layers should only be constructed with non-empty ranges vectors", - ); - for node in nodes.iter() { - let mut preceding_range = Range { - start_byte: 0, - start_point: Point::new(0, 0), - end_byte: node.start_byte(), - end_point: node.start_position(), - }; - let following_range = Range { - start_byte: node.end_byte(), - start_point: node.end_position(), - end_byte: usize::MAX, - end_point: Point::new(usize::MAX, usize::MAX), - }; - - for excluded_range in node - .children(&mut cursor) - .filter_map(|child| { - if includes_children { - None - } else { - Some(child.range()) - } - }) - .chain([following_range].iter().cloned()) - { - let mut range = Range { - start_byte: preceding_range.end_byte, - start_point: preceding_range.end_point, - end_byte: excluded_range.start_byte, - end_point: excluded_range.start_point, - }; - preceding_range = excluded_range; - - if range.end_byte < parent_range.start_byte { - continue; - } - - while parent_range.start_byte <= range.end_byte { - if parent_range.end_byte > range.start_byte { - if range.start_byte < parent_range.start_byte { - range.start_byte = parent_range.start_byte; - range.start_point = parent_range.start_point; - } - - if parent_range.end_byte < range.end_byte { - if range.start_byte < parent_range.end_byte { - result.push(Range { - start_byte: range.start_byte, - start_point: range.start_point, - end_byte: parent_range.end_byte, - end_point: parent_range.end_point, - }); - } - range.start_byte = parent_range.end_byte; - range.start_point = parent_range.end_point; - } else { - if range.start_byte < range.end_byte { - result.push(range); - } - break; - } - } - - if let Some(next_range) = parent_range_iter.next() { - parent_range = next_range; - } else { - return result; - } - } - } - } - result - } - - // First, sort scope boundaries by their byte offset in the document. At a - // given position, emit scope endings before scope beginnings. Finally, emit - // scope boundaries from deeper layers first. - fn sort_key(&mut self) -> Option<(usize, bool, isize)> { - let depth = -(self.depth as isize); - let next_start = self - .captures - .peek() - .map(|(m, i)| m.captures[*i].node.start_byte()); - let next_end = self.highlight_end_stack.last().cloned(); - match (next_start, next_end) { - (Some(start), Some(end)) => { - if start < end { - Some((start, true, depth)) - } else { - Some((end, false, depth)) - } - } - (Some(i), None) => Some((i, true, depth)), - (None, Some(j)) => Some((j, false, depth)), - _ => None, - } - } -} - -impl<'a, F> HighlightIter<'a, F> -where - F: FnMut(&str) -> Option<&'a HighlightConfiguration> + 'a, -{ - fn emit_event( - &mut self, - offset: usize, - event: Option, - ) -> Option> { - let result; - if self.byte_offset < offset { - result = Some(Ok(HighlightEvent::Source { - start: self.byte_offset, - end: offset, - })); - self.byte_offset = offset; - self.next_event = event; - } else { - result = event.map(Ok); - } - self.sort_layers(); - result - } - - fn sort_layers(&mut self) { - while !self.layers.is_empty() { - if let Some(sort_key) = self.layers[0].sort_key() { - let mut i = 0; - while i + 1 < self.layers.len() { - if let Some(next_offset) = self.layers[i + 1].sort_key() { - if next_offset < sort_key { - i += 1; - continue; - } - } - break; - } - if i > 0 { - self.layers[0..(i + 1)].rotate_left(1); - } - break; - } else { - let layer = self.layers.remove(0); - self.highlighter.cursors.push(layer.cursor); - } - } - } - - fn insert_layer(&mut self, mut layer: HighlightIterLayer<'a>) { - if let Some(sort_key) = layer.sort_key() { - let mut i = 1; - while i < self.layers.len() { - if let Some(sort_key_i) = self.layers[i].sort_key() { - if sort_key_i > sort_key { - self.layers.insert(i, layer); - return; - } - i += 1; - } else { - self.layers.remove(i); - } - } - self.layers.push(layer); - } - } -} - -impl<'a, F> Iterator for HighlightIter<'a, F> -where - F: FnMut(&str) -> Option<&'a HighlightConfiguration> + 'a, -{ - type Item = Result; - - fn next(&mut self) -> Option { - 'main: loop { - // If we've already determined the next highlight boundary, just return it. - if let Some(e) = self.next_event.take() { - return Some(Ok(e)); - } - - // Periodically check for cancellation, returning `Cancelled` error if the - // cancellation flag was flipped. - if let Some(cancellation_flag) = self.cancellation_flag { - self.iter_count += 1; - if self.iter_count >= CANCELLATION_CHECK_INTERVAL { - self.iter_count = 0; - if cancellation_flag.load(Ordering::Relaxed) != 0 { - return Some(Err(Error::Cancelled)); - } - } - } - - // If none of the layers have any more highlight boundaries, terminate. - if self.layers.is_empty() { - return if self.byte_offset < self.source.len() { - let result = Some(Ok(HighlightEvent::Source { - start: self.byte_offset, - end: self.source.len(), - })); - self.byte_offset = self.source.len(); - result - } else { - None - }; - } - - // Get the next capture from whichever layer has the earliest highlight boundary. - let range; - let layer = &mut self.layers[0]; - if let Some((next_match, capture_index)) = layer.captures.peek() { - let next_capture = next_match.captures[*capture_index]; - range = next_capture.node.byte_range(); - - // If any previous highlight ends before this node starts, then before - // processing this capture, emit the source code up until the end of the - // previous highlight, and an end event for that highlight. - if let Some(end_byte) = layer.highlight_end_stack.last().cloned() { - if end_byte <= range.start { - layer.highlight_end_stack.pop(); - return self.emit_event( - end_byte, - Some(HighlightEvent::HighlightEnd), - ); - } - } - } - // If there are no more captures, then emit any remaining highlight end events. - // And if there are none of those, then just advance to the end of the document. - else if let Some(end_byte) = layer.highlight_end_stack.last().cloned() - { - layer.highlight_end_stack.pop(); - return self - .emit_event(end_byte, Some(HighlightEvent::HighlightEnd)); - } else { - return self.emit_event(self.source.len(), None); - }; - - let (mut match_, capture_index) = layer.captures.next().unwrap(); - let mut capture = match_.captures[capture_index]; - - // If this capture represents an injection, then process the injection. - if match_.pattern_index < layer.config.locals_pattern_index { - let (language_name, content_node, include_children) = - injection_for_match( - layer.config, - &layer.config.query, - &match_, - self.source, - ); - - // Explicitly remove this match so that none of its other captures will remain - // in the stream of captures. - match_.remove(); - - // If a language is found with the given name, then add a new language layer - // to the highlighted document. - if let (Some(language_name), Some(content_node)) = - (language_name, content_node) - { - if let Some(config) = (self.injection_callback)(language_name) { - let ranges = HighlightIterLayer::intersect_ranges( - &self.layers[0].ranges, - &[content_node], - include_children, - ); - if !ranges.is_empty() { - for layer in HighlightIterLayer::new( - self.tree.clone(), - self.source, - self.highlighter, - &mut self.injection_callback, - config, - self.layers[0].depth + 1, - ranges, - ) { - self.insert_layer(layer); - } - } - } - } - - self.sort_layers(); - continue 'main; - } - - // Remove from the local scope stack any local scopes that have already ended. - while range.start > layer.scope_stack.last().unwrap().range.end { - layer.scope_stack.pop(); - } - - // If this capture is for tracking local variables, then process the - // local variable info. - let mut reference_highlight = None; - let mut definition_highlight = None; - while match_.pattern_index < layer.config.highlights_pattern_index { - // If the node represents a local scope, push a new local scope onto - // the scope stack. - if Some(capture.index) == layer.config.local_scope_capture_index { - definition_highlight = None; - let mut scope = LocalScope { - inherits: true, - range: range.clone(), - local_defs: Vec::new(), - }; - for prop in - layer.config.query.property_settings(match_.pattern_index) - { - if prop.key.as_ref() == "local.scope-inherits" { - scope.inherits = prop - .value - .as_ref() - .map_or(true, |r| r.as_ref() == "true"); - } - } - layer.scope_stack.push(scope); - } - // If the node represents a definition, add a new definition to the - // local scope at the top of the scope stack. - else if Some(capture.index) == layer.config.local_def_capture_index - { - reference_highlight = None; - definition_highlight = None; - let scope = layer.scope_stack.last_mut().unwrap(); - - let mut value_range = 0..0; - for capture in match_.captures { - if Some(capture.index) - == layer.config.local_def_value_capture_index - { - value_range = capture.node.byte_range(); - } - } - - if let Ok(name) = str::from_utf8(&self.source[range.clone()]) { - scope.local_defs.push(LocalDef { - name, - value_range, - highlight: None, - }); - definition_highlight = - scope.local_defs.last_mut().map(|s| &mut s.highlight); - } - } - // If the node represents a reference, then try to find the corresponding - // definition in the scope stack. - else if Some(capture.index) == layer.config.local_ref_capture_index - && definition_highlight.is_none() - { - definition_highlight = None; - if let Ok(name) = str::from_utf8(&self.source[range.clone()]) { - for scope in layer.scope_stack.iter().rev() { - if let Some(highlight) = - scope.local_defs.iter().rev().find_map(|def| { - if def.name == name - && range.start >= def.value_range.end - { - Some(def.highlight) - } else { - None - } - }) - { - reference_highlight = highlight; - break; - } - if !scope.inherits { - break; - } - } - } - } - - // Continue processing any additional matches for the same node. - if let Some((next_match, next_capture_index)) = layer.captures.peek() - { - let next_capture = next_match.captures[*next_capture_index]; - if next_capture.node == capture.node { - capture = next_capture; - match_ = layer.captures.next().unwrap().0; - continue; - } - } - - self.sort_layers(); - continue 'main; - } - - // Otherwise, this capture must represent a highlight. - // If this exact range has already been highlighted by an earlier pattern, or by - // a different layer, then skip over this one. - if let Some((last_start, last_end, last_depth)) = - self.last_highlight_range - { - if range.start == last_start - && range.end == last_end - && layer.depth < last_depth - { - self.sort_layers(); - continue 'main; - } - } - - // If the current node was found to be a local variable, then skip over any - // highlighting patterns that are disabled for local variables. - if definition_highlight.is_some() || reference_highlight.is_some() { - while layer.config.non_local_variable_patterns[match_.pattern_index] - { - match_.remove(); - if let Some((next_match, next_capture_index)) = - layer.captures.peek() - { - let next_capture = next_match.captures[*next_capture_index]; - if next_capture.node == capture.node { - capture = next_capture; - match_ = layer.captures.next().unwrap().0; - continue; - } - } - - self.sort_layers(); - continue 'main; - } - } - - // Once a highlighting pattern is found for the current node, skip over - // any later highlighting patterns that also match this node. Captures - // for a given node are ordered by pattern index, so these subsequent - // captures are guaranteed to be for highlighting, not injections or - // local variables. - while let Some((next_match, next_capture_index)) = layer.captures.peek() - { - let next_capture = next_match.captures[*next_capture_index]; - if next_capture.node == capture.node { - layer.captures.next(); - } else { - break; - } - } - - let current_highlight = - layer.config.highlight_indices[capture.index as usize]; - - // If this node represents a local definition, then store the current - // highlight value on the local scope entry representing this node. - if let Some(definition_highlight) = definition_highlight { - *definition_highlight = current_highlight; - } - - // Emit a scope start event and push the node's end position to the stack. - if let Some(highlight) = reference_highlight.or(current_highlight) { - self.last_highlight_range = - Some((range.start, range.end, layer.depth)); - layer.highlight_end_stack.push(range.end); - return self.emit_event( - range.start, - Some(HighlightEvent::HighlightStart(highlight)), - ); - } - - self.sort_layers(); - } - } -} - pub fn line_styles( text: &Rope, line: usize, styles: &Spans