Compare commits

..

1 Commits

Author SHA1 Message Date
Julia
da3031c2db Try constructing the current frame's opaque layers during a post-layout phase
Unfinished, non-functional
2024-02-13 12:13:03 -05:00
981 changed files with 23453 additions and 53611 deletions

View File

@@ -10,6 +10,3 @@
# in one spot, that's going to trigger a rebuild of all of the artifacts. Using ci-config.toml we can define these overrides for CI in one spot and not worry about it.
[build]
rustflags = ["-D", "warnings"]
[alias]
xtask = "run --package xtask --"

View File

@@ -1,6 +1,3 @@
[build]
# v0 mangling scheme provides more detailed backtraces around closures
rustflags = ["-C", "symbol-mangling-version=v0", "--cfg", "tokio_unstable"]
[alias]
xtask = "run --package xtask --"
rustflags = ["-C", "symbol-mangling-version=v0"]

View File

@@ -0,0 +1,47 @@
name: Language Support
description: Request language support
title: "<name_of_language> support"
labels:
[
"admin read",
"triage",
"enhancement",
"language",
"unsupported language",
"potential plugin",
]
body:
- type: checkboxes
attributes:
label: Check for existing issues
description: Check the backlog of issues to reduce the chances of creating duplicates; if an issue already exists, place a `+1` (👍) on it.
options:
- label: Completed
required: true
- type: input
attributes:
label: Language
description: What language do you want support for?
placeholder: HTML
validations:
required: true
- type: input
attributes:
label: Tree Sitter parser link
description: If applicable, provide a link to the appropriate tree sitter parser. Look here first - https://tree-sitter.github.io/tree-sitter/#available-parsers
placeholder: https://github.com/tree-sitter/tree-sitter-html
validations:
required: false
- type: input
attributes:
label: Language server link
description: If applicable, provide a link to the appropriate language server. Look here first - https://microsoft.github.io/language-server-protocol/implementors/servers/
placeholder: https://github.com/Microsoft/vscode/tree/main/extensions/html-language-features/server
validations:
required: false
- type: textarea
attributes:
label: Misc notes
description: Provide any additional things the team should consider when adding support for this language
validations:
required: false

View File

@@ -1,7 +1,5 @@
name: Bug Report
description: |
Use this template for **non-crash-related** bug reports.
Tip: open this issue template from within Zed with the `file bug report` command palette action.
description: "Tip: open this issue template from within Zed with the `file bug report` command palette action"
labels: ["admin read", "triage", "defect"]
body:
- type: checkboxes
@@ -32,9 +30,9 @@ body:
required: false
- type: textarea
attributes:
label: If applicable, attach your `~/Library/Logs/Zed/Zed.log` file to this issue.
description: |
Drag Zed.log into the text input below.
label: |
If applicable, attach your `~/Library/Logs/Zed/Zed.log` file to this issue.
If you only need the most recent lines, you can run the `zed: open log` command palette action to see the last 1000.
description: Drag Zed.log into the text input below
validations:
required: false

View File

@@ -1,39 +0,0 @@
name: Crash Report
description: |
Use this template for crash reports.
labels: ["admin read", "triage", "defect", "panic / crash"]
body:
- type: checkboxes
attributes:
label: Check for existing issues
description: Check the backlog of issues to reduce the chances of creating duplicates; if an issue already exists, place a `+1` (👍) on it.
options:
- label: Completed
required: true
- type: textarea
attributes:
label: Describe the bug / provide steps to reproduce it
description: A clear and concise description of what the bug is.
validations:
required: true
- type: textarea
id: environment
attributes:
label: Environment
description: Run the `copy system specs into clipboard` command palette action and paste the output in the field below.
validations:
required: true
- type: textarea
attributes:
label: If applicable, add mockups / screenshots to help explain present your vision of the feature
description: Drag issues into the text input below
validations:
required: false
- type: textarea
attributes:
label: If applicable, attach your `~/Library/Logs/Zed/Zed.log` file to this issue.
description: |
Drag Zed.log into the text input below.
If you only need the most recent lines, you can run the `zed: open log` command palette action to see the last 1000.
validations:
required: false

View File

@@ -1,17 +1,10 @@
blank_issues_enabled: false
contact_links:
- name: Language Request
url: https://github.com/zed-industries/extensions/issues/new?assignees=&labels=language&projects=&template=1_language_request.yml&title=%3Cname_of_language%3E
about: Request a language in the extensions repository
- name: Theme Request
url: https://github.com/zed-industries/extensions/issues/new?assignees=&labels=theme&projects=&template=0_theme_request.yml&title=%3Cname_of_theme%3E+theme
about: Request a theme in the extensions repository
- name: Top-Ranking Issues
url: https://github.com/zed-industries/zed/issues/5393
about: See an overview of the most popular Zed issues
- name: Platform Support
url: https://github.com/zed-industries/zed/issues/5391
about: A quick note on platform support
- name: Positive Feedback
url: https://github.com/zed-industries/zed/discussions/5397
about: A central location for kind words about Zed
- name: Top-Ranking Issues
url: https://github.com/zed-industries/zed/issues/5393
about: See an overview of the most popular Zed issues
- name: Platform Support
url: https://github.com/zed-industries/zed/issues/5391
about: A quick note on platform support
- name: Positive Feedback
url: https://github.com/zed-industries/zed/discussions/5397
about: A central location for kind words about Zed

View File

@@ -2,14 +2,14 @@ name: "Check formatting"
description: "Checks code formatting use cargo fmt"
runs:
using: "composite"
steps:
- name: cargo fmt
shell: bash -euxo pipefail {0}
run: cargo fmt --all -- --check
using: "composite"
steps:
- name: cargo fmt
shell: bash -euxo pipefail {0}
run: cargo fmt --all -- --check
- name: Find modified migrations
shell: bash -euxo pipefail {0}
run: |
export SQUAWK_GITHUB_TOKEN=${{ github.token }}
. ./script/squawk
- name: Find modified migrations
shell: bash -euxo pipefail {0}
run: |
export SQUAWK_GITHUB_TOKEN=${{ github.token }}
. ./script/squawk

View File

@@ -2,22 +2,22 @@ name: "Run tests"
description: "Runs the tests"
runs:
using: "composite"
steps:
- name: Install Rust
shell: bash -euxo pipefail {0}
run: |
cargo install cargo-nextest
using: "composite"
steps:
- name: Install Rust
shell: bash -euxo pipefail {0}
run: |
cargo install cargo-nextest
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: "18"
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: "18"
- name: Limit target directory size
shell: bash -euxo pipefail {0}
run: script/clear-target-dir-if-larger-than 100
- name: Limit target directory size
shell: bash -euxo pipefail {0}
run: script/clear-target-dir-if-larger-than 100
- name: Run tests
shell: bash -euxo pipefail {0}
run: cargo nextest run --workspace --no-fail-fast
- name: Run tests
shell: bash -euxo pipefail {0}
run: cargo nextest run --workspace --no-fail-fast

View File

@@ -1,2 +0,0 @@
enabled: true
preservePullRequestTitle: true

View File

@@ -4,8 +4,6 @@ Release Notes:
- Added/Fixed/Improved ... ([#<public_issue_number_if_exists>](https://github.com/zed-industries/zed/issues/<public_issue_number_if_exists>)).
Optionally, include screenshots / media showcasing your addition that can be included in the release notes.
**or**
- N/A

View File

@@ -1,306 +1,204 @@
name: CI
on:
push:
branches:
- main
- "v[0-9]+.[0-9]+.x"
tags:
- "v*"
pull_request:
branches:
- "**"
push:
branches:
- main
- "v[0-9]+.[0-9]+.x"
tags:
- "v*"
pull_request:
branches:
- "**"
concurrency:
# Allow only one workflow per any non-`main` branch.
group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }}
cancel-in-progress: true
# Allow only one workflow per any non-`main` branch.
group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: 0
RUST_BACKTRACE: 1
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: 0
RUST_BACKTRACE: 1
jobs:
style:
name: Check formatting and spelling
runs-on:
- self-hosted
- test
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
clean: false
submodules: "recursive"
fetch-depth: 0
style:
name: Check formatting and spelling
runs-on:
- self-hosted
- test
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
clean: false
submodules: "recursive"
fetch-depth: 0
- name: Remove untracked files
run: git clean -df
- name: Set up default .cargo/config.toml
run: cp ./.cargo/ci-config.toml ~/.cargo/config.toml
- name: Set up default .cargo/config.toml
run: cp ./.cargo/ci-config.toml ~/.cargo/config.toml
- name: Check spelling
run: |
if ! which typos > /dev/null; then
cargo install typos-cli
fi
typos
- name: Check spelling
run: |
if ! which typos > /dev/null; then
cargo install typos-cli
fi
typos
- name: Run style checks
uses: ./.github/actions/check_style
- name: Run style checks
uses: ./.github/actions/check_style
- name: Ensure fresh merge
shell: bash -euxo pipefail {0}
run: |
if [ -z "$GITHUB_BASE_REF" ];
then
echo "BUF_BASE_BRANCH=$(git merge-base origin/main HEAD)" >> $GITHUB_ENV
else
git checkout -B temp
git merge -q origin/$GITHUB_BASE_REF -m "merge main into temp"
echo "BUF_BASE_BRANCH=$GITHUB_BASE_REF" >> $GITHUB_ENV
fi
- name: Check unused dependencies
uses: bnjbvr/cargo-machete@main
- uses: bufbuild/buf-setup-action@v1
- uses: bufbuild/buf-breaking-action@v1
with:
input: "crates/rpc/proto/"
against: "https://github.com/${GITHUB_REPOSITORY}.git#branch=${BUF_BASE_BRANCH},subdir=crates/rpc/proto/"
- name: Ensure fresh merge
shell: bash -euxo pipefail {0}
run: |
if [ -z "$GITHUB_BASE_REF" ];
then
echo "BUF_BASE_BRANCH=$(git merge-base origin/main HEAD)" >> $GITHUB_ENV
else
git checkout -B temp
git merge -q origin/$GITHUB_BASE_REF -m "merge main into temp"
echo "BUF_BASE_BRANCH=$GITHUB_BASE_REF" >> $GITHUB_ENV
fi
macos_tests:
name: (macOS) Run Clippy and tests
runs-on:
- self-hosted
- test
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
clean: false
submodules: "recursive"
- uses: bufbuild/buf-setup-action@v1
with:
version: v1.29.0
- uses: bufbuild/buf-breaking-action@v1
with:
input: "crates/rpc/proto/"
against: "https://github.com/${GITHUB_REPOSITORY}.git#branch=${BUF_BASE_BRANCH},subdir=crates/rpc/proto/"
- name: cargo clippy
shell: bash -euxo pipefail {0}
run: script/clippy
macos_tests:
name: (macOS) Run Clippy and tests
runs-on:
- self-hosted
- test
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
clean: false
submodules: "recursive"
- name: Run tests
uses: ./.github/actions/run_tests
- name: cargo clippy
run: cargo xtask clippy
- name: Build collab
run: cargo build -p collab
- name: Run tests
uses: ./.github/actions/run_tests
- name: Build other binaries
run: cargo build --workspace --bins --all-features
- name: Build collab
run: cargo build -p collab
# todo!(linux): Actually run the tests
linux_tests:
name: (Linux) Run Clippy and tests
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
clean: false
submodules: "recursive"
- name: Build other binaries and features
run: cargo build --workspace --bins --all-features; cargo check -p gpui --features "macos-blade"
- name: Restore from cache
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/rust-toolchain.toml') }}-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-${{ hashFiles('**/rust-toolchain.toml') }}-
# todo(linux): Actually run the tests
linux_tests:
name: (Linux) Run Clippy and tests
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
clean: false
submodules: "recursive"
- name: configure linux
shell: bash -euxo pipefail {0}
run: script/linux
- name: Cache dependencies
uses: swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: cargo clippy
shell: bash -euxo pipefail {0}
run: script/clippy
- name: configure linux
shell: bash -euxo pipefail {0}
run: script/linux
- name: cargo clippy
run: cargo xtask clippy
- name: Build Zed
run: cargo build -p zed
# todo(windows): Actually run the tests
windows_tests:
name: (Windows) Run Clippy and tests
runs-on: windows-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
clean: false
submodules: "recursive"
- name: Cache dependencies
uses: swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: cargo clippy
run: cargo xtask clippy
- name: Build Zed
run: cargo build -p zed
bundle-mac:
name: Create a macOS bundle
runs-on:
- self-hosted
- bundle
if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
needs: [macos_tests]
env:
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
steps:
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: "18"
- name: Checkout repo
uses: actions/checkout@v4
with:
clean: false
submodules: "recursive"
- name: Limit target directory size
run: script/clear-target-dir-if-larger-than 100
- name: Determine version and release channel
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
run: |
set -eu
version=$(script/get-crate-version zed)
channel=$(cat crates/zed/RELEASE_CHANNEL)
echo "Publishing version: ${version} on release channel ${channel}"
echo "RELEASE_CHANNEL=${channel}" >> $GITHUB_ENV
expected_tag_name=""
case ${channel} in
stable)
expected_tag_name="v${version}";;
preview)
expected_tag_name="v${version}-pre";;
nightly)
expected_tag_name="v${version}-nightly";;
*)
echo "can't publish a release on channel ${channel}"
exit 1;;
esac
if [[ $GITHUB_REF_NAME != $expected_tag_name ]]; then
echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
exit 1
fi
- name: Generate license file
run: script/generate-licenses
- name: Create macOS app bundle
run: script/bundle-mac
- name: Upload app bundle to workflow run if main branch or specific label
uses: actions/upload-artifact@v4
if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
with:
name: Zed_${{ github.event.pull_request.head.sha || github.sha }}.dmg
path: target/release/Zed.dmg
- uses: softprops/action-gh-release@v1
name: Upload app bundle to release
if: ${{ env.RELEASE_CHANNEL == 'preview' || env.RELEASE_CHANNEL == 'stable' }}
with:
draft: true
prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
files: target/release/Zed.dmg
body: ""
- name: Build Zed
run: cargo build -p zed
bundle:
name: Bundle app
runs-on:
- self-hosted
- bundle
if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-build-dmg') }}
needs: [macos_tests, linux_tests]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
steps:
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: "18"
bundle-deb:
name: Create a *.deb Linux bundle
runs-on: ubuntu-22.04 # keep the version fixed to avoid libc and dynamic linked library issues
if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
needs: [linux_tests]
env:
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
clean: false
submodules: "recursive"
- name: Checkout repo
uses: actions/checkout@v4
with:
clean: false
submodules: "recursive"
- name: Cache dependencies
uses: swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Limit target directory size
run: script/clear-target-dir-if-larger-than 100
- name: Configure linux
shell: bash -euxo pipefail {0}
run: script/linux
- name: Determine version and release channel
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
run: |
set -eu
- name: Determine version and release channel
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
run: |
set -eu
version=$(script/get-crate-version zed)
channel=$(cat crates/zed/RELEASE_CHANNEL)
echo "Publishing version: ${version} on release channel ${channel}"
echo "RELEASE_CHANNEL=${channel}" >> $GITHUB_ENV
version=$(script/get-crate-version zed)
channel=$(cat crates/zed/RELEASE_CHANNEL)
echo "Publishing version: ${version} on release channel ${channel}"
echo "RELEASE_CHANNEL=${channel}" >> $GITHUB_ENV
expected_tag_name=""
case ${channel} in
stable)
expected_tag_name="v${version}";;
preview)
expected_tag_name="v${version}-pre";;
nightly)
expected_tag_name="v${version}-nightly";;
*)
echo "can't publish a release on channel ${channel}"
exit 1;;
esac
if [[ $GITHUB_REF_NAME != $expected_tag_name ]]; then
echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
exit 1
fi
expected_tag_name=""
case ${channel} in
stable)
expected_tag_name="v${version}";;
preview)
expected_tag_name="v${version}-pre";;
nightly)
expected_tag_name="v${version}-nightly";;
*)
echo "can't publish a release on channel ${channel}"
exit 1;;
esac
if [[ $GITHUB_REF_NAME != $expected_tag_name ]]; then
echo "invalid release tag ${GITHUB_REF_NAME}. expected ${expected_tag_name}"
exit 1
fi
- name: Generate license file
run: script/generate-licenses
# TODO linux : Find a way to add licenses to the final bundle
# - name: Generate license file
# run: script/generate-licenses
- name: Create app bundle
run: script/bundle
- name: Create Linux *.deb bundle
run: script/bundle-linux
- name: Upload app bundle to workflow run if main branch or specific label
uses: actions/upload-artifact@v3
if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-build-dmg') }}
with:
name: Zed_${{ github.event.pull_request.head.sha || github.sha }}.dmg
path: target/release/Zed.dmg
- name: Upload app bundle to workflow run if main branch or specific label
uses: actions/upload-artifact@v4
if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
with:
name: Zed_${{ github.event.pull_request.head.sha || github.sha }}.deb
path: target/release/*.deb
# TODO linux : make it stable enough to be uploaded as a release
# - uses: softprops/action-gh-release@v1
# name: Upload app bundle to release
# if: ${{ env.RELEASE_CHANNEL == 'preview' || env.RELEASE_CHANNEL == 'stable' }}
# with:
# draft: true
# prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
# files: target/release/Zed.dmg
# body: ""
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: softprops/action-gh-release@v1
name: Upload app bundle to release
if: ${{ env.RELEASE_CHANNEL == 'preview' || env.RELEASE_CHANNEL == 'stable' }}
with:
draft: true
prerelease: ${{ env.RELEASE_CHANNEL == 'preview' }}
files: target/release/Zed.dmg
body: ""
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,35 +1,35 @@
name: Danger
on:
pull_request:
branches: [main]
types:
- opened
- synchronize
- reopened
- edited
pull_request:
branches: [main]
types:
- opened
- synchronize
- reopened
- edited
jobs:
danger:
runs-on: ubuntu-latest
danger:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
with:
version: 8
- uses: pnpm/action-setup@v3
with:
version: 8
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "pnpm"
cache-dependency-path: "script/danger/pnpm-lock.yaml"
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "pnpm"
cache-dependency-path: "script/danger/pnpm-lock.yaml"
- run: pnpm install --dir script/danger
- run: pnpm install --dir script/danger
- name: Run Danger
run: pnpm run --dir script/danger danger ci
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Run Danger
run: pnpm run --dir script/danger danger ci
env:
GITHUB_TOKEN: ${{ github.token }}

View File

@@ -28,7 +28,8 @@ jobs:
uses: ./.github/actions/check_style
- name: Run clippy
run: cargo xtask clippy
shell: bash -euxo pipefail {0}
run: script/clippy
tests:
name: Run tests
@@ -44,18 +45,8 @@ jobs:
submodules: "recursive"
fetch-depth: 0
- name: Install cargo nextest
shell: bash -euxo pipefail {0}
run: |
cargo install cargo-nextest
- name: Limit target directory size
shell: bash -euxo pipefail {0}
run: script/clear-target-dir-if-larger-than 100
- name: Run tests
shell: bash -euxo pipefail {0}
run: cargo nextest run --package collab --no-fail-fast
uses: ./.github/actions/run_tests
publish:
name: Publish collab server image
@@ -72,6 +63,9 @@ jobs:
- name: Sign into DigitalOcean docker registry
run: doctl registry login
- name: Prune Docker system
run: docker system prune --filter 'until=720h' -f
- name: Checkout repo
uses: actions/checkout@v4
with:
@@ -84,9 +78,6 @@ jobs:
- name: Publish docker image
run: docker push registry.digitalocean.com/zed/collab:${GITHUB_SHA}
- name: Prune Docker system
run: docker system prune --filter 'until=72h' -f
deploy:
name: Deploy new server image
needs:
@@ -99,38 +90,22 @@ jobs:
- name: Sign into Kubernetes
run: doctl kubernetes cluster kubeconfig save --expiry-seconds 600 ${{ secrets.CLUSTER_NAME }}
- name: Start rollout
- name: Determine namespace
run: |
set -eu
if [[ $GITHUB_REF_NAME = "collab-production" ]]; then
export ZED_KUBE_NAMESPACE=production
export ZED_COLLAB_LOAD_BALANCER_SIZE_UNIT=10
export ZED_API_LOAD_BALANCER_SIZE_UNIT=2
echo "Deploying collab:$GITHUB_SHA to production"
echo "KUBE_NAMESPACE=production" >> $GITHUB_ENV
elif [[ $GITHUB_REF_NAME = "collab-staging" ]]; then
export ZED_KUBE_NAMESPACE=staging
export ZED_COLLAB_LOAD_BALANCER_SIZE_UNIT=1
export ZED_API_LOAD_BALANCER_SIZE_UNIT=1
echo "Deploying collab:$GITHUB_SHA to staging"
echo "KUBE_NAMESPACE=staging" >> $GITHUB_ENV
else
echo "cowardly refusing to deploy from an unknown branch"
exit 1
fi
echo "Deploying collab:$GITHUB_SHA to $ZED_KUBE_NAMESPACE"
- name: Start rollout
run: kubectl -n "$KUBE_NAMESPACE" set image deployment/collab collab=registry.digitalocean.com/zed/collab:${GITHUB_SHA}
source script/lib/deploy-helpers.sh
export_vars_for_environment $ZED_KUBE_NAMESPACE
export ZED_DO_CERTIFICATE_ID=$(doctl compute certificate list --format ID --no-header)
export ZED_IMAGE_ID="registry.digitalocean.com/zed/collab:${GITHUB_SHA}"
export ZED_SERVICE_NAME=collab
export ZED_LOAD_BALANCER_SIZE_UNIT=$ZED_COLLAB_LOAD_BALANCER_SIZE_UNIT
envsubst < crates/collab/k8s/collab.template.yml | kubectl apply -f -
kubectl -n "$ZED_KUBE_NAMESPACE" rollout status deployment/$ZED_SERVICE_NAME --watch
echo "deployed ${ZED_SERVICE_NAME} to ${ZED_KUBE_NAMESPACE}"
export ZED_SERVICE_NAME=api
export ZED_LOAD_BALANCER_SIZE_UNIT=$ZED_API_LOAD_BALANCER_SIZE_UNIT
envsubst < crates/collab/k8s/collab.template.yml | kubectl apply -f -
kubectl -n "$ZED_KUBE_NAMESPACE" rollout status deployment/$ZED_SERVICE_NAME --watch
echo "deployed ${ZED_SERVICE_NAME} to ${ZED_KUBE_NAMESPACE}"
- name: Wait for rollout to finish
run: kubectl -n "$KUBE_NAMESPACE" rollout status deployment/collab

View File

@@ -3,35 +3,35 @@ name: Randomized Tests
concurrency: randomized-tests
on:
push:
branches:
- randomized-tests-runner
# schedule:
# - cron: '0 * * * *'
push:
branches:
- randomized-tests-runner
# schedule:
# - cron: '0 * * * *'
env:
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: 0
RUST_BACKTRACE: 1
ZED_SERVER_URL: https://zed.dev
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: 0
RUST_BACKTRACE: 1
ZED_SERVER_URL: https://zed.dev
jobs:
tests:
name: Run randomized tests
runs-on:
- self-hosted
- randomized-tests
steps:
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: "18"
tests:
name: Run randomized tests
runs-on:
- self-hosted
- randomized-tests
steps:
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: "18"
- name: Checkout repo
uses: actions/checkout@v4
with:
clean: false
submodules: "recursive"
- name: Checkout repo
uses: actions/checkout@v4
with:
clean: false
submodules: "recursive"
- name: Run randomized tests
run: script/randomized-test-ci
- name: Run randomized tests
run: script/randomized-test-ci

View File

@@ -1,136 +1,98 @@
name: Release Nightly
on:
schedule:
# Fire every day at 7:00am UTC (Roughly before EU workday and after US workday)
- cron: "0 7 * * *"
push:
tags:
- "nightly"
schedule:
# Fire every day at 7:00am UTC (Roughly before EU workday and after US workday)
- cron: "0 7 * * *"
push:
tags:
- "nightly"
env:
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: 0
RUST_BACKTRACE: 1
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: 0
RUST_BACKTRACE: 1
jobs:
style:
name: Check formatting and Clippy lints
if: github.repository_owner == 'zed-industries'
runs-on:
- self-hosted
- test
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
clean: false
submodules: "recursive"
fetch-depth: 0
style:
name: Check formatting and Clippy lints
if: github.repository_owner == 'zed-industries'
runs-on:
- self-hosted
- test
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
clean: false
submodules: "recursive"
fetch-depth: 0
- name: Run style checks
uses: ./.github/actions/check_style
- name: Run style checks
uses: ./.github/actions/check_style
- name: Run clippy
run: cargo xtask clippy
tests:
name: Run tests
if: github.repository_owner == 'zed-industries'
runs-on:
- self-hosted
- test
needs: style
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
clean: false
submodules: "recursive"
- name: Run clippy
shell: bash -euxo pipefail {0}
run: script/clippy
tests:
name: Run tests
if: github.repository_owner == 'zed-industries'
runs-on:
- self-hosted
- test
needs: style
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
clean: false
submodules: "recursive"
- name: Run tests
uses: ./.github/actions/run_tests
- name: Run tests
uses: ./.github/actions/run_tests
bundle-mac:
name: Create a macOS bundle
if: github.repository_owner == 'zed-industries'
runs-on:
- self-hosted
- bundle
needs: tests
env:
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
steps:
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: "18"
bundle:
name: Bundle app
if: github.repository_owner == 'zed-industries'
runs-on:
- self-hosted
- bundle
needs: tests
env:
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
steps:
- name: Install Node
uses: actions/setup-node@v4
with:
node-version: "18"
- name: Checkout repo
uses: actions/checkout@v4
with:
clean: false
submodules: "recursive"
- name: Checkout repo
uses: actions/checkout@v4
with:
clean: false
submodules: "recursive"
- name: Set release channel to nightly
run: |
set -eu
version=$(git rev-parse --short HEAD)
echo "Publishing version: ${version} on release channel nightly"
echo "nightly" > crates/zed/RELEASE_CHANNEL
- name: Limit target directory size
run: script/clear-target-dir-if-larger-than 100
- name: Generate license file
run: script/generate-licenses
- name: Set release channel to nightly
run: |
set -eu
version=$(git rev-parse --short HEAD)
echo "Publishing version: ${version} on release channel nightly"
echo "nightly" > crates/zed/RELEASE_CHANNEL
- name: Create macOS app bundle
run: script/bundle-mac
- name: Generate license file
run: script/generate-licenses
- name: Upload Zed Nightly
run: script/upload-nightly macos
- name: Create app bundle
run: script/bundle
bundle-deb:
name: Create a *.deb Linux bundle
if: github.repository_owner == 'zed-industries'
runs-on: ubuntu-22.04 # keep the version fixed to avoid libc and dynamic linked library issues
needs: tests
env:
DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
steps:
- name: Checkout repo
uses: actions/checkout@v4
with:
clean: false
submodules: "recursive"
- name: Cache dependencies
uses: swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Configure linux
shell: bash -euxo pipefail {0}
run: script/linux
- name: Set release channel to nightly
run: |
set -euo pipefail
version=$(git rev-parse --short HEAD)
echo "Publishing version: ${version} on release channel nightly"
echo "nightly" > crates/zed/RELEASE_CHANNEL
# TODO linux : find a way to add licenses to the final bundle
# - name: Generate license file
# run: script/generate-licenses
- name: Create Linux *.deb bundle
run: script/bundle-linux
- name: Upload Zed Nightly
run: script/upload-nightly linux-deb
- name: Upload Zed Nightly
run: script/upload-nightly

View File

@@ -1,18 +1,18 @@
on:
schedule:
- cron: "0 */12 * * *"
workflow_dispatch:
schedule:
- cron: "0 */12 * * *"
workflow_dispatch:
jobs:
update_top_ranking_issues:
runs-on: ubuntu-latest
if: github.repository_owner == 'zed-industries'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: "3.10.5"
architecture: "x64"
cache: "pip"
- run: pip install -r script/update_top_ranking_issues/requirements.txt
- run: python script/update_top_ranking_issues/main.py 5393 --github-token ${{ secrets.GITHUB_TOKEN }} --prod
update_top_ranking_issues:
runs-on: ubuntu-latest
if: github.repository_owner == 'zed-industries'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: "3.10.5"
architecture: "x64"
cache: "pip"
- run: pip install -r script/update_top_ranking_issues/requirements.txt
- run: python script/update_top_ranking_issues/main.py 5393 --github-token ${{ secrets.GITHUB_TOKEN }} --prod

View File

@@ -1,18 +1,18 @@
on:
schedule:
- cron: "0 15 * * *"
workflow_dispatch:
schedule:
- cron: "0 15 * * *"
workflow_dispatch:
jobs:
update_top_ranking_issues:
runs-on: ubuntu-latest
if: github.repository_owner == 'zed-industries'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: "3.10.5"
architecture: "x64"
cache: "pip"
- run: pip install -r script/update_top_ranking_issues/requirements.txt
- run: python script/update_top_ranking_issues/main.py 6952 --github-token ${{ secrets.GITHUB_TOKEN }} --prod --query-day-interval 7
update_top_ranking_issues:
runs-on: ubuntu-latest
if: github.repository_owner == 'zed-industries'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: "3.10.5"
architecture: "x64"
cache: "pip"
- run: pip install -r script/update_top_ranking_issues/requirements.txt
- run: python script/update_top_ranking_issues/main.py 6952 --github-token ${{ secrets.GITHUB_TOKEN }} --prod --query-day-interval 7

7
.gitignore vendored
View File

@@ -5,12 +5,15 @@
.DS_Store
/plugins/bin
/script/node_modules
/styles/node_modules
/styles/src/types/zed.ts
/crates/theme/schemas/theme.json
/crates/collab/static/styles.css
/crates/collab/.admins.json
/vendor/bin
/assets/*licenses.md
**/venv
.build
*.wasm
Packages
*.xcodeproj
xcuserdata/
@@ -22,5 +25,3 @@ DerivedData/
**/*.db
.pytest_cache
.venv
.blob_store
.vscode

View File

@@ -11,8 +11,6 @@
Antonio Scandurra <me@as-cii.com>
Antonio Scandurra <me@as-cii.com> <antonio@zed.dev>
Christian Bergschneider <christian.bergschneider@gmx.de>
Christian Bergschneider <christian.bergschneider@gmx.de> <magiclake@gmx.de>
Conrad Irwin <conrad@zed.dev>
Conrad Irwin <conrad@zed.dev> <conrad.irwin@gmail.com>
Greg Morenz <greg-morenz@droid.cafe>

View File

@@ -1,21 +1,6 @@
{
"languages": {
"Markdown": {
"tab_size": 2,
"formatter": "prettier"
},
"TOML": {
"formatter": "prettier",
"format_on_save": "off"
},
"YAML": {
"tab_size": 2,
"formatter": "prettier"
},
"JSON": {
"tab_size": 2,
"formatter": "prettier"
}
"JSON": {
"tab_size": 4
},
"formatter": "auto"
}

4268
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -16,15 +16,12 @@ members = [
"crates/collab_ui",
"crates/collections",
"crates/command_palette",
"crates/command_palette_hooks",
"crates/copilot",
"crates/copilot_ui",
"crates/db",
"crates/diagnostics",
"crates/editor",
"crates/extension",
"crates/extension_api",
"crates/extensions_ui",
"crates/feature_flags",
"crates/feedback",
"crates/file_finder",
@@ -40,7 +37,6 @@ members = [
"crates/language",
"crates/language_selector",
"crates/language_tools",
"crates/languages",
"crates/live_kit_client",
"crates/live_kit_server",
"crates/lsp",
@@ -52,6 +48,8 @@ members = [
"crates/notifications",
"crates/outline",
"crates/picker",
"crates/plugin",
"crates/plugin_macros",
"crates/prettier",
"crates/project",
"crates/project_panel",
@@ -64,8 +62,6 @@ members = [
"crates/rich_text",
"crates/rope",
"crates/rpc",
"crates/task",
"crates/tasks_ui",
"crates/search",
"crates/semantic_index",
"crates/settings",
@@ -81,22 +77,14 @@ members = [
"crates/theme",
"crates/theme_importer",
"crates/theme_selector",
"crates/telemetry_events",
"crates/time_format",
"crates/ui",
"crates/util",
"crates/vcs_menu",
"crates/vim",
"crates/welcome",
"crates/workspace",
"crates/worktree",
"crates/zed",
"crates/zed_actions",
"extensions/gleam",
"extensions/uiua",
"tooling/xtask",
]
default-members = ["crates/zed"]
resolver = "2"
@@ -108,7 +96,6 @@ assets = { path = "crates/assets" }
assistant = { path = "crates/assistant" }
audio = { path = "crates/audio" }
auto_update = { path = "crates/auto_update" }
base64 = "0.13"
breadcrumbs = { path = "crates/breadcrumbs" }
call = { path = "crates/call" }
channel = { path = "crates/channel" }
@@ -120,14 +107,12 @@ collab_ui = { path = "crates/collab_ui" }
collections = { path = "crates/collections" }
color = { path = "crates/color" }
command_palette = { path = "crates/command_palette" }
command_palette_hooks = { path = "crates/command_palette_hooks" }
copilot = { path = "crates/copilot" }
copilot_ui = { path = "crates/copilot_ui" }
db = { path = "crates/db" }
diagnostics = { path = "crates/diagnostics" }
editor = { path = "crates/editor" }
extension = { path = "crates/extension" }
extensions_ui = { path = "crates/extensions_ui" }
feature_flags = { path = "crates/feature_flags" }
feedback = { path = "crates/feedback" }
file_finder = { path = "crates/file_finder" }
@@ -143,7 +128,6 @@ journal = { path = "crates/journal" }
language = { path = "crates/language" }
language_selector = { path = "crates/language_selector" }
language_tools = { path = "crates/language_tools" }
languages = { path = "crates/languages" }
live_kit_client = { path = "crates/live_kit_client" }
live_kit_server = { path = "crates/live_kit_server" }
lsp = { path = "crates/lsp" }
@@ -159,7 +143,6 @@ plugin = { path = "crates/plugin" }
plugin_macros = { path = "crates/plugin_macros" }
prettier = { path = "crates/prettier" }
project = { path = "crates/project" }
worktree = { path = "crates/worktree" }
project_panel = { path = "crates/project_panel" }
project_symbols = { path = "crates/project_symbols" }
quick_action_bar = { path = "crates/quick_action_bar" }
@@ -168,8 +151,6 @@ release_channel = { path = "crates/release_channel" }
rich_text = { path = "crates/rich_text" }
rope = { path = "crates/rope" }
rpc = { path = "crates/rpc" }
task = { path = "crates/task" }
tasks_ui = { path = "crates/tasks_ui" }
search = { path = "crates/search" }
semantic_index = { path = "crates/semantic_index" }
settings = { path = "crates/settings" }
@@ -185,8 +166,6 @@ text = { path = "crates/text" }
theme = { path = "crates/theme" }
theme_importer = { path = "crates/theme_importer" }
theme_selector = { path = "crates/theme_selector" }
telemetry_events = { path = "crates/telemetry_events" }
time_format = { path = "crates/time_format" }
ui = { path = "crates/ui" }
util = { path = "crates/util" }
vcs_menu = { path = "crates/vcs_menu" }
@@ -198,55 +177,34 @@ zed_actions = { path = "crates/zed_actions" }
anyhow = "1.0.57"
async-compression = { version = "0.4", features = ["gzip", "futures-io"] }
async-fs = "1.6"
async-recursion = "1.0.0"
async-tar = "0.4.2"
async-trait = "0.1"
bitflags = "2.4.2"
blade-graphics = { git = "https://github.com/kvark/blade", rev = "43721bf42d298b7cbee2195ee66f73a5f1c7b2fc" }
blade-macros = { git = "https://github.com/kvark/blade", rev = "43721bf42d298b7cbee2195ee66f73a5f1c7b2fc" }
blade-rwh = { package = "raw-window-handle", version = "0.5" }
cap-std = "2.0"
chrono = { version = "0.4", features = ["serde"] }
clap = "4.4"
clickhouse = { version = "0.11.6" }
ctor = "0.2.6"
core-foundation = { version = "0.9.3" }
core-foundation-sys = "0.8.6"
derive_more = "0.99.17"
emojis = "0.6.1"
env_logger = "0.9"
futures = "0.3"
futures-lite = "1.13"
git2 = { version = "0.15", default-features = false }
globset = "0.4"
hex = "0.4.3"
ignore = "0.4.22"
indoc = "1"
# We explicitly disable http2 support in isahc.
# We explicitly disable a http2 support in isahc.
isahc = { version = "1.7.2", default-features = false, features = [
"static-curl",
"text-decoding",
] }
itertools = "0.11.0"
lazy_static = "1.4.0"
linkify = "0.10.0"
log = { version = "0.4.16", features = ["kv_unstable_serde"] }
ordered-float = "2.1.1"
palette = { version = "0.7.5", default-features = false, features = ["std"] }
parking_lot = "0.12.1"
profiling = "1"
parking_lot = "0.11.1"
postage = { version = "0.5", features = ["futures-traits"] }
pretty_assertions = "1.3.0"
prost = "0.8"
pulldown-cmark = { version = "0.10.0", default-features = false }
pulldown-cmark = { version = "0.9.2", default-features = false }
rand = "0.8.5"
refineable = { path = "./crates/refineable" }
regex = "1.5"
rusqlite = { version = "0.29.0", features = ["blob", "array", "modern_sqlite"] }
rust-embed = { version = "8.0", features = ["include-exclude"] }
schemars = "0.8"
semver = "1.0"
serde = { version = "1.0", features = ["derive", "rc"] }
serde_derive = { version = "1.0", features = ["deserialize_in_place"] }
serde_json = { version = "1.0", features = ["preserve_order", "raw_value"] }
@@ -255,164 +213,82 @@ serde_json_lenient = { version = "0.1", features = [
"raw_value",
] }
serde_repr = "0.1"
sha2 = "0.10"
shellexpand = "2.1.0"
smallvec = { version = "1.6", features = ["union"] }
smol = "1.2"
strum = { version = "0.25.0", features = ["derive"] }
subtle = "2.5.0"
sysinfo = "0.30.7"
sysinfo = "0.29.10"
tempfile = "3.9.0"
thiserror = "1.0.29"
tiktoken-rs = "0.5.7"
time = { version = "0.3", features = [
"serde",
"serde-well-known",
"formatting",
] }
toml = "0.8"
tower-http = "0.4.4"
time = { version = "0.3", features = ["serde", "serde-well-known"] }
toml = "0.5"
tree-sitter = { version = "0.20", features = ["wasm"] }
tree-sitter-astro = { git = "https://github.com/virchau13/tree-sitter-astro.git", rev = "e924787e12e8a03194f36a113290ac11d6dc10f3" }
tree-sitter-bash = { git = "https://github.com/tree-sitter/tree-sitter-bash", rev = "7331995b19b8f8aba2d5e26deb51d2195c18bc94" }
tree-sitter-beancount = { git = "https://github.com/polarmutex/tree-sitter-beancount", rev = "da1bf8c6eb0ae7a97588affde7227630bcd678b6" }
tree-sitter-c = "0.20.1"
tree-sitter-clojure = { git = "https://github.com/prcastro/tree-sitter-clojure", branch = "update-ts" }
tree-sitter-clojure = { git = "https://github.com/prcastro/tree-sitter-clojure", branch = "update-ts"}
tree-sitter-c-sharp = { git = "https://github.com/tree-sitter/tree-sitter-c-sharp", rev = "dd5e59721a5f8dae34604060833902b882023aaf" }
tree-sitter-cpp = { git = "https://github.com/tree-sitter/tree-sitter-cpp", rev = "f44509141e7e483323d2ec178f2d2e6c0fc041c1" }
tree-sitter-css = { git = "https://github.com/tree-sitter/tree-sitter-css", rev = "769203d0f9abe1a9a691ac2b9fe4bb4397a73c51" }
tree-sitter-dockerfile = { git = "https://github.com/camdencheek/tree-sitter-dockerfile", rev = "33e22c33bcdbfc33d42806ee84cfd0b1248cc392" }
tree-sitter-dart = { git = "https://github.com/agent3bood/tree-sitter-dart", rev = "48934e3bf757a9b78f17bdfaa3e2b4284656fdc7" }
tree-sitter-elixir = { git = "https://github.com/elixir-lang/tree-sitter-elixir", rev = "a2861e88a730287a60c11ea9299c033c7d076e30" }
tree-sitter-elm = { git = "https://github.com/elm-tooling/tree-sitter-elm", rev = "692c50c0b961364c40299e73c1306aecb5d20f40" }
tree-sitter-embedded-template = "0.20.0"
tree-sitter-erlang = "0.4.0"
tree-sitter-gitcommit = { git = "https://github.com/gbprod/tree-sitter-gitcommit" }
tree-sitter-gleam = { git = "https://github.com/gleam-lang/tree-sitter-gleam", rev = "58b7cac8fc14c92b0677c542610d8738c373fa81" }
tree-sitter-glsl = { git = "https://github.com/theHamsta/tree-sitter-glsl", rev = "2a56fb7bc8bb03a1892b4741279dd0a8758b7fb3" }
tree-sitter-go = { git = "https://github.com/tree-sitter/tree-sitter-go", rev = "aeb2f33b366fd78d5789ff104956ce23508b85db" }
tree-sitter-gomod = { git = "https://github.com/camdencheek/tree-sitter-go-mod" }
tree-sitter-gowork = { git = "https://github.com/d1y/tree-sitter-go-work" }
tree-sitter-haskell = { git = "https://github.com/tree-sitter/tree-sitter-haskell", rev = "8a99848fc734f9c4ea523b3f2a07df133cbbcec2" }
tree-sitter-haskell = { git = "https://github.com/tree-sitter/tree-sitter-haskell", rev = "cf98de23e4285b8e6bcb57b050ef2326e2cc284b" }
tree-sitter-hcl = { git = "https://github.com/MichaHoffmann/tree-sitter-hcl", rev = "v1.1.0" }
rustc-demangle = "0.1.23"
tree-sitter-heex = { git = "https://github.com/phoenixframework/tree-sitter-heex", rev = "2e1348c3cf2c9323e87c2744796cf3f3868aa82a" }
tree-sitter-html = "0.19.0"
tree-sitter-json = { git = "https://github.com/tree-sitter/tree-sitter-json", rev = "40a81c01a40ac48744e0c8ccabbaba1920441199" }
tree-sitter-lua = "0.0.14"
tree-sitter-markdown = { git = "https://github.com/MDeiml/tree-sitter-markdown", rev = "330ecab87a3e3a7211ac69bbadc19eabecdb1cca" }
tree-sitter-nix = { git = "https://github.com/nix-community/tree-sitter-nix", rev = "66e3e9ce9180ae08fc57372061006ef83f0abde7" }
tree-sitter-nu = { git = "https://github.com/nushell/tree-sitter-nu", rev = "7dd29f9616822e5fc259f5b4ae6c4ded9a71a132" }
tree-sitter-nu = { git = "https://github.com/nushell/tree-sitter-nu", rev = "26bbaecda0039df4067861ab38ea8ea169f7f5aa" }
tree-sitter-ocaml = { git = "https://github.com/tree-sitter/tree-sitter-ocaml", rev = "4abfdc1c7af2c6c77a370aee974627be1c285b3b" }
tree-sitter-php = "0.21.1"
tree-sitter-prisma-io = { git = "https://github.com/victorhqc/tree-sitter-prisma" }
tree-sitter-proto = { git = "https://github.com/rewinfrey/tree-sitter-proto", rev = "36d54f288aee112f13a67b550ad32634d0c2cb52" }
tree-sitter-purescript = { git = "https://github.com/postsolar/tree-sitter-purescript", rev = "v0.1.0" }
tree-sitter-purescript = { git = "https://github.com/ivanmoreau/tree-sitter-purescript", rev = "a37140f0c7034977b90faa73c94fcb8a5e45ed08" }
tree-sitter-python = "0.20.2"
tree-sitter-racket = { git = "https://github.com/zed-industries/tree-sitter-racket", rev = "eb010cf2c674c6fd9a6316a84e28ef90190fe51a" }
tree-sitter-ruby = "0.20.0"
tree-sitter-rust = "0.20.3"
tree-sitter-scheme = { git = "https://github.com/6cdh/tree-sitter-scheme", rev = "af0fd1fa452cb2562dc7b5c8a8c55551c39273b9" }
tree-sitter-svelte = { git = "https://github.com/Himujjal/tree-sitter-svelte", rev = "bd60db7d3d06f89b6ec3b287c9a6e9190b5564bd" }
tree-sitter-svelte = { git = "https://github.com/Himujjal/tree-sitter-svelte", rev = "697bb515471871e85ff799ea57a76298a71a9cca" }
tree-sitter-toml = { git = "https://github.com/tree-sitter/tree-sitter-toml", rev = "342d9be207c2dba869b9967124c679b5e6fd0ebe" }
tree-sitter-typescript = { git = "https://github.com/tree-sitter/tree-sitter-typescript", rev = "5d20856f34315b068c41edaee2ac8a100081d259" }
tree-sitter-uiua = { git = "https://github.com/shnarazk/tree-sitter-uiua", rev = "9260f11be5900beda4ee6d1a24ab8ddfaf5a19b2" }
tree-sitter-vue = { git = "https://github.com/zed-industries/tree-sitter-vue", rev = "6608d9d60c386f19d80af7d8132322fa11199c42" }
tree-sitter-yaml = { git = "https://github.com/zed-industries/tree-sitter-yaml", rev = "f545a41f57502e1b5ddf2a6668896c1b0620f930" }
tree-sitter-zig = { git = "https://github.com/maxxnino/tree-sitter-zig", rev = "0d08703e4c3f426ec61695d7617415fff97029bd" }
unindent = "0.1.7"
unicase = "2.6"
url = "2.2"
uuid = { version = "1.1.2", features = ["v4"] }
wasmparser = "0.121"
wasm-encoder = "0.41"
wasmtime = { version = "18.0", default-features = false, features = ["async", "demangle", "runtime", "cranelift", "component-model"] }
wasmtime-wasi = "18.0"
which = "6.0.0"
wit-component = "0.20"
sys-locale = "0.3.1"
[workspace.dependencies.windows]
version = "0.53.0"
features = [
"implement",
"Wdk_System_SystemServices",
"Win32_Graphics_Gdi",
"Win32_Graphics_DirectComposition",
"Win32_UI_Controls",
"Win32_UI_WindowsAndMessaging",
"Win32_UI_Input_KeyboardAndMouse",
"Win32_UI_Shell",
"Win32_System_Com",
"Win32_System_SystemInformation",
"Win32_System_SystemServices",
"Win32_System_Time",
"Win32_Security",
"Win32_System_Com",
"Win32_System_Com_StructuredStorage",
"Win32_System_Threading",
"Win32_System_DataExchange",
"Win32_System_Ole",
"Win32_System_Com",
]
wasmtime = "16"
[patch.crates-io]
tree-sitter = { git = "https://github.com/tree-sitter/tree-sitter", rev = "4294e59279205f503eb14348dd5128bd5910c8fb" }
# Workaround for a broken nightly build of gpui: See #7644 and revisit once 0.5.3 is released.
pathfinder_simd = { git = "https://github.com/servo/pathfinder.git", rev = "e4fcda0d5259d0acf902aee6de7d2501f2bd6629" }
tree-sitter = { git = "https://github.com/tree-sitter/tree-sitter", rev = "1d8975319c2d5de1bf710e7e21db25b0eee4bc66" }
wasmtime = { git = "https://github.com/bytecodealliance/wasmtime", rev = "v16.0.0" }
[profile.dev]
split-debuginfo = "unpacked"
debug = "limited"
# todo(linux) - Remove this
# todo!(linux) - Remove this
[profile.dev.package.blade-graphics]
split-debuginfo = "off"
debug = "full"
[profile.dev.package]
taffy = { opt-level = 3 }
cranelift-codegen = { opt-level = 3 }
rustybuzz = { opt-level = 3 }
ttf-parser = { opt-level = 3 }
wasmtime-cranelift = { opt-level = 3 }
[profile.dev.package.taffy]
opt-level = 3
[profile.release]
debug = "limited"
lto = "thin"
codegen-units = 1
[workspace.lints.clippy]
dbg_macro = "deny"
todo = "deny"
# These are all of the rules that currently have violations in the Zed
# codebase.
#
# We'll want to drive this list down by either:
# 1. fixing violations of the rule and begin enforcing it
# 2. deciding we want to allow the rule permanently, at which point
# we should codify that separately above.
#
# This list shouldn't be added to; it should only get shorter.
# =============================================================================
# There are a bunch of rules currently failing in the `style` group, so
# allow all of those, for now.
style = "allow"
# Individual rules that have violations in the codebase:
almost_complete_range = "allow"
arc_with_non_send_sync = "allow"
await_holding_lock = "allow"
borrowed_box = "allow"
derive_ord_xor_partial_ord = "allow"
eq_op = "allow"
let_underscore_future = "allow"
map_entry = "allow"
never_loop = "allow"
non_canonical_clone_impl = "allow"
non_canonical_partial_ord_impl = "allow"
reversed_empty_ranges = "allow"
single_range_in_vec_init = "allow"
type_complexity = "allow"
[workspace.metadata.cargo-machete]
ignored = ["bindgen", "cbindgen", "prost_build", "serde"]

View File

@@ -1,6 +1,6 @@
# syntax = docker/dockerfile:1.2
FROM rust:1.76-bookworm as builder
FROM rust:1.76-bullseye as builder
WORKDIR app
COPY . .
@@ -11,7 +11,6 @@ ARG GITHUB_SHA
ENV GITHUB_SHA=$GITHUB_SHA
RUN --mount=type=cache,target=./script/node_modules \
--mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git \
--mount=type=cache,target=./target \
cargo build --release --package collab --bin collab
@@ -20,10 +19,9 @@ RUN --mount=type=cache,target=./target \
cp /app/target/release/collab /app/collab
# Copy collab server binary to the runtime image
FROM debian:bookworm-slim as runtime
FROM debian:bullseye-slim as runtime
RUN apt-get update; \
apt-get install -y --no-install-recommends libcurl4-openssl-dev ca-certificates \
linux-perf binutils
apt-get install -y --no-install-recommends libcurl4-openssl-dev ca-certificates
WORKDIR app
COPY --from=builder /app/collab /app/collab
COPY --from=builder /app/crates/collab/migrations /app/migrations

View File

@@ -1,3 +1,2 @@
collab: RUST_LOG=${RUST_LOG:-warn,tower_http=info,collab=info} cargo run --package=collab serve
collab: cd crates/collab && RUST_LOG=${RUST_LOG:-warn,collab=info} cargo run serve
livekit: livekit-server --dev
blob_store: ./script/run-local-minio

View File

@@ -10,7 +10,7 @@ You can [download](https://zed.dev/download) Zed today for macOS (v10.15+).
Support for additional platforms is on our [roadmap](https://zed.dev/roadmap):
- Linux ([tracking issue](https://github.com/zed-industries/zed/issues/7015))
- Linux ([tracking issue](https://github.com/zed-industries/zed/issues/5395))
- Windows ([tracking issue](https://github.com/zed-industries/zed/issues/5394))
- Web ([tracking issue](https://github.com/zed-industries/zed/issues/5396))
@@ -21,9 +21,7 @@ brew install zed
## Developing Zed
- [Building Zed for macOS](./docs/src/developing_zed__building_zed_macos.md)
- [Building Zed for Linux](./docs/src/developing_zed__building_zed_linux.md)
- [Building Zed for Windows](./docs/src/developing_zed__building_zed_windows.md)
- [Building Zed](./docs/src/developing_zed__building_zed.md)
- [Running Collaboration Locally](./docs/src/developing_zed__local_collaboration.md)
## Contributing

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="14px" viewBox="0 0 14 14" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 7 13.179688 C 10.867188 13.179688 14 10.652344 14 7.53125 C 14 5.59375 12.800781 3.886719 10.957031 2.871094 C 10.207031 2.453125 9.617188 2.078125 9.125 1.769531 C 8.199219 1.179688 7.628906 0.820312 7 0.820312 C 6.359375 0.820312 5.636719 1.277344 4.6875 1.882812 C 4.148438 2.230469 3.601562 2.558594 3.042969 2.871094 C 1.199219 3.886719 0 5.59375 0 7.53125 C 0 10.652344 3.132812 13.179688 7 13.179688 Z M 6.183594 2.75 C 6.378906 2.308594 6.476562 1.828125 6.472656 1.34375 C 6.472656 1.261719 6.589844 1.234375 6.605469 1.328125 C 6.992188 2.953125 6.082031 3.757812 5.40625 4.027344 C 5.335938 4.054688 5.292969 3.953125 5.347656 3.902344 C 5.703125 3.582031 5.988281 3.191406 6.183594 2.75 Z M 7.382812 2.691406 C 7.328125 2.214844 7.171875 1.757812 6.925781 1.347656 L 6.925781 1.335938 C 6.886719 1.265625 6.976562 1.183594 7.035156 1.234375 C 8.179688 2.46875 7.796875 3.609375 7.359375 4.183594 C 7.3125 4.242188 7.226562 4.179688 7.25 4.109375 C 7.394531 3.652344 7.4375 3.167969 7.382812 2.691406 Z M 8.417969 2.363281 C 8.183594 1.949219 7.863281 1.589844 7.480469 1.308594 L 7.480469 1.300781 C 7.414062 1.253906 7.464844 1.140625 7.546875 1.175781 C 9.058594 1.808594 9.164062 3.03125 8.980469 3.746094 C 8.976562 3.761719 8.964844 3.777344 8.953125 3.785156 C 8.921875 3.808594 8.882812 3.800781 8.863281 3.773438 C 8.851562 3.757812 8.847656 3.742188 8.847656 3.722656 C 8.800781 3.246094 8.65625 2.78125 8.417969 2.363281 Z M 5.453125 2.691406 C 5.09375 3.007812 4.703125 3.132812 4.25 3.273438 C 4.179688 3.273438 4.132812 3.230469 4.15625 3.167969 C 5.179688 2.636719 5.542969 2.207031 5.90625 1.546875 C 5.90625 1.546875 5.996094 1.480469 6.015625 1.597656 C 6.015625 1.773438 5.8125 2.371094 5.453125 2.691406 Z M 8.335938 9.246094 C 8.253906 9.597656 8.0625 9.914062 7.789062 10.152344 C 7.589844 10.355469 7.324219 10.480469 7.039062 10.511719 C 6.746094 10.484375 6.472656 10.359375 6.265625 10.152344 C 5.996094 9.914062 5.808594 9.597656 5.726562 9.246094 C 5.71875 9.203125 5.734375 9.160156 5.761719 9.128906 C 5.792969 9.101562 5.835938 9.085938 5.875 9.089844 L 8.1875 9.089844 C 8.230469 9.085938 8.269531 9.101562 8.300781 9.132812 C 8.328125 9.160156 8.34375 9.203125 8.335938 9.246094 Z M 5.152344 7.976562 C 4.714844 8.273438 4.128906 8.210938 3.761719 7.832031 C 3.390625 7.445312 3.335938 6.855469 3.625 6.40625 C 3.746094 6.21875 3.917969 6.074219 4.121094 5.992188 C 4.320312 5.90625 4.542969 5.882812 4.757812 5.925781 C 4.972656 5.96875 5.167969 6.078125 5.320312 6.234375 C 5.636719 6.5625 5.730469 7.046875 5.558594 7.46875 C 5.476562 7.675781 5.335938 7.851562 5.152344 7.976562 Z M 10.109375 7.980469 C 9.671875 8.273438 9.085938 8.210938 8.71875 7.832031 C 8.511719 7.617188 8.398438 7.332031 8.398438 7.035156 C 8.398438 6.8125 8.464844 6.589844 8.585938 6.40625 C 8.707031 6.21875 8.878906 6.074219 9.082031 5.988281 C 9.28125 5.90625 9.503906 5.882812 9.71875 5.925781 C 9.933594 5.972656 10.128906 6.078125 10.285156 6.238281 C 10.597656 6.566406 10.691406 7.050781 10.515625 7.472656 C 10.433594 7.679688 10.292969 7.855469 10.109375 7.980469 Z M 10.109375 7.980469 "/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.9 KiB

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="14px" viewBox="0 0 14 14" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 10.601562 2.851562 L 3.398438 2.851562 L 3.511719 4.285156 L 9.050781 4.285156 L 8.910156 5.769531 L 5.28125 5.769531 L 5.410156 7.175781 L 8.789062 7.175781 L 8.589844 9.101562 L 7 9.542969 L 5.382812 9.097656 L 5.28125 7.945312 L 3.851562 7.945312 L 4.011719 10.054688 L 7 10.984375 L 9.9375 10.148438 Z M 1.257812 0.4375 L 12.742188 0.4375 L 11.695312 12.226562 L 6.988281 13.558594 L 2.304688 12.226562 Z M 1.257812 0.4375 "/>
</g>
</svg>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg">
<path d="M24.235 6.519l-16.47-0.004 0.266 3.277 12.653 0.002-0.319 3.394h-8.298l0.3 3.215h7.725l-0.457 4.403-3.636 1.005-3.694-1.012-0.235-2.637h-3.262l0.362 4.817 6.829 2.128 6.714-1.912 1.521-16.675zM2.879 1.004h26.242l-2.387 26.946-10.763 3.045-10.703-3.047z"></path>
</svg>

Before

Width:  |  Height:  |  Size: 730 B

After

Width:  |  Height:  |  Size: 482 B

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="14px" viewBox="0 0 14 14" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 9.203125 3.410156 C 8.792969 3 8.378906 2.597656 7.957031 2.207031 C 7.835938 2.078125 7.664062 1.996094 7.476562 1.996094 C 7.472656 1.996094 7.472656 1.996094 7.46875 1.996094 C 7.324219 2.011719 7.1875 2.042969 7.0625 2.089844 L 7.074219 2.085938 L 4.425781 3.40625 Z M 3.71875 3.71875 L 3.71875 9.078125 C 3.714844 9.109375 3.710938 9.144531 3.710938 9.179688 C 3.710938 9.40625 3.800781 9.613281 3.945312 9.765625 L 6.183594 12.003906 L 10.066406 12.003906 L 10.066406 10.066406 Z M 3.40625 3.40625 C 3.40625 3.40625 5.707031 2.257812 6.855469 1.683594 C 7.039062 1.59375 7.25 1.539062 7.476562 1.539062 C 7.496094 1.539062 7.515625 1.539062 7.53125 1.539062 C 7.824219 1.597656 8.082031 1.722656 8.296875 1.902344 L 8.292969 1.898438 L 12.460938 6.066406 L 12.460938 10.519531 L 10.519531 10.519531 L 10.519531 12.460938 L 5.996094 12.460938 L 1.898438 8.367188 C 1.683594 8.140625 1.546875 7.839844 1.542969 7.503906 C 1.558594 7.316406 1.609375 7.148438 1.6875 6.992188 L 1.683594 7 Z M 3.40625 3.40625 "/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="14px" viewBox="0 0 14 14" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 13.421875 5.847656 C 13.152344 5.671875 12.824219 5.566406 12.46875 5.566406 C 12.429688 5.566406 12.390625 5.566406 12.351562 5.570312 L 12.355469 5.570312 C 12.160156 5.570312 11.96875 5.585938 11.785156 5.621094 L 11.804688 5.617188 C 11.699219 5.023438 11.355469 4.523438 10.875 4.21875 L 10.867188 4.214844 L 10.679688 4.105469 L 10.554688 4.285156 C 10.410156 4.507812 10.292969 4.769531 10.226562 5.050781 L 10.222656 5.066406 C 10.183594 5.207031 10.160156 5.371094 10.160156 5.539062 C 10.160156 5.902344 10.265625 6.242188 10.445312 6.527344 L 10.441406 6.519531 C 10.164062 6.648438 9.839844 6.734375 9.496094 6.75 L 0.859375 6.75 C 0.632812 6.75 0.449219 6.929688 0.449219 7.15625 C 0.449219 7.179688 0.449219 7.210938 0.449219 7.238281 C 0.449219 8.003906 0.585938 8.738281 0.839844 9.417969 L 0.828125 9.375 C 1.070312 10.089844 1.53125 10.675781 2.128906 11.070312 L 2.144531 11.078125 C 2.90625 11.476562 3.808594 11.707031 4.765625 11.707031 C 4.855469 11.707031 4.945312 11.703125 5.035156 11.699219 L 5.023438 11.699219 C 5.03125 11.699219 5.039062 11.699219 5.050781 11.699219 C 5.605469 11.699219 6.148438 11.648438 6.675781 11.546875 L 6.621094 11.554688 C 7.40625 11.410156 8.109375 11.144531 8.742188 10.78125 L 8.710938 10.796875 C 9.261719 10.476562 9.730469 10.085938 10.128906 9.636719 L 10.136719 9.628906 C 10.714844 8.949219 11.1875 8.152344 11.511719 7.28125 L 11.527344 7.226562 L 11.648438 7.226562 C 11.671875 7.230469 11.703125 7.230469 11.730469 7.230469 C 12.265625 7.230469 12.753906 7.019531 13.113281 6.675781 C 13.277344 6.519531 13.410156 6.332031 13.496094 6.117188 L 13.5 6.105469 L 13.550781 5.949219 Z M 1.65625 6.496094 L 2.816406 6.496094 C 2.871094 6.496094 2.917969 6.449219 2.917969 6.394531 L 2.917969 5.363281 C 2.917969 5.308594 2.871094 5.265625 2.816406 5.261719 L 1.65625 5.261719 C 1.601562 5.265625 1.558594 5.308594 1.558594 5.363281 L 1.558594 6.394531 C 1.558594 6.453125 1.601562 6.496094 1.65625 6.496094 C 1.65625 6.496094 1.65625 6.496094 1.660156 6.496094 Z M 3.253906 6.496094 L 4.410156 6.496094 C 4.464844 6.496094 4.511719 6.453125 4.511719 6.394531 L 4.511719 5.363281 C 4.511719 5.308594 4.464844 5.265625 4.410156 5.261719 L 3.25 5.261719 C 3.195312 5.261719 3.152344 5.308594 3.152344 5.363281 L 3.152344 6.394531 C 3.152344 6.453125 3.195312 6.496094 3.25 6.496094 Z M 4.871094 6.496094 L 6.027344 6.496094 C 6.082031 6.496094 6.128906 6.449219 6.128906 6.394531 L 6.128906 5.363281 C 6.128906 5.308594 6.082031 5.265625 6.027344 5.261719 L 4.871094 5.261719 C 4.816406 5.265625 4.769531 5.308594 4.769531 5.363281 L 4.769531 6.394531 C 4.769531 6.449219 4.816406 6.496094 4.871094 6.496094 Z M 6.46875 6.496094 L 7.625 6.496094 C 7.683594 6.496094 7.726562 6.453125 7.726562 6.394531 L 7.726562 5.363281 C 7.726562 5.308594 7.683594 5.261719 7.625 5.261719 L 6.46875 5.261719 C 6.414062 5.261719 6.367188 5.308594 6.367188 5.363281 L 6.367188 6.394531 C 6.367188 6.453125 6.414062 6.496094 6.46875 6.496094 Z M 3.253906 5.015625 L 4.410156 5.015625 C 4.464844 5.015625 4.511719 4.96875 4.511719 4.914062 L 4.511719 3.882812 C 4.511719 3.828125 4.464844 3.78125 4.410156 3.78125 L 3.253906 3.78125 C 3.195312 3.78125 3.152344 3.828125 3.152344 3.882812 L 3.152344 4.914062 C 3.152344 4.96875 3.195312 5.015625 3.253906 5.015625 Z M 4.871094 5.015625 L 6.027344 5.015625 C 6.082031 5.015625 6.128906 4.96875 6.128906 4.914062 L 6.128906 3.882812 C 6.128906 3.828125 6.082031 3.78125 6.027344 3.78125 L 4.871094 3.78125 C 4.816406 3.78125 4.769531 3.828125 4.769531 3.882812 L 4.769531 4.914062 C 4.769531 4.96875 4.816406 5.015625 4.871094 5.015625 Z M 6.46875 5.015625 L 7.625 5.015625 C 7.683594 5.015625 7.726562 4.96875 7.726562 4.914062 L 7.726562 3.882812 C 7.726562 3.828125 7.683594 3.78125 7.625 3.78125 L 6.46875 3.78125 C 6.414062 3.78125 6.367188 3.828125 6.367188 3.882812 L 6.367188 4.914062 C 6.367188 4.96875 6.414062 5.015625 6.46875 5.015625 Z M 6.46875 3.53125 L 7.625 3.53125 C 7.683594 3.53125 7.726562 3.488281 7.726562 3.429688 L 7.726562 2.398438 C 7.726562 2.34375 7.683594 2.296875 7.625 2.296875 L 6.46875 2.296875 C 6.414062 2.296875 6.367188 2.34375 6.367188 2.398438 L 6.367188 3.429688 C 6.367188 3.488281 6.414062 3.53125 6.46875 3.53125 Z M 8.082031 6.496094 L 9.238281 6.496094 C 9.296875 6.496094 9.339844 6.453125 9.339844 6.394531 L 9.339844 5.363281 C 9.339844 5.308594 9.296875 5.261719 9.238281 5.261719 L 8.082031 5.261719 C 8.027344 5.261719 7.980469 5.308594 7.980469 5.363281 L 7.980469 6.394531 C 7.980469 6.449219 8.027344 6.496094 8.082031 6.496094 Z M 8.082031 6.496094 "/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.8 KiB

View File

@@ -1,12 +1 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="14px" viewBox="0 0 14 14" version="1.1">
<defs>
<linearGradient id="linear0" gradientUnits="userSpaceOnUse" x1="0" y1="128" x2="128" y2="0" gradientTransform="matrix(0.109375,0,0,0.109375,0,0)">
<stop offset="0" style="stop-color:rgb(20%,20%,20%);stop-opacity:1;"/>
<stop offset="1" style="stop-color:rgb(36.470588%,36.470588%,36.470588%);stop-opacity:1;"/>
</linearGradient>
</defs>
<g id="surface1">
<path style=" stroke:none;fill-rule:nonzero;fill:url(#linear0);" d="M 1.339844 3.355469 L 2.976562 3.355469 C 2.363281 3.953125 2.136719 4.523438 1.84375 5.324219 C 1.492188 6.28125 1.785156 8.605469 2.261719 9.433594 C 2.582031 9.992188 2.949219 10.417969 3.160156 10.644531 L 1.339844 10.644531 Z M 11.140625 3.355469 L 12.660156 3.355469 L 12.660156 10.644531 L 11.179688 10.644531 C 11.324219 10.453125 11.554688 10.148438 11.738281 9.941406 C 11.992188 9.65625 12.28125 9.179688 12.28125 9.179688 L 10.53125 8.289062 C 10.53125 8.289062 9.929688 9.558594 8.785156 10.035156 C 7.640625 10.515625 6.621094 9.945312 5.984375 9.214844 C 5.347656 8.480469 5.347656 6.792969 5.347656 6.792969 L 11.996094 6.792969 C 12.125 5.167969 11.710938 4.46875 11.484375 3.957031 C 11.386719 3.726562 11.277344 3.542969 11.140625 3.355469 Z M 6.945312 3.546875 C 6.984375 3.542969 7.023438 3.546875 7.066406 3.546875 C 8.371094 3.578125 8.492188 4.945312 8.492188 4.945312 L 5.507812 4.945312 C 5.507812 4.945312 5.742188 3.601562 6.945312 3.546875 Z M 6.945312 3.546875 "/>
</g>
</svg>
<svg height="64" viewBox="0 0 128 128" width="64" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="0" x2="128" y1="128" y2="0"><stop offset="0" stop-color="#333"/><stop offset="1" stop-color="#5d5d5d"/></linearGradient><path d="m12.239265 30.664279h14.960911c-5.59432 5.460938-7.654216 10.692785-10.342106 18.023379-3.200764 8.729348-.549141 29.987457 3.815534 37.55289 2.943384 5.101853 6.282685 8.994876 8.233522 11.095173h-16.667861zm89.614855 0h13.90661v66.671442h-13.55518c1.31391-1.750328 3.43934-4.534454 5.12085-6.426163 2.32782-2.618784 4.97023-6.978412 4.97023-6.978412l-16.015202-8.133112s-5.48977 11.600331-15.964999 15.964998c-10.475214 4.364666-19.784679-.838179-25.604243-7.530659-5.819578-6.692502-5.82371-22.14014-5.82371-22.14014h60.797524c1.16391-14.839892-2.63216-21.249816-4.66901-25.90547-.91799-2.098266-1.89261-3.810819-3.16287-5.522484zm-38.356164 1.757154c.35429-.01632.731685-.0092 1.104497 0 11.930114.290977 13.053143 12.802122 13.053143 12.802122h-27.311192s2.170772-12.298638 13.153552-12.802122z" fill="url(#a)"/></svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,341 +1,261 @@
{
"stems": {
"Podfile": "ruby",
"Procfile": "heroku",
"Dockerfile": "docker"
},
"suffixes": {
"astro": "astro",
"Emakefile": "erlang",
"aac": "audio",
"accdb": "storage",
"app.src": "erlang",
"avi": "video",
"avif": "image",
"bak": "backup",
"bash": "terminal",
"bash_aliases": "terminal",
"bash_logout": "terminal",
"bash_profile": "terminal",
"bashrc": "terminal",
"bmp": "image",
"c": "code",
"cc": "code",
"cjs": "code",
"conf": "settings",
"cpp": "code",
"css": "css",
"csv": "storage",
"cts": "typescript",
"coffee": "coffeescript",
"dart": "dart",
"dat": "storage",
"db": "storage",
"dbf": "storage",
"dll": "storage",
"doc": "document",
"docx": "document",
"eex": "elixir",
"elm": "elm",
"erl": "erlang",
"escript": "erlang",
"eslintrc": "eslint",
"eslintrc.js": "eslint",
"eslintrc.json": "eslint",
"ex": "elixir",
"exs": "elixir",
"fish": "terminal",
"flac": "audio",
"fmp": "storage",
"fp7": "storage",
"frm": "storage",
"fs": "fsharp",
"gdb": "storage",
"gif": "image",
"gitattributes": "vcs",
"gitignore": "vcs",
"gitkeep": "vcs",
"gitmodules": "vcs",
"go": "go",
"graphql": "graphql",
"h": "code",
"handlebars": "code",
"hbs": "template",
"heex": "elixir",
"heif": "image",
"heic": "image",
"hrl": "erlang",
"hs": "haskell",
"htm": "template",
"html": "template",
"ib": "storage",
"ico": "image",
"ini": "settings",
"j2k": "image",
"java": "java",
"jfif": "image",
"jp2": "image",
"jpeg": "image",
"jpg": "image",
"js": "code",
"json": "storage",
"jsonc": "storage",
"jxl": "image",
"kt": "kotlin",
"ldf": "storage",
"lock": "lock",
"lockb": "bun",
"log": "log",
"lua": "lua",
"m4a": "audio",
"m4v": "video",
"md": "document",
"mdb": "storage",
"mdf": "storage",
"mdx": "document",
"metadata": "code",
"mkv": "video",
"mjs": "code",
"mka": "audio",
"ml": "ocaml",
"mli": "ocaml",
"mov": "video",
"mp3": "audio",
"mp4": "video",
"mts": "typescript",
"myd": "storage",
"myi": "storage",
"nu": "terminal",
"nim": "nim",
"odp": "document",
"ods": "document",
"odt": "document",
"ogg": "audio",
"opus": "audio",
"otf": "font",
"pdb": "storage",
"pdf": "document",
"php": "php",
"plist": "template",
"png": "image",
"ppt": "document",
"pptx": "document",
"prettierignore": "prettier",
"prettierrc": "prettier",
"prisma": "prisma",
"profile": "terminal",
"ps1": "terminal",
"psd": "image",
"py": "python",
"qoi": "image",
"rb": "ruby",
"rebar.config": "erlang",
"rkt": "code",
"rs": "rust",
"r": "r",
"rtf": "document",
"sav": "storage",
"scm": "code",
"sdf": "storage",
"sh": "terminal",
"sqlite": "storage",
"svelte": "template",
"svg": "image",
"sc": "scala",
"scala": "scala",
"sql": "storage",
"swift": "swift",
"tf": "terraform",
"tfvars": "terraform",
"tiff": "image",
"toml": "toml",
"ts": "typescript",
"tsv": "storage",
"ttf": "font",
"tsx": "code",
"txt": "document",
"tcl": "tcl",
"vue": "vue",
"wav": "audio",
"webm": "video",
"webp": "image",
"wma": "audio",
"wmv": "video",
"wv": "audio",
"xls": "document",
"xlsx": "document",
"xml": "template",
"xrl": "erlang",
"yaml": "settings",
"yml": "settings",
"yrl": "erlang",
"zlogin": "terminal",
"zsh": "terminal",
"zsh_aliases": "terminal",
"zsh_histfile": "terminal",
"zsh_profile": "terminal",
"zshenv": "terminal",
"zshrc": "terminal"
},
"types": {
"astro": {
"icon": "icons/file_icons/astro.svg"
"suffixes": {
"astro": "astro",
"Emakefile": "erlang",
"aac": "audio",
"accdb": "storage",
"app.src": "erlang",
"avi": "video",
"avif": "image",
"bak": "backup",
"bash": "terminal",
"bash_aliases": "terminal",
"bash_logout": "terminal",
"bash_profile": "terminal",
"bashrc": "terminal",
"bmp": "image",
"c": "code",
"cc": "code",
"conf": "settings",
"cpp": "code",
"css": "css",
"csv": "storage",
"dat": "storage",
"db": "storage",
"dbf": "storage",
"dll": "storage",
"doc": "document",
"docx": "document",
"eex": "elixir",
"elm": "elm",
"erl": "erlang",
"escript": "erlang",
"eslintrc": "eslint",
"eslintrc.js": "eslint",
"eslintrc.json": "eslint",
"ex": "elixir",
"exs": "elixir",
"fish": "terminal",
"flac": "audio",
"fmp": "storage",
"fp7": "storage",
"frm": "storage",
"gdb": "storage",
"gif": "image",
"gitattributes": "vcs",
"gitignore": "vcs",
"gitkeep": "vcs",
"gitmodules": "vcs",
"go": "go",
"h": "code",
"handlebars": "code",
"hbs": "template",
"heex": "elixir",
"heif": "image",
"heic": "image",
"hrl": "erlang",
"hs": "haskell",
"htm": "template",
"html": "template",
"ib": "storage",
"ico": "image",
"ini": "settings",
"j2k": "image",
"java": "code",
"jfif": "image",
"jp2": "image",
"jpeg": "image",
"jpg": "image",
"js": "code",
"json": "storage",
"jsonc": "storage",
"jxl": "image",
"ldf": "storage",
"lock": "lock",
"log": "log",
"m4a": "audio",
"m4v": "video",
"md": "document",
"mdb": "storage",
"mdf": "storage",
"mdx": "document",
"mkv": "video",
"mka": "audio",
"ml": "ocaml",
"mli": "ocaml",
"mov": "video",
"mp3": "audio",
"mp4": "video",
"myd": "storage",
"myi": "storage",
"odp": "document",
"ods": "document",
"odt": "document",
"ogg": "audio",
"opus": "audio",
"pdb": "storage",
"pdf": "document",
"php": "php",
"png": "image",
"ppt": "document",
"pptx": "document",
"prettierignore": "prettier",
"prettierrc": "prettier",
"prisma": "prisma",
"profile": "terminal",
"ps1": "terminal",
"psd": "image",
"py": "python",
"qoi": "image",
"rb": "ruby",
"rebar.config": "erlang",
"rkt": "code",
"rs": "rust",
"rtf": "document",
"sav": "storage",
"scm": "code",
"sdf": "storage",
"sh": "terminal",
"sqlite": "storage",
"svelte": "template",
"svg": "image",
"swift": "code",
"tiff": "image",
"toml": "toml",
"ts": "typescript",
"tsv": "storage",
"tsx": "code",
"txt": "document",
"vue": "vue",
"wav": "audio",
"webm": "video",
"webp": "image",
"wma": "audio",
"wmv": "video",
"wv": "audio",
"xls": "document",
"xlsx": "document",
"xml": "template",
"xrl": "erlang",
"yaml": "settings",
"yml": "settings",
"yrl": "erlang",
"zlogin": "terminal",
"zsh": "terminal",
"zsh_aliases": "terminal",
"zsh_histfile": "terminal",
"zsh_profile": "terminal",
"zshenv": "terminal",
"zshrc": "terminal"
},
"audio": {
"icon": "icons/file_icons/audio.svg"
},
"code": {
"icon": "icons/file_icons/code.svg"
},
"collapsed_chevron": {
"icon": "icons/file_icons/chevron_right.svg"
},
"collapsed_folder": {
"icon": "icons/file_icons/folder.svg"
},
"css": {
"icon": "icons/file_icons/css.svg"
},
"coffeescript": {
"icon": "icons/file_icons/coffeescript.svg"
},
"dart": {
"icon": "icons/file_icons/dart.svg"
},
"default": {
"icon": "icons/file_icons/file.svg"
},
"docker": {
"icon": "icons/file_icons/docker.svg"
},
"document": {
"icon": "icons/file_icons/book.svg"
},
"elixir": {
"icon": "icons/file_icons/elixir.svg"
},
"elm": {
"icon": "icons/file_icons/elm.svg"
},
"erlang": {
"icon": "icons/file_icons/erlang.svg"
},
"eslint": {
"icon": "icons/file_icons/eslint.svg"
},
"expanded_chevron": {
"icon": "icons/file_icons/chevron_down.svg"
},
"expanded_folder": {
"icon": "icons/file_icons/folder_open.svg"
},
"font": {
"icon": "icons/file_icons/font.svg"
},
"fsharp": {
"icon": "icons/file_icons/fsharp.svg"
},
"haskell": {
"icon": "icons/file_icons/haskell.svg"
},
"heroku": {
"icon": "icons/file_icons/heroku.svg"
},
"go": {
"icon": "icons/file_icons/go.svg"
},
"graphql": {
"icon": "icons/file_icons/graphql.svg"
},
"image": {
"icon": "icons/file_icons/image.svg"
},
"java": {
"icon": "icons/file_icons/java.svg"
},
"kotlin": {
"icon": "icons/file_icons/kotlin.svg"
},
"lock": {
"icon": "icons/file_icons/lock.svg"
},
"bun": {
"icon": "icons/file_icons/bun.svg"
},
"log": {
"icon": "icons/file_icons/info.svg"
},
"lua": {
"icon": "icons/file_icons/lua.svg"
},
"ocaml": {
"icon": "icons/file_icons/ocaml.svg"
},
"nim": {
"icon": "icons/file_icons/nim.svg"
},
"phoenix": {
"icon": "icons/file_icons/phoenix.svg"
},
"php": {
"icon": "icons/file_icons/php.svg"
},
"prettier": {
"icon": "icons/file_icons/prettier.svg"
},
"prisma": {
"icon": "icons/file_icons/prisma.svg"
},
"python": {
"icon": "icons/file_icons/python.svg"
},
"ruby": {
"icon": "icons/file_icons/ruby.svg"
},
"rust": {
"icon": "icons/file_icons/rust.svg"
},
"r": {
"icon": "icons/file_icons/r.svg"
},
"settings": {
"icon": "icons/file_icons/settings.svg"
},
"storage": {
"icon": "icons/file_icons/database.svg"
},
"scala": {
"icon": "icons/file_icons/scala.svg"
},
"swift": {
"icon": "icons/file_icons/swift.svg"
},
"template": {
"icon": "icons/file_icons/html.svg"
},
"terraform": {
"icon": "icons/file_icons/terraform.svg"
},
"terminal": {
"icon": "icons/file_icons/terminal.svg"
},
"toml": {
"icon": "icons/file_icons/toml.svg"
},
"typescript": {
"icon": "icons/file_icons/typescript.svg"
},
"tcl": {
"icon": "icons/file_icons/tcl.svg"
},
"vcs": {
"icon": "icons/file_icons/git.svg"
},
"video": {
"icon": "icons/file_icons/video.svg"
},
"vue": {
"icon": "icons/file_icons/vue.svg"
"types": {
"astro": {
"icon": "icons/file_icons/astro.svg"
},
"audio": {
"icon": "icons/file_icons/audio.svg"
},
"code": {
"icon": "icons/file_icons/code.svg"
},
"collapsed_chevron": {
"icon": "icons/file_icons/chevron_right.svg"
},
"collapsed_folder": {
"icon": "icons/file_icons/folder.svg"
},
"css": {
"icon": "icons/file_icons/css.svg"
},
"default": {
"icon": "icons/file_icons/file.svg"
},
"document": {
"icon": "icons/file_icons/book.svg"
},
"elixir": {
"icon": "icons/file_icons/elixir.svg"
},
"elm": {
"icon": "icons/file_icons/elm.svg"
},
"erlang": {
"icon": "icons/file_icons/erlang.svg"
},
"eslint": {
"icon": "icons/file_icons/eslint.svg"
},
"expanded_chevron": {
"icon": "icons/file_icons/chevron_down.svg"
},
"expanded_folder": {
"icon": "icons/file_icons/folder_open.svg"
},
"haskell": {
"icon": "icons/file_icons/haskell.svg"
},
"go": {
"icon": "icons/file_icons/go.svg"
},
"image": {
"icon": "icons/file_icons/image.svg"
},
"lock": {
"icon": "icons/file_icons/lock.svg"
},
"log": {
"icon": "icons/file_icons/info.svg"
},
"ocaml": {
"icon": "icons/file_icons/ocaml.svg"
},
"phoenix": {
"icon": "icons/file_icons/phoenix.svg"
},
"php": {
"icon": "icons/file_icons/php.svg"
},
"prettier": {
"icon": "icons/file_icons/prettier.svg"
},
"prisma": {
"icon": "icons/file_icons/prisma.svg"
},
"python": {
"icon": "icons/file_icons/python.svg"
},
"ruby": {
"icon": "icons/file_icons/ruby.svg"
},
"rust": {
"icon": "icons/file_icons/rust.svg"
},
"settings": {
"icon": "icons/file_icons/settings.svg"
},
"storage": {
"icon": "icons/file_icons/database.svg"
},
"template": {
"icon": "icons/file_icons/html.svg"
},
"terminal": {
"icon": "icons/file_icons/terminal.svg"
},
"toml": {
"icon": "icons/file_icons/toml.svg"
},
"typescript": {
"icon": "icons/file_icons/typescript.svg"
},
"vcs": {
"icon": "icons/file_icons/git.svg"
},
"video": {
"icon": "icons/file_icons/video.svg"
},
"vue": {
"icon": "icons/file_icons/vue.svg"
}
}
}
}

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="14px" viewBox="0 0 14 14" version="1.1">
<g id="surface1">
<path style="fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:4;" d="M 16.001786 21 L 19.497321 21 M 5.997321 21 L 12 3 L 18.002679 21 M 4.502679 21 L 7.998214 21 M 14.997321 14.000893 L 9.002679 14.000893 " transform="matrix(0.486111,0,0,0.486111,1.166667,1.166667)"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 559 B

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="14px" viewBox="0 0 14 14" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 3.324219 3.496094 C 1.507812 5.40625 0.0273438 6.984375 0.0273438 6.996094 C 0.0273438 7.015625 1.511719 8.59375 3.332031 10.503906 L 6.632812 13.980469 L 6.632812 10.472656 L 4.984375 8.734375 L 3.332031 6.996094 L 4.984375 5.257812 L 6.632812 3.519531 L 6.628906 1.773438 L 6.621094 0.0273438 Z M 3.324219 3.496094 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 7.125 1.773438 L 7.125 3.492188 L 8.769531 5.222656 C 9.675781 6.171875 10.421875 6.96875 10.425781 6.984375 C 10.433594 7.003906 9.691406 7.800781 8.78125 8.761719 L 7.125 10.503906 L 7.125 13.972656 L 7.214844 13.890625 C 7.296875 13.820312 8.203125 12.90625 9.167969 11.910156 C 9.398438 11.671875 9.605469 11.464844 9.621094 11.449219 C 9.671875 11.402344 11.261719 9.789062 11.601562 9.4375 C 11.773438 9.261719 11.957031 9.082031 12 9.035156 C 12.046875 8.988281 12.433594 8.59375 12.863281 8.160156 C 13.289062 7.726562 13.722656 7.289062 13.824219 7.183594 L 14.007812 6.996094 L 13.808594 6.796875 C 13.179688 6.167969 12.527344 5.503906 11.820312 4.785156 C 11.574219 4.53125 11.105469 4.058594 10.785156 3.734375 C 10.460938 3.414062 9.871094 2.8125 9.472656 2.402344 C 9.074219 1.996094 8.609375 1.515625 8.4375 1.339844 C 8.265625 1.160156 7.910156 0.800781 7.652344 0.539062 C 7.394531 0.273438 7.167969 0.0585938 7.15625 0.0585938 C 7.132812 0.0585938 7.125 0.59375 7.125 1.773438 Z M 7.125 1.773438 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 5.453125 5.757812 C 4.308594 6.964844 4.285156 6.992188 4.332031 7.050781 C 4.359375 7.082031 4.886719 7.636719 5.5 8.289062 L 6.621094 9.464844 L 6.628906 8.222656 C 6.632812 7.539062 6.632812 6.429688 6.628906 5.753906 L 6.621094 4.527344 Z M 5.453125 5.757812 "/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1 +0,0 @@
<svg width="14px" height="14px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" fill="#000000"><path fill-rule="evenodd" clip-rule="evenodd" d="M50 6.90308L87.323 28.4515V71.5484L50 93.0968L12.677 71.5484V28.4515L50 6.90308ZM16.8647 30.8693V62.5251L44.2795 15.0414L16.8647 30.8693ZM50 13.5086L18.3975 68.2457H81.6025L50 13.5086ZM77.4148 72.4334H22.5852L50 88.2613L77.4148 72.4334ZM83.1353 62.5251L55.7205 15.0414L83.1353 30.8693V62.5251Z"/><circle cx="50" cy="9.3209" r="8.82"/><circle cx="85.2292" cy="29.6605" r="8.82"/><circle cx="85.2292" cy="70.3396" r="8.82"/><circle cx="50" cy="90.6791" r="8.82"/><circle cx="14.7659" cy="70.3396" r="8.82"/><circle cx="14.7659" cy="29.6605" r="8.82"/></svg>

Before

Width:  |  Height:  |  Size: 709 B

View File

@@ -1,6 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="14px" viewBox="0 0 14 14" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 4.679688 3.894531 L 4.679688 3.9375 C 5.335938 4.945312 6.039062 5.949219 6.695312 6.957031 L 6.695312 7 C 6.039062 8.007812 5.335938 9.011719 4.679688 10.019531 L 4.679688 10.0625 L 6.210938 10.0625 L 6.257812 10.019531 C 6.648438 9.40625 7.085938 8.792969 7.480469 8.179688 C 7.523438 8.136719 7.480469 8.136719 7.523438 8.179688 C 7.917969 8.792969 8.355469 9.40625 8.75 10.019531 L 8.792969 10.0625 L 10.324219 10.0625 C 9.492188 8.75 8.617188 7.480469 7.742188 6.167969 C 7.21875 5.425781 6.738281 4.636719 6.210938 3.894531 Z M 2.625 3.9375 C 3.324219 4.945312 3.980469 5.949219 4.636719 7 L 4.636719 7.042969 C 4.15625 7.789062 3.675781 8.488281 3.195312 9.230469 C 2.976562 9.492188 2.800781 9.800781 2.625 10.0625 L 2.625 10.105469 L 4.15625 10.105469 C 4.855469 9.054688 5.554688 8.050781 6.210938 7.042969 L 6.210938 7 C 5.90625 6.476562 5.554688 5.992188 5.207031 5.46875 C 4.855469 4.988281 4.550781 4.460938 4.199219 3.980469 L 4.15625 3.9375 Z M 7.960938 5.6875 L 7.960938 5.730469 C 8.179688 6.082031 8.398438 6.386719 8.617188 6.738281 L 11.375 6.738281 L 11.375 5.6875 Z M 8.96875 7.261719 L 8.96875 7.304688 C 9.1875 7.65625 9.40625 7.960938 9.625 8.3125 L 11.375 8.3125 L 11.375 7.261719 Z M 8.96875 7.261719 "/>
</g>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 32 32"
version="1.1"
id="svg977"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs981" />
<path
id="path973"
d="M 10.699219 8.9003906 L 10.699219 9 C 12.199219 11.3 13.800781 13.600391 15.300781 15.900391 L 15.300781 16 C 13.800781 18.3 12.199219 20.600391 10.699219 22.900391 L 10.699219 23 L 14.199219 23 L 14.300781 22.900391 C 15.200781 21.500391 16.199609 20.099219 17.099609 18.699219 C 17.199609 18.599219 17.099219 18.599219 17.199219 18.699219 C 18.099219 20.099219 19.1 21.500391 20 22.900391 L 20.099609 23 L 23.599609 23 C 21.699609 20 19.699219 17.099609 17.699219 14.099609 C 16.499219 12.399609 15.399219 10.600391 14.199219 8.9003906 L 10.699219 8.9003906 z M 6 9 C 7.6 11.3 9.0996094 13.6 10.599609 16 L 10.599609 16.099609 C 9.4996094 17.799609 8.4007813 19.399609 7.3007812 21.099609 C 6.8007813 21.699609 6.4 22.4 6 23 L 6 23.099609 L 9.5 23.099609 C 11.1 20.699609 12.699219 18.399609 14.199219 16.099609 L 14.199219 16 C 13.499219 14.8 12.700391 13.7 11.900391 12.5 C 11.100391 11.4 10.399609 10.199609 9.5996094 9.0996094 L 9.5 9 L 6 9 z M 18.199219 13 L 18.199219 13.099609 C 18.699219 13.899609 19.199219 14.600391 19.699219 15.400391 L 26 15.400391 L 26 13 L 18.199219 13 z M 20.5 16.599609 L 20.5 16.699219 C 21 17.499219 21.5 18.2 22 19 L 26 19 L 26 16.599609 L 20.5 16.599609 z " />
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="14px" viewBox="0 0 14 14" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 12.023438 0 L 1.976562 0 C 1.277344 0 0.71875 0.558594 0.71875 1.261719 L 0.71875 12.738281 C 0.71875 13.441406 1.277344 14 1.976562 14 L 12.023438 14 C 12.722656 14 13.28125 13.441406 13.28125 12.738281 L 13.28125 1.261719 C 13.28125 0.558594 12.722656 0 12.023438 0 Z M 12.582031 12.738281 C 12.582031 13.054688 12.335938 13.300781 12.023438 13.300781 L 1.976562 13.300781 C 1.664062 13.300781 1.417969 13.054688 1.417969 12.738281 L 1.417969 1.261719 C 1.417969 0.945312 1.664062 0.699219 1.976562 0.699219 L 12.023438 0.699219 C 12.335938 0.699219 12.582031 0.945312 12.582031 1.261719 Z M 3.867188 11.898438 L 5.441406 10.5 L 3.867188 9.101562 Z M 9.539062 6.230469 C 9.257812 5.949219 8.734375 5.601562 7.859375 5.601562 C 6.914062 5.601562 5.933594 5.84375 5.234375 6.089844 L 5.234375 2.101562 L 3.832031 2.101562 L 3.832031 8.15625 L 4.8125 7.699219 C 4.8125 7.699219 6.421875 6.964844 7.824219 6.964844 C 8.523438 6.964844 8.699219 7.351562 8.699219 7.699219 L 8.699219 11.898438 L 10.097656 11.898438 L 10.097656 7.699219 C 10.132812 7.59375 10.132812 6.824219 9.539062 6.230469 Z M 7.683594 4.375 L 9.082031 4.375 C 9.710938 3.640625 10.027344 2.90625 10.132812 2.101562 L 8.734375 2.101562 C 8.59375 2.90625 8.242188 3.640625 7.683594 4.375 Z M 7.683594 4.375 "/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="14px" viewBox="0 0 14 14" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 10.644531 9.734375 C 9.640625 9.734375 8.824219 8.917969 8.824219 7.910156 C 8.824219 6.90625 9.640625 6.089844 10.644531 6.089844 C 11.652344 6.089844 12.46875 6.90625 12.46875 7.910156 C 12.46875 8.917969 11.652344 9.734375 10.644531 9.734375 Z M 10.644531 7 C 10.144531 7 9.734375 7.410156 9.734375 7.910156 C 9.734375 8.414062 10.144531 8.824219 10.644531 8.824219 C 11.148438 8.824219 11.558594 8.414062 11.558594 7.910156 C 11.558594 7.410156 11.148438 7 10.644531 7 Z M 7.457031 4.265625 L 6.542969 4.265625 L 6.542969 2.441406 L 7.457031 2.441406 Z M 6.089844 4.265625 L 5.175781 4.265625 L 5.175781 1.53125 L 6.089844 1.53125 Z M 4.722656 4.265625 L 3.808594 4.265625 L 3.808594 2.441406 L 4.722656 2.441406 Z M 4.722656 4.265625 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 5.632812 12.011719 C 3.617188 12.011719 1.988281 10.382812 1.988281 8.367188 L 1.988281 5.632812 L 9.277344 5.632812 L 9.277344 8.367188 C 9.277344 10.382812 7.648438 12.011719 5.632812 12.011719 Z M 5.632812 12.011719 "/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="14px" viewBox="0 0 14 14" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 12.125 12.125 L 1.875 12.125 L 1.875 1.875 L 12.125 1.875 L 7 7 Z M 12.125 12.125 "/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 385 B

View File

@@ -1,10 +0,0 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_34_7)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.2625 7.00157C12.2625 4.09565 9.90677 1.73994 7.00085 1.73994C4.09494 1.73994 1.73923 4.09565 1.73923 7.00157C1.73923 9.90749 4.09494 12.2632 7.00085 12.2632C9.90677 12.2632 12.2625 9.90749 12.2625 7.00157ZM10.7213 4.82205C10.7213 3.97095 10.0313 3.281 9.18023 3.281C8.32913 3.281 7.63917 3.97095 7.63917 4.82205C7.63917 5.67315 8.32913 6.3631 9.18023 6.3631C10.0313 6.3631 10.7213 5.67315 10.7213 4.82205ZM11.9704 11.3383L12.2849 11.6123C12.4856 11.3819 12.6732 11.1354 12.8424 10.8799L12.4947 10.6496C12.3355 10.8899 12.1591 11.1216 11.9704 11.3383ZM3.09019 12.8218C2.83557 12.6512 2.59021 12.4623 2.36091 12.2602L2.63665 11.9473C2.85224 12.1372 3.08295 12.3149 3.3224 12.4754L3.09019 12.8218ZM13.2533 9.09685L13.6488 9.22944C13.5516 9.51944 13.4341 9.806 13.2995 10.0812L12.9248 9.89792C13.0514 9.63912 13.1619 9.3696 13.2533 9.09685ZM11.3601 11.9516L11.6357 12.2647C11.4062 12.4667 11.1607 12.6555 10.9061 12.8259L10.6741 12.4793C10.9135 12.3191 11.1443 12.1415 11.3601 11.9516ZM9.92464 12.9125L10.1093 13.2865C9.83502 13.4219 9.54901 13.5406 9.25919 13.6391L9.12488 13.2442C9.39754 13.1515 9.66662 13.0399 9.92464 12.9125ZM0.698663 10.0754C0.564769 9.80041 0.447705 9.51376 0.350717 9.22346L0.746321 9.09128C0.837577 9.36442 0.947715 9.63411 1.0737 9.89286L0.698663 10.0754ZM4.7358 13.6379C4.44725 13.539 4.16148 13.4197 3.88645 13.2833L4.07178 12.9096C4.33065 13.038 4.59955 13.1503 4.871 13.2433L4.7358 13.6379ZM7.50907 0.425028L7.54103 0.00914471C7.84635 0.0326099 8.15299 0.0767322 8.45243 0.140276L8.36583 0.548303C8.08435 0.488557 7.79609 0.447081 7.50907 0.425028ZM8.28868 13.469L8.37042 13.878C8.07006 13.9381 7.76308 13.9787 7.45798 13.999L7.4304 13.5828C7.71737 13.5638 8.00614 13.5255 8.28868 13.469ZM6.56475 13.5831L6.5374 13.9993C6.23179 13.9792 5.92469 13.9385 5.62462 13.8783L5.70667 13.4693C5.98876 13.5259 6.27745 13.5642 6.56475 13.5831ZM1.71207 11.6074C1.51131 11.3768 1.32385 11.1303 1.15489 10.8748L1.5028 10.6447C1.66168 10.885 1.83795 11.1167 2.0267 11.3336L1.71207 11.6074ZM1.54706 3.2931L1.20185 3.05901C1.3739 2.80528 1.56421 2.56096 1.76748 2.33281L2.07891 2.61029C1.8878 2.82479 1.70885 3.05452 1.54706 3.2931ZM13.5829 7.4008L13.9993 7.42603C13.9807 7.73163 13.9418 8.03889 13.8834 8.33925L13.474 8.25969C13.5289 7.97721 13.5655 7.68824 13.5829 7.4008ZM2.69596 2.00373L2.42386 1.68762C2.65562 1.48813 2.90314 1.30202 3.15957 1.13448L3.38773 1.48365C3.14661 1.64119 2.91386 1.81619 2.69596 2.00373ZM4.14194 1.05867L3.96141 0.682649C4.23716 0.550267 4.52444 0.434775 4.8153 0.339358L4.9453 0.735689C4.67165 0.825447 4.40135 0.934116 4.14194 1.05867ZM6.64336 0.415732C6.35624 0.431589 6.06708 0.466692 5.78392 0.520066L5.70665 0.110177C6.00769 0.0534275 6.3151 0.0161137 6.62038 -0.00073251L6.64336 0.415732ZM9.33849 0.390492C9.62584 0.492485 9.91028 0.614901 10.1839 0.754324L9.99453 1.12595C9.73698 0.994735 9.46932 0.879534 9.19896 0.783565L9.33849 0.390492ZM0.116692 8.3334C0.0582983 8.03277 0.0192821 7.72556 0.000734408 7.42027L0.417082 7.39499C0.434525 7.68212 0.471213 7.97108 0.526144 8.25385L0.116692 8.3334ZM13.8694 5.59362C13.9308 5.89342 13.9729 6.20022 13.9945 6.50553L13.5785 6.53503C13.5581 6.24787 13.5185 5.95929 13.4607 5.67733L13.8694 5.59362ZM0.421578 6.52929L0.00551996 6.49964C0.0272978 6.19421 0.0697176 5.88734 0.131602 5.58753L0.540095 5.67184C0.48192 5.95369 0.442046 6.24218 0.421578 6.52929ZM13.268 3.85795C13.4053 4.1315 13.5257 4.41681 13.6258 4.70597L13.2317 4.84251C13.1375 4.57059 13.0243 4.30226 12.8952 4.045L13.268 3.85795ZM0.770731 4.83746L0.376902 4.70007C0.477381 4.41205 0.598242 4.12695 0.736138 3.85268L1.10878 4.04006C0.979007 4.29819 0.86526 4.56647 0.770731 4.83746ZM10.7213 1.73979C10.7213 0.888612 11.4113 0.198592 12.2625 0.198592C13.1137 0.198592 13.8037 0.888612 13.8037 1.73979C13.8037 2.59098 13.1137 3.281 12.2625 3.281C11.4113 3.281 10.7213 2.59098 10.7213 1.73979Z" fill="black"/>
</g>
<defs>
<clipPath id="clip0_34_7">
<rect width="14" height="14" fill="white" transform="matrix(-1 0 0 1 14 0)"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="14px" viewBox="0 0 14 14" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 7.054688 1.691406 C 7.054688 1.691406 6.519531 2.148438 5.972656 2.59375 C 5.410156 2.578125 4.304688 2.710938 3.710938 2.945312 C 3.15625 2.570312 2.671875 2.15625 2.671875 2.15625 C 2.671875 2.15625 2.257812 2.917969 2 3.367188 C 1.613281 3.585938 1.226562 3.832031 0.882812 4.160156 C 0.480469 3.988281 0.015625 3.78125 0 3.777344 C 0.53125 4.921875 0.886719 6.070312 1.863281 6.761719 C 3.410156 4.144531 10.601562 4.386719 12.183594 6.746094 C 13.203125 6.175781 13.597656 4.953125 14 3.820312 C 13.957031 3.835938 13.410156 4.03125 13.058594 4.175781 C 12.84375 3.929688 12.347656 3.550781 12.0625 3.367188 C 11.847656 2.949219 11.628906 2.539062 11.402344 2.128906 C 11.402344 2.128906 10.941406 2.496094 10.402344 2.902344 C 9.675781 2.757812 8.800781 2.585938 8.0625 2.628906 C 7.71875 2.320312 7.382812 2.011719 7.054688 1.691406 Z M 0.550781 6.210938 L 1.828125 9.519531 C 4.046875 12.652344 9.707031 12.867188 12.175781 9.582031 C 12.757812 8.171875 13.546875 6.191406 13.546875 6.191406 C 12.914062 7.199219 11.882812 7.890625 11.246094 8.261719 C 10.796875 8.527344 9.757812 8.6875 9.757812 8.6875 L 7.023438 7.171875 L 4.277344 8.65625 C 4.277344 8.65625 3.25 8.480469 2.785156 8.25 C 1.847656 7.714844 1.214844 7.078125 0.550781 6.210938 Z M 0.550781 6.210938 "/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,6 +1 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="14px" viewBox="0 0 14 14" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 4.65625 9.566406 C 4.589844 9.136719 4.410156 8.789062 3.972656 8.621094 C 3.800781 8.554688 3.652344 8.433594 3.484375 8.359375 C 3.292969 8.273438 3.097656 8.191406 2.894531 8.136719 C 2.742188 8.097656 2.597656 8.167969 2.507812 8.300781 C 2.421875 8.425781 2.484375 8.546875 2.554688 8.652344 C 2.636719 8.769531 2.726562 8.882812 2.816406 8.996094 C 2.96875 9.179688 3.128906 9.359375 3.277344 9.546875 C 3.417969 9.726562 3.535156 9.925781 3.515625 10.164062 C 3.46875 10.6875 3.234375 11.117188 2.851562 11.46875 C 2.8125 11.507812 2.738281 11.535156 2.683594 11.53125 C 2.441406 11.503906 2.21875 11.410156 2.042969 11.242188 C 1.835938 11.046875 1.867188 10.820312 2.113281 10.675781 C 2.171875 10.644531 2.230469 10.613281 2.285156 10.570312 C 2.433594 10.457031 2.484375 10.265625 2.402344 10.101562 C 2.367188 10.019531 2.320312 9.933594 2.257812 9.875 C 1.945312 9.589844 1.636719 9.296875 1.304688 9.035156 C 0.492188 8.40625 0.0742188 7.574219 0.0117188 6.5625 C -0.0585938 5.445312 0.199219 4.398438 0.792969 3.441406 C 1.015625 3.078125 1.277344 2.730469 1.675781 2.550781 C 1.949219 2.429688 2.246094 2.359375 2.539062 2.285156 C 3.339844 2.074219 4.148438 1.914062 4.984375 2.054688 C 5.703125 2.175781 6.226562 2.546875 6.46875 3.253906 C 6.625 3.714844 6.664062 4.191406 6.617188 4.679688 C 6.519531 5.640625 5.808594 6.5 4.882812 6.753906 C 4.484375 6.863281 4.261719 6.804688 4.023438 6.46875 C 3.847656 6.230469 3.707031 5.96875 3.550781 5.714844 C 3.527344 5.675781 3.511719 5.632812 3.492188 5.59375 C 3.472656 5.550781 3.453125 5.511719 3.433594 5.472656 C 3.492188 5.890625 3.585938 6.292969 3.816406 6.648438 C 3.9375 6.84375 4.101562 6.988281 4.34375 7.007812 C 5.226562 7.085938 5.972656 6.796875 6.503906 6.085938 C 7.097656 5.289062 7.226562 4.375 7.054688 3.410156 C 7.019531 3.21875 6.964844 3.035156 6.925781 2.84375 C 6.898438 2.722656 6.945312 2.632812 7.066406 2.589844 C 7.121094 2.570312 7.179688 2.554688 7.234375 2.542969 C 7.960938 2.386719 8.691406 2.335938 9.429688 2.410156 C 10.265625 2.496094 11.054688 2.722656 11.765625 3.191406 C 12.871094 3.917969 13.558594 4.957031 13.933594 6.210938 C 13.988281 6.394531 13.996094 6.59375 14 6.785156 C 14.003906 6.914062 13.921875 6.945312 13.824219 6.867188 C 13.714844 6.777344 13.617188 6.679688 13.523438 6.574219 C 13.4375 6.476562 13.371094 6.367188 13.285156 6.261719 C 13.222656 6.183594 13.164062 6.195312 13.132812 6.296875 C 13.113281 6.355469 13.097656 6.414062 13.078125 6.476562 C 12.886719 7.167969 12.582031 7.796875 12.085938 8.328125 C 12.015625 8.402344 11.957031 8.511719 11.949219 8.613281 C 11.925781 8.882812 11.910156 9.164062 11.9375 9.433594 C 11.992188 10.015625 12.074219 10.597656 12.140625 11.179688 C 12.179688 11.507812 12.070312 11.703125 11.761719 11.816406 C 11.546875 11.894531 11.3125 11.953125 11.082031 11.972656 C 10.71875 11.996094 10.347656 11.976562 9.980469 11.976562 C 9.96875 11.566406 10.003906 11.164062 9.621094 10.945312 C 9.695312 10.640625 9.78125 10.351562 9.832031 10.058594 C 9.875 9.8125 9.839844 9.570312 9.667969 9.371094 C 9.503906 9.179688 9.304688 9.128906 9.117188 9.238281 C 8.558594 9.5625 7.976562 9.5625 7.386719 9.351562 C 7.113281 9.253906 6.925781 9.308594 6.773438 9.554688 C 6.613281 9.824219 6.546875 10.121094 6.5625 10.425781 C 6.585938 10.804688 6.652344 11.183594 6.703125 11.5625 C 6.730469 11.777344 6.707031 11.832031 6.496094 11.886719 C 6.027344 12.003906 5.550781 12.015625 5.074219 11.976562 C 5.046875 11.976562 5.023438 11.964844 5.007812 11.960938 C 4.980469 11.5625 5.023438 11.148438 4.550781 10.9375 C 4.761719 10.492188 4.730469 10.03125 4.660156 9.570312 Z M 1.824219 8.003906 C 1.894531 7.9375 1.949219 7.835938 1.96875 7.742188 C 2.019531 7.503906 1.84375 7.1875 1.636719 7.101562 C 1.527344 7.054688 1.433594 7.070312 1.355469 7.15625 C 1.167969 7.371094 0.984375 7.585938 0.796875 7.800781 C 0.765625 7.835938 0.738281 7.882812 0.71875 7.925781 C 0.644531 8.066406 0.6875 8.167969 0.84375 8.207031 C 0.941406 8.230469 1.039062 8.238281 1.136719 8.25 C 1.390625 8.226562 1.636719 8.183594 1.824219 8.003906 Z M 1.847656 5.640625 C 1.847656 5.472656 1.703125 5.332031 1.539062 5.332031 C 1.367188 5.332031 1.21875 5.484375 1.226562 5.652344 C 1.230469 5.824219 1.375 5.957031 1.542969 5.957031 C 1.714844 5.953125 1.847656 5.8125 1.847656 5.644531 Z M 1.847656 5.640625 "/>
</g>
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="512" height="512"><path d="M170.322 349.808c-2.4-15.66-9-28.38-25.020-34.531-6.27-2.4-11.7-6.78-17.88-9.54-7.020-3.15-14.16-6.15-21.57-8.1-5.61-1.5-10.83 1.020-14.16 5.94-3.15 4.62-0.87 8.97 1.77 12.84 2.97 4.35 6.27 8.49 9.6 12.57 5.52 6.78 11.37 13.29 16.74 20.161 5.13 6.57 9.51 13.86 8.76 22.56-1.65 19.080-10.29 34.891-24.21 47.76-1.53 1.38-4.23 2.37-6.21 2.19-8.88-0.96-16.95-4.32-23.46-10.53-7.47-7.11-6.33-15.48 2.61-20.67 2.13-1.23 4.35-2.37 6.3-3.87 5.46-4.11 7.29-11.13 4.32-17.22-1.41-2.94-3-6.12-5.34-8.25-11.43-10.41-22.651-21.151-34.891-30.63-29.671-23.041-44.91-53.52-47.251-90.421-2.64-40.981 6.87-79.231 28.5-114.242 8.19-13.29 17.73-25.951 32.37-32.52 9.96-4.47 20.88-6.99 31.531-9.78 29.311-7.71 58.89-13.5 89.401-8.34 26.28 4.41 45.511 17.94 54.331 43.77 5.79 16.89 7.17 34.35 5.37 52.231-3.54 35.131-29.49 66.541-63.331 75.841-14.67 4.020-22.68 1.77-31.5-10.44-6.33-8.79-11.58-18.36-17.25-27.631-0.84-1.38-1.44-2.97-2.16-4.44-0.69-1.47-1.44-2.88-2.16-4.35 2.13 15.24 5.67 29.911 13.98 42.99 4.5 7.11 10.5 12.36 19.29 13.14 32.34 2.91 59.641-7.71 79.021-33.721 21.69-29.101 26.461-62.581 20.19-97.831-1.23-6.96-3.3-13.77-4.77-20.7-0.99-4.47 0.78-7.77 5.19-9.33 2.040-0.69 4.14-1.26 6.18-1.68 26.461-5.7 53.221-7.59 80.191-4.86 30.601 3.060 59.551 11.46 85.441 28.471 40.531 26.67 65.641 64.621 79.291 110.522 1.98 6.66 2.28 13.95 2.46 20.971 0.12 4.68-2.88 5.91-6.45 2.97-3.93-3.21-7.53-6.87-10.92-10.65-3.15-3.57-5.67-7.65-8.73-11.4-2.37-2.94-4.44-2.49-5.58 1.17-0.72 2.22-1.35 4.41-1.98 6.63-7.080 25.26-18.24 48.3-36.33 67.711-2.52 2.73-4.77 6.78-5.070 10.38-0.78 9.96-1.35 20.13-0.39 30.060 1.98 21.331 5.070 42.57 7.47 63.871 1.35 12.030-2.52 19.11-13.83 23.281-7.95 2.91-16.47 5.040-24.87 5.64-13.38 0.93-26.88 0.27-40.32 0.27-0.36-15 0.93-29.731-13.17-37.771 2.73-11.13 5.88-21.69 7.77-32.49 1.56-8.97 0.24-17.79-6.060-25.14-5.91-6.93-13.32-8.82-20.101-4.86-20.43 11.91-41.671 11.97-63.301 4.17-9.93-3.6-16.86-1.56-22.351 7.5-5.91 9.75-8.4 20.7-7.74 31.771 0.84 13.95 3.27 27.75 5.13 41.64 1.020 7.77 0.15 9.78-7.56 11.76-17.13 4.35-34.56 4.83-52.081 3.42-0.93-0.090-1.86-0.48-2.46-0.63-0.87-14.55 0.66-29.671-16.68-37.411 7.68-16.29 6.63-33.18 3.99-50.070l-0.060-0.15zM66.761 292.718c2.55-2.4 4.59-6.15 5.31-9.6 1.8-8.64-4.68-20.22-12.18-23.43-3.99-1.74-7.47-1.11-10.29 2.070-6.87 7.77-13.65 15.63-20.401 23.521-1.14 1.35-2.16 2.94-2.97 4.53-2.7 5.19-1.11 8.97 4.65 10.38 3.48 0.87 7.080 1.050 10.65 1.56 9.3-0.9 18.3-2.46 25.23-9v-0.030zM67.541 206.347c-0.030-6.18-5.19-11.34-11.28-11.37-6.27-0.030-11.67 5.58-11.46 11.76 0.27 6.21 5.43 11.19 11.61 11.070 6.24-0.090 11.22-5.19 11.16-11.43l-0.030-0.030z"></path></svg>

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="15px" height="14px" viewBox="0 0 15 14" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 14.0625 6.46875 C 14.0625 4.203125 11.125 2.367188 7.5 2.367188 C 3.875 2.367188 0.9375 4.203125 0.9375 6.46875 C 0.9375 8.488281 3.273438 10.160156 6.34375 10.503906 L 6.34375 11.8125 L 8.582031 11.8125 L 8.582031 10.511719 C 9.113281 10.457031 9.636719 10.359375 10.148438 10.21875 L 11.058594 11.8125 L 13.589844 11.8125 L 12.0625 9.410156 C 13.292969 8.667969 14.0625 7.625 14.0625 6.46875 Z M 3.515625 6.773438 C 3.515625 5.226562 5.75 3.96875 8.503906 3.96875 C 11.257812 3.96875 13.292969 4.828125 13.292969 6.773438 C 13.304688 7.757812 12.671875 8.644531 11.699219 9.015625 C 11.65625 8.988281 11.609375 8.964844 11.558594 8.941406 C 11.355469 8.851562 11.144531 8.78125 10.933594 8.71875 C 10.933594 8.71875 12.886719 8.582031 12.886719 6.765625 C 12.886719 4.949219 10.839844 4.914062 10.839844 4.914062 L 6.34375 4.914062 L 6.34375 9.300781 C 4.671875 8.847656 3.515625 7.886719 3.515625 6.773438 Z M 9.957031 7.582031 L 8.601562 7.582031 L 8.601562 6.410156 L 9.957031 6.410156 C 10.125 6.398438 10.292969 6.453125 10.410156 6.5625 C 10.53125 6.675781 10.597656 6.828125 10.585938 6.984375 C 10.589844 7.144531 10.527344 7.296875 10.410156 7.410156 C 10.289062 7.519531 10.128906 7.582031 9.957031 7.582031 Z M 8.582031 9.109375 L 9.183594 9.109375 C 9.300781 9.113281 9.40625 9.15625 9.484375 9.238281 C 9.578125 9.320312 9.65625 9.414062 9.722656 9.511719 C 9.34375 9.554688 8.964844 9.574219 8.582031 9.578125 Z M 8.582031 9.109375 "/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="14px" viewBox="0 0 14 14" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 11.214844 0.015625 C 11.214844 1.125 5.859375 1.976562 2.785156 2.179688 L 2.785156 5.335938 C 4.082031 5.421875 5.789062 5.628906 7.324219 5.917969 C 5.789062 6.207031 4.082031 6.410156 2.785156 6.492188 L 2.785156 9.648438 C 4.082031 9.734375 5.785156 9.9375 7.320312 10.226562 C 5.785156 10.515625 4.082031 10.71875 2.785156 10.804688 L 2.785156 13.988281 L 4.308594 13.765625 C 7.152344 13.339844 10.285156 12.53125 11.214844 11.820312 L 11.214844 8.632812 C 11.214844 8.433594 10.851562 8.21875 10.265625 8 C 10.675781 7.832031 11.003906 7.667969 11.214844 7.507812 L 11.214844 4.324219 C 11.214844 4.125 10.855469 3.90625 10.277344 3.6875 C 10.683594 3.523438 11.003906 3.355469 11.214844 3.195312 Z M 10.269531 8.339844 C 10.6875 8.503906 10.839844 8.617188 10.890625 8.664062 C 10.855469 8.734375 10.726562 8.871094 10.359375 9.050781 C 10.300781 9.078125 10.238281 9.105469 10.183594 9.128906 C 9.550781 9.402344 8.570312 9.667969 7.320312 9.90625 C 6.707031 9.792969 6.046875 9.6875 5.382812 9.597656 C 7.25 9.261719 9.09375 8.796875 10.269531 8.339844 Z M 10.277344 4.027344 C 10.691406 4.195312 10.839844 4.308594 10.890625 4.355469 C 10.863281 4.40625 10.78125 4.5 10.578125 4.625 L 10.574219 4.625 C 10.535156 4.648438 10.488281 4.675781 10.441406 4.699219 C 9.839844 5.011719 8.765625 5.324219 7.335938 5.59375 C 6.71875 5.480469 6.058594 5.375 5.394531 5.285156 C 7.269531 4.953125 9.097656 4.492188 10.277344 4.027344 Z M 10.277344 4.027344 "/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="14px" viewBox="0 0 14 14" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 8.269531 1.53125 C 13.078125 4.824219 11.523438 8.457031 11.523438 8.457031 C 11.523438 8.457031 12.890625 10.015625 12.335938 11.375 C 12.335938 11.375 11.773438 10.421875 10.828125 10.421875 C 9.914062 10.421875 9.378906 11.375 7.546875 11.375 C 3.460938 11.375 1.53125 7.9375 1.53125 7.9375 C 5.210938 10.375 7.722656 8.648438 7.722656 8.648438 C 6.066406 7.679688 2.539062 3.039062 2.539062 3.039062 C 5.609375 5.675781 6.9375 6.371094 6.9375 6.371094 C 6.144531 5.710938 3.921875 2.484375 3.921875 2.484375 C 5.699219 4.296875 9.230469 6.828125 9.230469 6.828125 C 10.234375 4.027344 8.269531 1.53125 8.269531 1.53125 "/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 926 B

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="14px" viewBox="0 0 14 14" version="1.1">
<g id="surface1">
<path style="fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:4;" d="M 21.946429 2.875 C 21.982143 5.348214 21.910714 7.785714 19.776786 10.107143 L 19.696429 10.196429 L 19.8125 10.196429 L 20.6875 10.205357 C 19.267857 13.160714 18.348214 16.098214 16.303571 19.035714 L 16.232143 19.142857 L 16.357143 19.125 L 17.4375 18.919643 C 16.883929 20.598214 15.607143 21.946429 13.955357 22.571429 C 13.5625 17.116071 16.285714 12.303571 18.598214 7.5 L 18.607143 7.491071 L 18.517857 7.428571 C 14.732143 11.660714 13.026786 17.625 12.383929 22.553571 C 11.285714 21.901786 10.5 20.821429 10.241071 19.5625 L 11.133929 19.946429 L 11.232143 19.982143 L 11.214286 19.883929 C 10.526786 16.857143 11.589286 14.678571 12.607143 11.830357 L 13.348214 12.321429 L 13.4375 12.383929 L 13.4375 12.276786 C 13.375 9.964286 14.9375 7.633929 17.008929 5.553571 L 17.294643 6.321429 L 17.339286 6.419643 L 17.392857 6.321429 L 18.026786 5.267857 C 18.973214 3.991071 20.375 3.133929 21.946429 2.875 Z M 21.946429 2.875 " transform="matrix(0.4375,0,0,0.4375,0,0)"/>
<path style="fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(100%,100%,100%);stroke-opacity:1;stroke-miterlimit:4;" d="M 21.946429 2.875 C 20.375 3.133929 18.973214 3.991071 18.017857 5.258929 L 18.017857 5.267857 L 17.392857 6.321429 L 17.339286 6.419643 L 17.294643 6.321429 L 17 5.544643 C 14.928571 7.625 13.366071 9.955357 13.419643 12.267857 L 13.419643 12.375 L 13.339286 12.3125 L 12.598214 11.821429 C 11.571429 14.669643 10.517857 16.848214 11.196429 19.875 L 11.223214 19.973214 L 11.125 19.9375 L 10.241071 19.5625 C 10.241071 19.580357 10.25 19.598214 10.25 19.616071 C 10.517857 20.839286 11.294643 21.901786 12.375 22.544643 C 12.428571 22.160714 12.482143 21.776786 12.544643 21.383929 C 11 17.767857 12.348214 15.107143 12.955357 12.723214 L 13.892857 13.258929 C 13.758929 11.026786 15.080357 8.607143 16.785714 6.508929 L 17.285714 7.375 C 18.553571 4.767857 19.5625 3.723214 21.946429 2.875 Z M 21.946429 2.875 " transform="matrix(0.4375,0,0,0.4375,0,0)"/>
<path style="fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:4;" d="M 22.517857 2 L 22.464286 2.008929 C 20.383929 2.375 18.339286 3.133929 17.446429 4.973214 L 17.071429 4.3125 L 17.035714 4.25 L 16.991071 4.303571 C 15.883929 5.357143 14.892857 6.526786 14.044643 7.803571 C 13.339286 8.723214 12.919643 9.839286 12.839286 11 L 12.303571 10.339286 L 12.25 10.267857 L 12.214286 10.348214 C 11.508929 11.857143 10.9375 13.428571 10.517857 15.044643 C 10.116071 16.25 10.0625 17.535714 10.366071 18.767857 L 9.482143 18.258929 L 9.410714 18.214286 L 9.401786 18.294643 C 9.223214 20.151786 9.982143 21.973214 11.419643 23.142857 L 10.455357 23.383929 L 10.25 23.428571 L 10.455357 23.482143 C 10.973214 23.598214 11.464286 23.794643 11.901786 24.089286 C 12.3125 24.383929 12.508929 24.892857 12.419643 25.383929 L 12.419643 28.098214 L 12.428571 28.116071 L 13.651786 29.857143 L 13.75 30 L 13.75 25.723214 C 13.839286 25.178571 14.053571 24.678571 14.366071 24.232143 C 14.660714 23.910714 15.071429 23.723214 15.5 23.696429 L 15.678571 23.678571 L 15.517857 23.598214 L 14.875 23.303571 C 16.714286 22.035714 18.035714 20.142857 18.571429 17.982143 L 18.589286 17.892857 L 18.508929 17.919643 L 17.714286 18.133929 C 18.607143 17.098214 19.3125 15.910714 19.803571 14.633929 C 20.508929 13 21.178571 11.169643 21.732143 9.696429 L 21.758929 9.625 L 21.678571 9.625 L 21.0625 9.669643 C 21.857143 8.651786 22.339286 7.428571 22.446429 6.142857 C 22.633929 4.785714 22.660714 3.419643 22.526786 2.053571 Z M 21.946429 2.875 C 21.982143 5.348214 21.910714 7.785714 19.776786 10.107143 L 19.696429 10.196429 L 19.8125 10.196429 L 20.6875 10.205357 C 19.267857 13.160714 18.348214 16.098214 16.303571 19.035714 L 16.232143 19.142857 L 16.357143 19.125 L 17.4375 18.919643 C 16.883929 20.598214 15.607143 21.946429 13.955357 22.571429 C 13.5625 17.116071 16.285714 12.303571 18.598214 7.5 L 18.607143 7.491071 L 18.517857 7.428571 C 14.732143 11.660714 13.026786 17.625 12.383929 22.553571 C 11.285714 21.901786 10.508929 20.821429 10.241071 19.5625 L 11.142857 19.946429 L 11.232143 19.982143 L 11.214286 19.883929 C 10.526786 16.857143 11.589286 14.678571 12.616071 11.830357 L 13.348214 12.321429 L 13.4375 12.383929 L 13.4375 12.276786 C 13.375 9.964286 14.9375 7.633929 17.008929 5.553571 L 17.303571 6.321429 L 17.339286 6.419643 L 17.392857 6.321429 L 18.026786 5.267857 C 18.973214 3.991071 20.375 3.133929 21.946429 2.875 Z M 21.946429 2.875 " transform="matrix(0.4375,0,0,0.4375,0,0)"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.9 KiB

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="14px" viewBox="0 0 14 14" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 5.472656 3.507812 L 8.417969 5.296875 L 8.417969 8.875 L 5.472656 7.085938 Z M 5.472656 3.507812 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 8.761719 5.296875 L 8.761719 8.875 L 11.882812 7.085938 L 11.882812 3.507812 Z M 8.761719 5.296875 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 2.007812 1.601562 L 2.007812 5.066406 L 5.125 6.796875 L 5.125 3.332031 Z M 2.007812 1.601562 "/>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 5.472656 10.953125 L 8.417969 12.6875 L 8.417969 9.222656 L 5.472656 7.492188 Z M 5.472656 10.953125 "/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 961 B

View File

@@ -1 +0,0 @@
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M3.24182 2.32181C3.3919 2.23132 3.5784 2.22601 3.73338 2.30781L12.7334 7.05781C12.8974 7.14436 13 7.31457 13 7.5C13 7.68543 12.8974 7.85564 12.7334 7.94219L3.73338 12.6922C3.5784 12.774 3.3919 12.7687 3.24182 12.6782C3.09175 12.5877 3 12.4252 3 12.25V2.75C3 2.57476 3.09175 2.4123 3.24182 2.32181ZM4 3.57925V11.4207L11.4288 7.5L4 3.57925Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>

Before

Width:  |  Height:  |  Size: 518 B

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20 17V15.8C20 14.1198 20 13.2798 19.673 12.638C19.3854 12.0735 18.9265 11.6146 18.362 11.327C17.7202 11 16.8802 11 15.2 11H4M4 11L8 7M4 11L8 15" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 468 B

View File

@@ -55,14 +55,38 @@
"bindings": {
"alt-cmd-/": "search::ToggleRegex",
"ctrl-0": "project_panel::ToggleFocus",
"cmd-1": ["pane::ActivateItem", 0],
"cmd-2": ["pane::ActivateItem", 1],
"cmd-3": ["pane::ActivateItem", 2],
"cmd-4": ["pane::ActivateItem", 3],
"cmd-5": ["pane::ActivateItem", 4],
"cmd-6": ["pane::ActivateItem", 5],
"cmd-7": ["pane::ActivateItem", 6],
"cmd-8": ["pane::ActivateItem", 7],
"cmd-1": [
"pane::ActivateItem",
0
],
"cmd-2": [
"pane::ActivateItem",
1
],
"cmd-3": [
"pane::ActivateItem",
2
],
"cmd-4": [
"pane::ActivateItem",
3
],
"cmd-5": [
"pane::ActivateItem",
4
],
"cmd-6": [
"pane::ActivateItem",
5
],
"cmd-7": [
"pane::ActivateItem",
6
],
"cmd-8": [
"pane::ActivateItem",
7
],
"cmd-9": "pane::ActivateLastItem"
}
},

View File

@@ -1,584 +0,0 @@
[
{
"bindings": {
"up": "menu::SelectPrev",
"pageup": "menu::SelectFirst",
"shift-pageup": "menu::SelectFirst",
"ctrl-p": "menu::SelectPrev",
"down": "menu::SelectNext",
"pagedown": "menu::SelectLast",
"shift-pagedown": "menu::SelectFirst",
"ctrl-n": "menu::SelectNext",
"ctrl-up": "menu::SelectFirst",
"ctrl-down": "menu::SelectLast",
"enter": "menu::Confirm",
"shift-f10": "menu::ShowContextMenu",
"ctrl-enter": "menu::SecondaryConfirm",
"escape": "menu::Cancel",
"ctrl-c": "menu::Cancel",
"shift-enter": "menu::UseSelectedQuery",
"ctrl-shift-w": "workspace::CloseWindow",
"shift-escape": "workspace::ToggleZoom",
"ctrl-o": "workspace::Open",
"ctrl-=": "zed::IncreaseBufferFontSize",
"ctrl-+": "zed::IncreaseBufferFontSize",
"ctrl--": "zed::DecreaseBufferFontSize",
"ctrl-0": "zed::ResetBufferFontSize",
"ctrl-,": "zed::OpenSettings",
"ctrl-q": "zed::Quit",
"ctrl-h": "zed::Hide",
"alt-ctrl-h": "zed::HideOthers",
"ctrl-m": "zed::Minimize",
"f11": "zed::ToggleFullScreen"
}
},
{
"context": "Editor",
"bindings": {
"escape": "editor::Cancel",
"backspace": "editor::Backspace",
"shift-backspace": "editor::Backspace",
"ctrl-h": "editor::Backspace",
"delete": "editor::Delete",
"ctrl-d": "editor::Delete",
"tab": "editor::Tab",
"shift-tab": "editor::TabPrev",
"ctrl-k": "editor::CutToEndOfLine",
"ctrl-t": "editor::Transpose",
"ctrl-backspace": "editor::DeleteToBeginningOfLine",
"ctrl-delete": "editor::DeleteToEndOfLine",
"alt-backspace": "editor::DeleteToPreviousWordStart",
"alt-delete": "editor::DeleteToNextWordEnd",
"alt-h": "editor::DeleteToPreviousWordStart",
"alt-d": "editor::DeleteToNextWordEnd",
"ctrl-x": "editor::Cut",
"ctrl-c": "editor::Copy",
"ctrl-v": "editor::Paste",
"ctrl-z": "editor::Undo",
"ctrl-shift-z": "editor::Redo",
"ctrl-y": "editor::Redo",
"up": "editor::MoveUp",
"ctrl-up": "editor::MoveToStartOfParagraph",
"pageup": "editor::PageUp",
"shift-pageup": "editor::MovePageUp",
"home": "editor::MoveToBeginningOfLine",
"down": "editor::MoveDown",
"ctrl-down": "editor::MoveToEndOfParagraph",
"pagedown": "editor::PageDown",
"shift-pagedown": "editor::MovePageDown",
"end": "editor::MoveToEndOfLine",
"left": "editor::MoveLeft",
"right": "editor::MoveRight",
"ctrl-p": "editor::MoveUp",
"ctrl-n": "editor::MoveDown",
"ctrl-b": "editor::MoveLeft",
"ctrl-f": "editor::MoveRight",
"ctrl-shift-l": "editor::NextScreen", // todo(linux): What is this
"alt-left": "editor::MoveToPreviousWordStart",
"alt-b": "editor::MoveToPreviousWordStart",
"alt-right": "editor::MoveToNextWordEnd",
"alt-f": "editor::MoveToNextWordEnd",
"ctrl-e": "editor::MoveToEndOfLine",
"ctrl-home": "editor::MoveToBeginning",
"ctrl-=end": "editor::MoveToEnd",
"shift-up": "editor::SelectUp",
"ctrl-shift-p": "editor::SelectUp",
"shift-down": "editor::SelectDown",
"ctrl-shift-n": "editor::SelectDown",
"shift-left": "editor::SelectLeft",
"ctrl-shift-b": "editor::SelectLeft",
"shift-right": "editor::SelectRight",
"ctrl-shift-f": "editor::SelectRight",
"alt-shift-left": "editor::SelectToPreviousWordStart",
"alt-shift-b": "editor::SelectToPreviousWordStart",
"alt-shift-right": "editor::SelectToNextWordEnd",
"alt-shift-f": "editor::SelectToNextWordEnd",
"ctrl-shift-up": "editor::SelectToStartOfParagraph",
"ctrl-shift-down": "editor::SelectToEndOfParagraph",
"ctrl-shift-home": "editor::SelectToBeginning",
"ctrl-shift-end": "editor::SelectToEnd",
"ctrl-a": "editor::SelectAll",
"ctrl-l": "editor::SelectLine",
"ctrl-shift-i": "editor::Format",
"shift-home": [
"editor::SelectToBeginningOfLine",
{
"stop_at_soft_wraps": true
}
],
"shift-end": [
"editor::SelectToEndOfLine",
{
"stop_at_soft_wraps": true
}
],
"ctrl-shift-e": [
"editor::SelectToEndOfLine",
{
"stop_at_soft_wraps": true
}
],
"ctrl-;": "editor::ToggleLineNumbers",
"ctrl-alt-z": "editor::RevertSelectedHunks"
}
},
{
"context": "Editor && mode == full",
"bindings": {
"enter": "editor::Newline",
"shift-enter": "editor::Newline",
"ctrl-shift-enter": "editor::NewlineAbove",
"ctrl-enter": "editor::NewlineBelow",
"alt-z": "editor::ToggleSoftWrap",
"ctrl-f": [
"buffer_search::Deploy",
{
"focus": true
}
],
"ctrl->": "assistant::QuoteSelection"
}
},
{
"context": "Editor && mode == full && copilot_suggestion",
"bindings": {
"alt-]": "copilot::NextSuggestion",
"alt-[": "copilot::PreviousSuggestion",
"alt-right": "editor::AcceptPartialCopilotSuggestion"
}
},
{
"context": "Editor && !copilot_suggestion",
"bindings": {
"alt-\\": "copilot::Suggest"
}
},
{
"context": "Editor && mode == auto_height",
"bindings": {
"ctrl-enter": "editor::Newline",
"shift-enter": "editor::Newline",
"ctrl-shift-enter": "editor::NewlineBelow"
}
},
{
"context": "AssistantPanel",
"bindings": {
"f3": "search::SelectNextMatch",
"shift-f3": "search::SelectPrevMatch"
}
},
{
"context": "ConversationEditor > Editor",
"bindings": {
"ctrl-enter": "assistant::Assist",
"ctrl-s": "workspace::Save",
"ctrl->": "assistant::QuoteSelection",
"shift-enter": "assistant::Split",
"ctrl-r": "assistant::CycleMessageRole"
}
},
{
"context": "BufferSearchBar",
"bindings": {
"escape": "buffer_search::Dismiss",
"tab": "buffer_search::FocusEditor",
"enter": "search::SelectNextMatch",
"shift-enter": "search::SelectPrevMatch",
"alt-enter": "search::SelectAllMatches",
"alt-tab": "search::CycleMode"
}
},
{
"context": "BufferSearchBar && in_replace",
"bindings": {
"enter": "search::ReplaceNext",
"ctrl-enter": "search::ReplaceAll"
}
},
{
"context": "BufferSearchBar && !in_replace > Editor",
"bindings": {
"up": "search::PreviousHistoryQuery",
"down": "search::NextHistoryQuery"
}
},
{
"context": "ProjectSearchBar",
"bindings": {
"escape": "project_search::ToggleFocus",
"alt-tab": "search::CycleMode",
"ctrl-shift-h": "search::ToggleReplace",
"ctrl-alt-g": "search::ActivateRegexMode",
"ctrl-alt-s": "search::ActivateSemanticMode",
"ctrl-alt-x": "search::ActivateTextMode"
}
},
{
"context": "ProjectSearchBar > Editor",
"bindings": {
"up": "search::PreviousHistoryQuery",
"down": "search::NextHistoryQuery"
}
},
{
"context": "ProjectSearchBar && in_replace",
"bindings": {
"enter": "search::ReplaceNext",
"ctrl-enter": "search::ReplaceAll"
}
},
{
"context": "ProjectSearchView",
"bindings": {
"escape": "project_search::ToggleFocus",
"alt-tab": "search::CycleMode",
"ctrl-shift-h": "search::ToggleReplace",
"ctrl-alt-g": "search::ActivateRegexMode",
"ctrl-alt-s": "search::ActivateSemanticMode",
"ctrl-alt-x": "search::ActivateTextMode"
}
},
{
"context": "Pane",
"bindings": {
"ctrl-{": "pane::ActivatePrevItem",
"ctrl-}": "pane::ActivateNextItem",
"ctrl-alt-left": "pane::ActivatePrevItem",
"ctrl-alt-right": "pane::ActivateNextItem",
"ctrl-w": "pane::CloseActiveItem",
"ctrl-alt-t": "pane::CloseInactiveItems",
"ctrl-alt-shift-w": "workspace::CloseInactiveTabsAndPanes",
"ctrl-k u": "pane::CloseCleanItems",
"ctrl-k ctrl-w": "pane::CloseAllItems",
"ctrl-f": "project_search::ToggleFocus",
"f3": "search::SelectNextMatch",
"shift-f3": "search::SelectPrevMatch",
"ctrl-shift-h": "search::ToggleReplace",
"alt-enter": "search::SelectAllMatches",
"ctrl-alt-c": "search::ToggleCaseSensitive",
"ctrl-alt-w": "search::ToggleWholeWord",
"alt-tab": "search::CycleMode",
"ctrl-alt-f": "project_search::ToggleFilters",
"ctrl-alt-g": "search::ActivateRegexMode",
"ctrl-alt-s": "search::ActivateSemanticMode",
"ctrl-alt-x": "search::ActivateTextMode"
}
},
// Bindings from VS Code
{
"context": "Editor",
"bindings": {
"ctrl-[": "editor::Outdent",
"ctrl-]": "editor::Indent",
"ctrl-alt-up": "editor::AddSelectionAbove",
"ctrl-alt-down": "editor::AddSelectionBelow",
"ctrl-d": [
"editor::SelectNext",
{
"replace_newest": false
}
],
"ctrl-shift-l": "editor::SelectAllMatches",
"ctrl-shift-d": [
"editor::SelectPrevious",
{
"replace_newest": false
}
],
"ctrl-k ctrl-d": [
"editor::SelectNext",
{
"replace_newest": true
}
],
"ctrl-k ctrl-shift-d": [
"editor::SelectPrevious",
{
"replace_newest": true
}
],
"ctrl-k ctrl-i": "editor::Hover",
"ctrl-/": [
"editor::ToggleComments",
{
"advance_downwards": false
}
],
"alt-up": "editor::SelectLargerSyntaxNode",
"alt-down": "editor::SelectSmallerSyntaxNode",
"ctrl-u": "editor::UndoSelection",
"ctrl-shift-u": "editor::RedoSelection",
"f8": "editor::GoToDiagnostic",
"shift-f8": "editor::GoToPrevDiagnostic",
"f2": "editor::Rename",
"f12": "editor::GoToDefinition",
"alt-f12": "editor::GoToDefinitionSplit",
"ctrl-f12": "editor::GoToTypeDefinition",
"ctrl-alt-f12": "editor::GoToTypeDefinitionSplit",
"alt-shift-f12": "editor::FindAllReferences",
"ctrl-m": "editor::MoveToEnclosingBracket",
"ctrl-alt-[": "editor::Fold",
"ctrl-alt-]": "editor::UnfoldLines",
"ctrl-space": "editor::ShowCompletions",
"ctrl-.": "editor::ToggleCodeActions",
"ctrl-alt-r": "editor::RevealInFinder",
"ctrl-alt-c": "editor::DisplayCursorNames"
}
},
{
"context": "Editor && mode == full",
"bindings": {
"ctrl-shift-o": "outline::Toggle",
"ctrl-g": "go_to_line::Toggle"
}
},
{
"context": "Pane",
"bindings": {
"ctrl-1": ["pane::ActivateItem", 0],
"ctrl-2": ["pane::ActivateItem", 1],
"ctrl-3": ["pane::ActivateItem", 2],
"ctrl-4": ["pane::ActivateItem", 3],
"ctrl-5": ["pane::ActivateItem", 4],
"ctrl-6": ["pane::ActivateItem", 5],
"ctrl-7": ["pane::ActivateItem", 6],
"ctrl-8": ["pane::ActivateItem", 7],
"ctrl-9": ["pane::ActivateItem", 8],
"ctrl-0": "pane::ActivateLastItem",
"ctrl--": "pane::GoBack",
"ctrl-_": "pane::GoForward",
"ctrl-shift-t": "pane::ReopenClosedItem",
"ctrl-shift-f": "project_search::ToggleFocus"
}
},
{
"context": "Workspace",
"bindings": {
// Change the default action on `menu::Confirm` by setting the parameter
// "alt-cmd-o": [
// "projects::OpenRecent",
// {
// "create_new_window": true
// }
// ]
"ctrl-alt-o": "projects::OpenRecent",
"ctrl-alt-b": "branches::OpenRecent",
"ctrl-~": "workspace::NewTerminal",
"ctrl-s": "workspace::Save",
"ctrl-k s": "workspace::SaveWithoutFormat",
"ctrl-shift-s": "workspace::SaveAs",
"ctrl-n": "workspace::NewFile",
"ctrl-shift-n": "workspace::NewWindow",
"ctrl-`": "terminal_panel::ToggleFocus",
"ctrl-1": ["workspace::ActivatePane", 0],
"ctrl-2": ["workspace::ActivatePane", 1],
"ctrl-3": ["workspace::ActivatePane", 2],
"ctrl-4": ["workspace::ActivatePane", 3],
"ctrl-5": ["workspace::ActivatePane", 4],
"ctrl-6": ["workspace::ActivatePane", 5],
"ctrl-7": ["workspace::ActivatePane", 6],
"ctrl-8": ["workspace::ActivatePane", 7],
"ctrl-9": ["workspace::ActivatePane", 8],
"ctrl-b": "workspace::ToggleLeftDock",
"ctrl-r": "workspace::ToggleRightDock",
"ctrl-j": "workspace::ToggleBottomDock",
"ctrl-alt-y": "workspace::CloseAllDocks",
"ctrl-shift-f": "pane::DeploySearch",
"ctrl-k ctrl-t": "theme_selector::Toggle",
"ctrl-k ctrl-s": "zed::OpenKeymap",
"ctrl-t": "project_symbols::Toggle",
"ctrl-p": "file_finder::Toggle",
"ctrl-shift-p": "command_palette::Toggle",
"ctrl-shift-m": "diagnostics::Deploy",
"ctrl-shift-e": "project_panel::ToggleFocus",
"ctrl-?": "assistant::ToggleFocus",
"ctrl-alt-s": "workspace::SaveAll",
"ctrl-k m": "language_selector::Toggle",
"escape": "workspace::Unfollow",
"ctrl-k ctrl-left": ["workspace::ActivatePaneInDirection", "Left"],
"ctrl-k ctrl-right": ["workspace::ActivatePaneInDirection", "Right"],
"ctrl-k ctrl-up": ["workspace::ActivatePaneInDirection", "Up"],
"ctrl-k ctrl-down": ["workspace::ActivatePaneInDirection", "Down"],
"ctrl-k shift-left": ["workspace::SwapPaneInDirection", "Left"],
"ctrl-k shift-right": ["workspace::SwapPaneInDirection", "Right"],
"ctrl-k shift-up": ["workspace::SwapPaneInDirection", "Up"],
"ctrl-k shift-down": ["workspace::SwapPaneInDirection", "Down"],
"alt-t": "task::Rerun",
"alt-shift-t": "task::Spawn"
}
},
// Bindings from Sublime Text
// todo(linux) make sure these match linux bindings or remove above comment?
{
"context": "Editor",
"bindings": {
"ctrl-shift-k": "editor::DeleteLine",
"ctrl-shift-d": "editor::DuplicateLine",
"ctrl-j": "editor::JoinLines",
"ctrl-alt-up": "editor::MoveLineUp",
"ctrl-alt-down": "editor::MoveLineDown",
"ctrl-alt-backspace": "editor::DeleteToPreviousSubwordStart",
"ctrl-alt-h": "editor::DeleteToPreviousSubwordStart",
"ctrl-alt-delete": "editor::DeleteToNextSubwordEnd",
"ctrl-alt-d": "editor::DeleteToNextSubwordEnd",
"ctrl-alt-left": "editor::MoveToPreviousSubwordStart",
"ctrl-alt-b": "editor::MoveToPreviousSubwordStart",
"ctrl-alt-right": "editor::MoveToNextSubwordEnd",
"ctrl-alt-f": "editor::MoveToNextSubwordEnd",
"ctrl-alt-shift-left": "editor::SelectToPreviousSubwordStart",
"ctrl-alt-shift-b": "editor::SelectToPreviousSubwordStart",
"ctrl-alt-shift-right": "editor::SelectToNextSubwordEnd",
"ctrl-alt-shift-f": "editor::SelectToNextSubwordEnd"
}
},
// Bindings from Atom
// todo(linux) make sure these match linux bindings or remove above comment?
{
"context": "Pane",
"bindings": {
"ctrl-k up": "pane::SplitUp",
"ctrl-k down": "pane::SplitDown",
"ctrl-k left": "pane::SplitLeft",
"ctrl-k right": "pane::SplitRight"
}
},
// Bindings that should be unified with bindings for more general actions
{
"context": "Editor && renaming",
"bindings": {
"enter": "editor::ConfirmRename"
}
},
{
"context": "Editor && showing_completions",
"bindings": {
"enter": "editor::ConfirmCompletion",
"tab": "editor::ConfirmCompletion"
}
},
{
"context": "Editor && showing_code_actions",
"bindings": {
"enter": "editor::ConfirmCodeAction"
}
},
{
"context": "Editor && (showing_code_actions || showing_completions)",
"bindings": {
"up": "editor::ContextMenuPrev",
"ctrl-p": "editor::ContextMenuPrev",
"down": "editor::ContextMenuNext",
"ctrl-n": "editor::ContextMenuNext",
"pageup": "editor::ContextMenuFirst",
"pagedown": "editor::ContextMenuLast"
}
},
// Custom bindings
{
"bindings": {
"ctrl-alt-shift-f": "workspace::FollowNextCollaborator",
// TODO: Move this to a dock open action
"ctrl-alt-c": "collab_panel::ToggleFocus",
"ctrl-alt-i": "zed::DebugElements",
"ctrl-:": "editor::ToggleInlayHints"
}
},
{
"context": "Editor && mode == full",
"bindings": {
"alt-enter": "editor::OpenExcerpts",
"ctrl-k enter": "editor::OpenExcerptsSplit",
"ctrl-f8": "editor::GoToHunk",
"ctrl-shift-f8": "editor::GoToPrevHunk",
"ctrl-enter": "assistant::InlineAssist"
}
},
{
"context": "ProjectSearchBar && !in_replace",
"bindings": {
"ctrl-enter": "project_search::SearchInNew"
}
},
{
"context": "ProjectPanel",
"bindings": {
"left": "project_panel::CollapseSelectedEntry",
"right": "project_panel::ExpandSelectedEntry",
"ctrl-n": "project_panel::NewFile",
"ctrl-alt-n": "project_panel::NewDirectory",
"ctrl-x": "project_panel::Cut",
"ctrl-c": "project_panel::Copy",
"ctrl-v": "project_panel::Paste",
"ctrl-alt-c": "project_panel::CopyPath",
"ctrl-alt-shift-c": "project_panel::CopyRelativePath",
"f2": "project_panel::Rename",
"enter": "project_panel::Rename",
"backspace": "project_panel::Delete",
"ctrl-alt-r": "project_panel::RevealInFinder",
"alt-shift-f": "project_panel::NewSearchInDirectory"
}
},
{
"context": "ProjectPanel && not_editing",
"bindings": {
"space": "project_panel::Open"
}
},
{
"context": "CollabPanel && not_editing",
"bindings": {
"ctrl-backspace": "collab_panel::Remove",
"space": "menu::Confirm"
}
},
{
"context": "(CollabPanel && editing) > Editor",
"bindings": {
"space": "collab_panel::InsertSpace"
}
},
{
"context": "ChannelModal",
"bindings": {
"tab": "channel_modal::ToggleMode"
}
},
{
"context": "ChannelModal > Picker > Editor",
"bindings": {
"tab": "channel_modal::ToggleMode"
}
},
{
"context": "ChatPanel > MessageEditor",
"bindings": {
"escape": "chat_panel::CloseReplyPreview"
}
},
{
"context": "Terminal",
"bindings": {
"ctrl-alt-space": "terminal::ShowCharacterPalette",
"ctrl-shift-c": "terminal::Copy",
"ctrl-shift-v": "terminal::Paste",
"ctrl-k": "terminal::Clear",
// Some nice conveniences
"ctrl-backspace": ["terminal::SendText", "\u0015"],
"ctrl-right": ["terminal::SendText", "\u0005"],
"ctrl-left": ["terminal::SendText", "\u0001"],
// Terminal.app compatibility
"alt-left": ["terminal::SendText", "\u001bb"],
"alt-right": ["terminal::SendText", "\u001bf"],
// There are conflicting bindings for these keys in the global context.
// these bindings override them, remove at your own risk:
"up": ["terminal::SendKeystroke", "up"],
"pageup": ["terminal::SendKeystroke", "pageup"],
"down": ["terminal::SendKeystroke", "down"],
"pagedown": ["terminal::SendKeystroke", "pagedown"],
"escape": ["terminal::SendKeystroke", "escape"],
"enter": ["terminal::SendKeystroke", "enter"],
"ctrl-c": ["terminal::SendKeystroke", "ctrl-c"]
}
}
]

View File

@@ -17,7 +17,6 @@
"cmd-enter": "menu::SecondaryConfirm",
"escape": "menu::Cancel",
"ctrl-c": "menu::Cancel",
"shift-enter": "menu::UseSelectedQuery",
"cmd-shift-w": "workspace::CloseWindow",
"shift-escape": "workspace::ToggleZoom",
"cmd-o": "workspace::Open",
@@ -49,7 +48,6 @@
"cmd-backspace": "editor::DeleteToBeginningOfLine",
"cmd-delete": "editor::DeleteToEndOfLine",
"alt-backspace": "editor::DeleteToPreviousWordStart",
"ctrl-w": "editor::DeleteToPreviousWordStart",
"alt-delete": "editor::DeleteToNextWordEnd",
"alt-h": "editor::DeleteToPreviousWordStart",
"alt-d": "editor::DeleteToNextWordEnd",
@@ -152,9 +150,7 @@
"center_cursor": true
}
],
"ctrl-cmd-space": "editor::ShowCharacterPalette",
"cmd-;": "editor::ToggleLineNumbers",
"cmd-alt-z": "editor::RevertSelectedHunks"
"ctrl-cmd-space": "editor::ShowCharacterPalette"
}
},
{
@@ -177,21 +173,10 @@
"focus": false
}
],
"cmd->": "assistant::QuoteSelection"
}
},
{
"context": "Editor && mode == full && copilot_suggestion",
"bindings": {
"alt-\\": "copilot::Suggest",
"alt-]": "copilot::NextSuggestion",
"alt-[": "copilot::PreviousSuggestion",
"alt-right": "editor::AcceptPartialCopilotSuggestion"
}
},
{
"context": "Editor && !copilot_suggestion",
"bindings": {
"alt-\\": "copilot::Suggest"
"cmd->": "assistant::QuoteSelection"
}
},
{
@@ -316,18 +301,6 @@
"cmd-ctrl-p": "editor::AddSelectionAbove",
"cmd-alt-down": "editor::AddSelectionBelow",
"cmd-ctrl-n": "editor::AddSelectionBelow",
"cmd-shift-k": "editor::DeleteLine",
"alt-up": "editor::MoveLineUp",
"alt-down": "editor::MoveLineDown",
"alt-shift-up": [
"editor::DuplicateLine",
{
"move_upwards": true
}
],
"alt-shift-down": "editor::DuplicateLine",
"ctrl-shift-right": "editor::SelectLargerSyntaxNode",
"ctrl-shift-left": "editor::SelectSmallerSyntaxNode",
"cmd-d": [
"editor::SelectNext",
{
@@ -360,6 +333,8 @@
"advance_downwards": false
}
],
"alt-up": "editor::SelectLargerSyntaxNode",
"alt-down": "editor::SelectSmallerSyntaxNode",
"cmd-u": "editor::UndoSelection",
"cmd-shift-u": "editor::RedoSelection",
"f8": "editor::GoToDiagnostic",
@@ -408,18 +383,10 @@
{
"context": "Workspace",
"bindings": {
// Change the default action on `menu::Confirm` by setting the parameter
// "alt-cmd-o": [
// "projects::OpenRecent",
// {
// "create_new_window": true
// }
// ]
"alt-cmd-o": "projects::OpenRecent",
"alt-cmd-b": "branches::OpenRecent",
"ctrl-~": "workspace::NewTerminal",
"cmd-s": "workspace::Save",
"cmd-k s": "workspace::SaveWithoutFormat",
"cmd-shift-s": "workspace::SaveAs",
"cmd-n": "workspace::NewFile",
"cmd-shift-n": "workspace::NewWindow",
@@ -438,8 +405,8 @@
"cmd-j": "workspace::ToggleBottomDock",
"alt-cmd-y": "workspace::CloseAllDocks",
"cmd-shift-f": "pane::DeploySearch",
"cmd-k cmd-s": "zed::OpenKeymap",
"cmd-k cmd-t": "theme_selector::Toggle",
"cmd-k cmd-s": "zed::OpenKeymap",
"cmd-t": "project_symbols::Toggle",
"cmd-p": "file_finder::Toggle",
"cmd-shift-p": "command_palette::Toggle",
@@ -456,16 +423,18 @@
"cmd-k shift-left": ["workspace::SwapPaneInDirection", "Left"],
"cmd-k shift-right": ["workspace::SwapPaneInDirection", "Right"],
"cmd-k shift-up": ["workspace::SwapPaneInDirection", "Up"],
"cmd-k shift-down": ["workspace::SwapPaneInDirection", "Down"],
"alt-t": "task::Rerun",
"alt-shift-t": "task::Spawn"
"cmd-k shift-down": ["workspace::SwapPaneInDirection", "Down"]
}
},
// Bindings from Sublime Text
{
"context": "Editor",
"bindings": {
"ctrl-shift-k": "editor::DeleteLine",
"cmd-shift-d": "editor::DuplicateLine",
"ctrl-j": "editor::JoinLines",
"ctrl-cmd-up": "editor::MoveLineUp",
"ctrl-cmd-down": "editor::MoveLineDown",
"ctrl-alt-backspace": "editor::DeleteToPreviousSubwordStart",
"ctrl-alt-h": "editor::DeleteToPreviousSubwordStart",
"ctrl-alt-delete": "editor::DeleteToNextSubwordEnd",
@@ -535,7 +504,6 @@
"context": "Editor && mode == full",
"bindings": {
"alt-enter": "editor::OpenExcerpts",
"cmd-k enter": "editor::OpenExcerptsSplit",
"cmd-f8": "editor::GoToHunk",
"cmd-shift-f8": "editor::GoToPrevHunk",
"ctrl-enter": "assistant::InlineAssist"
@@ -561,8 +529,7 @@
"alt-cmd-shift-c": "project_panel::CopyRelativePath",
"f2": "project_panel::Rename",
"enter": "project_panel::Rename",
"delete": "project_panel::Delete",
"cmd-backspace": "project_panel::Delete",
"backspace": "project_panel::Delete",
"alt-cmd-r": "project_panel::RevealInFinder",
"alt-shift-f": "project_panel::NewSearchInDirectory"
}

View File

@@ -39,8 +39,6 @@
"advance_downwards": true
}
],
"alt-up": "editor::SelectLargerSyntaxNode",
"alt-down": "editor::SelectSmallerSyntaxNode",
"shift-alt-up": "editor::MoveLineUp",
"shift-alt-down": "editor::MoveLineDown",
"cmd-alt-l": "editor::Format",

View File

@@ -1,23 +0,0 @@
[
// Standard macOS bindings
{
"bindings": {
"up": "menu::SelectPrev",
"pageup": "menu::SelectFirst",
"shift-pageup": "menu::SelectFirst",
"ctrl-p": "menu::SelectPrev",
"down": "menu::SelectNext",
"pagedown": "menu::SelectLast",
"shift-pagedown": "menu::SelectFirst",
"ctrl-n": "menu::SelectNext",
"cmd-up": "menu::SelectFirst",
"cmd-down": "menu::SelectLast",
"enter": "menu::Confirm",
"ctrl-enter": "menu::ShowContextMenu",
"cmd-enter": "menu::SecondaryConfirm",
"escape": "menu::Cancel",
"ctrl-c": "menu::Cancel",
"cmd-q": "storybook::Quit"
}
}
]

View File

@@ -37,42 +37,30 @@
"_": "vim::StartOfLineDownward",
"g _": "vim::EndOfLineDownward",
"shift-g": "vim::EndOfDocument",
"w": "vim::NextWordStart",
"{": "vim::StartOfParagraph",
"}": "vim::EndOfParagraph",
"|": "vim::GoToColumn",
// Word motions
"w": "vim::NextWordStart",
"e": "vim::NextWordEnd",
"b": "vim::PreviousWordStart",
"g e": "vim::PreviousWordEnd",
// Subword motions
// "w": "vim::NextSubwordStart",
// "b": "vim::PreviousSubwordStart",
// "e": "vim::NextSubwordEnd",
// "g e": "vim::PreviousSubwordEnd",
"shift-w": [
"vim::NextWordStart",
{
"ignorePunctuation": true
}
],
"e": "vim::NextWordEnd",
"shift-e": [
"vim::NextWordEnd",
{
"ignorePunctuation": true
}
],
"b": "vim::PreviousWordStart",
"shift-b": [
"vim::PreviousWordStart",
{
"ignorePunctuation": true
}
],
"g shift-e": ["vim::PreviousWordEnd", { "ignorePunctuation": true }],
"n": "search::SelectNextMatch",
"shift-n": "search::SelectPrevMatch",
"%": "vim::Matching",
@@ -135,7 +123,6 @@
"g shift-t": "pane::ActivatePrevItem",
"g d": "editor::GoToDefinition",
"g shift-d": "editor::GoToTypeDefinition",
"g x": "editor::OpenUrl",
"g n": "vim::SelectNext",
"g shift-n": "vim::SelectPrevious",
"g >": [
@@ -228,7 +215,6 @@
// z commands
"z t": "editor::ScrollCursorTop",
"z z": "editor::ScrollCursorCenter",
"z .": ["workspace::SendKeystrokes", "z z ^"],
"z b": "editor::ScrollCursorBottom",
"z c": "editor::Fold",
"z o": "editor::UnfoldLines",
@@ -299,13 +285,6 @@
"ctrl-w ctrl-o": "workspace::CloseInactiveTabsAndPanes",
"ctrl-w n": ["workspace::NewFileInDirection", "Up"],
"ctrl-w ctrl-n": ["workspace::NewFileInDirection", "Up"],
"ctrl-w d": "editor::GoToDefinitionSplit",
"ctrl-w g d": "editor::GoToDefinitionSplit",
"ctrl-w shift-d": "editor::GoToTypeDefinitionSplit",
"ctrl-w g shift-d": "editor::GoToTypeDefinitionSplit",
"ctrl-w space": "editor::OpenExcerptsSplit",
"ctrl-w g space": "editor::OpenExcerptsSplit",
"-": "pane::RevealInProjectPanel"
}
},
@@ -360,12 +339,10 @@
"r": ["vim::PushOperator", "Replace"],
"s": "vim::Substitute",
"shift-s": "vim::SubstituteLine",
"> >": "vim::Indent",
"< <": "vim::Outdent",
"> >": "editor::Indent",
"< <": "editor::Outdent",
"ctrl-pagedown": "pane::ActivateNextItem",
"ctrl-pageup": "pane::ActivatePrevItem",
"[ x": "editor::SelectLargerSyntaxNode",
"] x": "editor::SelectSmallerSyntaxNode"
"ctrl-pageup": "pane::ActivatePrevItem"
}
},
{
@@ -403,9 +380,7 @@
"ignorePunctuation": true
}
],
"t": "vim::Tag",
"s": "vim::Sentence",
"p": "vim::Paragraph",
"'": "vim::Quotes",
"`": "vim::BackQuotes",
"\"": "vim::DoubleQuotes",
@@ -419,8 +394,7 @@
"}": "vim::CurlyBrackets",
"shift-b": "vim::CurlyBrackets",
"<": "vim::AngleBrackets",
">": "vim::AngleBrackets",
"a": "vim::Argument"
">": "vim::AngleBrackets"
}
},
{
@@ -481,8 +455,8 @@
"ctrl-c": ["vim::SwitchMode", "Normal"],
"escape": ["vim::SwitchMode", "Normal"],
"ctrl-[": ["vim::SwitchMode", "Normal"],
">": "vim::Indent",
"<": "vim::Outdent",
">": "editor::Indent",
"<": "editor::Outdent",
"i": [
"vim::PushOperator",
{
@@ -511,11 +485,7 @@
"ctrl-x ctrl-a": "assistant::InlineAssist", // zed specific
"ctrl-x ctrl-c": "copilot::Suggest", // zed specific
"ctrl-x ctrl-l": "editor::ToggleCodeActions", // zed specific
"ctrl-x ctrl-z": "editor::Cancel",
"ctrl-w": "editor::DeleteToPreviousWordStart",
"ctrl-u": "editor::DeleteToBeginningOfLine",
"ctrl-t": "vim::Indent",
"ctrl-d": "vim::Outdent"
"ctrl-x ctrl-z": "editor::Cancel"
}
},
{
@@ -533,27 +503,5 @@
"enter": "vim::SearchSubmit",
"escape": "buffer_search::Dismiss"
}
},
{
// netrw compatibility
"context": "ProjectPanel && not_editing",
"bindings": {
":": "command_palette::Toggle",
"%": "project_panel::NewFile",
"/": "project_panel::NewSearchInDirectory",
"d": "project_panel::NewDirectory",
"enter": "project_panel::Open",
"escape": "project_panel::ToggleFocus",
"h": "project_panel::CollapseSelectedEntry",
"j": "menu::SelectNext",
"k": "menu::SelectPrev",
"l": "project_panel::ExpandSelectedEntry",
"o": "project_panel::Open",
"shift-d": "project_panel::Delete",
"shift-r": "project_panel::Rename",
"t": "project_panel::Open",
"v": "project_panel::Open",
"x": "project_panel::RevealInFinder"
}
}
]

View File

@@ -104,10 +104,8 @@
"show_whitespaces": "selection",
// Settings related to calls in Zed
"calls": {
// Join calls with the microphone live by default
"mute_on_join": false,
// Share your project when you are the first to join a channel
"share_on_join": true
// Join calls with the microphone muted by default
"mute_on_join": false
},
// Toolbar related settings
"toolbar": {
@@ -140,23 +138,6 @@
// Whether to show diagnostic indicators in the scrollbar.
"diagnostics": true
},
// What to do when multibuffer is double clicked in some of its excerpts
// (parts of singleton buffers).
// May take 2 values:
// 1. Behave as a regular buffer and select the whole word (default).
// "double_click_in_multibuffer": "select"
// 2. Open the excerpt clicked as a new buffer in the new tab.
// "double_click_in_multibuffer": "open",
// For the case of "open", regular selection behavior can be achieved by holding `alt` when double clicking.
"double_click_in_multibuffer": "select",
"gutter": {
// Whether to show line numbers in the gutter.
"line_numbers": true,
// Whether to show code action buttons in the gutter.
"code_actions": true,
// Whether to show fold buttons in the gutter.
"folds": true
},
// The number of lines to keep above/below the cursor when scrolling.
"vertical_scroll_margin": 3,
"relative_line_numbers": false,
@@ -178,18 +159,12 @@
"show_type_hints": true,
"show_parameter_hints": true,
// Corresponds to null/None LSP hint type value.
"show_other_hints": true,
// Time to wait after editing the buffer, before requesting the hints,
// set to 0 to disable debouncing.
"edit_debounce_ms": 700,
// Time to wait after scrolling the buffer, before requesting the hints,
// set to 0 to disable debouncing.
"scroll_debounce_ms": 50
"show_other_hints": true
},
"project_panel": {
// Default width of the project panel.
"default_width": 240,
// Where to dock the project panel. Can be 'left' or 'right'.
// Where to dock project panel. Can be 'left' or 'right'.
"dock": "left",
// Whether to show file icons in the project panel.
"file_icons": true,
@@ -207,64 +182,45 @@
"collaboration_panel": {
// Whether to show the collaboration panel button in the status bar.
"button": true,
// Where to dock the collaboration panel. Can be 'left' or 'right'.
// Where to dock channels panel. Can be 'left' or 'right'.
"dock": "left",
// Default width of the collaboration panel.
// Default width of the channels panel.
"default_width": 240
},
"chat_panel": {
// Whether to show the chat panel button in the status bar.
// Whether to show the collaboration panel button in the status bar.
"button": true,
// Where to the chat panel. Can be 'left' or 'right'.
// Where to dock channels panel. Can be 'left' or 'right'.
"dock": "right",
// Default width of the chat panel.
// Default width of the channels panel.
"default_width": 240
},
"message_editor": {
// Whether to automatically replace emoji shortcodes with emoji characters.
// For example: typing `:wave:` gets replaced with `👋`.
"auto_replace_emoji_shortcode": true
},
"notification_panel": {
// Whether to show the notification panel button in the status bar.
// Whether to show the collaboration panel button in the status bar.
"button": true,
// Where to dock the notification panel. Can be 'left' or 'right'.
// Where to dock channels panel. Can be 'left' or 'right'.
"dock": "right",
// Default width of the notification panel.
// Default width of the channels panel.
"default_width": 380
},
"assistant": {
// Whether to show the assistant panel button in the status bar.
"button": true,
// Where to dock the assistant panel. Can be 'left', 'right' or 'bottom'.
// Where to dock the assistant. Can be 'left', 'right' or 'bottom'.
"dock": "right",
// Default width when the assistant is docked to the left or right.
"default_width": 640,
// Default height when the assistant is docked to the bottom.
"default_height": 320,
// Deprecated: Please use `provider.api_url` instead.
// The default OpenAI API endpoint to use when starting new conversations.
"openai_api_url": "https://api.openai.com/v1",
// Deprecated: Please use `provider.default_model` instead.
// The default OpenAI model to use when starting new conversations. This
// setting can take three values:
//
// 1. "gpt-3.5-turbo-0613""
// 2. "gpt-4-0613""
// 3. "gpt-4-1106-preview"
"default_open_ai_model": "gpt-4-1106-preview",
"provider": {
"type": "openai",
// The default OpenAI API endpoint to use when starting new conversations.
"api_url": "https://api.openai.com/v1",
// The default OpenAI model to use when starting new conversations. This
// setting can take three values:
//
// 1. "gpt-3.5-turbo-0613""
// 2. "gpt-4-0613""
// 3. "gpt-4-1106-preview"
"default_model": "gpt-4-1106-preview"
}
"default_open_ai_model": "gpt-4-1106-preview"
},
// Whether the screen sharing icon is shown in the os status bar.
"show_call_status_icon": true,
@@ -486,10 +442,6 @@
// Can also be 'csh', 'fish', and `nushell`
"activate_script": "default"
}
},
"toolbar": {
// Whether to display the terminal title in its toolbar.
"title": true
}
// Set the terminal's font size. If this option is not included,
// the terminal will default to matching the buffer's font size.
@@ -497,10 +449,7 @@
// Set the terminal's font family. If this option is not included,
// the terminal will default to matching the buffer's font family.
// "font_family": "Zed Mono",
// Sets the maximum number of lines in the terminal's scrollback buffer.
// Default: 10_000, maximum: 100_000 (all bigger values set will be treated as 100_000), 0 disables the scrolling.
// Existing terminals will not pick up this change until they are recreated.
// "max_scroll_history_lines": 10000,
// ---
},
// Difference settings for semantic_index
"semantic_index": {
@@ -531,7 +480,6 @@
"deno": {
"enable": false
},
"code_actions_on_format": {},
// Different settings for specific languages.
"languages": {
"Plain Text": {
@@ -540,18 +488,11 @@
"Elixir": {
"tab_size": 2
},
"Gleam": {
"tab_size": 2
},
"Go": {
"tab_size": 4,
"hard_tabs": true,
"code_actions_on_format": {
"source.organizeImports": true
}
"hard_tabs": true
},
"Markdown": {
"tab_size": 2,
"soft_wrap": "preferred_line_length"
},
"JavaScript": {
@@ -593,20 +534,14 @@
"lsp": {
// Specify the LSP name as a key here.
// "rust-analyzer": {
// // These initialization options are merged into Zed's defaults
// //These initialization options are merged into Zed's defaults
// "initialization_options": {
// "check": {
// "command": "clippy" // rust-analyzer.check.command (default: "check")
// "checkOnSave": {
// "command": "clippy"
// }
// }
// }
},
// Vim settings
"vim": {
"use_system_clipboard": "always",
"use_multiline_find": false,
"use_smartcase_find": false
},
// The server to connect to. If the environment variable
// ZED_SERVER_URL is set, it will override this setting.
"server_url": "https://zed.dev",

View File

@@ -1,17 +0,0 @@
// Static tasks configuration.
//
// Example:
[
{
"label": "Example task",
"command": "for i in {1..5}; do echo \"Hello $i/5\"; sleep 1; done",
// Env overrides for the command, will be appended to the terminal's environment from the settings.
"env": { "foo": "bar" },
// Current working directory to spawn the command into, defaults to current project root.
//"cwd": "/path/to/working/directory",
// Whether to use a new terminal tab or reuse the existing one to spawn the process, defaults to `false`.
"use_new_terminal": false,
// Whether to allow multiple instances of the same task to be run, or rather wait for the existing ones to finish, defaults to `false`.
"allow_concurrent_runs": false
}
]

View File

@@ -46,7 +46,7 @@
"panel.background": "#21242bff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#f7f7f84c",
"scrollbar_thumb.background": "#f7f7f84c",
"scrollbar.thumb.hover_background": "#252931ff",
"scrollbar.thumb.border": "#252931ff",
"scrollbar.track.background": "#00000000",

View File

@@ -46,7 +46,7 @@
"panel.background": "#221f26ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#efecf44c",
"scrollbar_thumb.background": "#efecf44c",
"scrollbar.thumb.hover_background": "#332f38ff",
"scrollbar.thumb.border": "#332f38ff",
"scrollbar.track.background": "#00000000",
@@ -430,7 +430,7 @@
"panel.background": "#e6e3ebff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#19171c4c",
"scrollbar_thumb.background": "#19171c4c",
"scrollbar.thumb.hover_background": "#cbc8d1ff",
"scrollbar.thumb.border": "#cbc8d1ff",
"scrollbar.track.background": "#00000000",
@@ -814,7 +814,7 @@
"panel.background": "#262622ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#fefbec4c",
"scrollbar_thumb.background": "#fefbec4c",
"scrollbar.thumb.hover_background": "#3b3933ff",
"scrollbar.thumb.border": "#3b3933ff",
"scrollbar.track.background": "#00000000",
@@ -1198,7 +1198,7 @@
"panel.background": "#eeebd7ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#20201d4c",
"scrollbar_thumb.background": "#20201d4c",
"scrollbar.thumb.hover_background": "#d7d3beff",
"scrollbar.thumb.border": "#d7d3beff",
"scrollbar.track.background": "#00000000",
@@ -1582,7 +1582,7 @@
"panel.background": "#2c2b23ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#f4f3ec4c",
"scrollbar_thumb.background": "#f4f3ec4c",
"scrollbar.thumb.hover_background": "#3c3b31ff",
"scrollbar.thumb.border": "#3c3b31ff",
"scrollbar.track.background": "#00000000",
@@ -1966,7 +1966,7 @@
"panel.background": "#ebeae3ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#22221b4c",
"scrollbar_thumb.background": "#22221b4c",
"scrollbar.thumb.hover_background": "#d0cfc5ff",
"scrollbar.thumb.border": "#d0cfc5ff",
"scrollbar.track.background": "#00000000",
@@ -2350,7 +2350,7 @@
"panel.background": "#27211eff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#f0eeed4c",
"scrollbar_thumb.background": "#f0eeed4c",
"scrollbar.thumb.hover_background": "#3b3431ff",
"scrollbar.thumb.border": "#3b3431ff",
"scrollbar.track.background": "#00000000",
@@ -2734,7 +2734,7 @@
"panel.background": "#e9e6e4ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#1b19184c",
"scrollbar_thumb.background": "#1b19184c",
"scrollbar.thumb.hover_background": "#d6d1cfff",
"scrollbar.thumb.border": "#d6d1cfff",
"scrollbar.track.background": "#00000000",
@@ -3118,7 +3118,7 @@
"panel.background": "#252025ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#f7f3f74c",
"scrollbar_thumb.background": "#f7f3f74c",
"scrollbar.thumb.hover_background": "#393239ff",
"scrollbar.thumb.border": "#393239ff",
"scrollbar.track.background": "#00000000",
@@ -3502,7 +3502,7 @@
"panel.background": "#e0d5e0ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#1b181b4c",
"scrollbar_thumb.background": "#1b181b4c",
"scrollbar.thumb.hover_background": "#ccbdccff",
"scrollbar.thumb.border": "#ccbdccff",
"scrollbar.track.background": "#00000000",
@@ -3886,7 +3886,7 @@
"panel.background": "#1c2529ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#ebf8ff4c",
"scrollbar_thumb.background": "#ebf8ff4c",
"scrollbar.thumb.hover_background": "#2c3b42ff",
"scrollbar.thumb.border": "#2c3b42ff",
"scrollbar.track.background": "#00000000",
@@ -4270,7 +4270,7 @@
"panel.background": "#cdeaf9ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#161b1d4c",
"scrollbar_thumb.background": "#161b1d4c",
"scrollbar.thumb.hover_background": "#b0d3e5ff",
"scrollbar.thumb.border": "#b0d3e5ff",
"scrollbar.track.background": "#00000000",
@@ -4654,7 +4654,7 @@
"panel.background": "#252020ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#f4ecec4c",
"scrollbar_thumb.background": "#f4ecec4c",
"scrollbar.thumb.hover_background": "#352f2fff",
"scrollbar.thumb.border": "#352f2fff",
"scrollbar.track.background": "#00000000",
@@ -5038,7 +5038,7 @@
"panel.background": "#ebe3e3ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#1b18184c",
"scrollbar_thumb.background": "#1b18184c",
"scrollbar.thumb.hover_background": "#cfc7c7ff",
"scrollbar.thumb.border": "#cfc7c7ff",
"scrollbar.track.background": "#00000000",
@@ -5422,7 +5422,7 @@
"panel.background": "#1f2621ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#ecf4ee4c",
"scrollbar_thumb.background": "#ecf4ee4c",
"scrollbar.thumb.hover_background": "#2f3832ff",
"scrollbar.thumb.border": "#2f3832ff",
"scrollbar.track.background": "#00000000",
@@ -5806,7 +5806,7 @@
"panel.background": "#e3ebe6ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#171c194c",
"scrollbar_thumb.background": "#171c194c",
"scrollbar.thumb.hover_background": "#c8d1cbff",
"scrollbar.thumb.border": "#c8d1cbff",
"scrollbar.track.background": "#00000000",
@@ -6190,7 +6190,7 @@
"panel.background": "#1f231fff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#f3faf34c",
"scrollbar_thumb.background": "#f3faf34c",
"scrollbar.thumb.hover_background": "#333b33ff",
"scrollbar.thumb.border": "#333b33ff",
"scrollbar.track.background": "#00000000",
@@ -6574,7 +6574,7 @@
"panel.background": "#daeedaff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#1315134c",
"scrollbar_thumb.background": "#1315134c",
"scrollbar.thumb.hover_background": "#bed7beff",
"scrollbar.thumb.border": "#bed7beff",
"scrollbar.track.background": "#00000000",
@@ -6958,7 +6958,7 @@
"panel.background": "#262f51ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#f5f7ff4c",
"scrollbar_thumb.background": "#f5f7ff4c",
"scrollbar.thumb.hover_background": "#363f62ff",
"scrollbar.thumb.border": "#363f62ff",
"scrollbar.track.background": "#00000000",
@@ -7342,7 +7342,7 @@
"panel.background": "#e5e8f5ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#2026464c",
"scrollbar_thumb.background": "#2026464c",
"scrollbar.thumb.hover_background": "#ccd0e1ff",
"scrollbar.thumb.border": "#ccd0e1ff",
"scrollbar.track.background": "#00000000",

View File

@@ -46,7 +46,7 @@
"panel.background": "#1f2127ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#bfbdb64c",
"scrollbar_thumb.background": "#bfbdb64c",
"scrollbar.thumb.hover_background": "#2d2f34ff",
"scrollbar.thumb.border": "#2d2f34ff",
"scrollbar.track.background": "#00000000",
@@ -415,7 +415,7 @@
"panel.background": "#ececedff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#5c61664c",
"scrollbar_thumb.background": "#5c61664c",
"scrollbar.thumb.hover_background": "#dfe0e1ff",
"scrollbar.thumb.border": "#dfe0e1ff",
"scrollbar.track.background": "#00000000",
@@ -784,7 +784,7 @@
"panel.background": "#353944ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#cccac24c",
"scrollbar_thumb.background": "#cccac24c",
"scrollbar.thumb.hover_background": "#43464fff",
"scrollbar.thumb.border": "#43464fff",
"scrollbar.track.background": "#00000000",

View File

@@ -46,7 +46,7 @@
"panel.background": "#3a3735ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#fbf1c74c",
"scrollbar_thumb.background": "#fbf1c74c",
"scrollbar.thumb.hover_background": "#494340ff",
"scrollbar.thumb.border": "#494340ff",
"scrollbar.track.background": "#00000000",
@@ -420,7 +420,7 @@
"panel.background": "#393634ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#fbf1c74c",
"scrollbar_thumb.background": "#fbf1c74c",
"scrollbar.thumb.hover_background": "#494340ff",
"scrollbar.thumb.border": "#494340ff",
"scrollbar.track.background": "#00000000",
@@ -482,7 +482,7 @@
"hidden": "#998b78ff",
"hidden.background": "#4c4642ff",
"hidden.border": "#544c48ff",
"hint": "#6a695bff",
"hint": "#8c957dff",
"hint.background": "#1e2321ff",
"hint.border": "#303a36ff",
"ignored": "#c5b597ff",
@@ -794,7 +794,7 @@
"panel.background": "#3b3735ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#fbf1c74c",
"scrollbar_thumb.background": "#fbf1c74c",
"scrollbar.thumb.hover_background": "#494340ff",
"scrollbar.thumb.border": "#494340ff",
"scrollbar.track.background": "#00000000",
@@ -1168,7 +1168,7 @@
"panel.background": "#ecddb4ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#2828284c",
"scrollbar_thumb.background": "#2828284c",
"scrollbar.thumb.hover_background": "#ddcca7ff",
"scrollbar.thumb.border": "#ddcca7ff",
"scrollbar.track.background": "#00000000",
@@ -1542,7 +1542,7 @@
"panel.background": "#ecddb5ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#2828284c",
"scrollbar_thumb.background": "#2828284c",
"scrollbar.thumb.hover_background": "#ddcca7ff",
"scrollbar.thumb.border": "#ddcca7ff",
"scrollbar.track.background": "#00000000",
@@ -1916,7 +1916,7 @@
"panel.background": "#ecdcb3ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#2828284c",
"scrollbar_thumb.background": "#2828284c",
"scrollbar.thumb.hover_background": "#ddcca7ff",
"scrollbar.thumb.border": "#ddcca7ff",
"scrollbar.track.background": "#00000000",

View File

@@ -46,7 +46,7 @@
"panel.background": "#2f343eff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#c8ccd44c",
"scrollbar_thumb.background": "#c8ccd44c",
"scrollbar.thumb.hover_background": "#363c46ff",
"scrollbar.thumb.border": "#363c46ff",
"scrollbar.track.background": "#00000000",
@@ -420,7 +420,7 @@
"panel.background": "#ebebecff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#383a414c",
"scrollbar_thumb.background": "#383a414c",
"scrollbar.thumb.hover_background": "#dfdfe0ff",
"scrollbar.thumb.border": "#dfdfe0ff",
"scrollbar.track.background": "#00000000",

View File

@@ -46,7 +46,7 @@
"panel.background": "#1c1b2aff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#e0def44c",
"scrollbar_thumb.background": "#e0def44c",
"scrollbar.thumb.hover_background": "#232132ff",
"scrollbar.thumb.border": "#232132ff",
"scrollbar.track.background": "#00000000",
@@ -77,7 +77,7 @@
"terminal.ansi.green": "#5cc1a3ff",
"terminal.ansi.bright_green": "#31614fff",
"terminal.ansi.dim_green": "#b3e1d1ff",
"terminal.ansi.yellow": "#f6c177ff",
"terminal.ansi.yellow": "#f5c177ff",
"terminal.ansi.bright_yellow": "#8a643aff",
"terminal.ansi.dim_yellow": "#fedfbbff",
"terminal.ansi.blue": "#9bced6ff",
@@ -93,7 +93,7 @@
"terminal.ansi.bright_white": "#e0def4ff",
"terminal.ansi.dim_white": "#514e68ff",
"link_text.hover": "#9bced6ff",
"conflict": "#f6c177ff",
"conflict": "#f5c177ff",
"conflict.background": "#50331aff",
"conflict.border": "#6d4d2bff",
"created": "#5cc1a3ff",
@@ -117,7 +117,7 @@
"info": "#9bced6ff",
"info.background": "#2f3639ff",
"info.border": "#435255ff",
"modified": "#f6c177ff",
"modified": "#f5c177ff",
"modified.background": "#50331aff",
"modified.border": "#6d4d2bff",
"predictive": "#556b81ff",
@@ -132,7 +132,7 @@
"unreachable": "#74708dff",
"unreachable.background": "#292738ff",
"unreachable.border": "#423f55ff",
"warning": "#f6c177ff",
"warning": "#f5c177ff",
"warning.background": "#50331aff",
"warning.border": "#6d4d2bff",
"players": [
@@ -167,9 +167,9 @@
"selection": "#ea6e923d"
},
{
"cursor": "#f6c177ff",
"background": "#f6c177ff",
"selection": "#f6c1773d"
"cursor": "#f5c177ff",
"background": "#f5c177ff",
"selection": "#f5c1773d"
},
{
"cursor": "#5cc1a3ff",
@@ -319,7 +319,7 @@
"font_weight": null
},
"string": {
"color": "#f6c177ff",
"color": "#f5c177ff",
"font_style": null,
"font_weight": null
},
@@ -354,7 +354,7 @@
"font_weight": null
},
"title": {
"color": "#f6c177ff",
"color": "#f5c177ff",
"font_style": null,
"font_weight": 700
},
@@ -425,7 +425,7 @@
"panel.background": "#fef9f2ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#5752794c",
"scrollbar_thumb.background": "#5752794c",
"scrollbar.thumb.hover_background": "#e5e0dfff",
"scrollbar.thumb.border": "#e5e0dfff",
"scrollbar.track.background": "#00000000",
@@ -804,7 +804,7 @@
"panel.background": "#28253cff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#e0def44c",
"scrollbar_thumb.background": "#e0def44c",
"scrollbar.thumb.hover_background": "#322f48ff",
"scrollbar.thumb.border": "#322f48ff",
"scrollbar.track.background": "#00000000",
@@ -835,7 +835,7 @@
"terminal.ansi.green": "#5cc1a3ff",
"terminal.ansi.bright_green": "#31614fff",
"terminal.ansi.dim_green": "#b3e1d1ff",
"terminal.ansi.yellow": "#f6c177ff",
"terminal.ansi.yellow": "#f5c177ff",
"terminal.ansi.bright_yellow": "#8a643aff",
"terminal.ansi.dim_yellow": "#fedfbbff",
"terminal.ansi.blue": "#9bced6ff",
@@ -851,7 +851,7 @@
"terminal.ansi.bright_white": "#e0def4ff",
"terminal.ansi.dim_white": "#74708dff",
"link_text.hover": "#9bced6ff",
"conflict": "#f6c177ff",
"conflict": "#f5c177ff",
"conflict.background": "#50331aff",
"conflict.border": "#6d4d2bff",
"created": "#5cc1a3ff",
@@ -875,7 +875,7 @@
"info": "#9bced6ff",
"info.background": "#2f3639ff",
"info.border": "#435255ff",
"modified": "#f6c177ff",
"modified": "#f5c177ff",
"modified.background": "#50331aff",
"modified.border": "#6d4d2bff",
"predictive": "#516b83ff",
@@ -890,7 +890,7 @@
"unreachable": "#85819eff",
"unreachable.background": "#38354eff",
"unreachable.border": "#504c68ff",
"warning": "#f6c177ff",
"warning": "#f5c177ff",
"warning.background": "#50331aff",
"warning.border": "#6d4d2bff",
"players": [
@@ -925,9 +925,9 @@
"selection": "#ea6e923d"
},
{
"cursor": "#f6c177ff",
"background": "#f6c177ff",
"selection": "#f6c1773d"
"cursor": "#f5c177ff",
"background": "#f5c177ff",
"selection": "#f5c1773d"
},
{
"cursor": "#5cc1a3ff",
@@ -1077,7 +1077,7 @@
"font_weight": null
},
"string": {
"color": "#f6c177ff",
"color": "#f5c177ff",
"font_style": null,
"font_weight": null
},
@@ -1112,7 +1112,7 @@
"font_weight": null
},
"title": {
"color": "#f6c177ff",
"color": "#f5c177ff",
"font_style": null,
"font_weight": 700
},

View File

@@ -46,7 +46,7 @@
"panel.background": "#2b3038ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#fdf4c14c",
"scrollbar_thumb.background": "#fdf4c14c",
"scrollbar.thumb.hover_background": "#313741ff",
"scrollbar.thumb.border": "#313741ff",
"scrollbar.track.background": "#00000000",

View File

@@ -46,7 +46,7 @@
"panel.background": "#04313bff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#fdf6e34c",
"scrollbar_thumb.background": "#fdf6e34c",
"scrollbar.thumb.hover_background": "#053541ff",
"scrollbar.thumb.border": "#053541ff",
"scrollbar.track.background": "#00000000",
@@ -415,7 +415,7 @@
"panel.background": "#f3eddaff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#002a354c",
"scrollbar_thumb.background": "#002a354c",
"scrollbar.thumb.hover_background": "#dcdacbff",
"scrollbar.thumb.border": "#dcdacbff",
"scrollbar.track.background": "#00000000",

View File

@@ -46,7 +46,7 @@
"panel.background": "#231f16ff",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "#f8f5de4c",
"scrollbar_thumb.background": "#f8f5de4c",
"scrollbar.thumb.hover_background": "#29251bff",
"scrollbar.thumb.border": "#29251bff",
"scrollbar.track.background": "#00000000",

View File

@@ -5,9 +5,6 @@ edition = "2021"
publish = false
license = "GPL-3.0-or-later"
[lints]
workspace = true
[lib]
path = "src/activity_indicator.rs"
doctest = false
@@ -20,7 +17,9 @@ futures.workspace = true
gpui.workspace = true
language.workspace = true
project.workspace = true
settings.workspace = true
smallvec.workspace = true
theme.workspace = true
ui.workspace = true
util.workspace = true
workspace.workspace = true

View File

@@ -6,7 +6,7 @@ use gpui::{
ParentElement as _, Render, SharedString, StatefulInteractiveElement, Styled, View,
ViewContext, VisualContext as _,
};
use language::{LanguageRegistry, LanguageServerBinaryStatus, LanguageServerName};
use language::{LanguageRegistry, LanguageServerBinaryStatus};
use project::{LanguageServerProgress, Project};
use smallvec::SmallVec;
use std::{cmp::Reverse, fmt::Write, sync::Arc};
@@ -30,7 +30,7 @@ pub struct ActivityIndicator {
}
struct LspStatus {
name: LanguageServerName,
name: Arc<str>,
status: LanguageServerBinaryStatus,
}
@@ -58,10 +58,13 @@ impl ActivityIndicator {
let this = cx.new_view(|cx: &mut ViewContext<Self>| {
let mut status_events = languages.language_server_binary_statuses();
cx.spawn(|this, mut cx| async move {
while let Some((name, status)) = status_events.next().await {
while let Some((language, event)) = status_events.next().await {
this.update(&mut cx, |this, cx| {
this.statuses.retain(|s| s.name != name);
this.statuses.push(LspStatus { name, status });
this.statuses.retain(|s| s.name != language.name());
this.statuses.push(LspStatus {
name: language.name(),
status: event,
});
cx.notify();
})?;
}
@@ -94,7 +97,7 @@ impl ActivityIndicator {
cx,
);
});
workspace.add_item_to_active_pane(
workspace.add_item(
Box::new(
cx.new_view(|cx| Editor::for_buffer(buffer, Some(project.clone()), cx)),
),
@@ -111,7 +114,7 @@ impl ActivityIndicator {
self.statuses.retain(|status| {
if let LanguageServerBinaryStatus::Failed { error } = &status.status {
cx.emit(Event::ShowError {
lsp_name: status.name.0.clone(),
lsp_name: status.name.clone(),
error: error.clone(),
});
false
@@ -199,12 +202,11 @@ impl ActivityIndicator {
let mut checking_for_update = SmallVec::<[_; 3]>::new();
let mut failed = SmallVec::<[_; 3]>::new();
for status in &self.statuses {
let name = status.name.clone();
match status.status {
LanguageServerBinaryStatus::CheckingForUpdate => {
checking_for_update.push(status.name.0.as_ref())
}
LanguageServerBinaryStatus::Downloading => downloading.push(status.name.0.as_ref()),
LanguageServerBinaryStatus::Failed { .. } => failed.push(status.name.0.as_ref()),
LanguageServerBinaryStatus::CheckingForUpdate => checking_for_update.push(name),
LanguageServerBinaryStatus::Downloading => downloading.push(name),
LanguageServerBinaryStatus::Failed { .. } => failed.push(name),
LanguageServerBinaryStatus::Downloaded | LanguageServerBinaryStatus::Cached => {}
}
}
@@ -212,28 +214,34 @@ impl ActivityIndicator {
if !downloading.is_empty() {
return Content {
icon: Some(DOWNLOAD_ICON),
message: format!("Downloading {}...", downloading.join(", "),),
message: format!(
"Downloading {} language server{}...",
downloading.join(", "),
if downloading.len() > 1 { "s" } else { "" }
),
on_click: None,
};
}
if !checking_for_update.is_empty() {
} else if !checking_for_update.is_empty() {
return Content {
icon: Some(DOWNLOAD_ICON),
message: format!(
"Checking for updates to {}...",
"Checking for updates to {} language server{}...",
checking_for_update.join(", "),
if checking_for_update.len() > 1 {
"s"
} else {
""
}
),
on_click: None,
};
}
if !failed.is_empty() {
} else if !failed.is_empty() {
return Content {
icon: Some(WARNING_ICON),
message: format!(
"Failed to download {}. Click to show error.",
"Failed to download {} language server{}. Click to show error.",
failed.join(", "),
if failed.len() > 1 { "s" } else { "" }
),
on_click: Some(Arc::new(|this, cx| {
this.show_error_message(&Default::default(), cx)
@@ -241,17 +249,6 @@ impl ActivityIndicator {
};
}
// Show any formatting failure
if let Some(failure) = self.project.read(cx).last_formatting_failure() {
return Content {
icon: Some(WARNING_ICON),
message: format!("Formatting failed: {}. Click to see logs.", failure),
on_click: Some(Arc::new(|_, cx| {
cx.dispatch_action(Box::new(workspace::OpenLog));
})),
};
}
// Show any application auto-update info.
if let Some(updater) = &self.auto_updater {
return match &updater.read(cx).status() {

View File

@@ -5,9 +5,6 @@ edition = "2021"
publish = false
license = "GPL-3.0-or-later"
[lints]
workspace = true
[lib]
path = "src/ai.rs"
doctest = false
@@ -23,6 +20,7 @@ futures.workspace = true
gpui.workspace = true
isahc.workspace = true
language.workspace = true
lazy_static.workspace = true
log.workspace = true
matrixmultiply = "0.3.7"
ordered-float.workspace = true
@@ -30,8 +28,8 @@ parking_lot.workspace = true
parse_duration = "2.1.1"
postage.workspace = true
rand.workspace = true
regex.workspace = true
rusqlite = { version = "0.29.0", features = ["blob", "array", "modern_sqlite"] }
schemars.workspace = true
serde.workspace = true
serde_json.workspace = true
tiktoken-rs.workspace = true

View File

@@ -19,9 +19,11 @@ pub struct Embedding(pub Vec<f32>);
impl FromSql for Embedding {
fn column_result(value: ValueRef) -> FromSqlResult<Self> {
let bytes = value.as_blob()?;
let embedding =
bincode::deserialize(bytes).map_err(|err| rusqlite::types::FromSqlError::Other(err))?;
Ok(Embedding(embedding))
let embedding: Result<Vec<f32>, Box<bincode::ErrorKind>> = bincode::deserialize(bytes);
if embedding.is_err() {
return Err(rusqlite::types::FromSqlError::Other(embedding.unwrap_err()));
}
Ok(Embedding(embedding.unwrap()))
}
}
@@ -110,7 +112,7 @@ mod tests {
}
fn round_to_decimals(n: OrderedFloat<f32>, decimal_places: i32) -> f32 {
let factor = 10.0_f32.powi(decimal_places);
let factor = (10.0 as f32).powi(decimal_places);
(n * factor).round() / factor
}

View File

@@ -30,7 +30,7 @@ impl PromptArguments {
if self
.language_name
.as_ref()
.map(|name| !["Markdown", "Plain Text"].contains(&name.as_str()))
.and_then(|name| Some(!["Markdown", "Plain Text"].contains(&name.as_str())))
.unwrap_or(true)
{
PromptFileType::Code
@@ -51,10 +51,8 @@ pub trait PromptTemplate {
#[repr(i8)]
#[derive(PartialEq, Eq, Ord)]
pub enum PromptPriority {
/// Ignores truncation.
Mandatory,
/// Truncates based on priority.
Ordered { order: usize },
Mandatory, // Ignores truncation
Ordered { order: usize }, // Truncates based on priority
}
impl PartialOrd for PromptPriority {
@@ -88,6 +86,7 @@ impl PromptChain {
let mut sorted_indices = (0..self.templates.len()).collect::<Vec<_>>();
sorted_indices.sort_by_key(|&i| Reverse(&self.templates[i].0));
// If Truncate
let mut tokens_outstanding = if truncate {
Some(self.args.model.capacity()? - self.args.reserved_tokens)
} else {

View File

@@ -24,9 +24,11 @@ impl PromptCodeSnippet {
let language_name = buffer
.language()
.map(|language| language.name().to_string().to_lowercase());
.and_then(|language| Some(language.name().to_string().to_lowercase()));
let file_path = buffer.file().map(|file| file.path().to_path_buf());
let file_path = buffer
.file()
.and_then(|file| Some(file.path().to_path_buf()));
(content, language_name, file_path)
})?;
@@ -44,7 +46,7 @@ impl ToString for PromptCodeSnippet {
let path = self
.path
.as_ref()
.map(|path| path.to_string_lossy().to_string())
.and_then(|path| Some(path.to_string_lossy().to_string()))
.unwrap_or("".to_string());
let language_name = self.language_name.clone().unwrap_or("".to_string());
let content = self.content.clone();
@@ -65,7 +67,7 @@ impl PromptTemplate for RepositoryContext {
let template = "You are working inside a large repository, here are a few code snippets that may be useful.";
let mut prompt = String::new();
let mut remaining_tokens = max_token_length;
let mut remaining_tokens = max_token_length.clone();
let separator_token_length = args.model.count_tokens("\n")?;
for snippet in &args.snippets {
let mut snippet_prompt = template.to_string();

View File

@@ -6,4 +6,4 @@ pub use completion::*;
pub use embedding::*;
pub use model::OpenAiLanguageModel;
pub const OPEN_AI_API_URL: &str = "https://api.openai.com/v1";
pub const OPEN_AI_API_URL: &'static str = "https://api.openai.com/v1";

View File

@@ -1,10 +1,3 @@
use std::{
env,
fmt::{self, Display},
io,
sync::Arc,
};
use anyhow::{anyhow, Result};
use futures::{
future::BoxFuture, io::BufReader, stream::BoxStream, AsyncBufReadExt, AsyncReadExt, FutureExt,
@@ -13,17 +6,23 @@ use futures::{
use gpui::{AppContext, BackgroundExecutor};
use isahc::{http::StatusCode, Request, RequestExt};
use parking_lot::RwLock;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::{
env,
fmt::{self, Display},
io,
sync::Arc,
};
use util::ResultExt;
use crate::providers::open_ai::{OpenAiLanguageModel, OPEN_AI_API_URL};
use crate::{
auth::{CredentialProvider, ProviderCredential},
completion::{CompletionProvider, CompletionRequest},
models::LanguageModel,
};
use crate::providers::open_ai::{OpenAiLanguageModel, OPEN_AI_API_URL};
#[derive(Clone, Copy, Serialize, Deserialize, Debug, Eq, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum Role {
@@ -103,9 +102,8 @@ pub struct OpenAiResponseStreamEvent {
pub usage: Option<OpenAiUsage>,
}
async fn stream_completion(
pub async fn stream_completion(
api_url: String,
kind: OpenAiCompletionProviderKind,
credential: ProviderCredential,
executor: BackgroundExecutor,
request: Box<dyn CompletionRequest>,
@@ -119,11 +117,10 @@ async fn stream_completion(
let (tx, rx) = futures::channel::mpsc::unbounded::<Result<OpenAiResponseStreamEvent>>();
let (auth_header_name, auth_header_value) = kind.auth_header(api_key);
let json_data = request.data()?;
let mut response = Request::post(kind.completions_endpoint_url(&api_url))
let mut response = Request::post(format!("{api_url}/chat/completions"))
.header("Content-Type", "application/json")
.header(auth_header_name, auth_header_value)
.header("Authorization", format!("Bearer {}", api_key))
.body(json_data)?
.send_async()
.await?;
@@ -197,109 +194,22 @@ async fn stream_completion(
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema)]
pub enum AzureOpenAiApiVersion {
/// Retiring April 2, 2024.
#[serde(rename = "2023-03-15-preview")]
V2023_03_15Preview,
#[serde(rename = "2023-05-15")]
V2023_05_15,
/// Retiring April 2, 2024.
#[serde(rename = "2023-06-01-preview")]
V2023_06_01Preview,
/// Retiring April 2, 2024.
#[serde(rename = "2023-07-01-preview")]
V2023_07_01Preview,
/// Retiring April 2, 2024.
#[serde(rename = "2023-08-01-preview")]
V2023_08_01Preview,
/// Retiring April 2, 2024.
#[serde(rename = "2023-09-01-preview")]
V2023_09_01Preview,
#[serde(rename = "2023-12-01-preview")]
V2023_12_01Preview,
#[serde(rename = "2024-02-15-preview")]
V2024_02_15Preview,
}
impl fmt::Display for AzureOpenAiApiVersion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
match self {
Self::V2023_03_15Preview => "2023-03-15-preview",
Self::V2023_05_15 => "2023-05-15",
Self::V2023_06_01Preview => "2023-06-01-preview",
Self::V2023_07_01Preview => "2023-07-01-preview",
Self::V2023_08_01Preview => "2023-08-01-preview",
Self::V2023_09_01Preview => "2023-09-01-preview",
Self::V2023_12_01Preview => "2023-12-01-preview",
Self::V2024_02_15Preview => "2024-02-15-preview",
}
)
}
}
#[derive(Clone)]
pub enum OpenAiCompletionProviderKind {
OpenAi,
AzureOpenAi {
deployment_id: String,
api_version: AzureOpenAiApiVersion,
},
}
impl OpenAiCompletionProviderKind {
/// Returns the chat completion endpoint URL for this [`OpenAiCompletionProviderKind`].
fn completions_endpoint_url(&self, api_url: &str) -> String {
match self {
Self::OpenAi => {
// https://platform.openai.com/docs/api-reference/chat/create
format!("{api_url}/chat/completions")
}
Self::AzureOpenAi {
deployment_id,
api_version,
} => {
// https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#chat-completions
format!("{api_url}/openai/deployments/{deployment_id}/chat/completions?api-version={api_version}")
}
}
}
/// Returns the authentication header for this [`OpenAiCompletionProviderKind`].
fn auth_header(&self, api_key: String) -> (&'static str, String) {
match self {
Self::OpenAi => ("Authorization", format!("Bearer {api_key}")),
Self::AzureOpenAi { .. } => ("Api-Key", api_key),
}
}
}
#[derive(Clone)]
pub struct OpenAiCompletionProvider {
api_url: String,
kind: OpenAiCompletionProviderKind,
model: OpenAiLanguageModel,
credential: Arc<RwLock<ProviderCredential>>,
executor: BackgroundExecutor,
}
impl OpenAiCompletionProvider {
pub async fn new(
api_url: String,
kind: OpenAiCompletionProviderKind,
model_name: String,
executor: BackgroundExecutor,
) -> Self {
pub async fn new(api_url: String, model_name: String, executor: BackgroundExecutor) -> Self {
let model = executor
.spawn(async move { OpenAiLanguageModel::load(&model_name) })
.await;
let credential = Arc::new(RwLock::new(ProviderCredential::NoCredentials));
Self {
api_url,
kind,
model,
credential,
executor,
@@ -387,7 +297,6 @@ impl CompletionProvider for OpenAiCompletionProvider {
let model: Box<dyn LanguageModel> = Box::new(self.model.clone());
model
}
fn complete(
&self,
prompt: Box<dyn CompletionRequest>,
@@ -398,8 +307,7 @@ impl CompletionProvider for OpenAiCompletionProvider {
// At some point in the future we should rectify this.
let credential = self.credential.read().clone();
let api_url = self.api_url.clone();
let kind = self.kind.clone();
let request = stream_completion(api_url, kind, credential, self.executor.clone(), prompt);
let request = stream_completion(api_url, credential, self.executor.clone(), prompt);
async move {
let response = request.await?;
let stream = response
@@ -414,7 +322,6 @@ impl CompletionProvider for OpenAiCompletionProvider {
}
.boxed()
}
fn box_clone(&self) -> Box<dyn CompletionProvider> {
Box::new((*self).clone())
}

View File

@@ -8,6 +8,7 @@ use gpui::BackgroundExecutor;
use isahc::http::StatusCode;
use isahc::prelude::Configurable;
use isahc::{AsyncBody, Response};
use lazy_static::lazy_static;
use parking_lot::{Mutex, RwLock};
use parse_duration::parse;
use postage::watch;
@@ -15,7 +16,7 @@ use serde::{Deserialize, Serialize};
use serde_json;
use std::env;
use std::ops::Add;
use std::sync::{Arc, OnceLock};
use std::sync::Arc;
use std::time::{Duration, Instant};
use tiktoken_rs::{cl100k_base, CoreBPE};
use util::http::{HttpClient, Request};
@@ -28,9 +29,8 @@ use crate::providers::open_ai::OpenAiLanguageModel;
use crate::providers::open_ai::OPEN_AI_API_URL;
pub(crate) fn open_ai_bpe_tokenizer() -> &'static CoreBPE {
static OPEN_AI_BPE_TOKENIZER: OnceLock<CoreBPE> = OnceLock::new();
OPEN_AI_BPE_TOKENIZER.get_or_init(|| cl100k_base().unwrap())
lazy_static! {
pub(crate) static ref OPEN_AI_BPE_TOKENIZER: CoreBPE = cl100k_base().unwrap();
}
#[derive(Clone)]

View File

@@ -3,7 +3,7 @@ use tiktoken_rs::CoreBPE;
use crate::models::{LanguageModel, TruncationDirection};
use super::open_ai_bpe_tokenizer;
use super::OPEN_AI_BPE_TOKENIZER;
#[derive(Clone)]
pub struct OpenAiLanguageModel {
@@ -13,8 +13,8 @@ pub struct OpenAiLanguageModel {
impl OpenAiLanguageModel {
pub fn load(model_name: &str) -> Self {
let bpe = tiktoken_rs::get_bpe_from_model(model_name)
.unwrap_or(open_ai_bpe_tokenizer().to_owned());
let bpe =
tiktoken_rs::get_bpe_from_model(model_name).unwrap_or(OPEN_AI_BPE_TOKENIZER.to_owned());
OpenAiLanguageModel {
name: model_name.to_string(),
bpe: Some(bpe),

View File

@@ -54,7 +54,6 @@ impl LanguageModel for FakeLanguageModel {
}
}
#[derive(Default)]
pub struct FakeEmbeddingProvider {
pub embedding_count: AtomicUsize,
}
@@ -67,6 +66,14 @@ impl Clone for FakeEmbeddingProvider {
}
}
impl Default for FakeEmbeddingProvider {
fn default() -> Self {
FakeEmbeddingProvider {
embedding_count: AtomicUsize::default(),
}
}
}
impl FakeEmbeddingProvider {
pub fn embedding_count(&self) -> usize {
self.embedding_count.load(atomic::Ordering::SeqCst)

View File

@@ -5,9 +5,6 @@ edition = "2021"
publish = false
license = "GPL-3.0-or-later"
[lints]
workspace = true
[dependencies]
anyhow.workspace = true
gpui.workspace = true

View File

@@ -5,9 +5,6 @@ edition = "2021"
publish = false
license = "GPL-3.0-or-later"
[lints]
workspace = true
[lib]
path = "src/assistant.rs"
doctest = false
@@ -16,17 +13,20 @@ doctest = false
ai.workspace = true
anyhow.workspace = true
chrono.workspace = true
client.workspace = true
collections.workspace = true
editor.workspace = true
fs.workspace = true
futures.workspace = true
gpui.workspace = true
indoc.workspace = true
isahc.workspace = true
language.workspace = true
log.workspace = true
menu.workspace = true
multi_buffer.workspace = true
ordered-float.workspace = true
parking_lot.workspace = true
project.workspace = true
regex.workspace = true
schemars.workspace = true
@@ -36,7 +36,6 @@ serde.workspace = true
serde_json.workspace = true
settings.workspace = true
smol.workspace = true
telemetry_events.workspace = true
theme.workspace = true
tiktoken-rs.workspace = true
ui.workspace = true

View File

@@ -1,5 +1,5 @@
pub mod assistant_panel;
pub mod assistant_settings;
mod assistant_settings;
mod codegen;
mod prompts;
mod streaming_diff;

View File

@@ -7,16 +7,15 @@ use crate::{
SavedMessage, Split, ToggleFocus, ToggleIncludeConversation, ToggleRetrieveContext,
};
use ai::prompts::repository_context::PromptCodeSnippet;
use ai::providers::open_ai::OPEN_AI_API_URL;
use ai::{
auth::ProviderCredential,
completion::{CompletionProvider, CompletionRequest},
providers::open_ai::{
OpenAiCompletionProvider, OpenAiCompletionProviderKind, OpenAiRequest, RequestMessage,
OPEN_AI_API_URL,
},
providers::open_ai::{OpenAiCompletionProvider, OpenAiRequest, RequestMessage},
};
use anyhow::{anyhow, Result};
use chrono::{DateTime, Local};
use client::telemetry::AssistantKind;
use collections::{hash_map, HashMap, HashSet, VecDeque};
use editor::{
actions::{MoveDown, MoveUp},
@@ -31,9 +30,9 @@ use fs::Fs;
use futures::StreamExt;
use gpui::{
canvas, div, point, relative, rems, uniform_list, Action, AnyElement, AppContext,
AsyncAppContext, AsyncWindowContext, ClipboardItem, Context, EventEmitter, FocusHandle,
FocusableView, FontStyle, FontWeight, HighlightStyle, InteractiveElement, IntoElement, Model,
ModelContext, ParentElement, Pixels, PromptLevel, Render, SharedString,
AsyncAppContext, AsyncWindowContext, AvailableSpace, ClipboardItem, Context, EventEmitter,
FocusHandle, FocusableView, FontStyle, FontWeight, HighlightStyle, InteractiveElement,
IntoElement, Model, ModelContext, ParentElement, Pixels, PromptLevel, Render, SharedString,
StatefulInteractiveElement, Styled, Subscription, Task, TextStyle, UniformListScrollHandle,
View, ViewContext, VisualContext, WeakModel, WeakView, WhiteSpace, WindowContext,
};
@@ -53,7 +52,6 @@ use std::{
sync::Arc,
time::{Duration, Instant},
};
use telemetry_events::AssistantKind;
use theme::ThemeSettings;
use ui::{
prelude::*,
@@ -124,18 +122,18 @@ impl AssistantPanel {
.await
.log_err()
.unwrap_or_default();
let (provider_kind, api_url, model_name) = cx.update(|cx| {
let settings = AssistantSettings::get_global(cx);
anyhow::Ok((
settings.provider_kind()?,
settings.provider_api_url()?,
settings.provider_model_name()?,
))
})??;
let (api_url, model_name) = cx
.update(|cx| {
let settings = AssistantSettings::get_global(cx);
(
settings.openai_api_url.clone(),
settings.default_open_ai_model.full_name().to_string(),
)
})
.log_err()
.unwrap();
let completion_provider = OpenAiCompletionProvider::new(
api_url,
provider_kind,
model_name,
cx.background_executor().clone(),
)
@@ -367,7 +365,7 @@ impl AssistantPanel {
move |cx: &mut BlockContext| {
measurements.set(BlockMeasurements {
anchor_x: cx.anchor_x,
gutter_width: cx.gutter_dimensions.width,
gutter_width: cx.gutter_width,
});
inline_assistant.clone().into_any_element()
}
@@ -652,7 +650,7 @@ impl AssistantPanel {
// If Markdown or No Language is Known, increase the randomness for more creative output
// If Code, decrease temperature to get more deterministic outputs
let temperature = if let Some(language) = language_name.clone() {
if *language != *"Markdown" {
if language.to_string() != "Markdown".to_string() {
0.5
} else {
1.0
@@ -695,29 +693,24 @@ impl AssistantPanel {
Task::ready(Ok(Vec::new()))
};
let Some(mut model_name) = AssistantSettings::get_global(cx)
.provider_model_name()
.log_err()
else {
return;
};
let mut model = AssistantSettings::get_global(cx)
.default_open_ai_model
.clone();
let model_name = model.full_name();
let prompt = cx.background_executor().spawn({
let model_name = model_name.clone();
async move {
let snippets = snippets.await?;
let prompt = cx.background_executor().spawn(async move {
let snippets = snippets.await?;
let language_name = language_name.as_deref();
generate_content_prompt(
user_prompt,
language_name,
buffer,
range,
snippets,
&model_name,
project_name,
)
}
let language_name = language_name.as_deref();
generate_content_prompt(
user_prompt,
language_name,
buffer,
range,
snippets,
model_name,
project_name,
)
});
let mut messages = Vec::new();
@@ -729,7 +722,7 @@ impl AssistantPanel {
.messages(cx)
.map(|message| message.to_open_ai_message(buffer)),
);
model_name = conversation.model.full_name().to_string();
model = conversation.model.clone();
}
cx.spawn(|_, mut cx| async move {
@@ -742,7 +735,7 @@ impl AssistantPanel {
});
let request = Box::new(OpenAiRequest {
model: model_name,
model: model.full_name().into(),
messages,
stream: true,
stop: vec!["|END|>".to_string()],
@@ -781,7 +774,7 @@ impl AssistantPanel {
} else {
editor.highlight_background::<PendingInlineAssist>(
background_ranges,
|theme| theme.editor_active_line_background, // todo("use the appropriate color")
|theme| theme.editor_active_line_background, // todo!("use the appropriate color")
cx,
);
}
@@ -979,7 +972,7 @@ impl AssistantPanel {
font_size: rems(0.875).into(),
font_weight: FontWeight::NORMAL,
font_style: FontStyle::Normal,
line_height: relative(1.3),
line_height: relative(1.3).into(),
background_color: None,
underline: None,
strikethrough: None,
@@ -1284,25 +1277,25 @@ impl Render for AssistantPanel {
let view = cx.view().clone();
let scroll_handle = self.saved_conversations_scroll_handle.clone();
let conversation_count = self.saved_conversations.len();
canvas(
move |bounds, cx| {
let mut list = uniform_list(
view,
"saved_conversations",
conversation_count,
|this, range, cx| {
range
.map(|ix| this.render_saved_conversation(ix, cx))
.collect()
},
)
.track_scroll(scroll_handle)
.into_any_element();
list.layout(bounds.origin, bounds.size.into(), cx);
list
},
|_bounds, mut list, cx| list.paint(cx),
)
canvas(move |bounds, cx| {
uniform_list(
view,
"saved_conversations",
conversation_count,
|this, range, cx| {
range
.map(|ix| this.render_saved_conversation(ix, cx))
.collect()
},
)
.track_scroll(scroll_handle)
.into_any_element()
.draw(
bounds.origin,
bounds.size.map(AvailableSpace::Definite),
cx,
);
})
.size_full()
.into_any_element()
}),
@@ -1461,14 +1454,8 @@ impl Conversation {
});
let settings = AssistantSettings::get_global(cx);
let model = settings
.provider_model()
.log_err()
.unwrap_or(OpenAiModel::FourTurbo);
let api_url = settings
.provider_api_url()
.log_err()
.unwrap_or_else(|| OPEN_AI_API_URL.to_string());
let model = settings.default_open_ai_model.clone();
let api_url = settings.openai_api_url.clone();
let mut this = Self {
id: Some(Uuid::new_v4().to_string()),
@@ -1483,7 +1470,7 @@ impl Conversation {
max_token_count: tiktoken_rs::model::get_context_size(&model.full_name()),
pending_token_count: Task::ready(None),
api_url: Some(api_url),
model,
model: model.clone(),
_subscriptions: vec![cx.subscribe(&buffer, Self::handle_buffer_event)],
pending_save: Task::ready(Ok(())),
path: None,
@@ -1527,7 +1514,7 @@ impl Conversation {
.as_ref()
.map(|summary| summary.text.clone())
.unwrap_or_default(),
model: self.model,
model: self.model.clone(),
api_url: self.api_url.clone(),
}
}
@@ -1549,7 +1536,6 @@ impl Conversation {
api_url
.clone()
.unwrap_or_else(|| OPEN_AI_API_URL.to_string()),
OpenAiCompletionProviderKind::OpenAi,
model.full_name().into(),
cx.background_executor().clone(),
)
@@ -1633,23 +1619,26 @@ impl Conversation {
fn count_remaining_tokens(&mut self, cx: &mut ModelContext<Self>) {
let messages = self
.messages(cx)
.map(|message| tiktoken_rs::ChatCompletionRequestMessage {
role: match message.role {
Role::User => "user".into(),
Role::Assistant => "assistant".into(),
Role::System => "system".into(),
},
content: Some(
self.buffer
.read(cx)
.text_for_range(message.offset_range)
.collect(),
),
name: None,
function_call: None,
.into_iter()
.filter_map(|message| {
Some(tiktoken_rs::ChatCompletionRequestMessage {
role: match message.role {
Role::User => "user".into(),
Role::Assistant => "assistant".into(),
Role::System => "system".into(),
},
content: Some(
self.buffer
.read(cx)
.text_for_range(message.offset_range)
.collect(),
),
name: None,
function_call: None,
})
})
.collect::<Vec<_>>();
let model = self.model;
let model = self.model.clone();
self.pending_token_count = cx.spawn(|this, mut cx| {
async move {
cx.background_executor()
@@ -2413,9 +2402,7 @@ impl ConversationEditor {
.read(cx)
.messages(cx)
.map(|message| BlockProperties {
position: buffer
.anchor_in_excerpt(excerpt_id, message.anchor)
.unwrap(),
position: buffer.anchor_in_excerpt(excerpt_id, message.anchor),
height: 2,
style: BlockStyle::Sticky,
render: Arc::new({
@@ -2834,7 +2821,6 @@ impl FocusableView for InlineAssistant {
}
impl InlineAssistant {
#[allow(clippy::too_many_arguments)]
fn new(
id: usize,
measurements: Rc<Cell<BlockMeasurements>>,
@@ -3200,7 +3186,7 @@ impl InlineAssistant {
font_size: rems(0.875).into(),
font_weight: FontWeight::NORMAL,
font_style: FontStyle::Normal,
line_height: relative(1.3),
line_height: relative(1.3).into(),
background_color: None,
underline: None,
strikethrough: None,
@@ -3668,9 +3654,9 @@ fn report_assistant_event(
let client = workspace.read(cx).project().read(cx).client();
let telemetry = client.telemetry();
let Ok(model_name) = AssistantSettings::get_global(cx).provider_model_name() else {
return;
};
let model = AssistantSettings::get_global(cx)
.default_open_ai_model
.clone();
telemetry.report_assistant_event(conversation_id, assistant_kind, &model_name)
telemetry.report_assistant_event(conversation_id, assistant_kind, model.full_name())
}

View File

@@ -1,14 +1,10 @@
use ai::providers::open_ai::{
AzureOpenAiApiVersion, OpenAiCompletionProviderKind, OPEN_AI_API_URL,
};
use anyhow::anyhow;
use anyhow;
use gpui::Pixels;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::Settings;
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
#[serde(rename_all = "snake_case")]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
pub enum OpenAiModel {
#[serde(rename = "gpt-3.5-turbo-0613")]
ThreePointFiveTurbo,
@@ -21,25 +17,25 @@ pub enum OpenAiModel {
impl OpenAiModel {
pub fn full_name(&self) -> &'static str {
match self {
Self::ThreePointFiveTurbo => "gpt-3.5-turbo-0613",
Self::Four => "gpt-4-0613",
Self::FourTurbo => "gpt-4-1106-preview",
OpenAiModel::ThreePointFiveTurbo => "gpt-3.5-turbo-0613",
OpenAiModel::Four => "gpt-4-0613",
OpenAiModel::FourTurbo => "gpt-4-1106-preview",
}
}
pub fn short_name(&self) -> &'static str {
match self {
Self::ThreePointFiveTurbo => "gpt-3.5-turbo",
Self::Four => "gpt-4",
Self::FourTurbo => "gpt-4-turbo",
OpenAiModel::ThreePointFiveTurbo => "gpt-3.5-turbo",
OpenAiModel::Four => "gpt-4",
OpenAiModel::FourTurbo => "gpt-4-turbo",
}
}
pub fn cycle(&self) -> Self {
match self {
Self::ThreePointFiveTurbo => Self::Four,
Self::Four => Self::FourTurbo,
Self::FourTurbo => Self::ThreePointFiveTurbo,
OpenAiModel::ThreePointFiveTurbo => OpenAiModel::Four,
OpenAiModel::Four => OpenAiModel::FourTurbo,
OpenAiModel::FourTurbo => OpenAiModel::ThreePointFiveTurbo,
}
}
}
@@ -52,113 +48,14 @@ pub enum AssistantDockPosition {
Bottom,
}
#[derive(Debug, Deserialize)]
#[derive(Deserialize, Debug)]
pub struct AssistantSettings {
/// Whether to show the assistant panel button in the status bar.
pub button: bool,
/// Where to dock the assistant.
pub dock: AssistantDockPosition,
/// Default width in pixels when the assistant is docked to the left or right.
pub default_width: Pixels,
/// Default height in pixels when the assistant is docked to the bottom.
pub default_height: Pixels,
/// The default OpenAI model to use when starting new conversations.
#[deprecated = "Please use `provider.default_model` instead."]
pub default_open_ai_model: OpenAiModel,
/// OpenAI API base URL to use when starting new conversations.
#[deprecated = "Please use `provider.api_url` instead."]
pub openai_api_url: String,
/// The settings for the AI provider.
pub provider: AiProviderSettings,
}
impl AssistantSettings {
pub fn provider_kind(&self) -> anyhow::Result<OpenAiCompletionProviderKind> {
match &self.provider {
AiProviderSettings::OpenAi(_) => Ok(OpenAiCompletionProviderKind::OpenAi),
AiProviderSettings::AzureOpenAi(settings) => {
let deployment_id = settings
.deployment_id
.clone()
.ok_or_else(|| anyhow!("no Azure OpenAI deployment ID"))?;
let api_version = settings
.api_version
.ok_or_else(|| anyhow!("no Azure OpenAI API version"))?;
Ok(OpenAiCompletionProviderKind::AzureOpenAi {
deployment_id,
api_version,
})
}
}
}
pub fn provider_api_url(&self) -> anyhow::Result<String> {
match &self.provider {
AiProviderSettings::OpenAi(settings) => Ok(settings
.api_url
.clone()
.unwrap_or_else(|| OPEN_AI_API_URL.to_string())),
AiProviderSettings::AzureOpenAi(settings) => settings
.api_url
.clone()
.ok_or_else(|| anyhow!("no Azure OpenAI API URL")),
}
}
pub fn provider_model(&self) -> anyhow::Result<OpenAiModel> {
match &self.provider {
AiProviderSettings::OpenAi(settings) => {
Ok(settings.default_model.unwrap_or(OpenAiModel::FourTurbo))
}
AiProviderSettings::AzureOpenAi(settings) => {
let deployment_id = settings
.deployment_id
.as_deref()
.ok_or_else(|| anyhow!("no Azure OpenAI deployment ID"))?;
match deployment_id {
// https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models#gpt-4-and-gpt-4-turbo-preview
"gpt-4" | "gpt-4-32k" => Ok(OpenAiModel::Four),
// https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models#gpt-35
"gpt-35-turbo" | "gpt-35-turbo-16k" | "gpt-35-turbo-instruct" => {
Ok(OpenAiModel::ThreePointFiveTurbo)
}
_ => Err(anyhow!(
"no matching OpenAI model found for deployment ID: '{deployment_id}'"
)),
}
}
}
}
pub fn provider_model_name(&self) -> anyhow::Result<String> {
match &self.provider {
AiProviderSettings::OpenAi(settings) => Ok(settings
.default_model
.unwrap_or(OpenAiModel::FourTurbo)
.full_name()
.to_string()),
AiProviderSettings::AzureOpenAi(settings) => settings
.deployment_id
.clone()
.ok_or_else(|| anyhow!("no Azure OpenAI deployment ID")),
}
}
}
impl Settings for AssistantSettings {
const KEY: Option<&'static str> = Some("assistant");
type FileContent = AssistantSettingsContent;
fn load(
default_value: &Self::FileContent,
user_values: &[&Self::FileContent],
_: &mut gpui::AppContext,
) -> anyhow::Result<Self> {
Self::load_via_json_merge(default_value, user_values)
}
}
/// Assistant panel settings
@@ -180,88 +77,26 @@ pub struct AssistantSettingsContent {
///
/// Default: 320
pub default_height: Option<f32>,
/// Deprecated: Please use `provider.default_model` instead.
/// The default OpenAI model to use when starting new conversations.
///
/// Default: gpt-4-1106-preview
#[deprecated = "Please use `provider.default_model` instead."]
pub default_open_ai_model: Option<OpenAiModel>,
/// Deprecated: Please use `provider.api_url` instead.
/// OpenAI API base URL to use when starting new conversations.
///
/// Default: https://api.openai.com/v1
#[deprecated = "Please use `provider.api_url` instead."]
pub openai_api_url: Option<String>,
/// The settings for the AI provider.
#[serde(default)]
pub provider: AiProviderSettingsContent,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum AiProviderSettings {
/// The settings for the OpenAI provider.
#[serde(rename = "openai")]
OpenAi(OpenAiProviderSettings),
/// The settings for the Azure OpenAI provider.
#[serde(rename = "azure_openai")]
AzureOpenAi(AzureOpenAiProviderSettings),
}
impl Settings for AssistantSettings {
const KEY: Option<&'static str> = Some("assistant");
/// The settings for the AI provider used by the Zed Assistant.
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum AiProviderSettingsContent {
/// The settings for the OpenAI provider.
#[serde(rename = "openai")]
OpenAi(OpenAiProviderSettingsContent),
/// The settings for the Azure OpenAI provider.
#[serde(rename = "azure_openai")]
AzureOpenAi(AzureOpenAiProviderSettingsContent),
}
type FileContent = AssistantSettingsContent;
impl Default for AiProviderSettingsContent {
fn default() -> Self {
Self::OpenAi(OpenAiProviderSettingsContent::default())
fn load(
default_value: &Self::FileContent,
user_values: &[&Self::FileContent],
_: &mut gpui::AppContext,
) -> anyhow::Result<Self> {
Self::load_via_json_merge(default_value, user_values)
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct OpenAiProviderSettings {
/// The OpenAI API base URL to use when starting new conversations.
pub api_url: Option<String>,
/// The default OpenAI model to use when starting new conversations.
pub default_model: Option<OpenAiModel>,
}
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema)]
pub struct OpenAiProviderSettingsContent {
/// The OpenAI API base URL to use when starting new conversations.
///
/// Default: https://api.openai.com/v1
pub api_url: Option<String>,
/// The default OpenAI model to use when starting new conversations.
///
/// Default: gpt-4-1106-preview
pub default_model: Option<OpenAiModel>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct AzureOpenAiProviderSettings {
/// The Azure OpenAI API base URL to use when starting new conversations.
pub api_url: Option<String>,
/// The Azure OpenAI API version.
pub api_version: Option<AzureOpenAiApiVersion>,
/// The Azure OpenAI API deployment ID.
pub deployment_id: Option<String>,
}
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema)]
pub struct AzureOpenAiProviderSettingsContent {
/// The Azure OpenAI API base URL to use when starting new conversations.
pub api_url: Option<String>,
/// The Azure OpenAI API version.
pub api_version: Option<AzureOpenAiApiVersion>,
/// The Azure OpenAI deployment ID.
pub deployment_id: Option<String>,
}

View File

@@ -297,7 +297,7 @@ fn strip_invalid_spans_from_codeblock(
} else if buffer.starts_with("<|")
|| buffer.starts_with("<|S")
|| buffer.starts_with("<|S|")
|| buffer.ends_with('|')
|| buffer.ends_with("|")
|| buffer.ends_with("|E")
|| buffer.ends_with("|E|")
{
@@ -335,7 +335,7 @@ fn strip_invalid_spans_from_codeblock(
.strip_suffix("|E|>")
.or_else(|| text.strip_suffix("E|>"))
.or_else(|| text.strip_prefix("|>"))
.or_else(|| text.strip_prefix('>'))
.or_else(|| text.strip_prefix(">"))
.unwrap_or(&text)
.to_string();
};

View File

@@ -5,9 +5,6 @@ edition = "2021"
publish = false
license = "GPL-3.0-or-later"
[lints]
workspace = true
[lib]
path = "src/audio.rs"
doctest = false
@@ -16,7 +13,9 @@ doctest = false
anyhow.workspace = true
collections.workspace = true
derive_more.workspace = true
futures.workspace = true
gpui.workspace = true
log.workspace = true
parking_lot.workspace = true
rodio = { version = "0.17.1", default-features = false, features = ["wav"] }
util.workspace = true

View File

@@ -5,9 +5,6 @@ edition = "2021"
publish = false
license = "GPL-3.0-or-later"
[lints]
workspace = true
[lib]
path = "src/auto_update.rs"
doctest = false
@@ -16,12 +13,12 @@ doctest = false
anyhow.workspace = true
client.workspace = true
db.workspace = true
editor.workspace = true
gpui.workspace = true
isahc.workspace = true
lazy_static.workspace = true
log.workspace = true
markdown_preview.workspace = true
menu.workspace = true
project.workspace = true
release_channel.workspace = true
schemars.workspace = true
serde.workspace = true
@@ -30,5 +27,6 @@ serde_json.workspace = true
settings.workspace = true
smol.workspace = true
tempfile.workspace = true
theme.workspace = true
util.workspace = true
workspace.workspace = true

View File

@@ -4,14 +4,12 @@ use anyhow::{anyhow, Context, Result};
use client::{Client, TelemetrySettings, ZED_APP_PATH};
use db::kvp::KEY_VALUE_STORE;
use db::RELEASE_CHANNEL;
use editor::{Editor, MultiBuffer};
use gpui::{
actions, AppContext, AsyncAppContext, Context as _, Global, Model, ModelContext,
SemanticVersion, SharedString, Task, View, ViewContext, VisualContext, WindowContext,
SemanticVersion, Task, ViewContext, VisualContext, WindowContext,
};
use isahc::AsyncBody;
use markdown_preview::markdown_preview_view::MarkdownPreviewView;
use schemars::JsonSchema;
use serde::Deserialize;
use serde_derive::Serialize;
@@ -20,7 +18,7 @@ use smol::io::AsyncReadExt;
use settings::{Settings, SettingsStore};
use smol::{fs::File, process::Command};
use release_channel::{AppCommitSha, AppVersion, ReleaseChannel};
use release_channel::{AppCommitSha, ReleaseChannel};
use std::{
env::consts::{ARCH, OS},
ffi::OsString,
@@ -28,24 +26,13 @@ use std::{
time::Duration,
};
use update_notification::UpdateNotification;
use util::{
http::{HttpClient, HttpClientWithUrl},
ResultExt,
};
use util::http::{HttpClient, ZedHttpClient};
use workspace::Workspace;
const SHOULD_SHOW_UPDATE_NOTIFICATION_KEY: &str = "auto-updater-should-show-updated-notification";
const POLL_INTERVAL: Duration = Duration::from_secs(60 * 60);
actions!(
auto_update,
[
Check,
DismissErrorMessage,
ViewReleaseNotes,
ViewReleaseNotesLocally
]
);
actions!(auto_update, [Check, DismissErrorMessage, ViewReleaseNotes]);
#[derive(Serialize)]
struct UpdateRequestBody {
@@ -67,7 +54,7 @@ pub enum AutoUpdateStatus {
pub struct AutoUpdater {
status: AutoUpdateStatus,
current_version: SemanticVersion,
http_client: Arc<HttpClientWithUrl>,
http_client: Arc<ZedHttpClient>,
pending_poll: Option<Task<Option<()>>>,
}
@@ -109,13 +96,7 @@ struct GlobalAutoUpdate(Option<Model<AutoUpdater>>);
impl Global for GlobalAutoUpdate {}
#[derive(Deserialize)]
struct ReleaseNotesBody {
title: String,
release_notes: String,
}
pub fn init(http_client: Arc<HttpClientWithUrl>, cx: &mut AppContext) {
pub fn init(http_client: Arc<ZedHttpClient>, cx: &mut AppContext) {
AutoUpdateSetting::register(cx);
cx.observe_new_views(|workspace: &mut Workspace, _cx| {
@@ -124,10 +105,6 @@ pub fn init(http_client: Arc<HttpClientWithUrl>, cx: &mut AppContext) {
workspace.register_action(|_, action, cx| {
view_release_notes(action, cx);
});
workspace.register_action(|workspace, _: &ViewReleaseNotesLocally, cx| {
view_release_notes_locally(workspace, cx);
});
})
.detach();
@@ -181,80 +158,13 @@ pub fn view_release_notes(_: &ViewReleaseNotes, cx: &mut AppContext) -> Option<(
let current_version = auto_updater.current_version;
let url = &auto_updater
.http_client
.build_url(&format!("/releases/{release_channel}/{current_version}"));
.zed_url(&format!("/releases/{release_channel}/{current_version}"));
cx.open_url(&url);
}
None
}
fn view_release_notes_locally(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
let release_channel = ReleaseChannel::global(cx);
let version = AppVersion::global(cx).to_string();
let client = client::Client::global(cx).http_client();
let url = client.build_url(&format!(
"/api/release_notes/{}/{}",
release_channel.dev_name(),
version
));
let markdown = workspace
.app_state()
.languages
.language_for_name("Markdown");
workspace
.with_local_workspace(cx, move |_, cx| {
cx.spawn(|workspace, mut cx| async move {
let markdown = markdown.await.log_err();
let response = client.get(&url, Default::default(), true).await;
let Some(mut response) = response.log_err() else {
return;
};
let mut body = Vec::new();
response.body_mut().read_to_end(&mut body).await.ok();
let body: serde_json::Result<ReleaseNotesBody> =
serde_json::from_slice(body.as_slice());
if let Ok(body) = body {
workspace
.update(&mut cx, |workspace, cx| {
let project = workspace.project().clone();
let buffer = project
.update(cx, |project, cx| project.create_buffer("", markdown, cx))
.expect("creating buffers on a local workspace always succeeds");
buffer.update(cx, |buffer, cx| {
buffer.edit([(0..0, body.release_notes)], None, cx)
});
let language_registry = project.read(cx).languages().clone();
let buffer = cx.new_model(|cx| MultiBuffer::singleton(buffer, cx));
let tab_description = SharedString::from(body.title.to_string());
let editor = cx
.new_view(|cx| Editor::for_multibuffer(buffer, Some(project), cx));
let workspace_handle = workspace.weak_handle();
let view: View<MarkdownPreviewView> = MarkdownPreviewView::new(
editor,
workspace_handle,
Some(tab_description),
language_registry,
cx,
);
workspace.add_item_to_active_pane(Box::new(view.clone()), cx);
cx.notify();
})
.log_err();
}
})
.detach();
})
.detach();
}
pub fn notify_of_any_new_update(cx: &mut ViewContext<Workspace>) -> Option<()> {
let updater = AutoUpdater::get(cx)?;
let version = updater.read(cx).current_version;
@@ -285,7 +195,7 @@ impl AutoUpdater {
cx.default_global::<GlobalAutoUpdate>().0.clone()
}
fn new(current_version: SemanticVersion, http_client: Arc<HttpClientWithUrl>) -> Self {
fn new(current_version: SemanticVersion, http_client: Arc<ZedHttpClient>) -> Self {
Self {
status: AutoUpdateStatus::Idle,
current_version,
@@ -339,13 +249,14 @@ impl AutoUpdater {
(this.http_client.clone(), this.current_version)
})?;
let mut url_string = client.build_url(&format!(
let mut url_string = client.zed_url(&format!(
"/api/releases/latest?asset=Zed.dmg&os={}&arch={}",
OS, ARCH
));
cx.update(|cx| {
if let Some(param) = ReleaseChannel::try_global(cx)
.and_then(|release_channel| release_channel.release_query_param())
.map(|release_channel| release_channel.release_query_param())
.flatten()
{
url_string += "&";
url_string += param;

View File

@@ -44,7 +44,7 @@ impl Render for UpdateNotification {
crate::view_release_notes(&Default::default(), cx);
this.dismiss(&menu::Cancel, cx)
})),
)
);
}
}

View File

@@ -5,18 +5,20 @@ edition = "2021"
publish = false
license = "GPL-3.0-or-later"
[lints]
workspace = true
[lib]
path = "src/breadcrumbs.rs"
doctest = false
[dependencies]
collections.workspace = true
editor.workspace = true
gpui.workspace = true
itertools.workspace = true
itertools = "0.10"
language.workspace = true
outline.workspace = true
project.workspace = true
search.workspace = true
settings.workspace = true
theme.workspace = true
ui.workspace = true
workspace.workspace = true

View File

@@ -4,11 +4,10 @@ use gpui::{
ViewContext,
};
use itertools::Itertools;
use std::cmp;
use theme::ActiveTheme;
use ui::{prelude::*, ButtonLike, ButtonStyle, Label, Tooltip};
use workspace::{
item::{BreadcrumbText, ItemEvent, ItemHandle},
item::{ItemEvent, ItemHandle},
ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView,
};
@@ -32,30 +31,14 @@ impl EventEmitter<ToolbarItemEvent> for Breadcrumbs {}
impl Render for Breadcrumbs {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
const MAX_SEGMENTS: usize = 12;
let element = h_flex().text_ui();
let Some(active_item) = self.active_item.as_ref() else {
return element;
};
let Some(mut segments) = active_item.breadcrumbs(cx.theme(), cx) else {
let Some(segments) = active_item.breadcrumbs(cx.theme(), cx) else {
return element;
};
let prefix_end_ix = cmp::min(segments.len(), MAX_SEGMENTS / 2);
let suffix_start_ix = cmp::max(
prefix_end_ix,
segments.len().saturating_sub(MAX_SEGMENTS / 2),
);
if suffix_start_ix > prefix_end_ix {
segments.splice(
prefix_end_ix..suffix_start_ix,
Some(BreadcrumbText {
text: "".into(),
highlights: None,
}),
);
}
let highlighted_segments = segments.into_iter().map(|segment| {
let mut text_style = cx.text_style();
text_style.color = Color::Muted.color(cx);

View File

@@ -5,9 +5,6 @@ edition = "2021"
publish = false
license = "GPL-3.0-or-later"
[lints]
workspace = true
[lib]
path = "src/call.rs"
doctest = false
@@ -24,21 +21,26 @@ test-support = [
[dependencies]
anyhow.workspace = true
async-broadcast = "0.4"
audio.workspace = true
client.workspace = true
collections.workspace = true
fs.workspace = true
futures.workspace = true
gpui.workspace = true
image = "0.23"
language.workspace = true
live_kit_client.workspace = true
log.workspace = true
media.workspace = true
postage.workspace = true
project.workspace = true
schemars.workspace = true
serde.workspace = true
serde_derive.workspace = true
serde_json.workspace = true
settings.workspace = true
smallvec.workspace = true
util.workspace = true
[dev-dependencies]

View File

@@ -5,7 +5,7 @@ pub mod room;
use anyhow::{anyhow, Result};
use audio::Audio;
use call_settings::CallSettings;
use client::{proto, ChannelId, Client, TypedEnvelope, User, UserStore, ZED_ALWAYS_ACTIVE};
use client::{proto, Client, TypedEnvelope, User, UserStore, ZED_ALWAYS_ACTIVE};
use collections::HashSet;
use futures::{channel::oneshot, future::Shared, Future, FutureExt};
use gpui::{
@@ -84,6 +84,7 @@ pub struct ActiveCall {
),
client: Arc<Client>,
user_store: Model<UserStore>,
pending_channel_id: Option<u64>,
_subscriptions: Vec<client::Subscription>,
}
@@ -97,6 +98,7 @@ impl ActiveCall {
location: None,
pending_invites: Default::default(),
incoming_call: watch::channel(),
pending_channel_id: None,
_join_debouncer: OneAtATime { cancel: None },
_subscriptions: vec![
client.add_request_handler(cx.weak_model(), Self::handle_incoming_call),
@@ -107,10 +109,14 @@ impl ActiveCall {
}
}
pub fn channel_id(&self, cx: &AppContext) -> Option<ChannelId> {
pub fn channel_id(&self, cx: &AppContext) -> Option<u64> {
self.room()?.read(cx).channel_id()
}
pub fn pending_channel_id(&self) -> Option<u64> {
self.pending_channel_id
}
async fn handle_incoming_call(
this: Model<Self>,
envelope: TypedEnvelope<proto::IncomingCall>,
@@ -302,7 +308,7 @@ impl ActiveCall {
return Task::ready(Ok(()));
}
let room_id = call.room_id;
let room_id = call.room_id.clone();
let client = self.client.clone();
let user_store = self.user_store.clone();
let join = self
@@ -336,14 +342,16 @@ impl ActiveCall {
pub fn join_channel(
&mut self,
channel_id: ChannelId,
channel_id: u64,
cx: &mut ModelContext<Self>,
) -> Task<Result<Option<Model<Room>>>> {
let mut leave = None;
if let Some(room) = self.room().cloned() {
if room.read(cx).channel_id() == Some(channel_id) {
return Task::ready(Ok(Some(room)));
} else {
room.update(cx, |room, cx| room.clear_state(cx));
let (room, _) = self.room.take().unwrap();
leave = room.update(cx, |room, cx| Some(room.leave(cx)));
}
}
@@ -353,14 +361,21 @@ impl ActiveCall {
let client = self.client.clone();
let user_store = self.user_store.clone();
self.pending_channel_id = Some(channel_id);
let join = self._join_debouncer.spawn(cx, move |cx| async move {
if let Some(task) = leave {
task.await?
}
Room::join_channel(channel_id, client, user_store, cx).await
});
cx.spawn(|this, mut cx| async move {
let room = join.await?;
this.update(&mut cx, |this, cx| this.set_room(room.clone(), cx))?
.await?;
this.update(&mut cx, |this, cx| {
this.pending_channel_id.take();
this.set_room(room.clone(), cx)
})?
.await?;
this.update(&mut cx, |this, cx| {
this.report_call_event("join channel", cx)
})?;
@@ -487,7 +502,7 @@ impl ActiveCall {
pub fn report_call_event_for_room(
operation: &'static str,
room_id: u64,
channel_id: Option<ChannelId>,
channel_id: Option<u64>,
client: &Arc<Client>,
) {
let telemetry = client.telemetry();
@@ -497,7 +512,7 @@ pub fn report_call_event_for_room(
pub fn report_call_event_for_channel(
operation: &'static str,
channel_id: ChannelId,
channel_id: u64,
client: &Arc<Client>,
cx: &AppContext,
) {

View File

@@ -7,7 +7,6 @@ use settings::Settings;
#[derive(Deserialize, Debug)]
pub struct CallSettings {
pub mute_on_join: bool,
pub share_on_join: bool,
}
/// Configuration of voice calls in Zed.
@@ -17,11 +16,6 @@ pub struct CallSettingsContent {
///
/// Default: false
pub mute_on_join: Option<bool>,
/// Whether your current project should be shared when joining an empty channel.
///
/// Default: true
pub share_on_join: Option<bool>,
}
impl Settings for CallSettings {

View File

@@ -49,6 +49,7 @@ pub struct RemoteParticipant {
pub participant_index: ParticipantIndex,
pub muted: bool,
pub speaking: bool,
pub in_call: bool,
pub video_tracks: HashMap<live_kit_client::Sid, Arc<RemoteVideoTrack>>,
pub audio_tracks: HashMap<live_kit_client::Sid, Arc<RemoteAudioTrack>>,
}

View File

@@ -6,7 +6,7 @@ use anyhow::{anyhow, Result};
use audio::{Audio, Sound};
use client::{
proto::{self, PeerId},
ChannelId, Client, ParticipantIndex, TypedEnvelope, User, UserStore,
Client, ParticipantIndex, TypedEnvelope, User, UserStore,
};
use collections::{BTreeMap, HashMap, HashSet};
use fs::Fs;
@@ -27,7 +27,7 @@ pub const RECONNECT_TIMEOUT: Duration = Duration::from_secs(30);
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Event {
RoomJoined {
channel_id: Option<ChannelId>,
channel_id: Option<u64>,
},
ParticipantLocationChanged {
participant_id: proto::PeerId,
@@ -53,14 +53,15 @@ pub enum Event {
project_id: u64,
},
Left {
channel_id: Option<ChannelId>,
channel_id: Option<u64>,
},
}
pub struct Room {
id: u64,
channel_id: Option<ChannelId>,
channel_id: Option<u64>,
live_kit: Option<LiveKitRoom>,
live_kit_connection_info: Option<proto::LiveKitConnectionInfo>,
status: RoomStatus,
shared_projects: HashSet<WeakModel<Project>>,
joined_projects: HashSet<WeakModel<Project>>,
@@ -84,7 +85,7 @@ pub struct Room {
impl EventEmitter<Event> for Room {}
impl Room {
pub fn channel_id(&self) -> Option<ChannelId> {
pub fn channel_id(&self) -> Option<u64> {
self.channel_id
}
@@ -106,97 +107,24 @@ impl Room {
fn new(
id: u64,
channel_id: Option<ChannelId>,
channel_id: Option<u64>,
live_kit_connection_info: Option<proto::LiveKitConnectionInfo>,
client: Arc<Client>,
user_store: Model<UserStore>,
cx: &mut ModelContext<Self>,
) -> Self {
let live_kit_room = if let Some(connection_info) = live_kit_connection_info {
let room = live_kit_client::Room::new();
let mut status = room.status();
// Consume the initial status of the room.
let _ = status.try_recv();
let _maintain_room = cx.spawn(|this, mut cx| async move {
while let Some(status) = status.next().await {
let this = if let Some(this) = this.upgrade() {
this
} else {
break;
};
if status == live_kit_client::ConnectionState::Disconnected {
this.update(&mut cx, |this, cx| this.leave(cx).log_err())
.ok();
break;
}
}
});
let _handle_updates = cx.spawn({
let room = room.clone();
move |this, mut cx| async move {
let mut updates = room.updates();
while let Some(update) = updates.next().await {
let this = if let Some(this) = this.upgrade() {
this
} else {
break;
};
this.update(&mut cx, |this, cx| {
this.live_kit_room_updated(update, cx).log_err()
})
.ok();
}
}
});
let connect = room.connect(&connection_info.server_url, &connection_info.token);
cx.spawn(|this, mut cx| async move {
connect.await?;
this.update(&mut cx, |this, cx| {
if this.can_use_microphone() {
if let Some(live_kit) = &this.live_kit {
if !live_kit.muted_by_user && !live_kit.deafened {
return this.share_microphone(cx);
}
}
}
Task::ready(Ok(()))
})?
.await
})
.detach_and_log_err(cx);
Some(LiveKitRoom {
room,
screen_track: LocalTrack::None,
microphone_track: LocalTrack::None,
next_publish_id: 0,
muted_by_user: Self::mute_on_join(cx),
deafened: false,
speaking: false,
_maintain_room,
_handle_updates,
})
} else {
None
};
let maintain_connection = cx.spawn({
let client = client.clone();
move |this, cx| Self::maintain_connection(this, client.clone(), cx).log_err()
});
Audio::play_sound(Sound::Joined, cx);
let (room_update_completed_tx, room_update_completed_rx) = watch::channel();
Self {
let mut this = Self {
id,
channel_id,
live_kit: live_kit_room,
live_kit: None,
live_kit_connection_info,
status: RoomStatus::Online,
shared_projects: Default::default(),
joined_projects: Default::default(),
@@ -220,7 +148,11 @@ impl Room {
maintain_connection: Some(maintain_connection),
room_update_completed_tx,
room_update_completed_rx,
};
if this.live_kit_connection_info.is_some() {
this.join_call(cx).detach_and_log_err(cx);
}
this
}
pub(crate) fn create(
@@ -273,17 +205,13 @@ impl Room {
}
pub(crate) async fn join_channel(
channel_id: ChannelId,
channel_id: u64,
client: Arc<Client>,
user_store: Model<UserStore>,
cx: AsyncAppContext,
) -> Result<Model<Self>> {
Self::from_join_response(
client
.request(proto::JoinChannel {
channel_id: channel_id.0,
})
.await?,
client.request(proto::JoinChannel2 { channel_id }).await?,
client,
user_store,
cx,
@@ -328,7 +256,7 @@ impl Room {
}
pub fn mute_on_join(cx: &AppContext) -> bool {
CallSettings::get_global(cx).mute_on_join || client::IMPERSONATE_LOGIN.is_some()
CallSettings::get_global(cx).mute_on_join
}
fn from_join_response(
@@ -341,7 +269,7 @@ impl Room {
let room = cx.new_model(|cx| {
Self::new(
room_proto.id,
response.channel_id.map(ChannelId),
response.channel_id,
response.live_kit_connection_info,
client,
user_store,
@@ -378,7 +306,9 @@ impl Room {
}
log::info!("leaving room");
Audio::play_sound(Sound::Leave, cx);
if self.live_kit.is_some() {
Audio::play_sound(Sound::Leave, cx);
}
self.clear_state(cx);
@@ -597,6 +527,24 @@ impl Room {
&self.remote_participants
}
pub fn call_participants(&self, cx: &AppContext) -> Vec<Arc<User>> {
self.remote_participants()
.values()
.filter_map(|participant| {
if participant.in_call {
Some(participant.user.clone())
} else {
None
}
})
.chain(if self.in_call() {
self.user_store.read(cx).current_user()
} else {
None
})
.collect()
}
pub fn remote_participant_for_peer_id(&self, peer_id: PeerId) -> Option<&RemoteParticipant> {
self.remote_participants
.values()
@@ -621,10 +569,6 @@ impl Room {
self.local_participant.role == proto::ChannelRole::Admin
}
pub fn local_participant_is_guest(&self) -> bool {
self.local_participant.role == proto::ChannelRole::Guest
}
pub fn set_participant_role(
&mut self,
user_id: u64,
@@ -832,6 +776,7 @@ impl Room {
}
let role = participant.role();
let in_call = participant.in_call;
let location = ParticipantLocation::from_proto(participant.location)
.unwrap_or(ParticipantLocation::External);
if let Some(remote_participant) =
@@ -842,9 +787,15 @@ impl Room {
remote_participant.participant_index = participant_index;
if location != remote_participant.location
|| role != remote_participant.role
|| in_call != remote_participant.in_call
{
if in_call && !remote_participant.in_call {
Audio::play_sound(Sound::Joined, cx);
}
remote_participant.location = location;
remote_participant.role = role;
remote_participant.in_call = participant.in_call;
cx.emit(Event::ParticipantLocationChanged {
participant_id: peer_id,
});
@@ -861,12 +812,15 @@ impl Room {
role,
muted: true,
speaking: false,
in_call: participant.in_call,
video_tracks: Default::default(),
audio_tracks: Default::default(),
},
);
Audio::play_sound(Sound::Joined, cx);
if participant.in_call {
Audio::play_sound(Sound::Joined, cx);
}
if let Some(live_kit) = this.live_kit.as_ref() {
let video_tracks =
@@ -1055,15 +1009,6 @@ impl Room {
}
RoomUpdate::SubscribedToRemoteAudioTrack(track, publication) => {
if let Some(live_kit) = &self.live_kit {
if live_kit.deafened {
track.stop();
cx.foreground_executor()
.spawn(publication.set_enabled(false))
.detach();
}
}
let user_id = track.publisher_id().parse()?;
let track_id = track.sid().to_string();
let participant = self
@@ -1182,10 +1127,19 @@ impl Room {
) -> Task<Result<Model<Project>>> {
let client = self.client.clone();
let user_store = self.user_store.clone();
let role = self.local_participant.role;
cx.emit(Event::RemoteProjectJoined { project_id: id });
cx.spawn(move |this, mut cx| async move {
let project =
Project::remote(id, client, user_store, language_registry, fs, cx.clone()).await?;
let project = Project::remote(
id,
client,
user_store,
language_registry,
fs,
role,
cx.clone(),
)
.await?;
this.update(&mut cx, |this, cx| {
this.joined_projects.retain(|project| {
@@ -1201,7 +1155,7 @@ impl Room {
})
}
pub fn share_project(
pub(crate) fn share_project(
&mut self,
project: Model<Project>,
cx: &mut ModelContext<Self>,
@@ -1303,18 +1257,19 @@ impl Room {
})
}
pub fn is_sharing_mic(&self) -> bool {
self.live_kit.as_ref().map_or(false, |live_kit| {
!matches!(live_kit.microphone_track, LocalTrack::None)
})
pub fn is_muted(&self) -> bool {
self.live_kit
.as_ref()
.map_or(true, |live_kit| match &live_kit.microphone_track {
LocalTrack::None => true,
LocalTrack::Pending { .. } => true,
LocalTrack::Published { track_publication } => track_publication.is_muted(),
})
}
pub fn is_muted(&self) -> bool {
self.live_kit.as_ref().map_or(false, |live_kit| {
matches!(live_kit.microphone_track, LocalTrack::None)
|| live_kit.muted_by_user
|| live_kit.deafened
})
pub fn read_only(&self) -> bool {
!(self.local_participant().role == proto::ChannelRole::Member
|| self.local_participant().role == proto::ChannelRole::Admin)
}
pub fn is_speaking(&self) -> bool {
@@ -1323,24 +1278,8 @@ impl Room {
.map_or(false, |live_kit| live_kit.speaking)
}
pub fn is_deafened(&self) -> Option<bool> {
self.live_kit.as_ref().map(|live_kit| live_kit.deafened)
}
pub fn can_use_microphone(&self) -> bool {
use proto::ChannelRole::*;
match self.local_participant.role {
Admin | Member | Talker => true,
Guest | Banned => false,
}
}
pub fn can_share_projects(&self) -> bool {
use proto::ChannelRole::*;
match self.local_participant.role {
Admin | Member => true,
Guest | Banned | Talker => false,
}
pub fn in_call(&self) -> bool {
self.live_kit.is_some()
}
#[track_caller]
@@ -1393,12 +1332,8 @@ impl Room {
Ok(publication) => {
if canceled {
live_kit.room.unpublish_track(publication);
live_kit.microphone_track = LocalTrack::None;
} else {
if live_kit.muted_by_user || live_kit.deafened {
cx.background_executor()
.spawn(publication.set_mute(true))
.detach();
}
live_kit.microphone_track = LocalTrack::Published {
track_publication: publication,
};
@@ -1502,50 +1437,140 @@ impl Room {
}
pub fn toggle_mute(&mut self, cx: &mut ModelContext<Self>) {
if let Some(live_kit) = self.live_kit.as_mut() {
// When unmuting, undeafen if the user was deafened before.
let was_deafened = live_kit.deafened;
if live_kit.muted_by_user
|| live_kit.deafened
|| matches!(live_kit.microphone_track, LocalTrack::None)
{
live_kit.muted_by_user = false;
live_kit.deafened = false;
} else {
live_kit.muted_by_user = true;
}
let muted = live_kit.muted_by_user;
let should_undeafen = was_deafened && !live_kit.deafened;
if let Some(task) = self.set_mute(muted, cx) {
task.detach_and_log_err(cx);
}
if should_undeafen {
if let Some(task) = self.set_deafened(false, cx) {
task.detach_and_log_err(cx);
}
}
let muted = !self.is_muted();
if let Some(task) = self.set_mute(muted, cx) {
task.detach_and_log_err(cx);
}
}
pub fn toggle_deafen(&mut self, cx: &mut ModelContext<Self>) {
if let Some(live_kit) = self.live_kit.as_mut() {
// When deafening, mute the microphone if it was not already muted.
// When un-deafening, unmute the microphone, unless it was explicitly muted.
let deafened = !live_kit.deafened;
live_kit.deafened = deafened;
let should_change_mute = !live_kit.muted_by_user;
pub fn join_call(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
if self.live_kit.is_some() {
return Task::ready(Ok(()));
}
if let Some(task) = self.set_deafened(deafened, cx) {
task.detach_and_log_err(cx);
}
let room = live_kit_client::Room::new();
let mut status = room.status();
// Consume the initial status of the room.
let _ = status.try_recv();
let _maintain_room = cx.spawn(|this, mut cx| async move {
while let Some(status) = status.next().await {
let this = if let Some(this) = this.upgrade() {
this
} else {
break;
};
if should_change_mute {
if let Some(task) = self.set_mute(deafened, cx) {
task.detach_and_log_err(cx);
if status == live_kit_client::ConnectionState::Disconnected {
this.update(&mut cx, |this, cx| this.leave(cx).log_err())
.ok();
break;
}
}
});
let _handle_updates = cx.spawn({
let room = room.clone();
move |this, mut cx| async move {
let mut updates = room.updates();
while let Some(update) = updates.next().await {
let this = if let Some(this) = this.upgrade() {
this
} else {
break;
};
this.update(&mut cx, |this, cx| {
this.live_kit_room_updated(update, cx).log_err()
})
.ok();
}
}
});
self.live_kit = Some(LiveKitRoom {
room: room.clone(),
screen_track: LocalTrack::None,
microphone_track: LocalTrack::None,
next_publish_id: 0,
speaking: false,
_maintain_room,
_handle_updates,
});
cx.spawn({
let client = self.client.clone();
let share_microphone = !self.read_only() && !Self::mute_on_join(cx);
let connection_info = self.live_kit_connection_info.clone();
let channel_id = self.channel_id;
move |this, mut cx| async move {
let connection_info = if let Some(connection_info) = connection_info {
connection_info.clone()
} else if let Some(channel_id) = channel_id {
if let Some(connection_info) = client
.request(proto::JoinChannelCall { channel_id })
.await?
.live_kit_connection_info
{
connection_info
} else {
return Err(anyhow!("failed to get connection info from server"));
}
} else {
return Err(anyhow!(
"tried to connect to livekit without connection info"
));
};
room.connect(&connection_info.server_url, &connection_info.token)
.await?;
let track_updates = this.update(&mut cx, |this, cx| {
Audio::play_sound(Sound::Joined, cx);
let Some(live_kit) = this.live_kit.as_mut() else {
return vec![];
};
let mut track_updates = Vec::new();
for participant in this.remote_participants.values() {
for publication in live_kit
.room
.remote_audio_track_publications(&participant.user.id.to_string())
{
track_updates.push(publication.set_enabled(true));
}
for track in participant.audio_tracks.values() {
track.start();
}
}
track_updates
})?;
if share_microphone {
this.update(&mut cx, |this, cx| this.share_microphone(cx))?
.await?
};
for result in futures::future::join_all(track_updates).await {
result?;
}
anyhow::Ok(())
}
})
}
pub fn leave_call(&mut self, cx: &mut ModelContext<Self>) {
Audio::play_sound(Sound::Leave, cx);
if let Some(channel_id) = self.channel_id() {
let client = self.client.clone();
cx.background_executor()
.spawn(client.request(proto::LeaveChannelCall { channel_id }))
.detach_and_log_err(cx);
self.live_kit.take();
self.live_kit_connection_info.take();
cx.notify();
} else {
self.leave(cx).detach_and_log_err(cx)
}
}
@@ -1576,40 +1601,6 @@ impl Room {
}
}
fn set_deafened(
&mut self,
deafened: bool,
cx: &mut ModelContext<Self>,
) -> Option<Task<Result<()>>> {
let live_kit = self.live_kit.as_mut()?;
cx.notify();
let mut track_updates = Vec::new();
for participant in self.remote_participants.values() {
for publication in live_kit
.room
.remote_audio_track_publications(&participant.user.id.to_string())
{
track_updates.push(publication.set_enabled(!deafened));
}
for track in participant.audio_tracks.values() {
if deafened {
track.stop();
} else {
track.start();
}
}
}
Some(cx.foreground_executor().spawn(async move {
for result in futures::future::join_all(track_updates).await {
result?;
}
Ok(())
}))
}
fn set_mute(
&mut self,
should_mute: bool,
@@ -1654,9 +1645,6 @@ struct LiveKitRoom {
room: Arc<live_kit_client::Room>,
screen_track: LocalTrack,
microphone_track: LocalTrack,
/// Tracks whether we're currently in a muted state due to auto-mute from deafening or manual mute performed by user.
muted_by_user: bool,
deafened: bool,
speaking: bool,
next_publish_id: usize,
_maintain_room: Task<()>,

View File

@@ -5,9 +5,6 @@ edition = "2021"
publish = false
license = "GPL-3.0-or-later"
[lints]
workspace = true
[lib]
path = "src/channel.rs"
doctest = false
@@ -20,18 +17,34 @@ anyhow.workspace = true
client.workspace = true
clock.workspace = true
collections.workspace = true
db.workspace = true
feature_flags.workspace = true
futures.workspace = true
gpui.workspace = true
image = "0.23"
language.workspace = true
lazy_static.workspace = true
log.workspace = true
parking_lot.workspace = true
postage.workspace = true
rand.workspace = true
release_channel.workspace = true
rpc.workspace = true
schemars.workspace = true
serde.workspace = true
serde_derive.workspace = true
settings.workspace = true
smallvec.workspace = true
smol.workspace = true
sum_tree.workspace = true
tempfile.workspace = true
text.workspace = true
thiserror.workspace = true
time.workspace = true
tiny_http = "0.8"
url.workspace = true
util.workspace = true
uuid.workspace = true
[dev-dependencies]
collections = { workspace = true, features = ["test-support"] }

View File

@@ -11,7 +11,7 @@ pub use channel_chat::{
mentions_to_proto, ChannelChat, ChannelChatEvent, ChannelMessage, ChannelMessageId,
MessageParams,
};
pub use channel_store::{Channel, ChannelEvent, ChannelMembership, ChannelStore};
pub use channel_store::{Channel, ChannelEvent, ChannelId, ChannelMembership, ChannelStore};
#[cfg(test)]
mod channel_store_tests;

View File

@@ -1,6 +1,6 @@
use crate::{Channel, ChannelStore};
use crate::{Channel, ChannelId, ChannelStore};
use anyhow::Result;
use client::{ChannelId, Client, Collaborator, UserStore, ZED_ALWAYS_ACTIVE};
use client::{Client, Collaborator, UserStore, ZED_ALWAYS_ACTIVE};
use collections::HashMap;
use gpui::{AppContext, AsyncAppContext, Context, EventEmitter, Model, ModelContext, Task};
use language::proto::serialize_version;
@@ -51,7 +51,7 @@ impl ChannelBuffer {
) -> Result<Model<Self>> {
let response = client
.request(proto::JoinChannelBuffer {
channel_id: channel.id.0,
channel_id: channel.id,
})
.await?;
let buffer_id = BufferId::new(response.buffer_id)?;
@@ -68,7 +68,7 @@ impl ChannelBuffer {
})?;
buffer.update(&mut cx, |buffer, cx| buffer.apply_ops(operations, cx))??;
let subscription = client.subscribe_to_entity(channel.id.0)?;
let subscription = client.subscribe_to_entity(channel.id)?;
anyhow::Ok(cx.new_model(|cx| {
cx.subscribe(&buffer, Self::on_buffer_update).detach();
@@ -97,7 +97,7 @@ impl ChannelBuffer {
}
self.client
.send(proto::LeaveChannelBuffer {
channel_id: self.channel_id.0,
channel_id: self.channel_id,
})
.log_err();
}
@@ -126,7 +126,7 @@ impl ChannelBuffer {
for (_, old_collaborator) in &self.collaborators {
if !new_collaborators.contains_key(&old_collaborator.peer_id) {
self.buffer.update(cx, |buffer, cx| {
buffer.remove_peer(old_collaborator.replica_id, cx)
buffer.remove_peer(old_collaborator.replica_id as u16, cx)
});
}
}
@@ -191,7 +191,7 @@ impl ChannelBuffer {
let operation = language::proto::serialize_operation(operation);
self.client
.send(proto::UpdateChannelBuffer {
channel_id: self.channel_id.0,
channel_id: self.channel_id,
operations: vec![operation],
})
.log_err();

View File

@@ -1,9 +1,9 @@
use crate::{Channel, ChannelStore};
use crate::{Channel, ChannelId, ChannelStore};
use anyhow::{anyhow, Result};
use client::{
proto,
user::{User, UserStore},
ChannelId, Client, Subscription, TypedEnvelope, UserId,
Client, Subscription, TypedEnvelope, UserId,
};
use collections::HashSet;
use futures::lock::Mutex;
@@ -104,12 +104,10 @@ impl ChannelChat {
mut cx: AsyncAppContext,
) -> Result<Model<Self>> {
let channel_id = channel.id;
let subscription = client.subscribe_to_entity(channel_id.0).unwrap();
let subscription = client.subscribe_to_entity(channel_id).unwrap();
let response = client
.request(proto::JoinChannelChat {
channel_id: channel_id.0,
})
.request(proto::JoinChannelChat { channel_id })
.await?;
let handle = cx.new_model(|cx| {
@@ -145,7 +143,7 @@ impl ChannelChat {
fn release(&mut self, _: &mut AppContext) {
self.rpc
.send(proto::LeaveChannelChat {
channel_id: self.channel_id.0,
channel_id: self.channel_id,
})
.log_err();
}
@@ -202,7 +200,7 @@ impl ChannelChat {
Ok(cx.spawn(move |this, mut cx| async move {
let outgoing_message_guard = outgoing_messages_lock.lock().await;
let request = rpc.request(proto::SendChannelMessage {
channel_id: channel_id.0,
channel_id,
body: message.text,
nonce: Some(nonce.into()),
mentions: mentions_to_proto(&message.mentions),
@@ -222,7 +220,7 @@ impl ChannelChat {
pub fn remove_message(&mut self, id: u64, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
let response = self.rpc.request(proto::RemoveChannelMessage {
channel_id: self.channel_id.0,
channel_id: self.channel_id,
message_id: id,
});
cx.spawn(move |this, mut cx| async move {
@@ -247,7 +245,7 @@ impl ChannelChat {
async move {
let response = rpc
.request(proto::GetChannelMessages {
channel_id: channel_id.0,
channel_id,
before_message_id,
})
.await?;
@@ -325,7 +323,7 @@ impl ChannelChat {
{
self.rpc
.send(proto::AckChannelMessage {
channel_id: self.channel_id.0,
channel_id: self.channel_id,
message_id: latest_message_id,
})
.ok();
@@ -403,11 +401,7 @@ impl ChannelChat {
let channel_id = self.channel_id;
cx.spawn(move |this, mut cx| {
async move {
let response = rpc
.request(proto::JoinChannelChat {
channel_id: channel_id.0,
})
.await?;
let response = rpc.request(proto::JoinChannelChat { channel_id }).await?;
Self::handle_loaded_messages(
this.clone(),
user_store.clone(),
@@ -424,7 +418,7 @@ impl ChannelChat {
for pending_message in pending_messages {
let request = rpc.request(proto::SendChannelMessage {
channel_id: channel_id.0,
channel_id,
body: pending_message.body,
mentions: mentions_to_proto(&pending_message.mentions),
nonce: Some(pending_message.nonce.into()),
@@ -467,7 +461,7 @@ impl ChannelChat {
if self.acknowledged_message_ids.insert(id) {
self.rpc
.send(proto::AckChannelMessage {
channel_id: self.channel_id.0,
channel_id: self.channel_id,
message_id: id,
})
.ok();
@@ -681,7 +675,7 @@ pub fn mentions_to_proto(mentions: &[(Range<usize>, UserId)]) -> Vec<proto::Chat
start: range.start as u64,
end: range.end as u64,
}),
user_id: *user_id,
user_id: *user_id as u64,
})
.collect()
}

View File

@@ -3,7 +3,7 @@ mod channel_index;
use crate::{channel_buffer::ChannelBuffer, channel_chat::ChannelChat, ChannelMessage};
use anyhow::{anyhow, Result};
use channel_index::ChannelIndex;
use client::{ChannelId, Client, ClientSettings, ProjectId, Subscription, User, UserId, UserStore};
use client::{Client, Subscription, User, UserId, UserStore};
use collections::{hash_map, HashMap, HashSet};
use futures::{channel::mpsc, future::Shared, Future, FutureExt, StreamExt};
use gpui::{
@@ -11,53 +11,35 @@ use gpui::{
Task, WeakModel,
};
use language::Capability;
use release_channel::RELEASE_CHANNEL;
use rpc::{
proto::{self, ChannelRole, ChannelVisibility},
TypedEnvelope,
};
use settings::Settings;
use std::{mem, sync::Arc, time::Duration};
use util::{async_maybe, maybe, ResultExt};
pub const RECONNECT_TIMEOUT: Duration = Duration::from_secs(30);
pub fn init(client: &Arc<Client>, user_store: Model<UserStore>, cx: &mut AppContext) {
let channel_store =
cx.new_model(|cx| ChannelStore::new(client.clone(), user_store.clone(), cx));
cx.set_global(GlobalChannelStore(channel_store));
}
#[derive(Debug, Clone, Default, PartialEq)]
pub const RECONNECT_TIMEOUT: Duration = Duration::from_secs(30);
pub type ChannelId = u64;
#[derive(Debug, Clone, Default)]
struct NotesVersion {
epoch: u64,
version: clock::Global,
}
#[derive(Debug, Clone)]
pub struct HostedProject {
project_id: ProjectId,
channel_id: ChannelId,
name: SharedString,
_visibility: proto::ChannelVisibility,
}
impl From<proto::HostedProject> for HostedProject {
fn from(project: proto::HostedProject) -> Self {
Self {
project_id: ProjectId(project.project_id),
channel_id: ChannelId(project.channel_id),
_visibility: project.visibility(),
name: project.name.into(),
}
}
}
pub struct ChannelStore {
pub channel_index: ChannelIndex,
channel_invitations: Vec<Arc<Channel>>,
channel_participants: HashMap<ChannelId, Vec<Arc<User>>>,
channel_states: HashMap<ChannelId, ChannelState>,
hosted_projects: HashMap<ProjectId, HostedProject>,
outgoing_invites: HashSet<(ChannelId, UserId)>,
update_channels_tx: mpsc::UnboundedSender<proto::UpdateChannels>,
@@ -76,31 +58,29 @@ pub struct Channel {
pub id: ChannelId,
pub name: SharedString,
pub visibility: proto::ChannelVisibility,
pub parent_path: Vec<ChannelId>,
pub parent_path: Vec<u64>,
}
#[derive(Default, Debug)]
#[derive(Default)]
pub struct ChannelState {
latest_chat_message: Option<u64>,
latest_notes_version: NotesVersion,
observed_notes_version: NotesVersion,
latest_notes_versions: Option<NotesVersion>,
observed_chat_message: Option<u64>,
observed_notes_versions: Option<NotesVersion>,
role: Option<ChannelRole>,
projects: HashSet<ProjectId>,
}
impl Channel {
pub fn link(&self, cx: &AppContext) -> String {
format!(
"{}/channel/{}-{}",
ClientSettings::get_global(cx).server_url,
Self::slug(&self.name),
self.id
)
pub fn link(&self) -> String {
RELEASE_CHANNEL.link_prefix().to_owned()
+ "channel/"
+ &Self::slug(&self.name)
+ "-"
+ &self.id.to_string()
}
pub fn notes_link(&self, heading: Option<String>, cx: &AppContext) -> String {
self.link(cx)
pub fn notes_link(&self, heading: Option<String>) -> String {
self.link()
+ "/notes"
+ &heading
.map(|h| format!("#{}", Self::slug(&h)))
@@ -112,7 +92,10 @@ impl Channel {
}
pub fn root_id(&self) -> ChannelId {
self.parent_path.first().copied().unwrap_or(self.id)
self.parent_path
.first()
.map(|id| *id as ChannelId)
.unwrap_or(self.id)
}
pub fn slug(str: &str) -> String {
@@ -137,8 +120,7 @@ impl ChannelMembership {
proto::ChannelRole::Admin => 0,
proto::ChannelRole::Member => 1,
proto::ChannelRole::Banned => 2,
proto::ChannelRole::Talker => 3,
proto::ChannelRole::Guest => 4,
proto::ChannelRole::Guest => 3,
},
kind_order: match self.kind {
proto::channel_member::Kind::Member => 0,
@@ -216,7 +198,6 @@ impl ChannelStore {
channel_invitations: Vec::default(),
channel_index: ChannelIndex::default(),
channel_participants: Default::default(),
hosted_projects: Default::default(),
outgoing_invites: Default::default(),
opened_buffers: Default::default(),
opened_chats: Default::default(),
@@ -303,19 +284,6 @@ impl ChannelStore {
self.channel_index.by_id().get(&channel_id)
}
pub fn projects_for_id(&self, channel_id: ChannelId) -> Vec<(SharedString, ProjectId)> {
let mut projects: Vec<(SharedString, ProjectId)> = self
.channel_states
.get(&channel_id)
.map(|state| state.projects.clone())
.unwrap_or_default()
.into_iter()
.flat_map(|id| Some((self.hosted_projects.get(&id)?.name.clone(), id)))
.collect();
projects.sort();
projects
}
pub fn has_open_channel_buffer(&self, channel_id: ChannelId, _cx: &AppContext) -> bool {
if let Some(buffer) = self.opened_buffers.get(&channel_id) {
if let OpenedModelHandle::Open(buffer) = buffer {
@@ -380,21 +348,6 @@ impl ChannelStore {
.is_some_and(|state| state.has_new_messages())
}
pub fn last_acknowledge_message_id(&self, channel_id: ChannelId) -> Option<u64> {
self.channel_states.get(&channel_id).and_then(|state| {
if let Some(last_message_id) = state.latest_chat_message {
if state
.last_acknowledged_message_id()
.is_some_and(|id| id < last_message_id)
{
return state.last_acknowledged_message_id();
}
}
None
})
}
pub fn acknowledge_message_id(
&mut self,
channel_id: ChannelId,
@@ -590,19 +543,16 @@ impl ChannelStore {
cx: &mut ModelContext<Self>,
) -> Task<Result<ChannelId>> {
let client = self.client.clone();
let name = name.trim_start_matches('#').to_owned();
let name = name.trim_start_matches("#").to_owned();
cx.spawn(move |this, mut cx| async move {
let response = client
.request(proto::CreateChannel {
name,
parent_id: parent_id.map(|cid| cid.0),
})
.request(proto::CreateChannel { name, parent_id })
.await?;
let channel = response
.channel
.ok_or_else(|| anyhow!("missing channel in response"))?;
let channel_id = ChannelId(channel.id);
let channel_id = channel.id;
this.update(&mut cx, |this, cx| {
let task = this.update_channels(
@@ -634,10 +584,7 @@ impl ChannelStore {
let client = self.client.clone();
cx.spawn(move |_, _| async move {
let _ = client
.request(proto::MoveChannel {
channel_id: channel_id.0,
to: to.0,
})
.request(proto::MoveChannel { channel_id, to })
.await?;
Ok(())
@@ -654,7 +601,7 @@ impl ChannelStore {
cx.spawn(move |_, _| async move {
let _ = client
.request(proto::SetChannelVisibility {
channel_id: channel_id.0,
channel_id,
visibility: visibility.into(),
})
.await?;
@@ -679,7 +626,7 @@ impl ChannelStore {
cx.spawn(move |this, mut cx| async move {
let result = client
.request(proto::InviteChannelMember {
channel_id: channel_id.0,
channel_id,
user_id,
role: role.into(),
})
@@ -711,7 +658,7 @@ impl ChannelStore {
cx.spawn(move |this, mut cx| async move {
let result = client
.request(proto::RemoveChannelMember {
channel_id: channel_id.0,
channel_id,
user_id,
})
.await;
@@ -741,7 +688,7 @@ impl ChannelStore {
cx.spawn(move |this, mut cx| async move {
let result = client
.request(proto::SetChannelMemberRole {
channel_id: channel_id.0,
channel_id,
user_id,
role: role.into(),
})
@@ -767,10 +714,7 @@ impl ChannelStore {
let name = new_name.to_string();
cx.spawn(move |this, mut cx| async move {
let channel = client
.request(proto::RenameChannel {
channel_id: channel_id.0,
name,
})
.request(proto::RenameChannel { channel_id, name })
.await?
.channel
.ok_or_else(|| anyhow!("missing channel in response"))?;
@@ -803,10 +747,7 @@ impl ChannelStore {
let client = self.client.clone();
cx.background_executor().spawn(async move {
client
.request(proto::RespondToChannelInvite {
channel_id: channel_id.0,
accept,
})
.request(proto::RespondToChannelInvite { channel_id, accept })
.await?;
Ok(())
})
@@ -821,9 +762,7 @@ impl ChannelStore {
let user_store = self.user_store.downgrade();
cx.spawn(move |_, mut cx| async move {
let response = client
.request(proto::GetChannelMembers {
channel_id: channel_id.0,
})
.request(proto::GetChannelMembers { channel_id })
.await?;
let user_ids = response.members.iter().map(|m| m.user_id).collect();
@@ -837,10 +776,12 @@ impl ChannelStore {
Ok(users
.into_iter()
.zip(response.members)
.map(|(user, member)| ChannelMembership {
user,
role: member.role(),
kind: member.kind(),
.filter_map(|(user, member)| {
Some(ChannelMembership {
user,
role: member.role(),
kind: member.kind(),
})
})
.collect())
})
@@ -849,11 +790,7 @@ impl ChannelStore {
pub fn remove_channel(&self, channel_id: ChannelId) -> impl Future<Output = Result<()>> {
let client = self.client.clone();
async move {
client
.request(proto::DeleteChannel {
channel_id: channel_id.0,
})
.await?;
client.request(proto::DeleteChannel { channel_id }).await?;
Ok(())
}
}
@@ -890,23 +827,19 @@ impl ChannelStore {
for buffer_version in message.payload.observed_channel_buffer_version {
let version = language::proto::deserialize_version(&buffer_version.version);
this.acknowledge_notes_version(
ChannelId(buffer_version.channel_id),
buffer_version.channel_id,
buffer_version.epoch,
&version,
cx,
);
}
for message_id in message.payload.observed_channel_message_id {
this.acknowledge_message_id(
ChannelId(message_id.channel_id),
message_id.message_id,
cx,
);
this.acknowledge_message_id(message_id.channel_id, message_id.message_id, cx);
}
for membership in message.payload.channel_memberships {
if let Some(role) = ChannelRole::from_i32(membership.role) {
this.channel_states
.entry(ChannelId(membership.channel_id))
.entry(membership.channel_id)
.or_insert_with(|| ChannelState::default())
.set_role(role)
}
@@ -939,7 +872,7 @@ impl ChannelStore {
let channel_buffer = buffer.read(cx);
let buffer = channel_buffer.buffer().read(cx);
buffer_versions.push(proto::ChannelBufferVersion {
channel_id: channel_buffer.channel_id.0,
channel_id: channel_buffer.channel_id,
epoch: channel_buffer.epoch(),
version: language::proto::serialize_version(&buffer.version()),
});
@@ -970,7 +903,7 @@ impl ChannelStore {
if let Some(remote_buffer) = response
.buffers
.iter_mut()
.find(|buffer| buffer.channel_id == channel_id.0)
.find(|buffer| buffer.channel_id == channel_id)
{
let channel_id = channel_buffer.channel_id;
let remote_version =
@@ -1006,7 +939,7 @@ impl ChannelStore {
{
client
.send(proto::UpdateChannelBuffer {
channel_id: channel_id.0,
channel_id,
operations: chunk,
})
.ok();
@@ -1061,12 +994,12 @@ impl ChannelStore {
) -> Option<Task<Result<()>>> {
if !payload.remove_channel_invitations.is_empty() {
self.channel_invitations
.retain(|channel| !payload.remove_channel_invitations.contains(&channel.id.0));
.retain(|channel| !payload.remove_channel_invitations.contains(&channel.id));
}
for channel in payload.channel_invitations {
match self
.channel_invitations
.binary_search_by_key(&channel.id, |c| c.id.0)
.binary_search_by_key(&channel.id, |c| c.id)
{
Ok(ix) => {
Arc::make_mut(&mut self.channel_invitations[ix]).name = channel.name.into()
@@ -1074,14 +1007,10 @@ impl ChannelStore {
Err(ix) => self.channel_invitations.insert(
ix,
Arc::new(Channel {
id: ChannelId(channel.id),
id: channel.id,
visibility: channel.visibility(),
name: channel.name.into(),
parent_path: channel
.parent_path
.into_iter()
.map(|cid| ChannelId(cid))
.collect(),
parent_path: channel.parent_path,
}),
),
}
@@ -1090,27 +1019,20 @@ impl ChannelStore {
let channels_changed = !payload.channels.is_empty()
|| !payload.delete_channels.is_empty()
|| !payload.latest_channel_message_ids.is_empty()
|| !payload.latest_channel_buffer_versions.is_empty()
|| !payload.hosted_projects.is_empty()
|| !payload.deleted_hosted_projects.is_empty();
|| !payload.latest_channel_buffer_versions.is_empty();
if channels_changed {
if !payload.delete_channels.is_empty() {
let delete_channels: Vec<ChannelId> = payload
.delete_channels
.into_iter()
.map(|cid| ChannelId(cid))
.collect();
self.channel_index.delete_channels(&delete_channels);
self.channel_index.delete_channels(&payload.delete_channels);
self.channel_participants
.retain(|channel_id, _| !delete_channels.contains(&channel_id));
.retain(|channel_id, _| !&payload.delete_channels.contains(channel_id));
for channel_id in &delete_channels {
for channel_id in &payload.delete_channels {
let channel_id = *channel_id;
if payload
.channels
.iter()
.any(|channel| channel.id == channel_id.0)
.any(|channel| channel.id == channel_id)
{
continue;
}
@@ -1126,7 +1048,7 @@ impl ChannelStore {
let mut index = self.channel_index.bulk_insert();
for channel in payload.channels {
let id = ChannelId(channel.id);
let id = channel.id;
let channel_changed = index.insert(channel);
if channel_changed {
@@ -1141,45 +1063,17 @@ impl ChannelStore {
for latest_buffer_version in payload.latest_channel_buffer_versions {
let version = language::proto::deserialize_version(&latest_buffer_version.version);
self.channel_states
.entry(ChannelId(latest_buffer_version.channel_id))
.entry(latest_buffer_version.channel_id)
.or_default()
.update_latest_notes_version(latest_buffer_version.epoch, &version)
}
for latest_channel_message in payload.latest_channel_message_ids {
self.channel_states
.entry(ChannelId(latest_channel_message.channel_id))
.entry(latest_channel_message.channel_id)
.or_default()
.update_latest_message_id(latest_channel_message.message_id);
}
for hosted_project in payload.hosted_projects {
let hosted_project: HostedProject = hosted_project.into();
if let Some(old_project) = self
.hosted_projects
.insert(hosted_project.project_id, hosted_project.clone())
{
self.channel_states
.entry(old_project.channel_id)
.or_default()
.remove_hosted_project(old_project.project_id);
}
self.channel_states
.entry(hosted_project.channel_id)
.or_default()
.add_hosted_project(hosted_project.project_id);
}
for hosted_project_id in payload.deleted_hosted_projects {
let hosted_project_id = ProjectId(hosted_project_id);
if let Some(old_project) = self.hosted_projects.remove(&hosted_project_id) {
self.channel_states
.entry(old_project.channel_id)
.or_default()
.remove_hosted_project(old_project.project_id);
}
}
}
cx.notify();
@@ -1219,7 +1113,7 @@ impl ChannelStore {
participants.sort_by_key(|u| u.id);
this.channel_participants
.insert(ChannelId(entry.channel_id), participants);
.insert(entry.channel_id, participants);
}
cx.notify();
@@ -1234,12 +1128,19 @@ impl ChannelState {
}
fn has_channel_buffer_changed(&self) -> bool {
self.latest_notes_version.epoch > self.observed_notes_version.epoch
|| (self.latest_notes_version.epoch == self.observed_notes_version.epoch
&& self
.latest_notes_version
.version
.changed_since(&self.observed_notes_version.version))
if let Some(latest_version) = &self.latest_notes_versions {
if let Some(observed_version) = &self.observed_notes_versions {
latest_version.epoch > observed_version.epoch
|| (latest_version.epoch == observed_version.epoch
&& latest_version
.version
.changed_since(&observed_version.version))
} else {
true
}
} else {
false
}
}
fn has_new_messages(&self) -> bool {
@@ -1251,10 +1152,6 @@ impl ChannelState {
})
}
fn last_acknowledged_message_id(&self) -> Option<u64> {
self.observed_chat_message
}
fn acknowledge_message_id(&mut self, message_id: u64) {
let observed = self.observed_chat_message.get_or_insert(message_id);
*observed = (*observed).max(message_id);
@@ -1266,32 +1163,28 @@ impl ChannelState {
}
fn acknowledge_notes_version(&mut self, epoch: u64, version: &clock::Global) {
if self.observed_notes_version.epoch == epoch {
self.observed_notes_version.version.join(version);
} else {
self.observed_notes_version = NotesVersion {
epoch,
version: version.clone(),
};
if let Some(existing) = &mut self.observed_notes_versions {
if existing.epoch == epoch {
existing.version.join(version);
return;
}
}
self.observed_notes_versions = Some(NotesVersion {
epoch,
version: version.clone(),
});
}
fn update_latest_notes_version(&mut self, epoch: u64, version: &clock::Global) {
if self.latest_notes_version.epoch == epoch {
self.latest_notes_version.version.join(version);
} else {
self.latest_notes_version = NotesVersion {
epoch,
version: version.clone(),
};
if let Some(existing) = &mut self.latest_notes_versions {
if existing.epoch == epoch {
existing.version.join(version);
return;
}
}
}
fn add_hosted_project(&mut self, project_id: ProjectId) {
self.projects.insert(project_id);
}
fn remove_hosted_project(&mut self, project_id: ProjectId) {
self.projects.remove(&project_id);
self.latest_notes_versions = Some(NotesVersion {
epoch,
version: version.clone(),
});
}
}

Some files were not shown because too many files have changed in this diff Show More